SignalWire AI Agents SDK Architecture πŸ”—

Overview πŸ”—

The SignalWire AI Agents SDK provides a Python framework for building, deploying, and managing AI agents as microservices. These agents are self-contained web applications that expose HTTP endpoints to interact with the SignalWire platform. The SDK simplifies the creation of custom AI agents by handling common functionality like HTTP routing, prompt management, and tool execution.

Core Components πŸ”—

Class Hierarchy πŸ”—

The SDK is built around a clear class hierarchy:

Key Components πŸ”—

  1. SWML Document Management
  2. Schema validation for SWML documents
  3. Dynamic SWML verb creation and validation
  4. Document rendering and serving

  5. Prompt Object Model (POM)

  6. Structured format for defining AI prompts
  7. Section-based organization (Personality, Goal, Instructions, etc.)
  8. Programmatic prompt construction and manipulation

  9. SWAIG Function Framework

  10. Tool definition and registration system
  11. Parameter validation using JSON schema
  12. Security tokens for function execution
  13. Handler registry for function execution

  14. HTTP Routing

  15. FastAPI-based web service
  16. Endpoint routing for SWML, SWAIG, and other services
  17. Custom routing callbacks for dynamic endpoint handling
  18. SIP request routing for voice applications
  19. Basic authentication

  20. State Management

  21. Session-based state tracking
  22. Persistence options (file system, memory)
  23. State lifecycle hooks (startup, hangup)

  24. Prefab Agents

  25. Ready-to-use agent implementations
  26. Customizable configurations
  27. Extensible designs for common use cases

  28. Skills System

  29. Modular skill architecture for extending agent capabilities
  30. Automatic skill discovery from directory structure
  31. Parameter-configurable skills for customization
  32. Dependency validation (packages and environment variables)
  33. Built-in skills (web_search, datetime, math)

DataMap Tools πŸ”—

The DataMap system provides a declarative approach to creating SWAIG tools that integrate with REST APIs without requiring custom webhook infrastructure. DataMap tools execute on SignalWire's server infrastructure, simplifying deployment and eliminating the need to expose webhook endpoints.

Architecture Overview πŸ”—

DataMap tools follow a pipeline execution model on the SignalWire server:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Function Call   β”‚    β”‚ Expression      β”‚    β”‚ Webhook         β”‚    β”‚ Response        β”‚
β”‚ (Arguments)     │━━━▢│ Processing      │━━━▢│ Execution       │━━━▢│ Generation      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚                       β”‚
         β”‚                       β”‚                       β”‚                       β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚Variable β”‚             β”‚Pattern  β”‚             β”‚HTTP     β”‚             β”‚Template β”‚
    β”‚Expansionβ”‚             β”‚Matching β”‚             β”‚Request  β”‚             β”‚Renderingβ”‚
    β”‚         β”‚             β”‚         β”‚             β”‚         β”‚             β”‚         β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components πŸ”—

  1. Builder Pattern: Fluent interface for constructing data_map configurations python tool = (DataMap('function_name') .description('Function purpose') .parameter('param', 'string', 'Description', required=True) .webhook('GET', 'https://api.example.com/endpoint') .output(SwaigFunctionResult('Response template')) )

  2. Processing Pipeline: Ordered execution with early termination

  3. Expressions: Pattern matching against arguments
  4. Webhooks: HTTP API calls with variable substitution
  5. Foreach: Array iteration for response processing
  6. Output: Final response generation using SwaigFunctionResult

  7. Variable Expansion: Dynamic substitution using ${variable} syntax

  8. Function arguments: ${args.parameter_name}
  9. API responses: ${response.field.nested_field}
  10. Array elements: ${foreach.item_field}
  11. Global data: ${global_data.key}
  12. Metadata: ${meta_data.call_id}

Tool Types πŸ”—

The system supports different tool patterns:

  1. API Integration Tools: Direct REST API calls python weather_tool = (DataMap('get_weather') .webhook('GET', 'https://api.weather.com/v1/current?q=${location}') .output(SwaigFunctionResult('Weather: ${response.current.condition}')) )

  2. Expression-Based Tools: Pattern matching without API calls python control_tool = (DataMap('file_control') .expression(r'start.*', SwaigFunctionResult().add_action('start', True)) .expression(r'stop.*', SwaigFunctionResult().add_action('stop', True)) )

  3. Array Processing Tools: Handle list responses python search_tool = (DataMap('search_docs') .webhook('GET', 'https://api.docs.com/search') .foreach('${response.results}') .output(SwaigFunctionResult('Found: ${foreach.title}')) )

