### Install and Start Project Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v3/guides/video/making-a-clubhouse-clone/index.mdx Install project dependencies and start both the backend and frontend servers. ```bash npm install npm run start # starts both backend and frontend ``` -------------------------------- ### Quick Start Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/livewire/index.mdx A basic example demonstrating how to set up an AgentServer, define an agent with tools, and run the application. ```APIDOC ## Quick Start ```python from signalwire.livewire import ( Agent, AgentSession, AgentServer, JobContext, JobProcess, function_tool, run_app, ) @function_tool def lookup_order(order_id: str) -> str: """Look up the status of a customer order.""" return f"Order {order_id} shipped yesterday." server = AgentServer() @server.rtc_session() async def entrypoint(ctx: JobContext): agent = Agent( instructions="You are a helpful order-status assistant.", tools=[lookup_order], ) session = AgentSession() await session.start(agent, room=ctx.room) run_app(server) ``` ``` -------------------------------- ### Agent Startup Output Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx This is an example of the JSON output you might see when your agent starts, containing configuration details. ```json { "version": "1.0.0", "sections": { "main": [ {"answer": {}}, { "ai": { "prompt": { "text": "# Role\nYou are a friendly and helpful assistant..." }, "languages": [ {"name": "English", "code": "en-US", "voice": "rime.spore"} ] } } ] } } ``` -------------------------------- ### Install and Run SignalWire Docs Project Source: https://github.com/signalwire/docs/blob/main/README.md Clone the repository, install dependencies using Yarn, and start the local development server for live reloading. ```bash git clone https://github.com/signalwire/docs.git cd docs yarn install yarn start:dev yarn build ``` -------------------------------- ### Start Agent Session Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/start.mdx Use this example to bind an Agent to a session and prepare SignalWire infrastructure. It registers tools and maps timing parameters. Ensure you have the necessary imports and an AgentServer instance. ```python from signalwire.livewire import Agent, AgentSession, AgentServer, JobContext, function_tool, run_app @function_tool def get_weather(city: str) -> str: """Get the current weather for a city.""" return f"Sunny in {city}" server = AgentServer() @server.rtc_session() async def entrypoint(ctx: JobContext): await ctx.connect() agent = Agent(instructions="You help with weather.", tools=[get_weather]) session = AgentSession() await session.start(agent, room=ctx.room) run_app(server) ``` -------------------------------- ### Full Agent Application Example with JobContext and JobProcess Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/livewire/job-context.mdx A comprehensive example demonstrating the integration of AgentServer, JobContext, JobProcess, and AgentSession. It shows how to set up a custom setup function, define an entrypoint, and run the agent application. ```python from signalwire.livewire import ( Agent, AgentSession, AgentServer, JobContext, JobProcess, run_app, ) server = AgentServer() def setup(proc: JobProcess): # Pre-warm: load config, connect to databases, etc. proc.userdata["greeting"] = "Welcome to Acme Corp!" server.setup_fnc = setup @server.rtc_session() async def entrypoint(ctx: JobContext): await ctx.connect() await ctx.wait_for_participant() greeting = ctx.proc.userdata.get("greeting", "Hello!") agent = Agent(instructions="You are a helpful assistant.") session = AgentSession() await session.start(agent, room=ctx.room) session.say(greeting) run_app(server) ``` -------------------------------- ### Clone Browser Audioconf Example Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v3/guides/video/making-a-clubhouse-clone/index.mdx Clone the repository to get started with the browser audioconf example. Use the 'livewire' branch for basic UI. ```bash git clone -b livewire https://github.com/signalwire/browser-audioconf-example.git ``` -------------------------------- ### Full Example with RunContext and AgentSession Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/livewire/run-context.mdx Demonstrates a complete setup including defining a tool that modifies session user data, setting up an Agent, and starting an AgentSession. The `userData` is typed as `SessionData` to manage notes. ```typescript import { Agent, AgentSession, tool, RunContext, defineAgent, runApp, JobContext, } from '@signalwire/sdk/livewire'; interface SessionData { notes: string[]; } const addNote = tool<{ note: string }>({ description: 'Add a note to the session.', parameters: { note: { type: 'string' } }, execute: (params, { ctx }) => { const data = ctx.userData as SessionData; data.notes.push(params.note); return `Note saved. You have ${data.notes.length} note(s).`; }, }); const agentDef = defineAgent({ entry: async (ctx: JobContext) => { const agent = new Agent({ instructions: 'You are a note-taking assistant.', tools: { addNote }, }); const session = new AgentSession({ userData: { notes: [] }, }); await session.start({ agent }); }, }); runApp(agentDef); ``` -------------------------------- ### Example Usage Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx Demonstrates how to get the SkillRegistry instance, register a skill, and create an instance. ```APIDOC ```typescript import { SkillRegistry, SkillBase } from '@signalwire/sdk'; // Get the singleton instance const registry = SkillRegistry.getInstance(); // Register a skill class (assuming MySkill has a static SKILL_NAME property) // registry.register(MySkill); // Log all registered skill names console.log(registry.listRegistered()); // Create an instance of a skill from the registry // const skill = registry.create('my-skill', { apiKey: 'abc' }); ``` ``` -------------------------------- ### Complete Agent Configuration Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/skill-config.mdx This example demonstrates a comprehensive agent setup, including registering external skills, adding skills with simple parameters, complex configurations, SWAIG field overrides, and multi-instance skills. It also shows how to add language models and prompt sections. ```python from signalwire import AgentBase from signalwire.skills.registry import skill_registry import os ## Register external skills skill_registry.add_skill_directory("/opt/my_company/skills") class ConfiguredAgent(AgentBase): def __init__(self): super().__init__(name="configured-agent") self.add_language("English", "en-US", "rime.spore") # Simple skill - no config self.add_skill("datetime") # Skill with parameters self.add_skill("web_search", { "api_key": os.getenv("GOOGLE_API_KEY"), "search_engine_id": os.getenv("SEARCH_ENGINE_ID"), "num_results": 5, "min_quality_score": 0.4 }) # Skill with SWAIG field overrides self.add_skill("math", { "swaig_fields": { "fillers": { "en-US": ["Calculating..."] } } }) # Multi-instance skill self.add_skill("native_vector_search", { "tool_name": "search_products", "index_path": "/data/products.swsearch" }) self.add_skill("native_vector_search", { "tool_name": "search_faqs", "index_path": "/data/faqs.swsearch" }) self.prompt_add_section( "Role", "You are a customer service agent." ) if __name__ == "__main__": agent = ConfiguredAgent() agent.run() ``` -------------------------------- ### Complete Agent Example in Java Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx This Java example mirrors the Ruby quickstart, showcasing a complete agent with custom prompts, defined tools for time and jokes, and language/parameter settings. It's useful for developers building sophisticated conversational AI agents in a Java environment. ```java // CompleteFirstAgent.java - Complete agent example with multiple features import com.signalwire.agents.agent.AgentBase; import com.signalwire.agents.swaig.FunctionResult; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.*; public class CompleteFirstAgent { public static void main(String[] args) throws Exception { var agent = AgentBase.builder() .name("complete-agent").autoAnswer(true).recordCall(false).build(); agent.addLanguage("English", "en-US", "rime.spore"); agent.setParams(Map.of("end_of_speech_timeout", 500, "attention_timeout", 15000)); agent.addHints(List.of("SignalWire", "SWML", "AI agent")); agent.promptAddSection("Identity", "You are Alex, a helpful AI assistant created by SignalWire."); agent.promptAddSection("Capabilities", "You can help callers with:", List.of( "Answering general questions", "Telling jokes", "Providing the current time", "Basic conversation")); agent.promptAddSection("Style", "Keep responses brief and friendly. Use a conversational tone."); agent.defineTool("get_current_time", "Get the current time", Map.of(), (a, r) -> new FunctionResult("The current time is " + LocalTime.now().format(DateTimeFormatter.ofPattern("h:mm a")))); agent.defineTool("tell_joke", "Tell a random joke", Map.of(), (a, r) -> { var jokes = List.of( "Why do programmers prefer dark mode? Because light attracts bugs!", "Why did the developer go broke? Because they used up all their cache!", "There are only 10 types of people: those who understand binary and those who don't."); return new FunctionResult(jokes.get(new Random().nextInt(jokes.size()))); }); System.out.println("Complete First Agent running at http://localhost:3000"); agent.run(); } } ``` -------------------------------- ### Quick Start Agent Initialization Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/deploy/overview.mdx Initialize a new agent with a name and add language and role configurations. This is a common setup for most agent implementations. ```Python #!/usr/bin/env python3 from signalwire import AgentBase class MyAgent(AgentBase): def __init__(self): super().__init__(name="my-agent") self.add_language("English", "en-US", "rime.spore") self.prompt_add_section("Role", "You are a helpful assistant.") if __name__ == "__main__": agent = MyAgent() agent.run() ``` ```TypeScript import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); agent.promptAddSection('Role', { body: 'You are a helpful assistant.' }); agent.run(); ``` ```Go package main import "github.com/signalwire/signalwire-agents-go/pkg/agent" func main() { a := agent.NewAgentBase( agent.WithName("my-agent"), ) a.AddLanguage("English", "en-US", "rime.spore") a.PromptAddSection("Role", "You are a helpful assistant.") a.Run() } ``` ```Ruby require 'signalwire' agent = SignalWireAgents::AgentBase.new(name: "my-agent") agent.add_language("English", "en-US", "rime.spore") agent.prompt_add_section("Role", "You are a helpful assistant.") agent.run ``` ```Java import com.signalwire.agents.agent.AgentBase; public class MyAgent { public static void main(String[] args) { AgentBase agent = AgentBase.builder() .name("my-agent") .build(); agent.addLanguage("English", "en-US", "rime.spore"); agent.promptAddSection("Role", "You are a helpful assistant."); agent.run(); } } ``` ```Perl use SignalWire::Agents::Agent::AgentBase; my $agent = AgentBase->new(name => "my-agent"); $agent->add_language("English", "en-US", "rime.spore"); $agent->prompt_add_section("Role", "You are a helpful assistant."); $agent->run; ``` ```C++ #include int main() { agent::AgentBase agent("my-agent"); agent.addLanguage("English", "en-US", "rime.spore"); agent.promptAddSection("Role", "You are a helpful assistant."); agent.run(); return 0; } ``` ```PHP addLanguage('English', 'en-US', 'rime.spore'); $agent->promptAddSection('Role', 'You are a helpful assistant.'); $agent->run(); ``` ```C# using SignalWire.Agent; var agent = new AgentBase(new AgentOptions { Name = "my-agent" }); agent.AddLanguage("English", "en-US", "rime.spore"); agent.PromptAddSection("Role", "You are a helpful assistant."); agent.Run(); ``` -------------------------------- ### Complete Agent Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/overview.mdx This example demonstrates a complete agent that answers calls, uses an AI prompt, and exposes a custom tool. It sets up the agent, defines a prompt, configures parameters, registers a tool for checking order status, adds a skill, and starts the agent server. ```python from signalwire import AgentBase from signalwire.core.function_result import FunctionResult agent = AgentBase(name="support-agent", route="/support") agent.set_prompt_text( "You are a friendly support agent for Acme Corp. " "Help customers check their order status. " "Be concise and professional." ) agent.set_params({"temperature": 0.5, "end_of_speech_timeout": 800}) @agent.tool(description="Look up an order by ID") def check_order(args, raw_data): order_id = args.get("order_id", "unknown") return FunctionResult(f"Order {order_id} shipped on March 28 and arrives tomorrow.") agent.add_skill("datetime") if __name__ == "__main__": agent.serve() ``` -------------------------------- ### Start and Stop Recording with AppKit Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v3/guides/video/recording-video/index.mdx Use the `setupRoomSession` callback in AppKit to get a `RoomSession` reference and control recordings. This example starts a recording and stops it after 10 seconds. ```html ``` -------------------------------- ### Complete Agent Example in C++ Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx This C++ code implements a SignalWire Agent with similar features to the Perl example. It includes language and parameter settings, prompt definitions, and tool implementations for getting the current time and telling jokes, then starts the agent. ```cpp // complete_first_agent.cpp - Complete agent example with multiple features #include #include #include #include using namespace signalwire; int main() { agent::AgentBase a("complete-agent"); a.add_language({"English", "en-US", "rime.spore"}); a.set_params({{"end_of_speech_timeout", 500}, {"attention_timeout", 15000}}); a.add_hints({"SignalWire", "SWML", "AI agent"}); a.prompt_add_section("Identity", "You are Alex, a helpful AI assistant created by SignalWire."); a.prompt_add_section("Capabilities", "You can help callers with:", { "Answering general questions", "Telling jokes", "Providing the current time", "Basic conversation"}); a.prompt_add_section("Style", "Keep responses brief and friendly. Use a conversational tone."); a.define_tool("get_current_time", "Get the current time", {{"type", "object"}, {"properties", json::object()}}, [](const json& args, const json& raw) -> swaig::FunctionResult { auto t = std::time(nullptr); char buf[64]; std::strftime(buf, sizeof(buf), "%I:%M %p", std::localtime(&t)); return swaig::FunctionResult(std::string("The current time is ") + buf); }); a.define_tool("tell_joke", "Tell a random joke", {{"type", "object"}, {"properties", json::object()}}, [](const json& args, const json& raw) -> swaig::FunctionResult { std::vector jokes = { "Why do programmers prefer dark mode? Because light attracts bugs!", "Why did the developer go broke? Because they used up all their cache!", "There are only 10 types of people: those who understand binary and those who don't.", }; return swaig::FunctionResult(jokes[rand() % jokes.size()]); }); std::cout << "Complete First Agent running at http://localhost:3000" << std::endl; a.run(); } ``` -------------------------------- ### setup Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/skill-base/index.mdx Initialize the skill and validate dependencies. ```APIDOC ## setup() ### Description Initialize the skill and validate dependencies. ### Method This is a method within the SkillBase class. ### Returns * bool - True if initialization was successful, False otherwise. ``` -------------------------------- ### Full workflow example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-dokku.mdx This example demonstrates a complete workflow: initializing a project with web UI and CI/CD, configuring environment variables, deploying, and monitoring logs. ```bash # 1. Create a Dokku-ready project with web UI and CI/CD sw-agent-dokku init my-agent --web --cicd --host dokku.example.com # 2. Configure environment variables cd my-agent sw-agent-dokku config set \ SWML_BASIC_AUTH_PASSWORD=secure-password \ SIGNALWIRE_SPACE_NAME=my-space \ SIGNALWIRE_PROJECT_ID=my-project-id \ SIGNALWIRE_TOKEN=my-token # 3. Deploy sw-agent-dokku deploy # 4. Monitor sw-agent-dokku logs -t ``` -------------------------------- ### PromptManager with Post-Prompt and Full Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/configuration/prompt-manager/index.mdx Demonstrates adding role and rules sections, setting post-prompt text, and then retrieving the fully rendered prompt. This shows a more complete setup for agent prompts. ```typescript import { PromptManager } from '@signalwire/sdk'; const pm = new PromptManager(); pm.addSection('Role', { body: 'You are a friendly customer support agent.' }); pm.addSection('Rules', { bullets: ['Be concise', 'Be polite', 'Never guess'] }); pm.setPostPrompt('Summarize the conversation in JSON format.'); console.log(pm.getPrompt()); // ## Role // You are a friendly customer support agent. // // ## Rules // - Be concise // - Be polite // - Never guess ``` -------------------------------- ### Full Configuration Build Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx Shows a comprehensive example of building an index with various configurations, including multiple file types, language support, exclusion patterns, and NLP backends. ```bash sw-search ./docs ./examples README.md \ --output ./knowledge.swsearch \ --chunking-strategy sentence \ --max-sentences-per-chunk 8 \ --file-types md,txt,rst,py \ --exclude "**/test/**,**/__pycache__/**" \ --languages en,es,fr \ --model base \ --tags documentation,api \ --index-nlp-backend nltk \ --validate \ --verbose ``` -------------------------------- ### SWML Request Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/lifecycle.mdx Example of an HTTP GET request to an agent endpoint for SWML interactions. ```http GET / HTTP/1.1 Host: your-agent.com Authorization: Basic c2lnbmFsd2lyZTpwYXNzd29yZA== Accept: application/json X-Forwarded-For: signalwire-ip X-Forwarded-Proto: https ``` -------------------------------- ### Initialize Agent and Configure Settings in Go Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx Demonstrates how to create an agent, add language support, set a role prompt, define hints, configure parameters like end-of-speech timeout, and define a tool with a handler in Go. ```Go a := agent.NewAgentBase(agent.WithName("my-agent")) a.AddLanguage(map[string]any{"name": "English", "code": "en-US", "voice": "rime.spore"}) a.PromptAddSection("Role", "You are helpful.", nil) a.AddHints([]string{"help", "support"}) a.SetParam("end_of_speech_timeout", 500) a.DefineTool(agent.ToolDefinition{Name: "get_help", Description: "Get help", Handler: fn}) ``` -------------------------------- ### Quick Start: Building a LiveWire Agent Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/livewire/index.mdx This example demonstrates how to set up a basic LiveWire agent server with a function tool for looking up order status. It initializes the AgentServer, defines a tool, and sets up an RTC session entrypoint. ```python from signalwire.livewire import ( Agent, AgentSession, AgentServer, JobContext, JobProcess, function_tool, run_app, ) @function_tool def lookup_order(order_id: str) -> str: """Look up the status of a customer order.""" return f"Order {order_id} shipped yesterday." server = AgentServer() @server.rtc_session() async def entrypoint(ctx: JobContext): agent = Agent( instructions="You are a helpful order-status assistant.", tools=[lookup_order], ) session = AgentSession() await session.start(agent, room=ctx.room) run_app(server) ``` -------------------------------- ### Start MCP Gateway with CLI Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/mcp-gateway.mdx Start the MCP Gateway using the installed CLI command, specifying the configuration file. ```bash mcp-gateway -c config.json ``` -------------------------------- ### SkillBase.setup() Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/skill-base/setup.mdx Initializes the skill by validating environment variables, checking required packages, initializing API clients, and preparing resources. This method must be implemented in every `SkillBase` subclass. It should return `True` if setup is successful, and `False` otherwise. ```APIDOC ## **setup()** ### Description Initializes the skill, validates environment variables and packages, initializes API clients, and prepares resources. This method is called once when the skill is loaded. It is an abstract method that must be implemented in every `SkillBase` subclass. ### Returns `bool` -- `True` if setup succeeded, `False` to indicate the skill should not be loaded. ### Example ```python import os from signalwire.core.skill_base import SkillBase class WeatherSkill(SkillBase): SKILL_NAME = "weather" SKILL_DESCRIPTION = "Provides weather information" REQUIRED_PACKAGES = ["requests"] REQUIRED_ENV_VARS = ["WEATHER_API_KEY"] def setup(self) -> bool: if not self.validate_packages(): return False if not self.validate_env_vars(): return False self.api_key = os.getenv("WEATHER_API_KEY") return True def register_tools(self): pass # See register_tools page ``` ``` -------------------------------- ### Start HTTP Server Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/web-service/start.mdx Starts the HTTP server on the specified host and port. This method blocks until the server is stopped. Ensure FastAPI and uvicorn are installed. ```python from signalwire import WebService web = WebService( port=8002, directories={"/recordings": "./recordings"}, basic_auth=("admin", "secret"), enable_directory_browsing=True ) web.start(host="0.0.0.0", port=8002) ``` -------------------------------- ### Start Audio Stream with C# Source: https://github.com/signalwire/docs/blob/main/fern/products/compatibility-api/pages/cxml/voice/stream.mdx Configure and start an audio stream to a WebSocket endpoint using the Signalwire C# SDK. This example demonstrates setting the stream name and URL. ```csharp using System; using Twilio.TwiML; using Twilio.TwiML.Voice; class Example { static void Main() { var response = new VoiceResponse(); var start = new Start(); start.Stream(name: "Example Audio Stream", url: "wss://your-application.com/audiostream"); response.Append(start); Console.WriteLine(response.ToString()); } } ``` -------------------------------- ### Initialize and Use SWMLService in Python Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/swml-service/index.mdx Demonstrates initializing the SWMLService with default settings and with custom routing, port, and authentication. Also shows how to build a SWML document by adding verbs and serving it. ```python from signalwire import SWMLService # Basic service with defaults service = SWMLService(name="ivr") # Service with custom route and auth service = SWMLService( name="ivr", route="/swml", port=8080, basic_auth=("admin", "secret123") ) # Build a SWML document service.add_verb("answer", {}) service.add_verb("play", {"url": "https://example.com/welcome.mp3"}) service.add_verb("hangup", {}) # Serve it service.serve() ``` -------------------------------- ### Get Address Type Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v4/reference/Address/type$.mdx Retrieves the resource type of the address, for example, 'room' or 'subscriber'. ```typescript get type(): ResourceType ``` -------------------------------- ### Minimal Calling SWML Example Source: https://github.com/signalwire/docs/blob/main/fern/products/swml/pages/get-started/index.mdx This YAML example demonstrates a basic Calling SWML script that answers a call, plays a greeting, and then hangs up. It's a starting point for voice applications. ```yaml version: 1.0.0 sections: main: - answer: {} - play: url: "say:Hello, thanks for calling SignalWire." - hangup: {} ``` -------------------------------- ### Initialize Agent and Configure Settings in PHP Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx Shows how to create an agent, add language configurations, set a role prompt, specify hints, configure parameters, and define a tool with a handler in PHP. ```PHP addLanguage(name: 'English', code: 'en-US', voice: 'rime.spore'); // -> languages $agent->promptAddSection('Role', 'You are helpful.'); // -> prompt $agent->addHints(['help', 'support']); // -> hints $agent->setParams(['end_of_speech_timeout' => 500]); // -> params $agent->defineTool('get_help', 'Get help', [], function ($args, $raw) { ... }); // -> SWAIG ``` -------------------------------- ### Start Live Transcribe (JSON) Source: https://github.com/signalwire/docs/blob/main/fern/products/swml/pages/reference/methods/calling/live_transcribe/index.mdx This JSON configuration achieves the same as the YAML example for starting a live transcription. It includes webhook, language, live events, direction, and speech engine settings. ```json { "version": "1.0.0", "sections": { "main": [ { "answer": {} }, { "live_transcribe": { "action": { "start": { "webhook": "https://example.com/webhook", "lang": "en", "live_events": true, "direction": ["remote-caller", "local-caller"], "speech_engine": "deepgram" } } } } ] } } ``` -------------------------------- ### Example Usage Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/configuration/ssl-config/index.mdx Demonstrates how to instantiate SslConfig and check if SSL is configured, retrieving server options if available. ```APIDOC ## **Example** ```typescript {3,6-7} import { SslConfig } from '@signalwire/sdk'; const ssl = new SslConfig(); if (ssl.isConfigured()) { const opts = ssl.getServerOptions(); console.log('SSL ready with cert and key'); } else { console.log('SSL not configured — set SWML_SSL_ENABLED=true'); } ``` ``` -------------------------------- ### List Video Rooms with Node.js (Axios) Source: https://github.com/signalwire/docs/blob/main/fern/products/platform/pages/platform/setup/api-credentials.mdx This Node.js example uses the Axios library to make an authenticated request to list video rooms. Install Axios using 'npm install axios'. ```javascript // npm install axios import axios from "axios"; await axios .get("https://.signalwire.com/api/video/rooms", { auth: { username: "", password: "" }, }) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); ``` -------------------------------- ### Complete FAQBotAgent Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx A full example demonstrating the initialization of FAQBotAgent with FAQs, related question suggestions enabled, a custom persona, and agent naming. It also shows how to add language support and run the agent. ```python #!/usr/bin/env python3 ## product_faq_bot.py - FAQ bot for product questions from signalwire.prefabs import FAQBotAgent agent = FAQBotAgent( faqs=[ { "question": "What is the warranty period?", "answer": "All products come with a 2-year warranty.", "categories": ["warranty", "products"] }, { "question": "How do I return a product?", "answer": "Start a return within 30 days at returns.example.com.", "categories": ["returns", "products"] }, { "question": "Do you ship internationally?", "answer": "Yes, we ship to over 50 countries.", "categories": ["shipping"] } ], suggest_related=True, persona="You are a helpful product specialist for TechGadgets Inc.", name="product-faq" ) ## Add language agent.add_language("English", "en-US", "rime.spore") if __name__ == "__main__": agent.run() ``` -------------------------------- ### Complete Development Setup with ngrok Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/exposing-agents.mdx This setup involves starting ngrok in one terminal to expose your local server to a public URL, and running your agent in another terminal with the necessary environment variables configured. ```bash ## Terminal 1: Start ngrok with static domain ngrok http --url=https://your-name.ngrok-free.app 3000 ## Terminal 2: Start agent with environment variables export SWML_PROXY_URL_BASE=https://your-name.ngrok-free.app export SWML_BASIC_AUTH_USER=signalwire export SWML_BASIC_AUTH_PASSWORD=your-secure-password-here python my_agent.py ## Terminal 3: Test (use the credentials from Terminal 2) curl -u signalwire:your-secure-password-here https://your-name.ngrok-free.app/ curl -u signalwire:your-secure-password-here https://your-name.ngrok-free.app/debug ``` -------------------------------- ### Initialize Agent and Configure Settings in Java Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx Illustrates agent initialization, adding language support, setting a role prompt, defining hints, configuring parameters, and defining a tool with a handler in Java. ```Java var agent = AgentBase.builder().name("my-agent").build(); agent.addLanguage("English", "en-US", "rime.spore"); // -> languages agent.promptAddSection("Role", "You are helpful."); // -> prompt agent.addHints(List.of("help", "support")); // -> hints agent.setParams(Map.of("end_of_speech_timeout", 500)); // -> params agent.defineTool("get_help", "Get help", Map.of(), (args, raw) -> result); // -> SWAIG ``` -------------------------------- ### Complete Click to Call Configuration Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/click-to-call/technical-reference.mdx This example demonstrates how to spawn a C2CButton with all available core and callback parameters. Ensure the necessary parent elements exist in your HTML. ```javascript sw.c2c.spawn('C2CButton', { // Core parameters destination: '/public/support', buttonParentSelector: '#click2call', callParentSelector: '#call', innerHTML: '', // Callback parameters beforeCallStartFn: () => { console.log('Preparing to start call...'); document.getElementById('loading').style.display = 'block'; return true; }, afterCallStartFn: () => { console.log('Call connected!'); document.getElementById('loading').style.display = 'none'; document.getElementById('click2call').style.display = 'none'; }, beforeCallLeaveFn: () => { return confirm('Are you sure you want to end this call?'); }, afterCallLeaveFn: () => { console.log('Call ended.'); document.getElementById('click2call').style.display = 'block'; document.getElementById('feedback-form').style.display = 'block'; }, onCallError: (error) => { console.error('Call error:', error); document.getElementById('loading').style.display = 'none'; alert('Sorry, we couldn\'t connect your call. Please try again later.'); } }); ``` -------------------------------- ### Get Agent in Skill Setup Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-agent.mdx Use `getAgent()` within the `setup()` method of a skill to access the owning agent. This is guaranteed to be available after the skill has been attached. The agent can be used to add hints or interact with agent configuration. ```typescript import { SkillBase } from '@signalwire/sdk'; export class MySkill extends SkillBase { static SKILL_NAME = 'my-skill'; static SKILL_DESCRIPTION = 'An example skill'; async setup(): Promise { const agent = this.getAgent(); agent.addHint('Prefer concise answers.'); return true; } } ``` -------------------------------- ### Validate Required Packages in Skill Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/validate-packages.mdx Use `validatePackages` within a skill's `setup` method to ensure all necessary npm packages are installed. If packages are missing, it logs an error with installation instructions and returns `false`. ```typescript import { SkillBase } from '@signalwire/sdk'; export class ScraperSkill extends SkillBase { static SKILL_NAME = 'scraper'; static SKILL_DESCRIPTION = 'Scrapes web pages.'; static REQUIRED_PACKAGES = ['cheerio']; async setup(): Promise { const missing = await this.validatePackages(); if (missing.length > 0) { this.logger.error(`Install: npm install ${missing.join(' ')}`); return false; } return true; } } ``` -------------------------------- ### Build and Search Workflow Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx Demonstrates a typical workflow: building an index from markdown documentation with specific chunking, validating it, and then performing an interactive search. ```bash # Build from documentation with markdown-aware chunking sw-search ./docs \ --chunking-strategy markdown \ --file-types md \ --output knowledge.swsearch \ --verbose # Validate the index sw-search validate knowledge.swsearch # Search interactively sw-search search knowledge.swsearch --shell ``` -------------------------------- ### Basic Agent with Additions and a Tool Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/agent-base/index.mdx Set up a basic agent with language support, prompt text, hints, parameters, and a defined tool. This example demonstrates a more complete agent configuration. ```python from signalwire import AgentBase from signalwire.core.function_result import FunctionResult agent = AgentBase(name="support-agent", route="/support") agent.add_language("English", "en-US", "rime.spore") agent.set_prompt_text("You are a friendly customer support agent.") agent.add_hints(["SignalWire", "SWML", "SWAIG"]) agent.set_params({"temperature": 0.7, "end_of_speech_timeout": 1000}) @agent.tool(description="Look up an order by ID") def lookup_order(args, raw_data=None): order_id = args.get("order_id") return FunctionResult(f"Order {order_id} shipped on March 28.") agent.run() ``` -------------------------------- ### Making a GET Request with `request` (JSON) Source: https://github.com/signalwire/docs/blob/main/fern/products/swml/pages/reference/methods/calling/request.mdx This JSON structure shows an equivalent to the YAML example for making a GET request, saving response variables, and utilizing them in a subsequent action. Ensure `save_variables` is true for response parsing. ```json { "version": "1.0.0", "sections": { "main": [ { "answer": {} }, { "request": { "url": "https://jsonplaceholder.typicode.com/todos/1", "method": "GET", "save_variables": true, "timeout": 10 } }, { "play": { "url": "say: the title is: ${request_response.title}" } } ] } } ``` -------------------------------- ### Implement SkillBase Setup Method Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/skill-base/setup.mdx Implement the `setup` method in your SkillBase subclass to validate required packages and environment variables, and initialize API clients. Return `False` if validation fails to prevent the skill from loading. ```python import os from signalwire.core.skill_base import SkillBase class WeatherSkill(SkillBase): SKILL_NAME = "weather" SKILL_DESCRIPTION = "Provides weather information" REQUIRED_PACKAGES = ["requests"] REQUIRED_ENV_VARS = ["WEATHER_API_KEY"] def setup(self) -> bool: if not self.validate_packages(): return False if not self.validate_env_vars(): return False self.api_key = os.getenv("WEATHER_API_KEY") return True def register_tools(self): pass # See register_tools page ``` -------------------------------- ### Initialize a Basic Local Agent Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-init.mdx Creates a new agent project named 'support-bot' for local deployment. It then navigates into the project directory, activates the virtual environment, and starts the agent application. ```bash sw-agent-init support-bot cd support-bot source .venv/bin/activate python app.py ``` -------------------------------- ### Python Agent Session Say Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/say.mdx Queue text to be spoken by the agent. Text queued before start() is used as an initial greeting in the generated SWML document. Text queued after start() is spoken as soon as the agent is ready. ```python from signalwire.livewire import Agent, AgentSession, AgentServer, JobContext, run_app server = AgentServer() @server.rtc_session() async def entrypoint(ctx: JobContext): await ctx.connect() agent = Agent(instructions="You are a friendly receptionist.") session = AgentSession() await session.start(agent, room=ctx.room) session.say("Welcome! How can I help you today?") run_app(server) ``` -------------------------------- ### Start and Stop Recording with Browser SDK Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v3/guides/video/recording-video/index.mdx Initiate a recording in an ongoing room session using the `RoomSession.startRecording()` method. The returned object allows for pausing and stopping the recording. This example starts a recording and stops it after 10 seconds. ```javascript // Join a room const roomSession = new SignalWire.Video.RoomSession({ token: "", rootElement: document.getElementById("root"), }); await roomSession.join(); // Start recording const rec = await roomSession.startRecording(); // Stop recording after 10 seconds setTimeout(rec.stop, 10 * 1000); ``` -------------------------------- ### Using an existing ContextBuilder Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-contexts.mdx This example shows how to initialize an agent with a pre-configured `ContextBuilder`. This is useful when you have already defined contexts and steps and want to associate them with an agent. ```APIDOC ## defineContexts(builder: ContextBuilder) ### Description Define contexts and steps for multi-step conversation workflows. Contexts allow an agent to guide the caller through a structured sequence of interactions -- such as gathering information, verifying identity, and then performing an action. Returns a [`ContextBuilder`][contextbuilder] for fluent context definition. If an existing `ContextBuilder` instance is passed, it is used directly. Otherwise a new empty `ContextBuilder` is created and returned. ### Parameters #### Path Parameters - **contexts** (ContextBuilder | Record | undefined) - Optional - An existing `ContextBuilder` instance to use directly. If omitted or a plain object is passed, a new empty `ContextBuilder` is created instead. ### Returns [`ContextBuilder`][contextbuilder] -- The active `ContextBuilder` for further configuration. ### Examples #### Using an existing ContextBuilder ```typescript { "example": "import { AgentBase, ContextBuilder } from '@signalwire/sdk';\n\nconst builder = new ContextBuilder();\nconst ctx = builder.addContext('default');\nctx.addStep('greeting').setText('Greet the caller.');\nctx.addStep('verify').setText('Verify identity.');\n\nconst agent = new AgentBase({ name: 'intake', route: '/intake' });\nagent.defineContexts(builder);\nawait agent.serve();" } ``` ``` -------------------------------- ### Skill Setup Method Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/custom-skills.mdx Implement the setup method to initialize the skill and validate its requirements, such as necessary packages and environment variables. It also allows for setting custom parameters like API URLs and timeouts. ```python def setup(self) -> bool: if not self.validate_packages(): return False if not self.validate_env_vars(): return False self.api_url = self.params.get("api_url", "https://api.example.com") self.timeout = self.params.get("timeout", 30) return True ``` -------------------------------- ### Validate Required Packages in Python Skill Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/skill-base/validate-packages.mdx Use `validate_packages()` to ensure all necessary Python packages are installed and importable before proceeding with skill setup. This method is typically called within the `setup` method of a custom skill inheriting from `SkillBase`. ```python from signalwire.core.skill_base import SkillBase class MySkill(SkillBase): SKILL_NAME = "my_skill" SKILL_DESCRIPTION = "Example skill" REQUIRED_PACKAGES = ["requests", "beautifulsoup4"] REQUIRED_ENV_VARS = ["MY_API_KEY", "MY_SECRET"] def setup(self) -> bool: if not self.validate_packages(): return False if not self.validate_env_vars(): return False return True def register_tools(self): pass ``` -------------------------------- ### Get Auth Info Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/configuration/auth-handler/index.mdx Retrieve a summary of the authentication methods configured for the AuthHandler. This is useful for understanding the current authentication setup. ```python from signalwire.core.security_config import SecurityConfig from signalwire.core.auth_handler import AuthHandler security = SecurityConfig() auth = AuthHandler(security) # Check which methods are configured info = auth.get_auth_info() print(info) # {'basic': {'enabled': True, 'username': 'signalwire'}} ``` -------------------------------- ### Initialize WebService Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/web-service/index.mdx Instantiate the WebService with specified port, directories to serve, and enable directory browsing. The server is then started. ```python from signalwire import WebService web = WebService( port=8002, directories={"/audio": "./audio_files", "/docs": "./public"}, enable_directory_browsing=True ) web.start() ``` -------------------------------- ### Localtunnel Setup Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/exposing-agents.mdx Install `localtunnel` globally using npm and then run it to expose your local port 3000 to a public URL. ```bash ## Install npm install -g localtunnel ## Run lt --port 3000 ``` -------------------------------- ### Complete Receptionist Agent Example Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/receptionist.mdx A full Python example demonstrating how to initialize and run a receptionist agent with multiple departments and a custom greeting. ```python #!/usr/bin/env python3 ## company_receptionist.py - Custom receptionist agent from signalwire.prefabs import ReceptionistAgent agent = ReceptionistAgent( departments=[ { "name": "sales", "description": "New orders, pricing, quotes, and product information", "number": "+15551001001" }, { "name": "support", "description": "Technical issues, troubleshooting, and product help", "number": "+15551001002" }, { "name": "billing", "description": "Invoices, payments, refunds, and account questions", "number": "+15551001003" }, { "name": "hr", "description": "Employment, careers, and benefits", "number": "+15551001004" } ], greeting="Thank you for calling Acme Corporation. How may I direct your call?", voice="rime.spore", name="acme-receptionist" ) ## Add custom prompt section agent.prompt_add_section( "Company", "You are the receptionist for Acme Corporation, a leading technology company." ) if __name__ == "__main__": agent.run() ``` -------------------------------- ### Cloudflare Tunnel Setup Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/getting-started/exposing-agents.mdx Install `cloudflared` and use it to create a tunnel for your local development server. This is a free alternative to ngrok. ```bash ## Install cloudflared brew install cloudflared # macOS ## Quick tunnel (no account needed) cloudflared tunnel --url http://localhost:3000 ``` -------------------------------- ### Create an FAQ Bot Agent in Go Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx Set up an FAQ Bot Agent in Go using the prefabs package. Configure it with a list of FAQs and then run the agent. ```go package main import "github.com/signalwire/signalwire-agents-go/pkg/prefabs" func main() { agent := prefabs.NewFAQBotAgent( prefabs.WithFAQs([]prefabs.FAQ{ {Question: "What are your business hours?", Answer: "We're open Monday through Friday, 9 AM to 5 PM."}, {Question: "Where are you located?", Answer: "Our main office is at 123 Main Street, Downtown."}, {Question: "How do I contact support?", Answer: "Email support@example.com or call 555-1234."}, }), ) agent.Run() } ``` -------------------------------- ### Example Configuration File Source: https://github.com/signalwire/docs/blob/main/fern/products/server-sdks/pages/reference/python/agents/configuration/index.mdx An example JSON configuration file demonstrating various settings including service details, security configurations (authentication, SSL), agent behavior, and skills with parameters. It uses environment variable substitution syntax like `${AUTH_USER|support_agent}`. ```json { "service": { "name": "support-agent", "host": "0.0.0.0", "port": 8080, "route": "/support" }, "security": { "auth": { "basic": { "user": "${AUTH_USER|support_agent}", "password": "${AUTH_PASSWORD}" } }, "ssl_enabled": true, "domain": "support.example.com", "ssl_cert_path": "/etc/ssl/certs/support.crt", "ssl_key_path": "/etc/ssl/private/support.key" }, "agent": { "auto_answer": true, "record_call": false }, "skills": [ { "name": "datetime" }, { "name": "native_vector_search", "params": { "index_file": "./support_docs.swsearch", "tool_name": "search_support" } } ] } ``` -------------------------------- ### Get statsBaselineSamples Source: https://github.com/signalwire/docs/blob/main/fern/products/browser-sdk/pages/v4/reference/ClientPreferences/statsBaselineSamples.mdx Retrieves the current number of baseline samples for stats monitoring. No setup is required beyond having a client instance. ```typescript console.log(client.preferences.statsBaselineSamples); ```