feat(node-voice-agent): use @deepgram/sdk for the Deepgram Agent connection - #22
feat(node-voice-agent): use @deepgram/sdk for the Deepgram Agent connection#22GregHolmes wants to merge 2 commits into
Conversation
…ection Replace the raw WebSocket proxy to the Voice Agent API with the official @deepgram/sdk client.agent.v1 streaming support. The SDK now manages the Deepgram-side WebSocket, auth, reconnection, and binary-audio framing. The browser-facing protocol is unchanged: the frontend still sends a Settings message plus live-update / inject control JSON and binary mic audio, and receives Deepgram's binary agent audio + JSON events exactly as before. Each browser control message is routed to the matching typed SDK send method, and mic audio is forwarded via sendMedia; early messages are buffered until the Deepgram socket is open. DEEPGRAM_BASE_URL is supported via the SDK environment (base/production/agent).
… clipping Binary agent audio arrives from the Deepgram SDK socket as a Blob and must be async-converted before forwarding, while JSON events (AgentAudioDone) forward synchronously. Firing each forward independently let the AgentAudioDone event overtake the still-converting final audio chunk, clipping the agent-audio tail. Serialize all forwards through a per-connection promise chain so frames reach the browser in the order Deepgram sent them.
|
Corey feedback addressed — agent audio tail clipping fixed Root cause: binary agent-audio frames arrive from the Fix ( let sendChain = Promise.resolve();
dgConn.on('message', (data) => {
sendChain = sendChain
.then(() => forwardToBrowser(clientWs, data))
.catch((err) => console.error('Failed to forward Deepgram message:', err));
});Ordering evidence — the real The last binary frame is now received before the terminal
|
What
Migrates the backend from a raw WebSocket proxy to Deepgram's Voice Agent API over to the official
@deepgram/sdk(^5.7.0) usingclient.agent.v1streaming support. Part of the SDK-migration rollout across the Node starters.How
new WebSocket('wss://agent.deepgram.com/...')connection withdeepgram.agent.v1.createConnection(), following the open sequencecreateConnection→ attachopen/message/error/closehandlers →connect()→await waitForOpen().sendSettings,sendUpdateListen/Think/Speak,sendUpdatePrompt,sendInjectUserMessage,sendInjectAgentMessage,sendFunctionCallResponse,sendKeepAlive); binary mic audio →sendMedia.DEEPGRAM_BASE_URLis honored via the SDKenvironment(base/production/agent).wsbrowser server, JWT/session auth,/api/session,/api/metadata, and graceful shutdown unchanged.@deepgram/sdk@^5.7.0topackage.json(+ lockfile), setsdk = "@deepgram/sdk"indeepgram.toml.Verified
node --check server.js— passes.DEEPGRAM_API_KEY=dummy PORT=<free> node server.jsstarts cleanly, banner prints;GET /api/metadatareturns the expected JSON (sdk: "@deepgram/sdk"),GET /api/sessionissues a JWT; graceful shutdown works.corepack pnpm installupdates the lockfile with@deepgram/sdk 5.7.0.Manual verification needed before merge
DEEPGRAM_API_KEY: full-duplex voice conversation viaWS /api/voice-agent(Settings applied, agent audio plays back, ConversationText events received).UpdateSpeak/UpdatePrompt/InjectUserMessage) mid-conversation.voice-agent-htmlfrontend works without changes.