Integration with Agent Architecture πŸ”—

DataMap tools integrate seamlessly with the existing agent architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ AgentBase       β”‚    β”‚ SWAIG           β”‚    β”‚ SignalWire      β”‚
β”‚                 β”‚    β”‚ Function        β”‚    β”‚ Server          β”‚
β”‚ .register_      │━━━▢│ Registry        │━━━▢│ Execution       β”‚
β”‚  swaig_function β”‚    β”‚                 β”‚    β”‚ Environment     β”‚
β”‚                 β”‚    β”‚ data_map field  β”‚    β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β”‚                       β”‚                       β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚DataMap  β”‚             β”‚Function β”‚             β”‚Variable β”‚
    β”‚Builder  β”‚             β”‚Definitionβ”‚             β”‚Expansionβ”‚
    β”‚         β”‚             β”‚         β”‚             β”‚         β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. Registration: DataMap tools are registered as SWAIG functions
  2. Execution: Tools run on SignalWire infrastructure, not agent servers
  3. Response: Results are returned to the agent as function responses

Configuration Architecture πŸ”—

DataMap configurations use a hierarchical structure:

{
  "function": "tool_name",
  "description": "Tool description", 
  "parameters": {
    "type": "object",
    "properties": {...},
    "required": [...]
  },
  "data_map": {
    "expressions": [...],
    "webhooks": [...], 
    "foreach": "path",
    "output": {...},
    "error_keys": [...]
  }
}

This structure separates: - Function Metadata: Name, description, parameters - Processing Logic: Expressions, webhooks, array handling - Output Definition: Response templates and actions

Benefits and Trade-offs πŸ”—

Benefits:

Trade-offs:

When to Choose DataMap vs Skills vs Custom Tools:

Skills System πŸ”—

The Skills System provides a modular architecture for extending agent capabilities through self-contained, reusable components. Skills are automatically discovered, validated, and can be configured with parameters.

Architecture Overview πŸ”—

The skills system follows a three-layer architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Agent Layer     β”‚    β”‚ Management      β”‚    β”‚ Skills Layer    β”‚
β”‚                 β”‚    β”‚ Layer           β”‚    β”‚                 β”‚
β”‚ AgentBase       │━━━▢│ SkillManager    │━━━▢│ SkillBase       β”‚
β”‚ .add_skill()    β”‚    β”‚ .load_skill()   β”‚    β”‚ .setup()        β”‚
β”‚                 β”‚    β”‚ .unload_skill() β”‚    β”‚ .register_tools()β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β”‚                       β”‚                       β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚Request  β”‚             β”‚Registry β”‚             β”‚Skill    β”‚
    β”‚Routing  β”‚             β”‚Discoveryβ”‚             β”‚Instance β”‚
    β”‚         β”‚             β”‚         β”‚             β”‚         β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components πŸ”—

  1. SkillBase: Abstract base class defining the skill interface
  2. Dependency validation (packages and environment variables)
  3. Tool registration with the agent
  4. Parameter support for configuration
  5. Lifecycle management (setup, cleanup)

  6. SkillManager: Manages skill loading and lifecycle

  7. Skill discovery and registration
  8. Dependency validation and error reporting
  9. Parameter passing to skills
  10. Integration with agent prompt and tool systems

  11. SkillRegistry: Automatic skill discovery system

  12. Directory-based skill discovery
  13. Class introspection and registration
  14. Metadata extraction for skill information

Skill Lifecycle πŸ”—

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Discovery       β”‚    β”‚ Loading         β”‚    β”‚ Registration    β”‚
β”‚                 β”‚    β”‚                 β”‚    β”‚                 β”‚
β”‚ 1. Scan dirs    │━━━▢│ 1. Validate     │━━━▢│ 1. Add tools    β”‚
β”‚ 2. Import mods  β”‚    β”‚    deps         β”‚    β”‚ 2. Add prompts  β”‚
β”‚ 3. Find classes β”‚    β”‚ 2. Create       β”‚    β”‚ 3. Add hints    β”‚
β”‚ 4. Register     β”‚    β”‚    instance     β”‚    β”‚ 4. Store ref    β”‚
β”‚                 β”‚    β”‚ 3. Call setup() β”‚    β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Parameter System πŸ”—

Skills support configurable parameters for customization:

# Default behavior
agent.add_skill("web_search")

# Custom configuration
agent.add_skill("web_search", {
    "num_results": 3,
    "delay": 0.5
})

Parameters are passed to the skill constructor and accessible via self.params:

