Skip to content

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 Display

Problems:

  • 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   Output

What 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

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 TTS

Returns: 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 * timeFactor

Usage:

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 estimate
  • rate (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 set
  • force (bool): If true, overrides internal checks (use true from 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 name
  • rate (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();         // 0

SetVoiceType(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:

  1. NLP Prediction: Markov model generates candidate completions
  2. Security Validation: Filter by user security level
  3. Behavior Matching: Check exuder patterns for valid commands
  4. 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 text
  • maxSuggestions (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; // DENIED

Wildcard 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 security
  • GetBehaviorDataOutput() / GetAbsorberDataOutput() / GetExuderDataOutput() - Scoped data stacks
  • SetStackSize() / GetStackSize() - Configurable stack limits
  • EnableDataOutput() / DataOutputEnabled() - Data stack control
  • EnableErrorOutput() / ErrorOutputEnabled() - Error stack control

DEPRECATED:

  • SetVoiceType() / GetVoiceType() - Use RegisterSetVoiceFontFunction() instead
  • LoadVisemes() / LoadVisemesCrop() / GetVisemesFolder() - Use PAGER tags for animation
  • eVoiceType enum - 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.

SILVIA is a registered Trademark of Cognitive Code Corp.