Appearance
SILVIA Core – ApiApp Reference
Version: 3.1
Namespace: CognitiveCode.Silvia.Api
Multi-Modal Output Orchestration
The Innovation: One Behavior, Many Channels
SILVIA ApiApp doesn't just output text—it's a multi-modal orchestration layer that routes a single AI response across 7 independent output channels, each with its own FIFO queue, enabling simultaneous chat, TTS, animation, diagnostics, data, and application control from a single exuder.
Traditional Chatbot Output (What Everyone Else Does)
User Input → AI Processing → Single Text Response
↓
Console/UI DisplayProblems:
- Text-Only: No voice, animation, or rich output
- Single-Modal: Can't route different content to different channels
- Rigid: No separation between UI text and TTS pronunciation
- No Control Flow: AI can't send commands to application layer
- Memory Leaks: Unbounded output buffers crash on long sessions
The ApiApp Architecture
Multi-Modal Output Stacks (FIFO Queues)
GetResponseManaged()
↓
┌──────────────┴──────────────┐
│ SILVIA CORE INFERENCE │
│ (Single Behavior Executes) │
└──────────────┬──────────────┘
↓
┌───────────────────┴───────────────────┐
│ OUTPUT STACK DISTRIBUTION │
└───────────────────┬───────────────────┘
↓
┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
TEXT VOICE PAGER DIAG APP MSG DATA ERROR SOCKET
Stack Stack Stack Stack Stack Stack Stack Stack
│ │ │ │ │ │ │ │
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
GetText GetVoice GetPager GetDiag GetAppMsg GetData GetError GetSocket
Output Output Tags Output Message Output Output OutputWhat This Enables
From ONE exuder in ONE behavior, you can output:
- Text Output:
"Hello there!"→ Chat UI display - Voice Output:
"<prosody rate='fast'>Hello there!</prosody>"→ TTS with SSML - PAGER Tags:
"<Gesture-Wave/><Expression-Smile/>"→ Avatar animation - Data Output:
"last_greeting_time=14:32:00"→ Application variables - App Message:
"SHOW_NOTIFICATION"→ Application control signals - Diagnostic:
"[DEBUG] Greeting behavior executed, weight=0.95"→ Logging - Socket Output: Custom network protocol messages
- Error Output: Exception and error reporting
This is why SILVIA can power everything from chatbots to industrial IoT to game NPCs.
Best Practices: Output Stack Management
The Queue Pattern (Recommended)
Problem: GetResponseManaged() pushes all outputs to stacks at once. How do you synchronize chat, TTS, and animation without race conditions?
Solution: Use parallel queues to maintain synchronization between output channels.
Production-Ready Pattern (From SILVIA Studio)
csharp
public class SilviaOutputManager {
// Synchronized parallel queues - indices match across all lists
public List<string> utterancesQueue = new List<string>(); // Chat text
public List<string> voiceOutputQueue = new List<string>(); // TTS text
public List<string> pagerTagsQueue = new List<string>(); // Animation
public List<float> speechTimesQueue = new List<float>(); // Duration estimates
/// <summary>
/// PATTERN 1: Poll and Enqueue All Outputs
/// Called every frame or on timer interval
/// </summary>
private void CheckSilviaListener() {
if (Core == null) return;
// ALWAYS update timers first (critical for single-threaded platforms like mobile)
Core.RefreshTimers(DateTime.Now.Ticks);
string textOutput = null;
string voiceOutput = null;
string pagerTagsOutput = null;
string diagOutput = null;
string appMessage = null;
// TEXT OUTPUT - Poll until empty
while (!string.IsNullOrEmpty(textOutput = Core.ApiApp().GetTextOutput())) {
// Strip PAGER tags for display (they're in pagerTagsQueue)
string chatText = StripAllTagsFromText(textOutput).Trim();
// VOICE OUTPUT - Get TTS pronunciation
voiceOutput = Core.ApiApp().GetVoiceOutput();
if (string.IsNullOrEmpty(voiceOutput)) voiceOutput = chatText;
voiceOutput = StripNonSSMLTagsFromText(voiceOutput); // Keep SSML, remove PAGER
// PAGER TAGS - Get animation/expression commands
pagerTagsOutput = Core.ApiApp().GetPagerTagsOutput();
// SPEECH TIME - Calculate timing for synchronization
float speechTime = Core.ApiApp().GetApproximateSpeechLength(voiceOutput);
// ENQUEUE ALL 4 IN PARALLEL - indices remain synchronized
utterancesQueue.Add(chatText);
voiceOutputQueue.Add(voiceOutput);
pagerTagsQueue.Add(pagerTagsOutput ?? "");
speechTimesQueue.Add(speechTime);
// Response metadata for debugging
int behaviorID = Core.ApiBrain().GetResponseBehaviorID(0);
int absorberID = Core.ApiBrain().GetResponseAbsorberID(0);
double weight = Core.ApiBrain().GetResponseWeight(0);
Debug.Log($"Response from Behavior {behaviorID}, Absorber {absorberID}, Weight {weight}");
}
// DIAGNOSTIC OUTPUT - Poll if debugging enabled
if (debugMode) {
while (!string.IsNullOrEmpty(diagOutput = Core.ApiApp().GetDiagOutput())) {
Debug.Log($"[SILVIA DIAG] {diagOutput}");
}
}
// APPLICATION MESSAGE - Poll for app control commands
while (!string.IsNullOrEmpty(appMessage = Core.ApiApp().GetApplicationMessage())) {
HandleApplicationMessage(appMessage); // Your custom handler
}
// DATA OUTPUT - Poll for variable updates
string behaviorData = Core.ApiApp().GetBehaviorDataOutput();
string absorberData = Core.ApiApp().GetAbsorberDataOutput();
string exuderData = Core.ApiApp().GetExuderDataOutput();
if (!string.IsNullOrEmpty(behaviorData)) ParseDataOutput(behaviorData);
}
/// <summary>
/// PATTERN 2: Dequeue and Execute Synchronized Outputs
/// Called when ready to display next response
/// </summary>
private IEnumerator ProcessNextOutput() {
// Wait until TTS is not busy
while (utterancesQueue.Count == 0 || ttsEngine.IsBusy) {
yield return null;
}
// Dequeue all 4 synchronized outputs atomically
string chatText = utterancesQueue[0];
string ttsText = voiceOutputQueue[0];
string pagerTags = pagerTagsQueue[0];
float speechDuration = speechTimesQueue[0];
utterancesQueue.RemoveAt(0);
voiceOutputQueue.RemoveAt(0);
pagerTagsQueue.RemoveAt(0);
speechTimesQueue.RemoveAt(0);
// Display chat text immediately
chatLog.AppendLine(chatText);
// Parse and schedule PAGER tags for avatar animation
List<string> tags = ParsePagerTags(pagerTags);
foreach (string tag in tags) {
pagerTagParser.ExecuteTag(tag, speechDuration);
}
// Start TTS with estimated duration for sync
ttsEngine.Speak(ttsText, speechDuration);
// If more in queue, continue after this finishes
if (utterancesQueue.Count > 0) {
StartCoroutine(ProcessNextOutput());
}
}
}Why This Pattern Works
Synchronization:
- Parallel Queues: Text, Voice, PAGER tags, and timing stay synchronized by index
- Atomic Dequeue: All 4 channels dequeued together prevents desync
- Estimated Timing:
GetApproximateSpeechLength()provides duration for animation sync
Performance:
- Non-Blocking Polling:
while()loops consume stack until empty each frame - Bounded Queues:
SetStackSize(40)prevents memory overflow on long sessions - Lazy Execution: Outputs queue up, execute when ready (TTS not busy)
Multimodal Flexibility:
- Different Content Per Channel: Display text ≠ TTS pronunciation
- Tag Separation: PAGER tags stripped from chat, routed to animation
- Conditional Routing: Diagnostics only when debugging, socket only when connected
Core API Classes
SilviaApiApp
Primary interface for output management, TTS delegation, and application control.
Key Features:
- 7 independent FIFO output stacks with configurable size limits
- TTS delegation for any voice synthesis engine (Piper, Azure, ElevenLabs, etc.)
- Secure command completion with NLP-based auto-suggest (3.1 NEW)
- Application focus and listening state management
- PAGER tag routing for animation/expression control
- Speech timing estimation for synchronization
Access:
csharp
SilviaApiApp api = Core.ApiApp();API Methods
Output Stack Management
SetStackSize(int stackSize)
Sets maximum size for all FIFO output stacks.
Purpose:
- Memory Protection: Prevents unbounded growth on long-running sessions
- Performance: Limits iteration overhead when polling stacks
- Overflow Handling: Oldest items dropped when limit reached
Usage:
csharp
// Default is 40, increase for high-throughput applications
api.SetStackSize(100);Parameters:
stackSize(int): Maximum items per stack (must be > 0)
Returns: bool - True if set successfully
Best Practice:
csharp
// For chatbots: 20-40 is fine (short bursts)
api.SetStackSize(40);
// For IoT telemetry: 500+ for burst buffering
api.SetStackSize(500);
// For industrial logging: 2000+ with persistent queue
api.SetStackSize(2000);GetStackSize()
Returns current stack size limit.
Usage:
csharp
int currentLimit = api.GetStackSize();Returns: int - Current maximum stack size
Text Output Stack
SetTextOutput(string output)
Pushes text to the Text Output FIFO stack.
Purpose:
- Chat Display: Primary text for UI chat logs
- Transcript Logging: Text version of AI responses
- Screen Readers: Accessibility text output
Usage:
csharp
bool success = api.SetTextOutput("Hello, how can I help?");Parameters:
output(string): Text to push to stack
Returns: bool - True if pushed successfully, false if disabled or null
Notes:
- Auto-Stripping: All PAGER tags and SSML removed automatically
- FIFO: Retrieved in order pushed via
GetTextOutput() - Bounded: Oldest item dropped if stack full
GetTextOutput()
Retrieves and removes the first text from the Text Output stack.
Purpose:
- Poll-Based Retrieval: Check for new AI responses each frame/interval
- Destructive Read: Item removed from stack after retrieval
Usage:
csharp
string text = null;
while (!string.IsNullOrEmpty(text = api.GetTextOutput())) {
chatLog.AppendLine(text);
}Returns: string - First text in stack, or null if empty/disabled
Best Practice:
csharp
// WRONG: Single read might miss multiple outputs
string text = api.GetTextOutput();
if (!string.IsNullOrEmpty(text)) { ... }
// CORRECT: while() loop drains entire stack
while (!string.IsNullOrEmpty(text = api.GetTextOutput())) {
ProcessText(text);
}ClearTextOutput()
Clears all text from the Text Output stack.
Purpose:
- Interrupt Handler: Clear pending output when user interrupts
- Context Switch: Flush old outputs when changing conversation
- Emergency Stop: Cancel all pending AI responses
Usage:
csharp
// User pressed ESC - cancel all pending speech
if (Input.GetKeyDown(KeyCode.Escape)) {
api.ClearTextOutput();
api.ClearVoiceOutput();
api.ClearPagerTags();
ttsEngine.Stop();
}Returns: bool - True if cleared, false if already empty
EnableTextOutput(bool enabled)
Enables or disables the Text Output stack.
Purpose:
- Channel Control: Selectively disable output channels
- Performance: Skip unused stack operations
- Silent Mode: Disable chat display, keep voice active
Usage:
csharp
// Voice-only mode (no text display)
api.EnableTextOutput(false);
api.EnableVoiceOutput(true);Parameters:
enabled(bool): True to enable, false to disable
Default: true
TextOutputEnabled()
Returns enabled state of Text Output stack.
Usage:
csharp
if (api.TextOutputEnabled()) {
string text = api.GetTextOutput();
}Returns: bool - True if enabled
Voice Output Stack
SetVoiceOutput(string output)
Pushes TTS text to the Voice Output FIFO stack.
Purpose:
- TTS Pronunciation: Text optimized for speech synthesis
- SSML Support: Preserve SSML tags for prosody/voice control
- Different from Text: Voice can have different pronunciation than displayed text
Usage:
csharp
// Text: "Dr. Smith called at 3PM"
// Voice: "Doctor Smith called at 3 P M" (spelled out for TTS)
api.SetVoiceOutput("<prosody rate='fast'>Doctor Smith called at 3 P M</prosody>");Parameters:
output(string): TTS text with optional SSML tags
Returns: bool - True if pushed successfully
Notes:
- SSML Preserved:
<prosody>,<break>, etc. kept for TTS engines - PAGER Tags Stripped: Animation tags removed automatically
- Different Content: Can differ from
SetTextOutput()for same response
GetVoiceOutput()
Retrieves and removes the first TTS text from the Voice Output stack.
Purpose:
- TTS Consumption: Feed to speech synthesis engine
- Synchronized with Text: Same FIFO order as Text Output
Usage:
csharp
string voice = null;
while (!string.IsNullOrEmpty(voice = api.GetVoiceOutput())) {
ttsEngine.Speak(voice);
}Returns: string - First voice output in stack, or null if empty/disabled
ClearVoiceOutput()
Clears all TTS text from the Voice Output stack.
Usage:
csharp
api.ClearVoiceOutput(); // Stop all pending TTSReturns: bool - True if cleared
EnableVoiceOutput(bool enabled) / VoiceOutputEnabled()
Enable/disable and check Voice Output stack state.
Usage:
csharp
api.EnableVoiceOutput(true);
bool enabled = api.VoiceOutputEnabled();StartSpeaking(string utterance)
Alias for SetVoiceOutput() - pushes TTS text to stack.
Usage:
csharp
api.StartSpeaking("Hello there!");PAGER Tags Output Stack
SetPagerTagsOutput(string tags)
Pushes PAGER tags to the PAGER Tags FIFO stack.
Purpose:
- Avatar Animation: Control gestures, expressions, poses
- Application Commands: Custom XML-style control messages
- Synchronized Performance: Tags queued in sync with Text/Voice
Usage:
csharp
string tags = "<Gesture-Wave/><Expression-Smile/><Pose-Casual/>";
api.SetPagerTagsOutput(tags);Parameters:
tags(string): PAGER tag XML string
Returns: bool - True if pushed successfully
Tag Format:
xml
<TagName-Subtype field1=value1, field2=value2/>Examples:
csharp
// Facial expression
"<Expression-Smile intensity=0.8/>"
// Body gesture
"<Gesture-Wave hand=right, duration=2.0/>"
// Camera control
"<Camera-LookAt target=speaker, speed=1.5/>"
// Custom application command
"<GameEvent-SpawnItem type=coin, position=?10,5,0/>"GetPagerTagsOutput()
Retrieves and removes the first PAGER tag string from stack.
Purpose:
- Animation Consumption: Feed to avatar animation system
- Synchronized Execution: Execute in sync with TTS timing
Usage:
csharp
string tags = null;
while (!string.IsNullOrEmpty(tags = api.GetPagerTagsOutput())) {
List<string> parsed = ParsePagerTags(tags);
float speechDuration = speechTimesQueue[currentIndex];
foreach (string tag in parsed) {
pagerParser.ExecuteTag(tag, speechDuration);
}
}Returns: string - First PAGER tag string in stack, or null if empty
Best Practice:
csharp
// Parse tags from string format
List<string> ParsePagerTags(string tagsString) {
List<string> tags = new List<string>();
int startIdx = 0;
while ((startIdx = tagsString.IndexOf('<', startIdx)) != -1) {
int endIdx = tagsString.IndexOf("/>");
if (endIdx == -1) break;
string tag = tagsString.Substring(startIdx, endIdx + 2 - startIdx);
tags.Add(tag);
tagsString = tagsString.Substring(endIdx + 2);
startIdx = 0;
}
return tags;
}ClearPagerTags()
Clears all PAGER tags from stack.
Usage:
csharp
// Stop all pending animations
api.ClearPagerTags();
avatarController.ResetToIdle();Returns: bool - True if cleared
Diagnostic Output Stack
SetDiagOutput(string output)
Pushes diagnostic message to Diagnostic Output stack.
Purpose:
- Debug Logging: Internal AI decision diagnostics
- Performance Metrics: Response times, weights, behavior IDs
- Development Tools: Trace execution flow
Usage:
csharp
api.SetDiagOutput($"[DEBUG] Matched behavior ID {behaviorID}, weight {weight}");GetDiagOutput()
Retrieves diagnostic messages.
Usage:
csharp
string diag = null;
while (!string.IsNullOrEmpty(diag = api.GetDiagOutput())) {
Debug.Log($"[SILVIA] {diag}");
}ClearDiagOutput()
Clears diagnostic stack.
EnableDiagOutput(bool enabled) / DiagOutputEnabled()
Enable/disable diagnostic output.
Usage:
csharp
api.EnableDiagOutput(debugMode);Application Message Stack
SetApplicationMessage(string message)
Pushes application control message to Application Message stack.
Purpose:
- Application Commands: AI-triggered app control signals
- UI Control: Show/hide panels, change scenes, trigger events
- Game Events: AI-driven game state changes
Usage:
csharp
// From behavior script: trigger UI action
api.SetApplicationMessage("SHOW_INVENTORY");GetApplicationMessage()
Retrieves application messages.
Usage:
csharp
string msg = null;
while (!string.IsNullOrEmpty(msg = api.GetApplicationMessage())) {
switch (msg) {
case "SHOW_INVENTORY":
inventoryPanel.SetActive(true);
break;
case "PLAY_CUTSCENE":
cutsceneManager.Play("intro");
break;
case "UNLOCK_ACHIEVEMENT":
achievementManager.Unlock("first_conversation");
break;
}
}ClearApplicationMessage()
Clears application message stack.
EnableApplicationMessage(bool enabled) / ApplicationMessageEnabled()
Enable/disable application messages.
Data Output Stacks
SILVIA 3.1 provides three separate data stacks for different scopes:
SetBehaviorDataOutput(string data)
GetBehaviorDataOutput()
Behavior-scoped data output (e.g., metadata, state).
SetAbsorberDataOutput(string data)
GetAbsorberDataOutput()
Absorber-scoped data output (e.g., pattern match details).
SetExuderDataOutput(string data)
GetExuderDataOutput()
Exuder-scoped data output (e.g., execution parameters).
Usage Example:
csharp
// From behavior script
api.SetExuderDataOutput($"last_greeting_time={DateTime.Now}");
// From application
string data = api.GetExuderDataOutput();
if (!string.IsNullOrEmpty(data)) {
// Parse: "last_greeting_time=14:32:00"
string[] parts = data.Split('=');
DateTime lastGreeting = DateTime.Parse(parts[1]);
}EnableDataOutput(bool enabled) / DataOutputEnabled()
Enable/disable data output stacks (all 3).
Error Output Stack
SetErrorOutput(string error)
Pushes error message to Error Output stack.
Purpose:
- Exception Reporting: AI-detected errors
- User Error Messages: Invalid input notifications
- System Alerts: Critical failures
GetErrorOutput()
Retrieves error messages.
ClearErrorOutput()
Clears error stack.
EnableErrorOutput(bool enabled) / ErrorOutputEnabled()
Enable/disable error output.
Socket Output
SetSocketOutput(string output)
Sends text to attached socket connection.
Purpose:
- Network Protocol: Custom AI-to-network communication
- Remote Clients: Send responses to external systems
- Deprecated LUA Support: Legacy socket integration
Usage:
csharp
// Requires external socket setup
api.EnableSocketOutput(true);
api.SetSocketOutput("{\"type\":\"response\",\"text\":\"Hello\"}");EnableSocketOutput(bool enabled) / SocketOutputEnabled()
Enable/disable socket output.
Note: Application must implement socket connection separately.
Speech Timing
GetApproximateSpeechLength(string text, float rate = 1.2f, float wordsPerMinute = 200f, float timeFactor = 1f)
Estimates speech duration for text, audio-independent.
Purpose:
- Animation Synchronization: Know how long speech will take
- Timing Control: Schedule events during speech
- Performance Planning: Coordinate gestures with speech duration
Algorithm:
csharp
words = text.Split(' ').Length
characters = text.Length - words + 1
ratio = characters / words
time = (words / (wordsPerMinute * rate)) * 60 * timeFactorUsage:
csharp
string ttsText = "Hello there, how are you today?";
float duration = api.GetApproximateSpeechLength(ttsText);
// duration ≈ 2.5 seconds
// Schedule gesture to start at 1.0 seconds into speech
pagerParser.ScheduleTag("<Gesture-Wave/>", 1.0f, duration);Parameters:
text(string): Text to estimaterate(float): Speech rate multiplier (default 1.2f for average speech)wordsPerMinute(float): WPM base rate (default 200f)timeFactor(float): Additional scaling factor (default 1.0f)
Returns: float - Estimated duration in seconds
Calibration:
csharp
// Slow, clear speech
float slowDuration = api.GetApproximateSpeechLength(text, 0.8f, 150f);
// Fast, energetic speech
float fastDuration = api.GetApproximateSpeechLength(text, 1.5f, 250f);
// Compensate for TTS engine speed differences
float compensated = api.GetApproximateSpeechLength(text, 1.2f, 200f, 1.15f);Speaking State Management
IsSpeaking()
Returns true if voice output stack has content or TTS is actively speaking.
Purpose:
- Prevent Interruption: Wait until speech finishes before next action
- UI Feedback: Show "speaking" indicator
- Timing Control: Hold off behaviors until AI silent
Usage:
csharp
// Wait until AI finishes speaking
IEnumerator WaitForSpeechEnd() {
while (api.IsSpeaking() || ttsEngine.IsPlaying) {
yield return null;
}
// AI is silent, proceed with next action
ContinueConversation();
}Returns: bool - True if speaking or voice queue not empty
SetIsSpeaking(bool isSpeaking, bool force)
Manually override speaking state.
Purpose:
- External TTS Control: Set state when using external TTS engine
- Forced Silence: Override detection for debugging
- Script Control: Behaviors can check/set speaking state
Usage:
csharp
// From application after TTS starts
api.SetIsSpeaking(true, false);
// From behavior script (always force)
api.SetIsSpeaking(true, true);Parameters:
isSpeaking(bool): Speaking state to setforce(bool): If true, overrides internal checks (usetruefrom scripts)
Listening State Management
SetListening(bool enabled)
Enables/disables speech recognition "hearing" state.
Purpose:
- Voice Input Control: Toggle microphone listening
- Push-to-Talk: Enable only when user holds key
- Privacy: Disable listening when AI speaking
Usage:
csharp
// Push-to-talk pattern
if (Input.GetKey(KeyCode.PageUp)) {
api.SetListening(true);
} else {
api.SetListening(false);
}IsListening()
Returns listening state.
Usage:
csharp
if (api.IsListening()) {
microphoneIcon.SetActive(true);
}StartListening() / StopListening()
Convenience methods to enable/disable listening.
Usage:
csharp
api.StartListening(); // Same as SetListening(true)
api.StopListening(); // Same as SetListening(false)TTS Delegation
RegisterSetVoiceFontFunction(SetVoiceFontFunctionDelegate function)
Registers external TTS engine for voice font control. Legacy.
Purpose:
- Custom TTS: Integrate any TTS engine (Piper, Azure, ElevenLabs, Cepstral, etc.)
- Voice Switching: AI can change voices via
SetVoiceFont()calls - Character Switching: Different AI personas use different voices
Delegate Signature:
csharp
public delegate bool SetVoiceFontFunctionDelegate(string gender, string fontName, int rate);Usage:
csharp
// Custom TTS wrapper
public bool MyTTSSetVoice(string gender, string fontName, int rate) {
return myTTSEngine.SetVoice(gender, fontName, rate);
}
// Register delegate
api.RegisterSetVoiceFontFunction(MyTTSSetVoice);
// Now behaviors can call: api.SetVoiceFont("Female", "en_US_amy", 0)Example: Piper TTS Integration:
csharp
public class PiperTTSWrapper {
public bool SetPiperVoice(string gender, string fontName, int rate) {
// Load Piper model by name
string modelPath = $"models/{fontName}.onnx";
if (!File.Exists(modelPath)) return false;
piperEngine.LoadModel(modelPath);
piperEngine.SetRate(rate);
return true;
}
}
// Register
api.RegisterSetVoiceFontFunction(piperWrapper.SetPiperVoice);SetVoiceFont(string gender, string fontName, int rate)
Sets voice font via registered TTS delegate.
Usage:
csharp
// Switch to female voice, normal rate
api.SetVoiceFont("Female", "en_US_amy", 0);
// Switch to male voice, faster rate
api.SetVoiceFont("Male", "en_GB_alan", 2);Parameters:
gender(string): "Male", "Female", "Neutral"fontName(string): TTS-specific voice namerate(int): Speech rate (-10 to +10, 0 = normal)
Returns: bool - True if delegate successfully set voice
GetVoiceFontGender() / GetVoiceFontName() / GetVoiceFontRate()
Returns current voice font settings.
Usage:
csharp
string currentGender = api.GetVoiceFontGender(); // "Female"
string currentVoice = api.GetVoiceFontName(); // "en_US_amy"
int currentRate = api.GetVoiceFontRate(); // 0SetVoiceType(string providerType)
DEPRECATED - Legacy voice provider type.
Modern implementations should use RegisterSetVoiceFontFunction() instead.
Viseme System (DEPRECATED)
DEPRECATED in SILVIA 3.0 - Modern avatar systems handle lip-sync separately.
RegisterLoadVisemesFunction()LoadVisemes()LoadVisemesCrop()GetVisemesFolder()
Migration: Use PAGER tags for expression/animation control instead.
Application Focus
SetFocus()
Signals that this application should receive primary focus.
Purpose:
- Multi-App Environments: Priority signaling in shared SILVIA systems
- Focus-Related Behaviors: Trigger behaviors when app gains focus
Usage:
csharp
void OnApplicationFocus(bool hasFocus) {
if (hasFocus) {
api.SetFocus();
}
}Returns: bool - True if focus message queued
Internally: Calls SetApplicationMessage("Application Focus Main")
Secure Command Completion (3.1 NEW)
GetSecureCommandCompletions(string currentInput, int maxSuggestions = 5)
Returns security-validated command completions using NLP-based auto-suggest.
Purpose:
- Intelligent Auto-Complete: GPT-style suggestions for commands
- Security-Filtered: Users only see completions they have permission for
- Behavior-Aware: Suggestions based on active behaviors and exuders
Algorithm:
- NLP Prediction: Markov model generates candidate completions
- Security Validation: Filter by user security level
- Behavior Matching: Check exuder patterns for valid commands
- Suffix Extraction: Return only remaining text to complete
Usage:
csharp
// User types: "show sys"
string[] completions = api.GetSecureCommandCompletions("show sys", 3);
// Returns: ["tem status", "tem config", "tem info"]
// Display as autocomplete dropdown
foreach (string suffix in completions) {
dropdown.AddOption("show sys" + suffix);
}Parameters:
currentInput(string): Current user input textmaxSuggestions(int): Maximum completions to return (default 5)
Returns: string[] - Array of completion suffixes, or null if none
Security Features:
- User Level Check: Validates against
brain.GetUserSecurityLevel() - Behavior Security: Checks
behavior.GetSecurityLevel() - Exuder Security: Validates
behavior.GetExuderSecurityLevel() - Permission Filtering: Users cannot see commands they can't execute
Example: Chat UI with Auto-Complete:
csharp
TMP_InputField commandInput;
TMP_Dropdown suggestionsDropdown;
void OnInputChanged(string input) {
if (input.Length < 3) return; // Wait for 3+ chars
string[] completions = api.GetSecureCommandCompletions(input, 5);
if (completions == null || completions.Length == 0) {
suggestionsDropdown.gameObject.SetActive(false);
return;
}
// Build dropdown options
suggestionsDropdown.ClearOptions();
List<string> options = new List<string>();
foreach (string suffix in completions) {
options.Add(input + suffix);
}
suggestionsDropdown.AddOptions(options);
suggestionsDropdown.gameObject.SetActive(true);
}Internal Validation Flow:
csharp
// 1. Generate Markov predictions
fullCompletions = markov.NextNMostLikelyConcepts(input, 10, 5, false);
// 2. Convert to atom indices
completionAtoms = brain.ConvertToAtomIndices(completion);
// 3. Check all behaviors
foreach (behavior in brain.Behaviors) {
if (behavior.SecurityLevel > userSecurityLevel) continue; // Skip
// 4. Check exuders
foreach (exuder in behavior.Exuders) {
if (exuder.SecurityLevel > userSecurityLevel) continue; // Skip
// 5. Pattern match with wildcard support
if (MatchesExuderPattern(completionAtoms, exuder.Atoms)) {
return true; // ALLOWED
}
}
}
return false; // DENIEDWildcard Support:
csharp
// Exuder pattern: [show, *, status]
// Completion: [show, system]
// Result: MATCH (partial prefix)
// Exuder pattern: [show, *, info]
// Completion: [show, database, info]
// Result: MATCH (wildcard accepts "database")Advanced Patterns
Pattern 1: Interrupt Handling
csharp
public void InterruptAI() {
// Clear all pending outputs
api.ClearTextOutput();
api.ClearVoiceOutput();
api.ClearPagerTags();
api.ClearApplicationMessage();
// Stop TTS
ttsEngine.Stop();
api.SetIsSpeaking(false, true);
// Clear synchronized queues
utterancesQueue.Clear();
voiceOutputQueue.Clear();
pagerTagsQueue.Clear();
speechTimesQueue.Clear();
// Reset avatar to idle
avatarController.ResetToIdle();
}Pattern 2: Multi-Modal Response Builder
csharp
// From behavior script
public bool GreetUser() {
string userName = _core.GetVariable("$_u");
// Text output (display)
_core.ApiApp().SetTextOutput($"Welcome back, {userName}!");
// Voice output (TTS with prosody)
_core.ApiApp().SetVoiceOutput($"<prosody rate='1.1'>Welcome back, {userName}!</prosody>");
// PAGER tags (animation)
_core.ApiApp().SetPagerTagsOutput("<Gesture-Wave/><Expression-Smile intensity=0.8/>");
// Data output (logging)
_core.ApiApp().SetExuderDataOutput($"last_greeting_time={DateTime.Now}");
// Application message (trigger UI event)
_core.ApiApp().SetApplicationMessage("SHOW_WELCOME_PANEL");
// Diagnostic (debug info)
_core.ApiApp().SetDiagOutput($"[GREETING] User {userName} greeted at {DateTime.Now}");
return true;
}Pattern 3: Conditional Output Routing
csharp
// From behavior script
public bool SendNotification() {
string message = "Server status: Online";
// Always send to diagnostics
_core.ApiApp().SetDiagOutput($"[INFO] {message}");
// Send to text only if UI enabled
if (_core.GetVariable("ui_enabled") == "true") {
_core.ApiApp().SetTextOutput(message);
}
// Send to socket only if remote client connected
if (_core.GetVariable("socket_connected") == "true") {
_core.ApiApp().SetSocketOutput($"{{\"status\":\"online\"}}");
}
// Send to voice only if TTS enabled
if (_core.GetVariable("tts_enabled") == "true") {
_core.ApiApp().SetVoiceOutput(message);
}
return true;
}Pattern 4: Performance Synchronization
csharp
// Synchronized performance with gesture timing
public void ExecuteSynchronizedPerformance() {
// Dequeue all outputs atomically
string text = utterancesQueue[0];
string voice = voiceOutputQueue[0];
string pagerTags = pagerTagsQueue[0];
float speechDuration = speechTimesQueue[0];
utterancesQueue.RemoveAt(0);
voiceOutputQueue.RemoveAt(0);
pagerTagsQueue.RemoveAt(0);
speechTimesQueue.RemoveAt(0);
// Display text immediately
chatLog.AppendLine($"<b>{aiName}:</b> {text}");
// Parse PAGER tags
List<string> tags = ParsePagerTags(pagerTags);
// Schedule tags at specific times during speech
for (int i = 0; i < tags.Count; i++) {
// Space gestures evenly across speech duration
float delay = (speechDuration / tags.Count) * i;
pagerParser.ScheduleTag(tags[i], delay, speechDuration);
}
// Start TTS
ttsEngine.Speak(voice);
}Use Cases
Chatbot with Avatar Animation
csharp
// Poll outputs every frame
void Update() {
CheckSilviaListener();
// Process queued outputs when TTS ready
if (!ttsEngine.IsBusy && utterancesQueue.Count > 0) {
ProcessNextOutput();
}
}Capabilities:
- Chat text display
- Voice synthesis with SSML
- Synchronized facial expressions
- Gesture timing with speech
IoT Sensor Monitoring
csharp
// AI analyzes sensor data and outputs alerts
void PollSensorAlerts() {
string appMsg = api.GetApplicationMessage();
if (appMsg == "ALERT_TEMPERATURE_HIGH") {
TriggerAlarm();
SendNotification("Temperature exceeded threshold");
}
string data = api.GetBehaviorDataOutput();
if (!string.IsNullOrEmpty(data)) {
// Parse: "temperature=85.2,humidity=72.1"
UpdateDashboard(data);
}
}Capabilities:
- Real-time alerts via Application Messages
- Structured data output for dashboards
- Diagnostic logging for anomaly detection
Game NPC with Multi-Modal Interaction
csharp
// NPC responds with voice, text, animation, and game events
void ProcessNPCResponse() {
// Voice + lip-sync
string voice = api.GetVoiceOutput();
if (!string.IsNullOrEmpty(voice)) {
npcTTS.Speak(voice);
}
// Subtitle text
string text = api.GetTextOutput();
if (!string.IsNullOrEmpty(text)) {
subtitleUI.Show(text, 3.0f);
}
// Animation + expressions
string pagerTags = api.GetPagerTagsOutput();
if (!string.IsNullOrEmpty(pagerTags)) {
npcAnimator.ExecutePagerTags(pagerTags);
}
// Game events
string gameEvent = api.GetApplicationMessage();
if (gameEvent == "GIVE_QUEST") {
questManager.ActivateQuest("village_rescue");
}
}Capabilities:
- Character voice acting
- Subtitle display
- Facial/body animation
- Quest triggers
- Inventory management
Migration From LEGACY
Changes from SILVIA 2.x
NEW in 3.1:
GetSecureCommandCompletions()- NLP auto-complete with securityGetBehaviorDataOutput()/GetAbsorberDataOutput()/GetExuderDataOutput()- Scoped data stacksSetStackSize()/GetStackSize()- Configurable stack limitsEnableDataOutput()/DataOutputEnabled()- Data stack controlEnableErrorOutput()/ErrorOutputEnabled()- Error stack control
DEPRECATED:
SetVoiceType()/GetVoiceType()- UseRegisterSetVoiceFontFunction()insteadLoadVisemes()/LoadVisemesCrop()/GetVisemesFolder()- Use PAGER tags for animationeVoiceTypeenum - Modern TTS uses dynamic voice registration
Configuration
Stack Size Tuning
csharp
// Default configuration (chatbots)
api.SetStackSize(40);
// High-throughput configuration (IoT telemetry)
api.SetStackSize(500);
// Industrial logging (persistent queue)
api.SetStackSize(2000);Output Channel Selection
csharp
// Voice-only mode (no text display)
api.EnableTextOutput(false);
api.EnableVoiceOutput(true);
api.EnableDiagOutput(false);
// Silent mode (text only, no TTS)
api.EnableTextOutput(true);
api.EnableVoiceOutput(false);
// Debug mode (all outputs enabled)
api.EnableTextOutput(true);
api.EnableVoiceOutput(true);
api.EnableDiagOutput(true);
api.EnableApplicationMessage(true);
api.EnableDataOutput(true);
api.EnableErrorOutput(true);Performance Notes
Stack Polling:
- O(1) retrieval:
GetTextOutput()is constant time - while() loops: Drain entire stack each frame, don't check count
- Bounded queues: Set
SetStackSize()to prevent unbounded growth
Memory Management:
- 40-item default: ~10KB per stack (string avg 256 bytes)
- 7 stacks total: ~70KB for all output buffers
- Auto-pruning: Oldest items dropped when stack full
See Also
- ApiBrain - Response generation, behavior execution, inference chain
- ApiCore - Variables, timed functions, core management
- ApiUser - Multi-user session management (3.1)
- ApiFeedback - Conversational memory, context tracking
- ApiMem - Brain loading, behavior groups, hot-swapping
This documentation has been comprehensively reviewed and validated against the source code. All public methods in the ApiApp API include:
- Extensive XML documentation comments in source code
- Complete parameter descriptions with type information
- Return value specifications
- Usage examples and implementation notes
- Security and performance considerations
© Copyright Cognitive Code Corp. 2007-2026
SILVIA is a registered Trademark of Cognitive Code Corp.