class WebSearchSkill(SkillBase):
    def setup(self) -> bool:
        self.num_results = self.params.get('num_results', 1)
        self.delay = self.params.get('delay', 0)
        # Configure behavior based on parameters

Error Handling πŸ”—

The system provides detailed error reporting for common issues:

Error messages are actionable and specific:

Failed to load skill 'web_search': Missing required environment variables: ['GOOGLE_SEARCH_API_KEY', 'GOOGLE_SEARCH_ENGINE_ID']

Integration Points πŸ”—

Skills integrate seamlessly with existing agent systems:

  1. SWAIG Tools: Skills register tools that become available to the AI
  2. Prompt System: Skills can add prompt sections and hints
  3. Global Data: Skills can contribute to agent context
  4. State Management: Skills can access agent state if needed

This architecture enables powerful one-liner integration while maintaining flexibility and extensibility.

Security Model πŸ”—

The SDK implements a multi-layer security model:

  1. Transport Security
  2. HTTPS support for encrypted communications
  3. SSL certificate configuration

  4. Authentication

  5. HTTP Basic Authentication for all endpoints
  6. Configurable via environment variables or programmatically

  7. Authorization

  8. Function-specific security tokens
  9. Token validation for secure function calls
  10. SessionManager-based security scope
  11. secure=True option on tool definitions (default)

  12. State Isolation

  13. Per-call state separation
  14. Call ID validation

Extension Points πŸ”—

The SDK is designed to be highly extensible:

  1. Custom Agents: Extend AgentBase to create specialized agents python class CustomAgent(AgentBase): def __init__(self): super().__init__(name="custom", route="/custom")

  2. Tool Registration: Add new tools using the decorator pattern python @AgentBase.tool( name="tool_name", description="Tool description", parameters={...}, secure=True ) def my_tool(self, args, raw_data): # Tool implementation

  3. Prompt Customization: Add sections, hints, languages python agent.add_language(name="English", code="en-US", voice="elevenlabs.josh") agent.add_hints(["SignalWire", "SWML", "SWAIG"])

  4. State Management: Implement custom state persistence python class CustomStateManager(StateManager): def get_state(self, call_id): # Implementation

  5. Request Handling: Override request handling methods python def on_swml_request(self, request_data): # Custom request handling

  6. Custom Prefabs: Create reusable agent patterns python class MyCustomPrefab(AgentBase): def __init__(self, config_param1, config_param2, **kwargs): super().__init__(**kwargs) # Configure the agent based on parameters self.prompt_add_section("Personality", body=f"Customized based on: {config_param1}")

  7. Dynamic Configuration: Per-request agent configuration for flexible behavior ```python def configure_agent_dynamically(self, query_params, body_params, headers, agent): # Configure agent differently based on request data tier = query_params.get('tier', 'standard') agent.set_params({"end_of_speech_timeout": 300 if tier == 'premium' else 500})

self.set_dynamic_config_callback(self.configure_agent_dynamically) ```

  1. Skills Integration: Add capabilities with one-liner calls ```python # Add built-in skills agent.add_skill("web_search") agent.add_skill("datetime") agent.add_skill("math")

# Configure skills with parameters agent.add_skill("web_search", { "num_results": 3, "delay": 0.5 }) ```

  1. Custom Skills: Create reusable skill modules ```python from signalwire_agents.core.skill_base import SkillBase

class MyCustomSkill(SkillBase): SKILL_NAME = "my_skill" SKILL_DESCRIPTION = "A custom skill" REQUIRED_PACKAGES = ["requests"] REQUIRED_ENV_VARS = ["API_KEY"]

   def setup(self) -> bool:
       # Initialize the skill
       return True

   def register_tools(self) -> None:
       # Register tools with the agent
       self.agent.define_tool(...)

```

Dynamic Configuration πŸ”—

The dynamic configuration system enables agents to adapt their behavior on a per-request basis by examining incoming HTTP request data. This architectural pattern supports complex use cases like multi-tenant applications, A/B testing, and personalization while maintaining a single agent deployment.

Architecture Overview πŸ”—

