[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EXFYZC549WFAS8Q5MQJYGV":3,"skill-same:01M6EXFYZC549WFAS8Q5MQJYGV":80},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":51,"commitSha":52,"skillDirectory":53,"forksCount":54,"repositoryHtmlUrl":55,"repositoryHomepageUrl":56,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":58,"updatedAt":59,"install":60,"resources":73},"01M6EXFYZC549WFAS8Q5MQJYGV","azure-ai-voicelive-ts",null,"Azure AI Voice Live SDK for JavaScript\u002FTypeScript. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots in Node.js or browser environments. Triggers: \"voice live\", \"real-time voice\", \"VoiceLiveClient\", \"VoiceLiveSession\", \"voice assistant TypeScript\", \"bidirectional audio\", \"speech-to-speech JavaScript\".","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-ai-voicelive-ts\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"azure ai","azure","azure ai voicelive ts","real-time","with","Conversational AI","triggers","live","time","use","node","Audio","applications","assistant","websocket","speech","communication","browser","javascript","typescript","2026-11-10 10:12:30",false,"---\nname: azure-ai-voicelive-ts\ndescription: |\n  Azure AI Voice Live SDK for JavaScript\u002FTypeScript. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots in Node.js or browser environments. Triggers: \"voice live\", \"real-time voice\", \"VoiceLiveClient\", \"VoiceLiveSession\", \"voice assistant TypeScript\", \"bidirectional audio\", \"speech-to-speech JavaScript\".\npackage: \"@azure\u002Fai-voicelive\"\n---\n\n# @azure\u002Fai-voicelive (JavaScript\u002FTypeScript)\n\nReal-time voice AI SDK for building bidirectional voice assistants with Azure AI in Node.js and browser environments.\n\n## Installation\n\n```bash\nnpm install @azure\u002Fai-voicelive @azure\u002Fidentity\n# TypeScript users\nnpm install @types\u002Fnode\n```\n\n**Current Version**: 1.0.0-beta.3\n\n**Supported Environments**:\n- Node.js LTS versions (20+)\n- Modern browsers (Chrome, Firefox, Safari, Edge)\n\n## Environment Variables\n\n```bash\nAZURE_VOICELIVE_ENDPOINT=https:\u002F\u002F\u003Cresource>.cognitiveservices.azure.com\n# Optional: API key if not using Entra ID\nAZURE_VOICELIVE_API_KEY=\u003Cyour-api-key>\n# Optional: Logging\nAZURE_LOG_LEVEL=info\n```\n\n## Authentication\n\n### Microsoft Entra ID (Recommended)\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst credential = new DefaultAzureCredential();\nconst endpoint = \"https:\u002F\u002Fyour-resource.cognitiveservices.azure.com\";\n\nconst client = new VoiceLiveClient(endpoint, credential);\n```\n\n### API Key\n\n```typescript\nimport { AzureKeyCredential } from \"@azure\u002Fcore-auth\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst endpoint = \"https:\u002F\u002Fyour-resource.cognitiveservices.azure.com\";\nconst credential = new AzureKeyCredential(\"your-api-key\");\n\nconst client = new VoiceLiveClient(endpoint, credential);\n```\n\n## Client Hierarchy\n\n```\nVoiceLiveClient\n└── VoiceLiveSession (WebSocket connection)\n    ├── updateSession()      → Configure session options\n    ├── subscribe()          → Event handlers (Azure SDK pattern)\n    ├── sendAudio()          → Stream audio input\n    ├── addConversationItem() → Add messages\u002Ffunction outputs\n    └── sendEvent()          → Send raw protocol events\n```\n\n## Quick Start\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst credential = new DefaultAzureCredential();\nconst endpoint = process.env.AZURE_VOICELIVE_ENDPOINT!;\n\n\u002F\u002F Create client and start session\nconst client = new VoiceLiveClient(endpoint, credential);\nconst session = await client.startSession(\"gpt-4o-mini-realtime-preview\");\n\n\u002F\u002F Configure session\nawait session.updateSession({\n  modalities: [\"text\", \"audio\"],\n  instructions: \"You are a helpful AI assistant. Respond naturally.\",\n  voice: {\n    type: \"azure-standard\",\n    name: \"en-US-AvaNeural\",\n  },\n  turnDetection: {\n    type: \"server_vad\",\n    threshold: 0.5,\n    prefixPaddingMs: 300,\n    silenceDurationMs: 500,\n  },\n  inputAudioFormat: \"pcm16\",\n  outputAudioFormat: \"pcm16\",\n});\n\n\u002F\u002F Subscribe to events\nconst subscription = session.subscribe({\n  onResponseAudioDelta: async (event, context) => {\n    \u002F\u002F Handle streaming audio output\n    const audioData = event.delta;\n    playAudioChunk(audioData);\n  },\n  onResponseTextDelta: async (event, context) => {\n    \u002F\u002F Handle streaming text\n    process.stdout.write(event.delta);\n  },\n  onInputAudioTranscriptionCompleted: async (event, context) => {\n    console.log(\"User said:\", event.transcript);\n  },\n});\n\n\u002F\u002F Send audio from microphone\nfunction sendAudioChunk(audioBuffer: ArrayBuffer) {\n  session.sendAudio(audioBuffer);\n}\n```\n\n## Session Configuration\n\n```typescript\nawait session.updateSession({\n  \u002F\u002F Modalities\n  modalities: [\"audio\", \"text\"],\n  \n  \u002F\u002F System instructions\n  instructions: \"You are a customer service representative.\",\n  \n  \u002F\u002F Voice selection\n  voice: {\n    type: \"azure-standard\",  \u002F\u002F or \"azure-custom\", \"openai\"\n    name: \"en-US-AvaNeural\",\n  },\n  \n  \u002F\u002F Turn detection (VAD)\n  turnDetection: {\n    type: \"server_vad\",      \u002F\u002F or \"azure_semantic_vad\"\n    threshold: 0.5,\n    prefixPaddingMs: 300,\n    silenceDurationMs: 500,\n  },\n  \n  \u002F\u002F Audio formats\n  inputAudioFormat: \"pcm16\",\n  outputAudioFormat: \"pcm16\",\n  \n  \u002F\u002F Tools (function calling)\n  tools: [\n    {\n      type: \"function\",\n      name: \"get_weather\",\n      description: \"Get current weather\",\n      parameters: {\n        type: \"object\",\n        properties: {\n          location: { type: \"string\" }\n        },\n        required: [\"location\"]\n      }\n    }\n  ],\n  toolChoice: \"auto\",\n});\n```\n\n## Event Handling (Azure SDK Pattern)\n\nThe SDK uses a subscription-based event handling pattern:\n\n```typescript\nconst subscription = session.subscribe({\n  \u002F\u002F Connection lifecycle\n  onConnected: async (args, context) => {\n    console.log(\"Connected:\", args.connectionId);\n  },\n  onDisconnected: async (args, context) => {\n    console.log(\"Disconnected:\", args.code, args.reason);\n  },\n  onError: async (args, context) => {\n    console.error(\"Error:\", args.error.message);\n  },\n  \n  \u002F\u002F Session events\n  onSessionCreated: async (event, context) => {\n    console.log(\"Session created:\", context.sessionId);\n  },\n  onSessionUpdated: async (event, context) => {\n    console.log(\"Session updated\");\n  },\n  \n  \u002F\u002F Audio input events (VAD)\n  onInputAudioBufferSpeechStarted: async (event, context) => {\n    console.log(\"Speech started at:\", event.audioStartMs);\n  },\n  onInputAudioBufferSpeechStopped: async (event, context) => {\n    console.log(\"Speech stopped at:\", event.audioEndMs);\n  },\n  \n  \u002F\u002F Transcription events\n  onConversationItemInputAudioTranscriptionCompleted: async (event, context) => {\n    console.log(\"User said:\", event.transcript);\n  },\n  onConversationItemInputAudioTranscriptionDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  \n  \u002F\u002F Response events\n  onResponseCreated: async (event, context) => {\n    console.log(\"Response started\");\n  },\n  onResponseDone: async (event, context) => {\n    console.log(\"Response complete\");\n  },\n  \n  \u002F\u002F Streaming text\n  onResponseTextDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  onResponseTextDone: async (event, context) => {\n    console.log(\"\\n--- Text complete ---\");\n  },\n  \n  \u002F\u002F Streaming audio\n  onResponseAudioDelta: async (event, context) => {\n    const audioData = event.delta;\n    playAudioChunk(audioData);\n  },\n  onResponseAudioDone: async (event, context) => {\n    console.log(\"Audio complete\");\n  },\n  \n  \u002F\u002F Audio transcript (what assistant said)\n  onResponseAudioTranscriptDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  \n  \u002F\u002F Function calling\n  onResponseFunctionCallArgumentsDone: async (event, context) => {\n    if (event.name === \"get_weather\") {\n      const args = JSON.parse(event.arguments);\n      const result = await getWeather(args.location);\n      \n      await session.addConversationItem({\n        type: \"function_call_output\",\n        callId: event.callId,\n        output: JSON.stringify(result),\n      });\n      \n      await session.sendEvent({ type: \"response.create\" });\n    }\n  },\n  \n  \u002F\u002F Catch-all for debugging\n  onServerEvent: async (event, context) => {\n    console.log(\"Event:\", event.type);\n  },\n});\n\n\u002F\u002F Clean up when done\nawait subscription.close();\n```\n\n## Function Calling\n\n```typescript\n\u002F\u002F Define tools in session config\nawait session.updateSession({\n  modalities: [\"audio\", \"text\"],\n  instructions: \"Help users with weather information.\",\n  tools: [\n    {\n      type: \"function\",\n      name: \"get_weather\",\n      description: \"Get current weather for a location\",\n      parameters: {\n        type: \"object\",\n        properties: {\n          location: {\n            type: \"string\",\n            description: \"City and state or country\",\n          },\n        },\n        required: [\"location\"],\n      },\n    },\n  ],\n  toolChoice: \"auto\",\n});\n\n\u002F\u002F Handle function calls\nconst subscription = session.subscribe({\n  onResponseFunctionCallArgumentsDone: async (event, context) => {\n    if (event.name === \"get_weather\") {\n      const args = JSON.parse(event.arguments);\n      const weatherData = await fetchWeather(args.location);\n      \n      \u002F\u002F Send function result\n      await session.addConversationItem({\n        type: \"function_call_output\",\n        callId: event.callId,\n        output: JSON.stringify(weatherData),\n      });\n      \n      \u002F\u002F Trigger response generation\n      await session.sendEvent({ type: \"response.create\" });\n    }\n  },\n});\n```\n\n## Voice Options\n\n| Voice Type | Config | Example |\n|------------|--------|---------|\n| Azure Standard | `{ type: \"azure-standard\", name: \"...\" }` | `\"en-US-AvaNeural\"` |\n| Azure Custom | `{ type: \"azure-custom\", name: \"...\", endpointId: \"...\" }` | Custom voice endpoint |\n| Azure Personal | `{ type: \"azure-personal\", speakerProfileId: \"...\" }` | Personal voice clone |\n| OpenAI | `{ type: \"openai\", name: \"...\" }` | `\"alloy\"`, `\"echo\"`, `\"shimmer\"` |\n\n## Supported Models\n\n| Model | Description | Use Case |\n|-------|-------------|----------|\n| `gpt-4o-realtime-preview` | GPT-4o with real-time audio | High-quality conversational AI |\n| `gpt-4o-mini-realtime-preview` | Lightweight GPT-4o | Fast, efficient interactions |\n| `phi4-mm-realtime` | Phi multimodal | Cost-effective applications |\n\n## Turn Detection Options\n\n```typescript\n\u002F\u002F Server VAD (default)\nturnDetection: {\n  type: \"server_vad\",\n  threshold: 0.5,\n  prefixPaddingMs: 300,\n  silenceDurationMs: 500,\n}\n\n\u002F\u002F Azure Semantic VAD (smarter detection)\nturnDetection: {\n  type: \"azure_semantic_vad\",\n}\n\n\u002F\u002F Azure Semantic VAD (English optimized)\nturnDetection: {\n  type: \"azure_semantic_vad_en\",\n}\n\n\u002F\u002F Azure Semantic VAD (Multilingual)\nturnDetection: {\n  type: \"azure_semantic_vad_multilingual\",\n}\n```\n\n## Audio Formats\n\n| Format | Sample Rate | Use Case |\n|--------|-------------|----------|\n| `pcm16` | 24kHz | Default, high quality |\n| `pcm16-8000hz` | 8kHz | Telephony |\n| `pcm16-16000hz` | 16kHz | Voice assistants |\n| `g711_ulaw` | 8kHz | Telephony (US) |\n| `g711_alaw` | 8kHz | Telephony (EU) |\n\n## Key Types Reference\n\n| Type | Purpose |\n|------|---------|\n| `VoiceLiveClient` | Main client for creating sessions |\n| `VoiceLiveSession` | Active WebSocket session |\n| `VoiceLiveSessionHandlers` | Event handler interface |\n| `VoiceLiveSubscription` | Active event subscription |\n| `ConnectionContext` | Context for connection events |\n| `SessionContext` | Context for session events |\n| `ServerEventUnion` | Union of all server events |\n\n## Error Handling\n\n```typescript\nimport {\n  VoiceLiveError,\n  VoiceLiveConnectionError,\n  VoiceLiveAuthenticationError,\n  VoiceLiveProtocolError,\n} from \"@azure\u002Fai-voicelive\";\n\nconst subscription = session.subscribe({\n  onError: async (args, context) => {\n    const { error } = args;\n    \n    if (error instanceof VoiceLiveConnectionError) {\n      console.error(\"Connection error:\", error.message);\n    } else if (error instanceof VoiceLiveAuthenticationError) {\n      console.error(\"Auth error:\", error.message);\n    } else if (error instanceof VoiceLiveProtocolError) {\n      console.error(\"Protocol error:\", error.message);\n    }\n  },\n  \n  onServerError: async (event, context) => {\n    console.error(\"Server error:\", event.error?.message);\n  },\n});\n```\n\n## Logging\n\n```typescript\nimport { setLogLevel } from \"@azure\u002Flogger\";\n\n\u002F\u002F Enable verbose logging\nsetLogLevel(\"info\");\n\n\u002F\u002F Or via environment variable\n\u002F\u002F AZURE_LOG_LEVEL=info\n```\n\n## Browser Usage\n\n```typescript\n\u002F\u002F Browser requires bundler (Vite, webpack, etc.)\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\nimport { InteractiveBrowserCredential } from \"@azure\u002Fidentity\";\n\n\u002F\u002F Use browser-compatible credential\nconst credential = new InteractiveBrowserCredential({\n  clientId: \"your-client-id\",\n  tenantId: \"your-tenant-id\",\n});\n\nconst client = new VoiceLiveClient(endpoint, credential);\n\n\u002F\u002F Request microphone access\nconst stream = await navigator.mediaDevices.getUserMedia({ audio: true });\nconst audioContext = new AudioContext({ sampleRate: 24000 });\n\n\u002F\u002F Process audio and send to session\n\u002F\u002F ... (see samples for full implementation)\n```\n\n## Best Practices\n\n1. **Always use `DefaultAzureCredential`** — Never hardcode API keys\n2. **Set both modalities** — Include `[\"text\", \"audio\"]` for voice assistants\n3. **Use Azure Semantic VAD** — Better turn detection than basic server VAD\n4. **Handle all error types** — Connection, auth, and protocol errors\n5. **Clean up subscriptions** — Call `subscription.close()` when done\n6. **Use appropriate audio format** — PCM16 at 24kHz for best quality\n\n## Reference Links\n\n| Resource | URL |\n|----------|-----|\n| npm Package | https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@azure\u002Fai-voicelive |\n| GitHub Source | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-js\u002Ftree\u002Fmain\u002Fsdk\u002Fai\u002Fai-voicelive |\n| Samples | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-js\u002Ftree\u002Fmain\u002Fsdk\u002Fai\u002Fai-voicelive\u002Fsamples |\n| API Reference | https:\u002F\u002Flearn.microsoft.com\u002Fjavascript\u002Fapi\u002F@azure\u002Fai-voicelive |\n","# @azure\u002Fai-voicelive (JavaScript\u002FTypeScript)\n\nReal-time voice AI SDK for building bidirectional voice assistants with Azure AI in Node.js and browser environments.\n\n## Installation\n\n```bash\nnpm install @azure\u002Fai-voicelive @azure\u002Fidentity\n# TypeScript users\nnpm install @types\u002Fnode\n```\n\n**Current Version**: 1.0.0-beta.3\n\n**Supported Environments**:\n- Node.js LTS versions (20+)\n- Modern browsers (Chrome, Firefox, Safari, Edge)\n\n## Environment Variables\n\n```bash\nAZURE_VOICELIVE_ENDPOINT=https:\u002F\u002F\u003Cresource>.cognitiveservices.azure.com\n# Optional: API key if not using Entra ID\nAZURE_VOICELIVE_API_KEY=\u003Cyour-api-key>\n# Optional: Logging\nAZURE_LOG_LEVEL=info\n```\n\n## Authentication\n\n### Microsoft Entra ID (Recommended)\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst credential = new DefaultAzureCredential();\nconst endpoint = \"https:\u002F\u002Fyour-resource.cognitiveservices.azure.com\";\n\nconst client = new VoiceLiveClient(endpoint, credential);\n```\n\n### API Key\n\n```typescript\nimport { AzureKeyCredential } from \"@azure\u002Fcore-auth\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst endpoint = \"https:\u002F\u002Fyour-resource.cognitiveservices.azure.com\";\nconst credential = new AzureKeyCredential(\"your-api-key\");\n\nconst client = new VoiceLiveClient(endpoint, credential);\n```\n\n## Client Hierarchy\n\n```\nVoiceLiveClient\n└── VoiceLiveSession (WebSocket connection)\n    ├── updateSession()      → Configure session options\n    ├── subscribe()          → Event handlers (Azure SDK pattern)\n    ├── sendAudio()          → Stream audio input\n    ├── addConversationItem() → Add messages\u002Ffunction outputs\n    └── sendEvent()          → Send raw protocol events\n```\n\n## Quick Start\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\n\nconst credential = new DefaultAzureCredential();\nconst endpoint = process.env.AZURE_VOICELIVE_ENDPOINT!;\n\n\u002F\u002F Create client and start session\nconst client = new VoiceLiveClient(endpoint, credential);\nconst session = await client.startSession(\"gpt-4o-mini-realtime-preview\");\n\n\u002F\u002F Configure session\nawait session.updateSession({\n  modalities: [\"text\", \"audio\"],\n  instructions: \"You are a helpful AI assistant. Respond naturally.\",\n  voice: {\n    type: \"azure-standard\",\n    name: \"en-US-AvaNeural\",\n  },\n  turnDetection: {\n    type: \"server_vad\",\n    threshold: 0.5,\n    prefixPaddingMs: 300,\n    silenceDurationMs: 500,\n  },\n  inputAudioFormat: \"pcm16\",\n  outputAudioFormat: \"pcm16\",\n});\n\n\u002F\u002F Subscribe to events\nconst subscription = session.subscribe({\n  onResponseAudioDelta: async (event, context) => {\n    \u002F\u002F Handle streaming audio output\n    const audioData = event.delta;\n    playAudioChunk(audioData);\n  },\n  onResponseTextDelta: async (event, context) => {\n    \u002F\u002F Handle streaming text\n    process.stdout.write(event.delta);\n  },\n  onInputAudioTranscriptionCompleted: async (event, context) => {\n    console.log(\"User said:\", event.transcript);\n  },\n});\n\n\u002F\u002F Send audio from microphone\nfunction sendAudioChunk(audioBuffer: ArrayBuffer) {\n  session.sendAudio(audioBuffer);\n}\n```\n\n## Session Configuration\n\n```typescript\nawait session.updateSession({\n  \u002F\u002F Modalities\n  modalities: [\"audio\", \"text\"],\n  \n  \u002F\u002F System instructions\n  instructions: \"You are a customer service representative.\",\n  \n  \u002F\u002F Voice selection\n  voice: {\n    type: \"azure-standard\",  \u002F\u002F or \"azure-custom\", \"openai\"\n    name: \"en-US-AvaNeural\",\n  },\n  \n  \u002F\u002F Turn detection (VAD)\n  turnDetection: {\n    type: \"server_vad\",      \u002F\u002F or \"azure_semantic_vad\"\n    threshold: 0.5,\n    prefixPaddingMs: 300,\n    silenceDurationMs: 500,\n  },\n  \n  \u002F\u002F Audio formats\n  inputAudioFormat: \"pcm16\",\n  outputAudioFormat: \"pcm16\",\n  \n  \u002F\u002F Tools (function calling)\n  tools: [\n    {\n      type: \"function\",\n      name: \"get_weather\",\n      description: \"Get current weather\",\n      parameters: {\n        type: \"object\",\n        properties: {\n          location: { type: \"string\" }\n        },\n        required: [\"location\"]\n      }\n    }\n  ],\n  toolChoice: \"auto\",\n});\n```\n\n## Event Handling (Azure SDK Pattern)\n\nThe SDK uses a subscription-based event handling pattern:\n\n```typescript\nconst subscription = session.subscribe({\n  \u002F\u002F Connection lifecycle\n  onConnected: async (args, context) => {\n    console.log(\"Connected:\", args.connectionId);\n  },\n  onDisconnected: async (args, context) => {\n    console.log(\"Disconnected:\", args.code, args.reason);\n  },\n  onError: async (args, context) => {\n    console.error(\"Error:\", args.error.message);\n  },\n  \n  \u002F\u002F Session events\n  onSessionCreated: async (event, context) => {\n    console.log(\"Session created:\", context.sessionId);\n  },\n  onSessionUpdated: async (event, context) => {\n    console.log(\"Session updated\");\n  },\n  \n  \u002F\u002F Audio input events (VAD)\n  onInputAudioBufferSpeechStarted: async (event, context) => {\n    console.log(\"Speech started at:\", event.audioStartMs);\n  },\n  onInputAudioBufferSpeechStopped: async (event, context) => {\n    console.log(\"Speech stopped at:\", event.audioEndMs);\n  },\n  \n  \u002F\u002F Transcription events\n  onConversationItemInputAudioTranscriptionCompleted: async (event, context) => {\n    console.log(\"User said:\", event.transcript);\n  },\n  onConversationItemInputAudioTranscriptionDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  \n  \u002F\u002F Response events\n  onResponseCreated: async (event, context) => {\n    console.log(\"Response started\");\n  },\n  onResponseDone: async (event, context) => {\n    console.log(\"Response complete\");\n  },\n  \n  \u002F\u002F Streaming text\n  onResponseTextDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  onResponseTextDone: async (event, context) => {\n    console.log(\"\\n--- Text complete ---\");\n  },\n  \n  \u002F\u002F Streaming audio\n  onResponseAudioDelta: async (event, context) => {\n    const audioData = event.delta;\n    playAudioChunk(audioData);\n  },\n  onResponseAudioDone: async (event, context) => {\n    console.log(\"Audio complete\");\n  },\n  \n  \u002F\u002F Audio transcript (what assistant said)\n  onResponseAudioTranscriptDelta: async (event, context) => {\n    process.stdout.write(event.delta);\n  },\n  \n  \u002F\u002F Function calling\n  onResponseFunctionCallArgumentsDone: async (event, context) => {\n    if (event.name === \"get_weather\") {\n      const args = JSON.parse(event.arguments);\n      const result = await getWeather(args.location);\n      \n      await session.addConversationItem({\n        type: \"function_call_output\",\n        callId: event.callId,\n        output: JSON.stringify(result),\n      });\n      \n      await session.sendEvent({ type: \"response.create\" });\n    }\n  },\n  \n  \u002F\u002F Catch-all for debugging\n  onServerEvent: async (event, context) => {\n    console.log(\"Event:\", event.type);\n  },\n});\n\n\u002F\u002F Clean up when done\nawait subscription.close();\n```\n\n## Function Calling\n\n```typescript\n\u002F\u002F Define tools in session config\nawait session.updateSession({\n  modalities: [\"audio\", \"text\"],\n  instructions: \"Help users with weather information.\",\n  tools: [\n    {\n      type: \"function\",\n      name: \"get_weather\",\n      description: \"Get current weather for a location\",\n      parameters: {\n        type: \"object\",\n        properties: {\n          location: {\n            type: \"string\",\n            description: \"City and state or country\",\n          },\n        },\n        required: [\"location\"],\n      },\n    },\n  ],\n  toolChoice: \"auto\",\n});\n\n\u002F\u002F Handle function calls\nconst subscription = session.subscribe({\n  onResponseFunctionCallArgumentsDone: async (event, context) => {\n    if (event.name === \"get_weather\") {\n      const args = JSON.parse(event.arguments);\n      const weatherData = await fetchWeather(args.location);\n      \n      \u002F\u002F Send function result\n      await session.addConversationItem({\n        type: \"function_call_output\",\n        callId: event.callId,\n        output: JSON.stringify(weatherData),\n      });\n      \n      \u002F\u002F Trigger response generation\n      await session.sendEvent({ type: \"response.create\" });\n    }\n  },\n});\n```\n\n## Voice Options\n\n| Voice Type | Config | Example |\n|------------|--------|---------|\n| Azure Standard | `{ type: \"azure-standard\", name: \"...\" }` | `\"en-US-AvaNeural\"` |\n| Azure Custom | `{ type: \"azure-custom\", name: \"...\", endpointId: \"...\" }` | Custom voice endpoint |\n| Azure Personal | `{ type: \"azure-personal\", speakerProfileId: \"...\" }` | Personal voice clone |\n| OpenAI | `{ type: \"openai\", name: \"...\" }` | `\"alloy\"`, `\"echo\"`, `\"shimmer\"` |\n\n## Supported Models\n\n| Model | Description | Use Case |\n|-------|-------------|----------|\n| `gpt-4o-realtime-preview` | GPT-4o with real-time audio | High-quality conversational AI |\n| `gpt-4o-mini-realtime-preview` | Lightweight GPT-4o | Fast, efficient interactions |\n| `phi4-mm-realtime` | Phi multimodal | Cost-effective applications |\n\n## Turn Detection Options\n\n```typescript\n\u002F\u002F Server VAD (default)\nturnDetection: {\n  type: \"server_vad\",\n  threshold: 0.5,\n  prefixPaddingMs: 300,\n  silenceDurationMs: 500,\n}\n\n\u002F\u002F Azure Semantic VAD (smarter detection)\nturnDetection: {\n  type: \"azure_semantic_vad\",\n}\n\n\u002F\u002F Azure Semantic VAD (English optimized)\nturnDetection: {\n  type: \"azure_semantic_vad_en\",\n}\n\n\u002F\u002F Azure Semantic VAD (Multilingual)\nturnDetection: {\n  type: \"azure_semantic_vad_multilingual\",\n}\n```\n\n## Audio Formats\n\n| Format | Sample Rate | Use Case |\n|--------|-------------|----------|\n| `pcm16` | 24kHz | Default, high quality |\n| `pcm16-8000hz` | 8kHz | Telephony |\n| `pcm16-16000hz` | 16kHz | Voice assistants |\n| `g711_ulaw` | 8kHz | Telephony (US) |\n| `g711_alaw` | 8kHz | Telephony (EU) |\n\n## Key Types Reference\n\n| Type | Purpose |\n|------|---------|\n| `VoiceLiveClient` | Main client for creating sessions |\n| `VoiceLiveSession` | Active WebSocket session |\n| `VoiceLiveSessionHandlers` | Event handler interface |\n| `VoiceLiveSubscription` | Active event subscription |\n| `ConnectionContext` | Context for connection events |\n| `SessionContext` | Context for session events |\n| `ServerEventUnion` | Union of all server events |\n\n## Error Handling\n\n```typescript\nimport {\n  VoiceLiveError,\n  VoiceLiveConnectionError,\n  VoiceLiveAuthenticationError,\n  VoiceLiveProtocolError,\n} from \"@azure\u002Fai-voicelive\";\n\nconst subscription = session.subscribe({\n  onError: async (args, context) => {\n    const { error } = args;\n    \n    if (error instanceof VoiceLiveConnectionError) {\n      console.error(\"Connection error:\", error.message);\n    } else if (error instanceof VoiceLiveAuthenticationError) {\n      console.error(\"Auth error:\", error.message);\n    } else if (error instanceof VoiceLiveProtocolError) {\n      console.error(\"Protocol error:\", error.message);\n    }\n  },\n  \n  onServerError: async (event, context) => {\n    console.error(\"Server error:\", event.error?.message);\n  },\n});\n```\n\n## Logging\n\n```typescript\nimport { setLogLevel } from \"@azure\u002Flogger\";\n\n\u002F\u002F Enable verbose logging\nsetLogLevel(\"info\");\n\n\u002F\u002F Or via environment variable\n\u002F\u002F AZURE_LOG_LEVEL=info\n```\n\n## Browser Usage\n\n```typescript\n\u002F\u002F Browser requires bundler (Vite, webpack, etc.)\nimport { VoiceLiveClient } from \"@azure\u002Fai-voicelive\";\nimport { InteractiveBrowserCredential } from \"@azure\u002Fidentity\";\n\n\u002F\u002F Use browser-compatible credential\nconst credential = new InteractiveBrowserCredential({\n  clientId: \"your-client-id\",\n  tenantId: \"your-tenant-id\",\n});\n\nconst client = new VoiceLiveClient(endpoint, credential);\n\n\u002F\u002F Request microphone access\nconst stream = await navigator.mediaDevices.getUserMedia({ audio: true });\nconst audioContext = new AudioContext({ sampleRate: 24000 });\n\n\u002F\u002F Process audio and send to session\n\u002F\u002F ... (see samples for full implementation)\n```\n\n## Best Practices\n\n1. **Always use `DefaultAzureCredential`** — Never hardcode API keys\n2. **Set both modalities** — Include `[\"text\", \"audio\"]` for voice assistants\n3. **Use Azure Semantic VAD** — Better turn detection than basic server VAD\n4. **Handle all error types** — Connection, auth, and protocol errors\n5. **Clean up subscriptions** — Call `subscription.close()` when done\n6. **Use appropriate audio format** — PCM16 at 24kHz for best quality\n\n## Reference Links\n\n| Resource | URL |\n|----------|-----|\n| npm Package | https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@azure\u002Fai-voicelive |\n| GitHub Source | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-js\u002Ftree\u002Fmain\u002Fsdk\u002Fai\u002Fai-voicelive |\n| Samples | https:\u002F\u002Fgithub.com\u002FAzure\u002Fazure-sdk-for-js\u002Ftree\u002Fmain\u002Fsdk\u002Fai\u002Fai-voicelive\u002Fsamples |\n| API Reference | https:\u002F\u002Flearn.microsoft.com\u002Fjavascript\u002Fapi\u002F@azure\u002Fai-voicelive |\n",{"name":5,"package":49,"description":50},"@azure\u002Fai-voicelive","Azure AI Voice Live SDK for JavaScript\u002FTypeScript. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots in Node.js or browser environments. Triggers: \"voice live\", \"real-time voice\", \"VoiceLiveClient\", \"VoiceLiveSession\", \"voice assistant TypeScript\", \"bidirectional audio\", \"speech-to-speech JavaScript\".\n","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-ai-voicelive-ts",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":61,"prompt":71,"zipAvailable":72},[62,65,68],{"tool":63,"command":64},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill azure-ai-voicelive-ts",{"tool":66,"command":67},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill azure-ai-voicelive-ts",{"tool":69,"command":70},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill azure-ai-voicelive-ts","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-ai-voicelive-ts\u002FSKILL.md",true,[74],{"path":75,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":78,"sourceHtmlUrl":79},"skill-report.json","REFERENCE","参考文档",8288,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-ai-voicelive-ts\u002Fskill-report.json",[81,93,103,112,118,125],{"skillNo":82,"name":83,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":89,"publishedAt":44},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[86],{"categoryNo":87,"categoryName":88,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[90,91,92],"model","model hierarchy","model hierarchy skill",{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":99,"publishedAt":44},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[98],{"categoryNo":87,"categoryName":88,"taxonomyType":21,"taxonomyTypeDesc":22},[100,101,102],"MCP","zoom","zoom mcp",{"skillNo":104,"name":105,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":44},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[109,110,111,101],"sdk","zoom apps sdk","apps",{"skillNo":113,"name":114,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":44},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[114],{"skillNo":119,"name":120,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":124,"publishedAt":44},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[123],{"categoryNo":87,"categoryName":88,"taxonomyType":21,"taxonomyTypeDesc":22},[120],{"skillNo":126,"name":127,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":44},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[127]]