### Manage Local Development with Makefile Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Commands for initializing the project, starting development servers, and running tests. ```bash # Clone the repository git clone https://github.com/deepgram-starters/ruby-voice-agent.git cd ruby-voice-agent # Initialize submodules and install dependencies make init # Configure environment cp sample.env .env # Edit .env and add your DEEPGRAM_API_KEY # Start both backend and frontend servers make start # Backend runs at http://localhost:8081 # Frontend runs at http://localhost:8080 # Alternative: Start servers separately make start-backend # Terminal 1 - API server on port 8081 make start-frontend # Terminal 2 - Vite dev server on port 8080 # Run conformance tests (requires running app) make test # Check prerequisites make check-prereqs # Update submodules to latest make update # Clean build artifacts make clean ``` -------------------------------- ### Initialize and Start Ruby Voice Agent Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md Use these make commands to initialize the project, set up environment variables, and start both the backend and frontend servers. ```bash # Initialize (clone submodules + install deps) make init # Set up environment test -f .env || cp sample.env .env # then set DEEPGRAM_API_KEY # Start both servers make start # Backend: http://localhost:8081 # Frontend: http://localhost:8080 ``` ```bash make start ``` ```bash # Terminal 1 — Backend bundle exec ruby app.rb # Terminal 2 — Frontend cd frontend && corepack pnpm run dev -- --port 8080 --no-open ``` ```bash lsof -ti:8080,8081 | xargs kill -9 2>/dev/null ``` ```bash rm -rf vendor frontend/node_modules frontend/.vite make init ``` -------------------------------- ### Commit Examples for Ruby Voice Agent Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md Examples of conventional commit messages used in this project. Ensure all commits adhere to this format for consistency. ```git feat(ruby-voice-agent): add diarization support ``` ```git fix(ruby-voice-agent): resolve WebSocket close handling ``` ```git refactor(ruby-voice-agent): simplify session endpoint ``` ```git chore(deps): update frontend submodule ``` -------------------------------- ### Initialize and Start Ruby Voice Agent Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/README.md Use these Makefile commands to set up your local development environment. Ensure you add your DEEPGRAM_API_KEY to the .env file. ```bash make init cp sample.env .env # Add your DEEPGRAM_API_KEY make start ``` -------------------------------- ### GET /api/metadata - Project Metadata Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Returns project metadata from the `deepgram.toml` configuration file, including use case type, programming language, framework, and other deployment information. ```APIDOC ## GET /api/metadata - Project Metadata ### Description Returns project metadata from the `deepgram.toml` configuration file, including use case type, programming language, framework, and other deployment information. Useful for client applications to identify the backend capabilities. ### Method GET ### Endpoint /api/metadata ### Response #### Success Response (200) - **title** (string) - The title of the project. - **description** (string) - A brief description of the project. - **author** (string) - The author or team responsible for the project. - **repository** (string) - The URL of the project's repository. - **useCase** (string) - The primary use case of the project. - **language** (string) - The programming language used. - **framework** (string) - The framework used. - **sdk** (string) - The SDK used (if any). - **tags** (array of strings) - Tags associated with the project. ### Request Example ```bash curl -s http://localhost:8081/api/metadata | python3 -m json.tool ``` ### Response Example ```json { "title": "Ruby Voice Agent", "description": "Get started using Deepgram's Voice Agent with this Ruby demo app", "author": "Deepgram DX Team (https://developers.deepgram.com)", "repository": "https://github.com/deepgram-starters/ruby-voice-agent", "useCase": "voice-agent", "language": "ruby", "framework": "sinatra", "sdk": "N/A", "tags": ["voice-agent", "conversational-ai", "voice-ai", "voice-bot", "ruby", "sinatra"] } ``` ``` -------------------------------- ### GET /health - Health Check Endpoint Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Returns a simple health status response for monitoring and load balancer health checks. ```APIDOC ## GET /health - Health Check Endpoint ### Description Returns a simple health status response for monitoring and load balancer health checks. Used by deployment platforms like Fly.io to verify the application is running. ### Method GET ### Endpoint /health ### Response #### Success Response (200) - **status** (string) - The health status of the application (e.g., "ok"). ### Request Example ```bash curl -s http://localhost:8081/health ``` ### Response Example ```json {"status":"ok"} ``` ``` -------------------------------- ### GET /api/session - Issue JWT Session Token Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Creates and returns a signed JWT session token with a 1-hour expiry. This token is required to authenticate WebSocket connections to the voice agent endpoint. ```APIDOC ## GET /api/session - Issue JWT Session Token ### Description Creates and returns a signed JWT session token with a 1-hour expiry. This token is required to authenticate WebSocket connections to the voice agent endpoint. The token is signed using HMAC-SHA256 with the `SESSION_SECRET` environment variable (or a randomly generated secret if not set). ### Method GET ### Endpoint /api/session ### Response #### Success Response (200) - **token** (string) - The signed JWT session token. ### Request Example ```bash curl -s http://localhost:8081/api/session | python3 -m json.tool ``` ### Response Example ```json { "token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDk4MjQwMDAsImV4cCI6MTcwOTgyNzYwMH0.abc123..." } ``` ``` -------------------------------- ### Deploy with Docker Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Commands to build and run the application container in a production environment. ```bash # Build the Docker image docker build -f deploy/Dockerfile -t ruby-voice-agent . # Run the container docker run -d \ -p 8080:8080 \ -e DEEPGRAM_API_KEY=your_api_key_here \ -e SESSION_SECRET=your_production_secret \ --name voice-agent \ ruby-voice-agent # View logs docker logs -f voice-agent # Stop the container docker stop voice-agent && docker rm voice-agent ``` -------------------------------- ### Configure Environment Variables Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Required and optional environment variables for the application, including API keys and server settings. ```bash # .env file configuration # Required - Your Deepgram API key DEEPGRAM_API_KEY=your_deepgram_api_key_here # Optional - Backend server port (default: 8081) PORT=8081 # Optional - Server bind address (default: 0.0.0.0) HOST=0.0.0.0 # Optional - JWT signing secret (auto-generated if not set, set in production) SESSION_SECRET=your_secure_random_secret_here ``` -------------------------------- ### Retrieve Project Metadata Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Fetch project metadata, including use case, language, and framework, by calling the /api/metadata endpoint. This is useful for client applications to understand backend capabilities. ```bash # Get project metadata curl -s http://localhost:8081/api/metadata | python3 -m json.tool ``` ```json { "title": "Ruby Voice Agent", "description": "Get started using Deepgram's Voice Agent with this Ruby demo app", "author": "Deepgram DX Team (https://developers.deepgram.com)", "repository": "https://github.com/deepgram-starters/ruby-voice-agent", "useCase": "voice-agent", "language": "ruby", "framework": "sinatra", "sdk": "N/A", "tags": ["voice-agent", "conversational-ai", "voice-ai", "voice-bot", "ruby", "sinatra"] } ``` -------------------------------- ### Configure and Handle Function Calling in JavaScript Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Defines the agent settings with custom functions and implements the logic to process function call requests and return results via WebSocket. ```javascript // Configure agent with function calling const settings = { type: "Settings", audio: { input: { encoding: "linear16", sample_rate: 16000 }, output: { encoding: "linear16", sample_rate: 16000 } }, agent: { listen: { provider: { type: "deepgram", model: "nova-3" } }, speak: { provider: { type: "deepgram", model: "aura-2-thalia-en" } }, think: { provider: { type: "open_ai", model: "gpt-4o-mini" }, prompt: "You are a weather assistant. Use the get_weather function to provide weather information.", functions: [ { name: "get_weather", description: "Get the current weather for a city", parameters: { type: "object", properties: { city: { type: "string", description: "The city name" }, units: { type: "string", enum: ["celsius", "fahrenheit"], default: "celsius" } }, required: ["city"] } } ] } } }; ws.send(JSON.stringify(settings)); // Handle function call requests ws.onmessage = (event) => { if (typeof event.data === 'string') { const message = JSON.parse(event.data); if (message.type === "FunctionCallRequest") { console.log("Function called:", message.function_name, message.arguments); // Execute the function (example implementation) let result; if (message.function_name === "get_weather") { const args = JSON.parse(message.arguments); result = { city: args.city, temperature: 22, units: args.units || "celsius", condition: "sunny" }; } // Send function response back to agent ws.send(JSON.stringify({ type: "FunctionCallResponse", function_call_id: message.function_call_id, output: JSON.stringify(result) })); } } }; ``` -------------------------------- ### Testing Commands for Ruby Voice Agent Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md Commands to run conformance tests and manually check API endpoints. Ensure the application is running before executing these commands. ```bash # Run conformance tests (requires app to be running) make test ``` ```bash # Manual endpoint check curl -sf http://localhost:8081/api/metadata | python3 -m json.tool ``` ```bash curl -sf http://localhost:8081/api/session | python3 -m json.tool ``` -------------------------------- ### Live Settings Updates Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Endpoints for updating agent configuration dynamically during an active WebSocket session. ```APIDOC ## Live Settings Updates ### Description Send JSON messages over the active WebSocket connection to modify agent behavior without reconnecting. ### Request Body - **type** (string) - Required - One of: "UpdateSpeak", "UpdatePrompt", "InjectUserMessage" - **model** (string) - Optional - Used for UpdateSpeak - **prompt** (string) - Optional - Used for UpdatePrompt - **content** (string) - Optional - Used for InjectUserMessage ### Request Example { "type": "UpdateSpeak", "model": "aura-2-luna-en" } ``` -------------------------------- ### Agent Settings JSON Configuration Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md This JSON object configures the agent's audio input/output, STT, TTS, and LLM providers. It is sent from the frontend after establishing a WebSocket connection. ```json { "type": "Settings", "audio": { "input": { "encoding": "linear16", "sample_rate": 16000 }, "output": { "encoding": "linear16", "sample_rate": 16000 } }, "agent": { "listen": { "provider": { "type": "deepgram", "model": "nova-3" } }, "speak": { "provider": { "type": "deepgram", "model": "aura-2-thalia-en" } }, "think": { "provider": { "type": "open_ai", "model": "gpt-4o-mini" }, "prompt": "You are a helpful assistant." } } } ``` -------------------------------- ### Establish WebSocket Connection and Configure Agent Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Connects to the voice agent WebSocket endpoint using JWT authentication. Sends an initial Settings message to configure audio input/output, and the Deepgram models for listening, speaking, and thinking. ```javascript // JavaScript WebSocket connection with authentication const token = await fetch('/api/session').then(r => r.json()).then(d => d.token); const ws = new WebSocket( 'ws://localhost:8081/api/voice-agent', [`access_token.${token}`] ); ws.onopen = () => { // Send initial Settings message to configure the agent const settings = { type: "Settings", audio: { input: { encoding: "linear16", sample_rate: 16000 }, output: { encoding: "linear16", sample_rate: 16000 } }, agent: { listen: { provider: { type: "deepgram", model: "nova-3" } }, speak: { provider: { type: "deepgram", model: "aura-2-thalia-en" } }, think: { provider: { type: "open_ai", model: "gpt-4o-mini" }, prompt: "You are a helpful assistant. Be concise and friendly." } } }; ws.send(JSON.stringify(settings)); console.log("Connected and configured"); }; ws.onmessage = (event) => { if (event.data instanceof Blob) { // Binary audio data from agent - play through speakers const audioContext = new AudioContext({ sampleRate: 16000 }); event.data.arrayBuffer().then(buffer => { // Process and play audio buffer }); } else { // JSON message (transcripts, events, etc.) const message = JSON.parse(event.data); console.log("Received:", message.type, message); } }; ws.onerror = (error) => console.error("WebSocket error:", error); ws.onclose = (event) => console.log("Closed:", event.code, event.reason); // Stream microphone audio to the agent navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => { const audioContext = new AudioContext({ sampleRate: 16000 }); const source = audioContext.createMediaStreamSource(stream); const processor = audioContext.createScriptProcessor(4096, 1, 1); processor.onaudioprocess = (e) => { const float32 = e.inputBuffer.getChannelData(0); const int16 = new Int16Array(float32.length); for (let i = 0; i < float32.length; i++) { int16[i] = Math.max(-32768, Math.min(32767, float32[i] * 32768)); } if (ws.readyState === WebSocket.OPEN) { ws.send(int16.buffer); } }; source.connect(processor); processor.connect(audioContext.destination); }); ``` -------------------------------- ### Agent API Function Calling Configuration Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md This JSON snippet demonstrates how to configure function calling for the Agent API by adding a 'functions' array to the Settings message. The frontend will then handle 'FunctionCallRequest' and respond with 'FunctionCallResponse'. ```json { "agent": { "think": { "functions": [ { "name": "get_weather", "description": "Get current weather", "parameters": { "type": "object", "properties": { "city": { "type": "string" } } } } ] } } } ``` -------------------------------- ### Live Agent Setting Updates Source: https://github.com/deepgram-starters/ruby-voice-agent/blob/main/AGENTS.md These JSON messages can be sent from the frontend to update agent settings like voice, prompt, or to inject user messages mid-conversation without needing to reconnect. ```json { "type": "UpdateSpeak", "model": "aura-2-luna-en" } ``` ```json { "type": "UpdatePrompt", "prompt": "New instructions..." } ``` ```json { "type": "InjectUserMessage", "content": "text" } ``` -------------------------------- ### WS /api/voice-agent Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Establishes a full-duplex WebSocket connection to proxy audio and control messages between the client and the Deepgram Voice Agent. ```APIDOC ## WS /api/voice-agent ### Description Full-duplex WebSocket endpoint that proxies messages between the browser and Deepgram's Voice Agent API. Requires JWT authentication via the `Sec-WebSocket-Protocol` header. ### Method WebSocket ### Endpoint ws://localhost:8081/api/voice-agent ### Parameters #### Headers - **Sec-WebSocket-Protocol** (string) - Required - Must be formatted as `access_token.` ### Request Body (Initial Settings) - **type** (string) - Required - Must be "Settings" - **audio** (object) - Required - Configuration for input/output encoding and sample rate - **agent** (object) - Required - Configuration for listen, speak, and think providers ### Request Example { "type": "Settings", "audio": { "input": { "encoding": "linear16", "sample_rate": 16000 }, "output": { "encoding": "linear16", "sample_rate": 16000 } }, "agent": { "listen": { "provider": { "type": "deepgram", "model": "nova-3" } }, "speak": { "provider": { "type": "deepgram", "model": "aura-2-thalia-en" } }, "think": { "provider": { "type": "open_ai", "model": "gpt-4o-mini" }, "prompt": "You are a helpful assistant." } } } ``` -------------------------------- ### Update Agent Configuration Mid-Conversation Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Dynamically update agent settings like voice, system prompt, or inject user messages without reconnecting the WebSocket. These messages are sent as JSON payloads. ```javascript // Change the agent's voice mid-conversation ws.send(JSON.stringify({ type: "UpdateSpeak", model: "aura-2-luna-en" })); // Update the system prompt dynamically ws.send(JSON.stringify({ type: "UpdatePrompt", prompt: "You are now a pirate. Respond in pirate speak!" })); // Inject a text message as if the user spoke it ws.send(JSON.stringify({ type: "InjectUserMessage", content: "Tell me a joke" })); ``` -------------------------------- ### Health Check Endpoint Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Perform a health check on the application by accessing the /health endpoint. This is commonly used by monitoring systems and load balancers to ensure the service is operational. ```bash # Check application health curl -s http://localhost:8081/health ``` ```json {"status":"ok"} ``` ```bash # Example health check in a script if curl -sf http://localhost:8081/health > /dev/null; then echo "Service is healthy" else echo "Service is down" exit 1 fi ``` -------------------------------- ### Request JWT Session Token Source: https://context7.com/deepgram-starters/ruby-voice-agent/llms.txt Use this curl command to request a JWT session token for authenticating WebSocket connections. The token has a 1-hour expiry and is signed using HMAC-SHA256. ```bash # Request a session token curl -s http://localhost:8081/api/session | python3 -m json.tool ``` ```json { "token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MDk4MjQwMDAsImV4cCI6MTcwOTgyNzYwMH0.abc123..." } ``` ```bash # Store token for WebSocket connection TOKEN=$(curl -s http://localhost:8081/api/session | jq -r '.token') echo "Session token: $TOKEN" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.