Dynamic configuration intercepts the SWML document generation process to apply request-specific configuration:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ HTTP        β”‚    β”‚ Dynamic Config   β”‚    β”‚ EphemeralAgent      β”‚    β”‚ SWML         β”‚
β”‚ Request     │━━━▢│ Callback         │━━━▢│ Config              │━━━▢│ Document     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                     β”‚                        β”‚                      β”‚
       β”‚                     β”‚                        β”‚                      β”‚
   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
   β”‚Query   β”‚           β”‚Request   β”‚            β”‚Agent       β”‚          β”‚Rendered β”‚
   β”‚Params  β”‚           β”‚Data      β”‚            β”‚Builder     β”‚          β”‚Response β”‚
   β”‚Body    β”‚           β”‚Analysis  β”‚            β”‚Methods     β”‚          β”‚         β”‚
   β”‚Headers β”‚           β”‚Logic     β”‚            β”‚Execution   β”‚          β”‚         β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Interaction πŸ”—

  1. Request Processing: The framework extracts query parameters, body data, and headers from incoming requests
  2. Callback Invocation: If a dynamic configuration callback is registered, it's called with the request data
  3. Ephemeral Configuration: The callback configures an EphemeralAgentConfig object using familiar AgentBase methods
  4. SWML Generation: The configuration is applied during SWML document rendering
  5. Response Delivery: The customized SWML document is returned to the client

Request Processing Flow πŸ”—

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Dynamic Configuration Request Flow                                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚ 1. HTTP Request arrives (GET/POST /)                                          β”‚
β”‚                         β”‚                                                       β”‚
β”‚ 2. Extract request data β”‚                                                       β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                 β”‚
β”‚    β”‚ β€’ Query Parameters (URL params)        β”‚                                 β”‚
β”‚    β”‚ β€’ Body Parameters (POST JSON)          β”‚                                 β”‚
β”‚    β”‚ β€’ Headers (HTTP headers)               β”‚                                 β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                 β”‚
β”‚                         β”‚                                                       β”‚
β”‚ 3. Check for callback   β”‚                                                       β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                 β”‚
β”‚    β”‚ if dynamic_config_callback is set:     β”‚                                 β”‚
β”‚    β”‚   - Create EphemeralAgentConfig        β”‚                                 β”‚
β”‚    β”‚   - Call callback with request data    β”‚                                 β”‚
β”‚    β”‚   - Apply ephemeral configuration      β”‚                                 β”‚
β”‚    β”‚ else:                                   β”‚                                 β”‚
β”‚    β”‚   - Use static agent configuration     β”‚                                 β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                 β”‚
β”‚                         β”‚                                                       β”‚
β”‚ 4. Generate SWML        β”‚                                                       β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                 β”‚
β”‚    β”‚ β€’ Render AI verb with configuration    β”‚                                 β”‚
β”‚    β”‚ β€’ Include languages, params, prompts   β”‚                                 β”‚
β”‚    β”‚ β€’ Apply hints and global data          β”‚                                 β”‚
β”‚    β”‚ β€’ Generate function URLs with tokens   β”‚                                 β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                 β”‚
β”‚                         β”‚                                                       β”‚
β”‚ 5. Return SWML Document β”‚                                                       β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                 β”‚
β”‚    β”‚ β€’ Complete SWML with customizations    β”‚                                 β”‚
β”‚    β”‚ β€’ Ready for SignalWire platform        β”‚                                 β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                 β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

EphemeralAgentConfig Architecture πŸ”—

The EphemeralAgentConfig object provides the same familiar methods as AgentBase but applies them temporarily for a single request:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ EphemeralAgentConfig Structure                                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚ β”‚ Prompt Sections β”‚   β”‚ Language Config β”‚   β”‚ AI Parameters   β”‚              β”‚
β”‚ β”‚ ─────────────── β”‚   β”‚ ─────────────── β”‚   β”‚ ─────────────── β”‚              β”‚
β”‚ β”‚ β€’ add_section() β”‚   β”‚ β€’ add_language()β”‚   β”‚ β€’ set_params()  β”‚              β”‚
β”‚ β”‚ β€’ set_prompt()  β”‚   β”‚ β€’ voice config  β”‚   β”‚ β€’ timeouts      β”‚              β”‚
β”‚ β”‚ β€’ post_prompt   β”‚   β”‚ β€’ fillers       β”‚   β”‚ β€’ volumes       β”‚              β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚                                                                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚ β”‚ Global Data     β”‚   β”‚ Hints & Speech  β”‚   β”‚ Functions       β”‚              β”‚
β”‚ β”‚ ─────────────── β”‚   β”‚ ─────────────── β”‚   β”‚ ─────────────── β”‚              β”‚
β”‚ β”‚ β€’ set_global()  β”‚   β”‚ β€’ add_hints()   β”‚   β”‚ β€’ native_funcs()β”‚              β”‚
β”‚ β”‚ β€’ update_data() β”‚   β”‚ β€’ pronunciation β”‚   β”‚ β€’ recognition   β”‚              β”‚
β”‚ β”‚ β€’ session data  β”‚   β”‚ β€’ recognition   β”‚   β”‚ β€’ external URLs β”‚              β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚                                                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Performance Considerations πŸ”—

