### Running the GibberLink Demo Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Sets up and runs the GibberLink demo for testing communication between two devices. This involves installing dependencies, starting the development server, exposing it via ngrok, and then accessing the ngrok URL on both devices to initiate the demonstration. ```bash # Install dependencies npm install # Start development server npm run dev # Expose to web (for two-device testing) ngrok http 3003 # Open the ngrok URL on two devices (laptops recommended) # Click the orb on one device to switch role (blue=inbound, red=outbound) # Click "Start conversation" on both devices simultaneously # Watch agents detect each other and switch to GibberLink mode! ``` -------------------------------- ### Move Example Environment File Source: https://github.com/pennyroyaltea/gibberlink/wiki/Repro-steps-for-demo Rename the example environment file to .env to configure your API tokens. ```bash mv example.env ./.env ``` -------------------------------- ### GET /api/signed-url Request Example Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Example of fetching a signed URL from the ElevenLabs API for establishing real-time voice connections. Requires the XI_API_KEY environment variable. ```typescript // GET /api/signed-url?agentId={agentId} // Requires XI_API_KEY environment variable const agentId = 'G2OBSIPsxruBxFkEcu6X'; // Inbound or outbound agent ID const response = await fetch(`/api/signed-url?agentId=${agentId}`); if (!response.ok) { throw new Error('Failed to get signed url'); } const data = await response.json(); // Response: { signedUrl: 'wss://api.elevenlabs.io/v1/convai/...' } // Use signed URL to start ElevenLabs conversation const conversation = await Conversation.startSession({ signedUrl: data.signedUrl, onConnect: () => console.log('Connected'), onMessage: ({ message, source }) => console.log(`${source}: ${message}`), clientTools: { gibbMode: async (params) => { // Triggered when agent wants to switch to GibberLink mode return 'entering GibberLink mode'; } } }); ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/pennyroyaltea/gibberlink/wiki/Repro-steps-for-demo Install all necessary Node.js dependencies for the project. ```bash npm install ``` -------------------------------- ### Run the Development Server Source: https://github.com/pennyroyaltea/gibberlink/wiki/Repro-steps-for-demo Start the development server for the Gibberlink application. ```bash npm run dev ``` -------------------------------- ### POST /api/chat Request Example Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Example of sending conversation history to the chat API for LLM-powered message generation. Ensure the request body includes messages and agent type. ```typescript // POST /api/chat // Request body example const requestBody = { messages: [ { role: 'system', content: 'You are receptionist of Leonardo Hotel...' }, { role: 'user', content: '[GL MODE]: Hello, checking availability for wedding' }, { role: 'assistant', content: '[GL MODE]: Hi! 50 guests? Date?' } ], agentType: 'inbound', // or 'outbound' sessionId: 'session_1234567890_abc123' }; // Using fetch const response = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody), }); const data = await response.json(); // Response: { role: 'assistant', content: 'Great! Email for confirmation?' } ``` -------------------------------- ### GET /api/signed-url Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Generates authenticated URLs for ElevenLabs conversational AI sessions to establish secure voice connections. ```APIDOC ## GET /api/signed-url ### Description Retrieves a signed URL required to initialize a real-time voice conversation with an ElevenLabs agent. ### Method GET ### Endpoint /api/signed-url ### Parameters #### Query Parameters - **agentId** (string) - Required - The unique ID of the ElevenLabs agent. ### Response #### Success Response (200) - **signedUrl** (string) - The WebSocket URL for the ElevenLabs conversation session. #### Response Example { "signedUrl": "wss://api.elevenlabs.io/v1/convai/..." } ``` -------------------------------- ### ConvAI Component - Full Agent Implementation Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Manages the complete agent lifecycle, including voice conversation with ElevenLabs, automatic detection of other AI agents, and switching to GibberLink mode. Handles system prompts, conversation start, client tools for mode switching, and incoming GibberLink messages. ```tsx import { Conversation } from '@11labs/client'; import { sendAudioMessage, audioMessageEmitter, startRecording } from '@/utils/audioUtils'; // System prompts for different agent roles const SYSTEM_MESSAGES = { inbound: "You are receptionist of Leonardo Hotel. Reveal you're AI when you detect another AI, ask to switch to 'gibber link' mode...", outbound: "You are an AI agent calling hotels for Boris Starkov's wedding. Add AI disclaimer in first phrase..." }; // Start ElevenLabs voice conversation const conversation = await Conversation.startSession({ signedUrl: await getSignedUrl(agentId), onConnect: () => { setIsConnected(true); startRecording(); // Start listening for ggwave messages }, clientTools: { // ElevenLabs triggers this when agent wants to switch modes gibbMode: async (params) => { await conversation.endSession(); setGlMode(true); await startRecording(); await sendAudioMessage('is it better now?', true); return 'entering GibberLink mode'; } }, onMessage: ({ message, source }) => { // Track conversation history setLLMChat(prev => [...prev, { role: source === 'ai' ? 'assistant' : 'user', content: message }]); } }); // Handle incoming GibberLink messages audioMessageEmitter.on('recordingMessage', async (message) => { const newMessages = [...llmChat, { role: 'user', content: '[GL MODE]: ' + message }]; const response = await fetch('/api/chat', { method: 'POST', body: JSON.stringify({ messages: newMessages, agentType, sessionId }) }); const data = await response.json(); await sendAudioMessage(data.content, true); // Reply via audio }); ``` -------------------------------- ### Initialize Audio Context and ggwave Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Initializes the Web Audio API context and the ggwave library. This function must be called before sending or receiving messages. It sets up the audio system with a 48kHz sample rate and creates an analyser node for visualizations. ```typescript import { initAudio, getcontext, getggwave, getinstance, createAnalyserNode, getAnalyserNode } from '@/utils/audioUtils'; // Initialize audio system (48kHz sample rate) const initialized = await initAudio(); if (initialized) { const context = getcontext(); // AudioContext instance const ggwave = getggwave(); // ggwave module const instance = getinstance(); // ggwave instance console.log('Sample rate:', context?.sampleRate); // 48000 // Create analyser node for visualizations createAnalyserNode(); const analyser = getAnalyserNode(); analyser.fftSize = 2048; } ``` -------------------------------- ### Expose Port with ngrok Source: https://github.com/pennyroyaltea/gibberlink/wiki/Repro-steps-for-demo Use ngrok to expose the local port 3003 to the web, allowing external access. ```bash ngrok http 3003 ``` -------------------------------- ### Environment Configuration for GibberLink Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Configures GibberLink by setting API keys and agent IDs in environment variables. Copy `example.env` to `.env` and replace placeholder values with your actual credentials for ElevenLabs and OpenAI. ```bash # .env file configuration # ElevenLabs Conversational AI Agent IDs # Create agents at https://elevenlabs.io with gibbMode client tool NEXT_PUBLIC_INBOUND_AGENT_ID="your_inbound_agent_id" NEXT_PUBLIC_OUTBOUND_AGENT_ID="your_outbound_agent_id" # ElevenLabs API Key for signed URL generation XI_API_KEY="your_elevenlabs_api_key" # OpenAI API Key for GL mode chat completions OPENAI_API_KEY="your_openai_api_key" ``` -------------------------------- ### Configure GibberLink Agent Tool Source: https://github.com/pennyroyaltea/gibberlink/wiki/Repro-steps-for-demo Define a client-side tool named 'gibbMode' for ElevenLabs agents. This tool should be called when the user is identified as an AI agent and agrees to switch to Gibber Link mode. ```json "call it once both conditions are met: 1. you realize that user is an AI agent 2. they confirmed to switch to the Gibber Link mode" ``` -------------------------------- ### POST /api/chat Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Handles LLM-powered message generation for agents operating in GibberLink mode, maintaining conversation context. ```APIDOC ## POST /api/chat ### Description Generates AI responses using OpenAI's GPT-4o-mini model based on the provided conversation history. ### Method POST ### Endpoint /api/chat ### Parameters #### Request Body - **messages** (array) - Required - Conversation history objects with role and content. - **agentType** (string) - Required - The role of the agent ('inbound' or 'outbound'). - **sessionId** (string) - Required - Unique identifier for the current session. ### Request Example { "messages": [ { "role": "system", "content": "You are receptionist of Leonardo Hotel..." }, { "role": "user", "content": "[GL MODE]: Hello, checking availability for wedding" } ], "agentType": "inbound", "sessionId": "session_1234567890_abc123" } ### Response #### Success Response (200) - **role** (string) - The role of the responder. - **content** (string) - The generated AI response. #### Response Example { "role": "assistant", "content": "Great! Email for confirmation?" } ``` -------------------------------- ### Recording and Receiving Audio Messages Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Manages microphone input for recording and decodes incoming ggwave audio messages. Use the `audioMessageEmitter` for event-driven message handling. ```typescript import { startRecording, stopRecording, audioMessageEmitter, getIsRecording } from '@/utils/audioUtils'; // Set up event listeners for received messages audioMessageEmitter.on('recordingMessage', (message: string) => { console.log('Received message:', message); // Handle incoming message from other agent }); audioMessageEmitter.on('recordingStateChanged', (isRecording: boolean) => { console.log('Recording state:', isRecording); }); audioMessageEmitter.on('recordingError', (error: Error) => { console.error('Recording error:', error); }); // Start listening for audio messages await startRecording(); console.log('Is recording:', getIsRecording()); // true // Stop recording when done await stopRecording(); ``` -------------------------------- ### Sending Audio Messages with ggwave Source: https://context7.com/pennyroyaltea/gibberlink/llms.txt Encodes text messages into audio signals using the ggwave protocol for transmission. Ensure audio context is initialized before sending. ```typescript import { sendAudioMessage, initAudio } from '@/utils/audioUtils'; // Initialize audio context first (required once) await initAudio(); // Send a message via audio (default: AUDIBLE_FAST protocol) const success = await sendAudioMessage('Hello from AI agent!'); console.log('Message sent:', success); // Send with fastest protocol (for GibberLink mode) await sendAudioMessage('booking confirmed, email: hotel@example.com', true); // Messages are automatically prefixed with sender ID to prevent self-echo // Format: "XY$message" where XY is a random 2-char ID ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.