{"_id":"@airsurfer09/rtvi-client","_rev":"2-b15fb9eeec82e6212a6dc2fb0fc6ff1c","name":"@airsurfer09/rtvi-client","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@airsurfer09/rtvi-client","version":"1.0.0","keywords":[],"author":"","license":"ISC","_id":"@airsurfer09/rtvi-client@1.0.0","maintainers":[{"name":"airsurfer09","email":"saurav@convai.com"}],"dist":{"shasum":"616ee4f94b4ee1fd78d10a6d33f06b57f200208e","tarball":"https://registry.npmjs.org/@airsurfer09/rtvi-client/-/rtvi-client-1.0.0.tgz","fileCount":5,"integrity":"sha512-aO6nSa7P9Pl6fr48GO9kND6ma7lD0DMumN9IOtr/0ZstaiaJRVstqNqzBt4vKPWynegzNQHTSSgCPGGbLRgJOQ==","signatures":[{"sig":"MEUCIQCJrcNGbBSmXlILkY+yK+I5UAne7Qlol4EWNSxsvikBkgIgHstJ4U9NqnTmw0ANqFEoTZwXfoPEDr7nZGL106uKxAc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34202},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"7ec72a5662aaf701e3d34c35254a4aa0b0d6af49","private":false,"scripts":{"dev":"tsup src/index.ts --dts --format esm,cjs --watch","lint":"eslint .","build":"tsup src/index.ts --dts --format esm,cjs","clean":"rm -rf dist"},"_npmUser":{"name":"airsurfer09","actor":{"name":"airsurfer09","type":"user","email":"saurav@convai.com"},"email":"saurav@convai.com"},"_npmVersion":"10.9.2","description":"RTVI Client Library","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@pipecat-ai/client-js":"^0.4.1","@pipecat-ai/daily-transport":"^0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.10.0","devDependencies":{"tsup":"^8.5.0","react":"^19.1.0","eslint":"^9.29.0","globals":"^16.2.0","typescript":"^5.8.3","@types/node":"^24.0.1","@types/react":"^19.1.8","typescript-eslint":"^8.34.0","eslint-plugin-react":"^7.37.5"},"peerDependencies":{"react":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/rtvi-client_1.0.0_1751354974134_0.9439253673886336","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@airsurfer09/rtvi-client","private":false,"version":"1.0.1","description":"RTVI Client Library","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","publishConfig":{"access":"public"},"scripts":{"build":"tsup src/index.ts --dts --format esm,cjs","dev":"tsup src/index.ts --dts --format esm,cjs --watch","lint":"eslint .","clean":"rm -rf dist"},"keywords":[],"author":"","license":"ISC","packageManager":"pnpm@10.10.0","devDependencies":{"@types/node":"^24.0.1","@types/react":"^19.1.8","eslint":"^9.29.0","eslint-plugin-react":"^7.37.5","globals":"^16.2.0","react":"^19.1.0","tsup":"^8.5.0","typescript":"^5.8.3","typescript-eslint":"^8.34.0"},"peerDependencies":{"react":"^18.0.0"},"dependencies":{"@pipecat-ai/client-js":"^0.4.1","@pipecat-ai/daily-transport":"^0.4.0"},"_id":"@airsurfer09/rtvi-client@1.0.1","gitHead":"6286da84d3d396070e6c80aaa458df9a805b25cf","_nodeVersion":"23.11.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-DzqG/DWfyXOL8BnZkmQEyuqhZivw1BpGt8jNzMgvvkcLLB5z56ikmWQbkziB9lBjXN7UgFFPMDYT22nEeYponw==","shasum":"1f2b39bbfd7aec0e7c488860c12f79833f0f0f8c","tarball":"https://registry.npmjs.org/@airsurfer09/rtvi-client/-/rtvi-client-1.0.1.tgz","fileCount":6,"unpackedSize":68456,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDEFjI7QShHyAvmMdyvqOnFKlbmqkns4vJor0msFIOlTgIhAJ8ClpW8CpvYEq1cyaFAervIFl0U8L5lXNbGn48RC0mx"}]},"_npmUser":{"name":"airsurfer09","email":"saurav@convai.com","actor":{"name":"airsurfer09","email":"saurav@convai.com","type":"user"}},"directories":{},"maintainers":[{"name":"airsurfer09","email":"saurav@convai.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rtvi-client_1.0.1_1751828776138_0.867968541338008"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-01T07:29:34.056Z","modified":"2025-07-06T19:06:16.547Z","1.0.0":"2025-07-01T07:29:34.386Z","1.0.1":"2025-07-06T19:06:16.322Z"},"license":"ISC","keywords":[],"description":"RTVI Client Library","maintainers":[{"name":"airsurfer09","email":"saurav@convai.com"}],"readme":"# RTVI Client\n\nA comprehensive TypeScript/JavaScript client library for Real-Time Voice Interface (RTVI) applications. This package provides both React hooks and vanilla JavaScript clients for building voice-enabled applications with support for multiple LLM providers.\n\n## Features\n\n- 🎤 **Real-time voice interaction** with audio streaming\n- 🤖 **Multiple LLM providers** (OpenAI, Claude, Gemini, Llama, Gemini Live)\n- ⚛️ **React hooks** for easy integration\n- 🎯 **TypeScript support** with full type definitions\n- 🔄 **Event-driven architecture** for real-time updates\n- 📱 **Cross-platform** (Web, React Native compatible)\n- 🎥 **Video support** (optional)\n- 📝 **Message handling** with transcript support\n\n## Installation\n\n```bash\nnpm install @convai/rtvi-client\n# or\nyarn add @convai/rtvi-client\n# or\npnpm add @convai/rtvi-client\n```\n\n## Quick Start\n\n### React Usage (Recommended)\n\nThe easiest way to get started is with the `useRtviBot` hook:\n\n```tsx\nimport React, { useState } from 'react';\nimport { useRtviBot } from '@convai/rtvi-client';\n\nfunction VoiceChat() {\n  const [apiKey, setApiKey] = useState('your-api-key');\n  const [characterId, setCharacterId] = useState('your-character-id');\n\n  const {\n    isConnected,\n    isConnecting,\n    error,\n    botStatus,\n    messages,\n    connect,\n    disconnect,\n    sendMessage,\n  } = useRtviBot({\n    apiKey,\n    characterId,\n    llmProvider: 'openai',\n    connectionType: 'audio',\n    enableMic: true,\n    onMessage: (message) => {\n      console.log(`${message.sender}: ${message.text}`);\n    },\n    onBotStatusChange: (status) => {\n      console.log(`Bot status: ${status}`);\n    },\n  });\n\n  const handleConnect = async () => {\n    try {\n      await connect({ characterId, llmProvider: 'openai' });\n    } catch (err) {\n      console.error('Failed to connect:', err);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={isConnected ? disconnect : handleConnect}>\n        {isConnecting ? 'Connecting...' : isConnected ? 'Disconnect' : 'Connect'}\n      </button>\n      \n      <p>Status: {botStatus}</p>\n      \n      <div>\n        {messages.map((msg) => (\n          <div key={msg.id}>\n            <strong>{msg.sender}:</strong> {msg.text}\n          </div>\n        ))}\n      </div>\n      \n      <button \n        onClick={() => sendMessage('Hello!')} \n        disabled={!isConnected}\n      >\n        Send Message\n      </button>\n    </div>\n  );\n}\n```\n\n### Vanilla JavaScript Usage\n\nFor non-React applications, use the client classes directly:\n\n```javascript\nimport { ChatbotClient, RTVIEvent } from '@convai/rtvi-client';\n\nconst client = new ChatbotClient({\n  apiKey: 'your-api-key',\n  characterId: 'your-character-id',\n  llmProvider: 'openai',\n  connectionType: 'audio',\n  enableMic: true,\n  callbacks: {\n    onTrackStart: (track, participant) => {\n      console.log('Audio track started:', track);\n    },\n    onError: (error) => {\n      console.error('Client error:', error);\n    },\n  },\n});\n\n// Set up event listeners\nclient.on(RTVIEvent.Connected, () => {\n  console.log('Connected to bot');\n});\n\nclient.on(RTVIEvent.BotLlmText, (data) => {\n  console.log('Bot said:', data.text);\n});\n\nclient.on(RTVIEvent.UserTranscript, (data) => {\n  if (data.final) {\n    console.log('User said:', data.text);\n  }\n});\n\n// Connect and start conversation\nasync function startConversation() {\n  try {\n    await client.connect();\n    client.sendMessage('Hello, how are you?');\n  } catch (error) {\n    console.error('Failed to connect:', error);\n  }\n}\n\nstartConversation();\n```\n\n## API Reference\n\n### React Hook\n\n#### `useRtviBot(options: UseRtviBotOptions): UseRtviBotReturn`\n\nThe main React hook for RTVI functionality.\n\n**Options:**\n```typescript\ninterface UseRtviBotOptions {\n  apiKey: string;                    // Your API key\n  characterId?: string;              // Character/bot ID\n  llmProvider?: LLMProvider;         // LLM provider to use\n  connectionType?: ConnectionType;   // 'audio' | 'text' | 'video'\n  enableMic?: boolean;              // Enable microphone (default: true)\n  enableCam?: boolean;              // Enable camera (default: false)\n  videoContainer?: HTMLElement;      // Container for video elements\n  onConnectionStatusChange?: (connected: boolean) => void;\n  onMessage?: (message: Message) => void;\n  onError?: (error: string) => void;\n  onBotStatusChange?: (status: BotStatus) => void;\n}\n```\n\n**Returns:**\n```typescript\ninterface UseRtviBotReturn {\n  // Connection state\n  client: ChatbotClient | null;\n  isConnected: boolean;\n  isConnecting: boolean;\n  error: string | null;\n  sessionId: string | null;\n  \n  // Bot state\n  botStatus: BotStatus;              // 'idle' | 'listening' | 'speaking' | 'thinking'\n  thinkingText: string;\n  isMicActive: boolean;\n  \n  // Messages\n  messages: Message[];\n  \n  // Actions\n  connect: (options?: { characterId?: string; llmProvider?: LLMProvider }) => Promise<void>;\n  disconnect: () => Promise<void>;\n  sendMessage: (text: string) => void;\n  clearMessages: () => void;\n  \n  // Audio/Video controls\n  enableMic: (enable: boolean) => void;\n  \n  // Event handlers (for custom usage)\n  on: (event: RTVIEvent, handler: (...args: any[]) => void) => void;\n  off: (event: RTVIEvent, handler: (...args: any[]) => void) => void;\n}\n```\n\n### Client Classes\n\n#### `ChatbotClient`\n\nHigh-level client for chatbot interactions.\n\n```typescript\nclass ChatbotClient {\n  constructor(options: ChatbotClientOptions);\n  \n  async connect(): Promise<ConnectResponse>;\n  async disconnect(): Promise<void>;\n  sendMessage(text: string): void;\n  on(event: RTVIEvent, handler: Function): void;\n  off(event: RTVIEvent, handler: Function): void;\n  isConnected(): boolean;\n  getSessionId(): string | null;\n  enableMic(enable: boolean): void;\n  setOptions(options: Partial<ChatbotClientOptions>): void;\n}\n```\n\n#### `RtviClient`\n\nLower-level RTVI protocol client.\n\n```typescript\nclass RtviClient {\n  constructor(options: RtviClientOptions);\n  \n  async connect(payload?: ConnectPayload): Promise<ConnectResponse>;\n  async disconnect(): Promise<DisconnectResponse>;\n  async healthCheck(): Promise<any>;\n  sendMessage(message: string | RTVIMessage): void;\n  on(event: RTVIEvent, handler: Function): void;\n  off(event: RTVIEvent, handler: Function): void;\n  isConnected(): boolean;\n  getSessionId(): string | null;\n  enableMic(enable: boolean): void;\n}\n```\n\n### Types\n\n#### Core Types\n\n```typescript\n// Message structure\ninterface Message {\n  id: string;\n  text: string;\n  sender: \"user\" | \"bot\";\n  timestamp: Date;\n}\n\n// Bot status\ntype BotStatus = \"idle\" | \"listening\" | \"speaking\" | \"thinking\";\n\n// Supported LLM providers\ntype LLMProvider = \"openai\" | \"claude\" | \"gemini\" | \"llama\" | \"gemini-live\";\n\n// Connection types\ntype ConnectionType = \"audio\" | \"text\" | \"video\";\n```\n\n#### Configuration Types\n\n```typescript\ninterface ChatbotClientOptions {\n  apiKey: string;\n  baseUrl?: string;                  // API base URL (default: convai.com)\n  characterId: string;\n  connectionType?: ConnectionType;\n  llmProvider?: LLMProvider;\n  videoContainer?: HTMLElement;\n  enableMic?: boolean;\n  enableCam?: boolean;\n  callbacks?: {\n    onTrackStart?: (track: MediaStreamTrack, participant?: any) => void;\n    onTrackStop?: (track: MediaStreamTrack, participant?: any) => void;\n    onError?: (error: any) => void;\n  };\n}\n```\n\n### Events\n\nThe library uses an event-driven architecture. Here are the main events:\n\n```typescript\nenum RTVIEvent {\n  Connected = 'connected',\n  Disconnected = 'disconnected',\n  Error = 'error',\n  \n  // Bot events\n  BotLlmText = 'bot-llm-text',           // Bot is speaking (text chunks)\n  BotStartedSpeaking = 'bot-started-speaking',\n  BotStoppedSpeaking = 'bot-stopped-speaking',\n  \n  // User events\n  UserTranscript = 'user-transcript',     // User speech transcript\n  UserStartedSpeaking = 'user-started-speaking',\n  UserStoppedSpeaking = 'user-stopped-speaking',\n  \n  // Media events\n  TrackStarted = 'track-started',         // Audio/video track started\n  TrackStopped = 'track-stopped',         // Audio/video track stopped\n}\n```\n\n## Advanced Usage\n\n### Custom Event Handling\n\n```typescript\nconst { client, on, off } = useRtviBot(options);\n\n// Custom event handler\nconst handleCustomEvent = (data) => {\n  console.log('Custom event:', data);\n};\n\n// Add event listener\non(RTVIEvent.BotLlmText, handleCustomEvent);\n\n// Remove event listener\noff(RTVIEvent.BotLlmText, handleCustomEvent);\n```\n\n### Video Support\n\n```tsx\nfunction VideoChat() {\n  const videoRef = useRef<HTMLDivElement>(null);\n  \n  const { connect } = useRtviBot({\n    apiKey: 'your-api-key',\n    characterId: 'your-character-id',\n    connectionType: 'video',\n    enableCam: true,\n    videoContainer: videoRef.current,\n  });\n\n  return (\n    <div>\n      <div ref={videoRef} style={{ width: '100%', height: '400px' }} />\n      <button onClick={() => connect()}>Start Video Chat</button>\n    </div>\n  );\n}\n```\n\n### Multiple LLM Providers\n\n```typescript\n// Switch between providers dynamically\nconst { connect } = useRtviBot({\n  apiKey: 'your-api-key',\n  characterId: 'your-character-id',\n});\n\n// Connect with OpenAI\nawait connect({ llmProvider: 'openai' });\n\n// Later, reconnect with Claude\nawait connect({ llmProvider: 'claude' });\n```\n\n### Error Handling\n\n```typescript\nconst { error, connect } = useRtviBot({\n  apiKey: 'your-api-key',\n  characterId: 'your-character-id',\n  onError: (errorMessage) => {\n    // Handle errors globally\n    console.error('RTVI Error:', errorMessage);\n    // Show user-friendly error message\n    alert(`Connection error: ${errorMessage}`);\n  },\n});\n\n// Handle connection errors\nconst handleConnect = async () => {\n  try {\n    await connect();\n  } catch (err) {\n    console.error('Failed to connect:', err);\n    // Handle specific connection errors\n  }\n};\n```\n\n## Examples\n\nCheck out the `/examples` directory for complete working examples:\n\n- **React Example**: Full-featured React app with UI\n- **Vanilla JavaScript Example**: Basic implementation without React\n\n### Running Examples\n\n```bash\n# React example\ncd examples/react\nnpm install\nnpm run dev\n\n# Vanilla example\ncd examples/vanilla\nnpm install\nnpm run dev\n```\n\n## Configuration\n\n### Environment Variables\n\nYou can set default configuration using environment variables:\n\n```bash\nRTVI_API_KEY=your-api-key\nRTVI_BASE_URL=https://your-api-endpoint.com\nRTVI_CHARACTER_ID=your-default-character\n```\n\n### API Endpoints\n\nThe library connects to the following endpoints by default:\n\n- **Connect**: `/connect` - Establish connection\n- **Disconnect**: `/disconnect` - Close connection  \n- **Health Check**: `/healthz` - Service health status\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Microphone not working**\n   - Ensure `enableMic: true` in options\n   - Check browser permissions for microphone access\n   - Verify HTTPS connection (required for microphone)\n\n2. **Connection failures**\n   - Verify API key is correct\n   - Check character ID exists\n   - Ensure network connectivity\n   - Check browser console for detailed errors\n\n3. **Audio not playing**\n   - Browser may require user interaction before audio playback\n   - Check if audio elements are being created properly\n   - Verify audio permissions\n\n### Debug Mode\n\nEnable detailed logging:\n\n```typescript\nconst { client } = useRtviBot({\n  // ... other options\n  onError: (error) => console.error('RTVI Error:', error),\n  onConnectionStatusChange: (connected) => console.log('Connected:', connected),\n  onBotStatusChange: (status) => console.log('Bot Status:', status),\n});\n```\n\n## Browser Compatibility\n\n- **Chrome**: Full support\n- **Firefox**: Full support  \n- **Safari**: Full support (iOS 14.3+)\n- **Edge**: Full support\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Support\n\nFor issues and questions:\n- GitHub Issues: [Repository Issues](https://github.com/your-org/rtvi-client/issues)\n- Documentation: [Full Documentation](https://docs.your-org.com/rtvi-client)\n- Discord: [Community Discord](https://discord.gg/your-community) ","readmeFilename":"README.md"}