The dynamic configuration system is designed with performance in mind:

  1. Lightweight Callbacks: Configuration callbacks should be fast and avoid heavy computations
  2. Stateless Operation: Each request is processed independently without shared state
  3. Ephemeral Scope: Configuration objects are created per-request and garbage collected afterward
  4. Caching Opportunities: External configuration data can be cached at the application level

Memory Management πŸ”—

Request 1 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    Request 2 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    Request 3 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
Lifecycle β”‚ CREATE      β”‚    Lifecycle β”‚ CREATE      β”‚    Lifecycle β”‚ CREATE      β”‚
          β”‚ EphemeralCfgβ”‚              β”‚ EphemeralCfgβ”‚              β”‚ EphemeralCfgβ”‚
          β”‚ ↓           β”‚              β”‚ ↓           β”‚              β”‚ ↓           β”‚
          β”‚ CONFIGURE   β”‚              β”‚ CONFIGURE   β”‚              β”‚ CONFIGURE   β”‚
          β”‚ ↓           β”‚              β”‚ ↓           β”‚              β”‚ ↓           β”‚
          β”‚ RENDER SWML β”‚              β”‚ RENDER SWML β”‚              β”‚ RENDER SWML β”‚
          β”‚ ↓           β”‚              β”‚ ↓           β”‚              β”‚ ↓           β”‚
          β”‚ DESTROY     β”‚              β”‚ DESTROY     β”‚              β”‚ DESTROY     β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚                             β”‚                             β”‚
               β–Ό                             β–Ό                             β–Ό
          Garbage                       Garbage                       Garbage
          Collection                    Collection                    Collection

Use Case Patterns πŸ”—

The dynamic configuration architecture supports several key patterns:

  1. Multi-Tenant Applications ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Tenant A β”‚ β”‚ Same Agent β”‚ β”‚ Config A β”‚ β”‚ Request │━━━▢│ Instance │━━━▢│ Applied β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Tenant B β”‚ β”‚ Same Agent β”‚ β”‚ Config B β”‚ β”‚ Request │━━━▢│ Instance │━━━▢│ Applied β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ```

  1. A/B Testing and Experimentation ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Control β”‚ β”‚ Decision β”‚ β”‚ Version A β”‚ β”‚ Group │━━━▢│ Logic │━━━▢│ Config β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Test β”‚ β”‚ Decision β”‚ β”‚ Version B β”‚ β”‚ Group │━━━▢│ Logic │━━━▢│ Config β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ```

  1. Geographic and Cultural Localization ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ US Request β”‚ β”‚ Locale β”‚ β”‚ English β”‚ β”‚ (en-US) │━━━▢│ Detection │━━━▢│ Voice + USD β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MX Request β”‚ β”‚ Locale β”‚ β”‚ Spanish β”‚ β”‚ (es-MX) │━━━▢│ Detection │━━━▢│ Voice + MXN β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ```

Integration Points πŸ”—

Dynamic configuration integrates with other SDK components:

Error Handling and Fallbacks πŸ”—

The system includes robust error handling:

def configure_agent_dynamically(self, query_params, body_params, headers, agent):
    try:
        # Primary configuration logic
        self.apply_custom_config(query_params, agent)
    except ConfigurationError as e:
        # Log error and apply safe defaults
        self.log.error("dynamic_config_error", error=str(e))
        self.apply_default_config(agent)
    except Exception as e:
        # Catch-all with minimal safe configuration
        self.log.error("dynamic_config_critical", error=str(e))
        agent.add_language("English", "en-US", "rime.spore:mistv2")

Migration Strategy πŸ”—

The architecture supports gradual migration from static to dynamic configuration:

  1. Phase 1: Deploy dynamic agent with static configuration callback
  2. Phase 2: Add request parameter detection and basic customization
  3. Phase 3: Implement full dynamic behavior based on use case requirements
  4. Phase 4: Remove static configuration and rely entirely on dynamic system

This approach ensures zero downtime and allows for testing and validation at each phase.

Prefab Agents πŸ”—

The SDK includes a collection of prefab agents that provide ready-to-use implementations for common use cases. These prefabs can be used directly or serve as templates for custom implementations.

Built-in Prefab Types πŸ”—

  1. InfoGathererAgent
  2. Purpose: Collect specific information from users in a structured conversation
  3. Configuration: Define fields to collect, validation rules, and confirmation templates
  4. Use cases: Form filling, survey collection, intake processes

  5. FAQBotAgent

  6. Purpose: Answer questions based on a provided knowledge base
  7. Configuration: Data sources, retrieval methods, citation options
  8. Use cases: FAQ bots, documentation assistants, support agents

  9. ConciergeAgent

  10. Purpose: Handle routing and delegation between multiple specialized agents
  11. Configuration: Connected agents, routing logic, handoff protocols
  12. Use cases: Front-desk services, triage systems, switchboard operators

  13. SurveyAgent

  14. Purpose: Conduct structured surveys with rating scales and open-ended questions
  15. Configuration: Survey questions, rating scales, branching logic
  16. Use cases: Customer satisfaction surveys, feedback collection, market research

  17. ReceptionistAgent

  18. Purpose: Greet callers and transfer them to appropriate departments
  19. Configuration: Department list with names, descriptions, and transfer numbers
  20. Use cases: Call routing, front desk services, automated phone systems

Creating Custom Prefabs πŸ”—

Users can create their own prefab agents by extending AgentBase or any existing prefab. Custom prefabs can be created within your project or packaged as reusable libraries.

Key steps for creating custom prefabs:

  1. Extend the base class: python class MyCustomPrefab(AgentBase): def __init__(self, custom_param, **kwargs): super().__init__(**kwargs) self._custom_param = custom_param

  2. Configure defaults: ```python # Set standard prompt sections self.prompt_add_section("Personality", body="I am a specialized agent for...") self.prompt_add_section("Goal", body="Help users with...")

# Add default tools self.register_default_tools() ```

  1. Add specialized tools: python @AgentBase.tool( name="specialized_function", description="Do something specialized", parameters={...} ) def specialized_function(self, args, raw_data): # Implementation return SwaigFunctionResult("Function result")

  2. Create a factory method (optional): python @classmethod def create(cls, config_dict, **kwargs): """Create an instance from a configuration dictionary""" return cls( custom_param=config_dict.get("custom_param", "default"), name=config_dict.get("name", "custom_prefab"), **kwargs )

Prefab Customization Points πŸ”—

When designing prefabs, consider exposing these customization points:

  1. Constructor parameters: Allow users to configure key behavior
  2. Override methods: Document which methods can be safely overridden
  3. Extension hooks: Provide callback methods for custom logic
  4. Configuration files: Support loading settings from external sources
  5. Runtime customization: Allow changing behavior after initialization

Prefab Best Practices πŸ”—

  1. Clear Documentation: Document the purpose, parameters, and extension points
  2. Sensible Defaults: Provide working defaults that make sense for the use case
  3. Error Handling: Implement robust error handling with helpful messages
  4. Modular Design: Keep prefabs focused on a specific use case
  5. Consistent Interface: Maintain consistent patterns across related prefabs

Implementation Details πŸ”—

POM Structure πŸ”—

The POM (Prompt Object Model) represents a structured approach to prompt construction:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Prompt                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚ β”‚ Personality     β”‚  β”‚ Goal                β”‚  β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚ β”‚ Instructions    β”‚  β”‚ Hints               β”‚  β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚ β”‚ Languages       β”‚  β”‚ Custom Sections     β”‚  β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Contexts and Steps Architecture πŸ”—

The Contexts and Steps system provides an alternative to traditional POM prompts for building structured, workflow-driven AI interactions. This system represents a fundamental shift from unstructured conversation to guided workflow execution.

Core Architecture πŸ”—

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ContextBuilder                                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Context A       β”‚   β”‚ Context B       β”‚   β”‚ Context C   β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Step 1      β”‚ β”‚   β”‚ β”‚ Step 1      β”‚ β”‚   β”‚ β”‚ Step 1  β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ - Content   β”‚ β”‚   β”‚ β”‚ - Content   β”‚ β”‚   β”‚ β”‚ - Contentβ”‚ β”‚ β”‚
β”‚ β”‚ β”‚ - Criteria  β”‚ β”‚   β”‚ β”‚ - Criteria  β”‚ β”‚   β”‚ β”‚ - Criteriaβ”‚ β”‚ β”‚
β”‚ β”‚ β”‚ - Functions β”‚ β”‚   β”‚ β”‚ - Functions β”‚ β”‚   β”‚ β”‚ - Functionsβ”‚ β”‚ β”‚
β”‚ β”‚ β”‚ - Navigationβ”‚ β”‚   β”‚ β”‚ - Navigationβ”‚ β”‚   β”‚ β”‚ - Navigationβ”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚   β”‚           β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Step 2      β”‚ β”‚   β”‚ β”‚ Step 2      β”‚ β”‚   β”‚           β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚   β”‚           β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The system implements sophisticated navigation control through two primary mechanisms:

Intra-Context Navigation (Steps within a Context):

Context: Customer Service
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    valid_steps    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    valid_steps    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  greeting  β”‚ ────────────────▢ β”‚   identify   β”‚ ────────────────▢ β”‚   resolve    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                               β”‚                                   β”‚
      β”‚ valid_steps = ["identify"]    β”‚ valid_steps = ["resolve", "escalate"] β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚
                                                                          β”‚
                                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚   escalate   β”‚   valid_steps = ["escalate"]
                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Inter-Context Navigation (Switching between Contexts):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    valid_contexts    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    valid_contexts    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Triage      β”‚ ─────────────────▢   β”‚   Technical     β”‚ ─────────────────▢   β”‚    Billing      β”‚
β”‚                 β”‚                      β”‚   Support       β”‚                      β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                        β”‚                                        β”‚
         β”‚ valid_contexts = ["technical", "billing", "general"]      β”‚                    β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
                                                                                           β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚    General      β”‚                 valid_contexts = ["triage"]
         β”‚   Inquiries     β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Function Restriction System πŸ”—

Each step can restrict available AI functions to enhance security and user experience:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Function Access Control by Step                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                 β”‚
β”‚ Public Context                                  β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β”‚
β”‚ β”‚ Initial Contact β”‚ Functions: ["datetime"]     β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β”‚
β”‚                                                 β”‚
β”‚ Authenticated Context                           β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β”‚
β”‚ β”‚ User Verified   β”‚ Functions: ["datetime",     β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            "web_search"]    β”‚
β”‚                                                 β”‚
β”‚ Sensitive Context                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β”‚
β”‚ β”‚ Account Access  β”‚ Functions: "none"           β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

SWML Generation Process πŸ”—

The contexts system integrates with the existing SWML generation pipeline:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ContextBuilder  β”‚ ───▢ β”‚ Context Data    β”‚ ───▢ β”‚ SWML AI Verb    β”‚
β”‚                 β”‚      β”‚ Serialization   β”‚      β”‚ Generation      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                        β”‚                        β”‚
         β”‚                        β”‚                        β–Ό
         β”‚                        β”‚               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                        β”‚               β”‚ prompt: {       β”‚
         β”‚                        β”‚               β”‚   contexts: {   β”‚
         β”‚                        β”‚               β”‚     "context1": β”‚
         β”‚                        β”‚               β”‚       steps: {} β”‚
         β”‚                        β”‚               β”‚   }             β”‚
         β”‚                        β”‚               β”‚ }               β”‚
         β”‚                        β”‚               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                        β”‚
         β–Ό                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step Content    β”‚      β”‚ Navigation      β”‚
β”‚ - Text/POM      β”‚      β”‚ - valid_steps   β”‚
β”‚ - Functions     β”‚      β”‚ - valid_contextsβ”‚
β”‚ - Criteria      β”‚      β”‚ - Restrictions  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Integration with Existing Systems πŸ”—

Coexistence with Traditional Prompts:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Agent Configuration                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚ β”‚ Traditional     β”‚   β”‚ Contexts and        β”‚   β”‚
β”‚ β”‚ POM Sections    β”‚   β”‚ Steps Workflow      β”‚   β”‚
β”‚ β”‚ (from skills,   β”‚   β”‚                     β”‚   β”‚
β”‚ β”‚ global config)  β”‚   β”‚                     β”‚   β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚         β”‚                       β”‚               β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚                     β–Ό                           β”‚
β”‚           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚
β”‚           β”‚ Combined SWML   β”‚                   β”‚
β”‚           β”‚ Output          β”‚                   β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Skills and Function Integration:

Implementation Details πŸ”—

Context Validation Rules:

Step Content Rules:

Navigation Validation:

Function Security:

Performance Considerations πŸ”—

Memory Usage:

Execution Flow:

Scalability:

When to Use Contexts vs DataMap vs Skills vs Custom Tools πŸ”—

Use Contexts and Steps when:

Use DataMap when:

Use Skills when:

Use Custom Tools when:

The architecture supports using all these approaches together, allowing developers to choose the right tool for each specific requirement within a single agent.

SWAIG Function Definition πŸ”—

Functions are defined with: - Name - Description - Parameters schema - Implementation - Security settings

Example:

@AgentBase.tool(
    name="get_weather",
    description="Get the current weather for a location",
    parameters={
        "location": {
            "type": "string",
            "description": "The city or location to get weather for"
        }
    }
)
def get_weather(self, args, raw_data):
    location = args.get("location", "Unknown location")
    return SwaigFunctionResult(f"It's sunny and 72Β°F in {location}.")

HTTP Routing πŸ”—

The SDK uses FastAPI for routing with these key endpoints:

The SDK also supports dynamic creation of custom routing endpoints:

Deployment Options πŸ”—

The SDK supports multiple deployment models:

  1. Standalone Mode
  2. Single agent on dedicated port
  3. Direct invocation via agent.run() (auto-detects deployment mode)

  4. Multi-Agent Mode

  5. Multiple agents on same server with different routes
  6. app.include_router(agent.as_router(), prefix=agent.route)

  7. Reverse Proxy Integration

  8. Set SWML_PROXY_URL_BASE for proper webhook URL generation
  9. Enable SSL termination at proxy level

  10. Direct HTTPS Mode

  11. Configure with SSL certificates
  12. agent.serve(ssl_cert="cert.pem", ssl_key="key.pem")

Best Practices πŸ”—

  1. Prompt Structure
  2. Use POM for clear, structured prompts
  3. Keep personality and goal sections concise
  4. Use specific instructions for behavior guidance

  5. SWAIG Functions

  6. Define clear parameter schemas
  7. Provide comprehensive descriptions for AI context
  8. Implement proper error handling
  9. Return structured responses

  10. State Management

  11. Store essential conversation context in state
  12. Enable automatic state tracking with enable_state_tracking=True
  13. Use secure state storage for sensitive data

  14. Security

  15. Use HTTPS in production
  16. Set strong authentication credentials
  17. Enable security for sensitive operations with secure=True

  18. Deployment

  19. Use environment variables for configuration
  20. Implement proper logging
  21. Monitor agent performance and usage

  22. Prefab Usage

  23. Use existing prefabs for common patterns
  24. Extend prefabs rather than starting from scratch
  25. Create your own prefabs for reusable patterns
  26. Share prefabs across projects for consistency

Schema Validation πŸ”—

The SDK uses JSON Schema validation for: - SWML document structure - POM section validation - SWAIG function parameter validation

Schema definitions are loaded from the schema.json file, which provides the complete specification for all supported SWML verbs and structures.

Logging πŸ”—

The SDK uses structlog for structured logging with JSON output format. Key events logged include: - Service initialization - Request handling - Function execution - Authentication events - Error conditions

Configuration πŸ”—

Configuration options are available through: 1. Constructor Parameters: Direct configuration in code 2. Environment Variables: System-level configuration 3. Method Calls: Runtime configuration updates

Key environment variables: - SWML_BASIC_AUTH_USER: Username for basic auth - SWML_BASIC_AUTH_PASSWORD: Password for basic auth - SWML_PROXY_URL_BASE: Base URL when behind reverse proxy - SWML_SSL_ENABLED: Enable HTTPS - SWML_SSL_CERT_PATH: Path to SSL certificate - SWML_SSL_KEY_PATH: Path to SSL key - SWML_DOMAIN: Domain name for the service - SWML_SCHEMA_PATH: Optional path to override the schema.json location

Request Flow πŸ”—

SWML Document Request (GET/POST /) πŸ”—

  1. Client requests the root endpoint
  2. Authentication is validated
  3. on_swml_request() is called to allow customization
  4. Current SWML document is rendered and returned

SWAIG Function Call (POST /swaig/) πŸ”—

  1. Client sends a POST request to the SWAIG endpoint
  2. Authentication is validated
  3. Function name and arguments are extracted
  4. Token validation occurs for secure functions
  5. Function is executed and result returned

Post-Prompt Processing (POST /post_prompt/) πŸ”—

  1. Client sends conversation summary data
  2. Authentication is validated
  3. Summary is extracted from request
  4. on_summary() is called to process the data

State Management πŸ”—

The SDK provides a flexible state management system:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Session       β”‚     β”‚ State           β”‚     β”‚ Persistence   β”‚
β”‚ Management    │━━━━▢│ Manager         │━━━━▢│ Layer         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Components: - SessionManager: Handles session creation, activation, and termination - StateManager: Interface for state operations - Implementation Options: FileStateManager, MemoryStateManager, etc.

State is indexed by call ID and can store arbitrary JSON data. When enable_state_tracking=True is set, the system automatically registers lifecycle hooks: - startup_hook: Called when a new call/session starts - hangup_hook: Called when a call/session ends

Common state management methods: - get_state(call_id): Retrieve state for a call - update_state(call_id, data): Update state for a call - set_state(call_id, data): Set state for a call (overriding existing) - clear_state(call_id): Remove state for a call