feat(react)!: harden lifecycle and expand agent APIs - #23
Conversation
BREAKING CHANGE: AgentMode now includes "thinking" and public context and hook result types add required members.
dg-coreylweathers
left a comment
There was a problem hiding this comment.
DevRel review — changes requested, for completeness of the 0.2.0 release rather than code. Gates, semver mechanics, and the live Voice Agent run all pass; the four items under "Should fix before 0.2.0 ships" are docs and changelog gaps on a breaking release, and the four questions at the end need answers before I sign off.
What this PR does
Moves @deepgram/react onto @deepgram/agents 0.1.2 / @deepgram/sdk 5.9.0 and exposes the SDK's newer surface through the provider, the focused hooks, and useDeepgramAgent: a "thinking" mode, sendAgentMessage, updateListen/Think/Speak/Prompt, and seven typed notification callbacks. It also rewrites start/stop/reconnect/StrictMode handling with generation counters so a cancelled start, a microphone failure, or a dropped session cannot leave stale audio running or send a client-tool result into a replacement session, and removes release-as so Release Please proposes 0.2.0 from the feat! commit.
What I checked
- Do the gates pass with the lockfile frozen? Yes:
bun install --frozen-lockfile, Biome lint (0 diagnostics),tscagainst the npm@deepgram/agents0.1.2 with no../agentcheckout, 64/64 tests,vite build+npm pack(7 files), all in a cleannode:24container. - Does every type, event, and method this PR re-exports exist in the published agents 0.1.2? Yes; checked its
dist/index.d.ts.fn.argumentsis the real field onFunctionCallItemin sdk 5.9.0. - Is the semver story honest? Yes. The built
index.d.tsdiff shows exactly the declared breaks (AgentModegains"thinking"; required members added toAgentContextValueand the hook result types;registerClientToolnow returns an unsubscribe function). No export, prop, or default was removed. Two behavior changes are not declared anywhere:useDeepgramAgent().start()now emptiesconversation, andmicrophone/ttsprop changes now take effect mid-session. - Does it work against the live Voice Agent API? Yes. I drove the built provider in Node with
microphone={false} tts={false}: connect in 180 ms, SettingsApplied ->listening,sendUserMessage-> user + assistant entries,updatePrompt-> PromptUpdated,updateListen->onListenUpdated,sendAgentMessage(..., "interrupt")-> injected assistant turn, a live FunctionCallRequest ->onFunctionCall-> reply "4711.", aregisterClientTooloverride -> reply "9090." with the prop handler never called, 16 latency reports, 0 Error/Warning/sdk-error,stop()->disconnected/idle, restart -> connected withconversationcleared. The standalone hook connected live, then the microphone failure rolled the session back todisconnected/micActive=false/mode="idle". - What did not match the README? For a text-injected turn the server sent no
AgentThinkingand noAgentStartedSpeaking, and withtts={false}the provider skips the audio-basedspeakinginference, somodestayedlisteningthrough the whole reply (97 audio chunks). Same as 0.1.0, but this PR is the one documenting four modes and addingisThinking. - Not live-verified:
tts={true}playback, microphone capture, mode transitions on voice turns, StrictMode replay, and reconnect after a dropped socket (browser audio APIs are unavailable in Node; the mocked unit tests cover these).
Should fix before 0.2.0 ships
- S1
packages/react/README.md"Mode Tracking": state thatspeakingis inferred from incoming agent audio and requirestts={true}, and thatthinkingis set only when the server sendsAgentThinking(not observed onsendUserMessagetext turns). - S2 The generated 0.2.0 changelog will be one Features line plus the BREAKING CHANGE footer. Edit the Release Please PR (or the squash-commit body) to list each new API, each lifecycle fix, and the full breaking list including the
registerClientToolreturn type anduseDeepgramAgent().start()clearingconversation. - S3
onListenUpdatedexists butonPromptUpdated/onSpeakUpdated/onThinkUpdateddo not, althoughupdatePrompt/Speak/Thinkand their message types are exported. Either add the three callbacks (additive) or document that confirmations come fromuseAgentSession().on(...). - S4 Document in the standalone-hook section that
start()begins a fresh session and clearsconversation.
Nits
- README.md:56
MicrophoneOptionshas no VAD option; list the real fields (sampleRate, echoCancellation, noiseSuppression, autoGainControl). - README.md:123 name the
behaviorvalues:"default" | "queue" | "interrupt". - README.md:62
onSdkErroralso receives microphone start failures after connect (provider.tsx:365, :381). - hooks/useAgentSession.ts:6 JSDoc still lists
updatePromptas an escape-hatch use; it is now onuseAgentControls. - ci.yml:19 / npm-publish.yml:45
bun installis unfrozen; add--frozen-lockfile(it passes). - README.md:86-93 / CONTRIBUTING.md:8 the
../agentsibling reads as required; tsconfigpathsfalls back to npm when it is absent, so mark it optional. - package.json:54 TypeScript pinned back 6.0.2 -> 5.9.3 with no stated reason; Dependabot will propose 6.x again (PR #9 already did).
Questions
- Where does the "independent DevRel re-review: approve" in the PR body live? Nothing is on GitHub and I could not find a Slack thread.
- Is "no
AgentThinking/AgentStartedSpeakingon text-injected turns" expected server behavior? It decides the exact S1 wording. - Add the three
*Updatedcallbacks in this release, or defer? - Why the TypeScript downgrade?
Summary
@deepgram/reactwith published@deepgram/agents0.1.2 and@deepgram/sdk5.9Breaking Changes
AgentModenow includes"thinking"; exhaustive consumers must handle the new memberBREAKING CHANGE: AgentMode now includes "thinking" and public context and hook result types add required members.
The breaking conventional title and commit footer intentionally direct Release Please to propose
0.2.0from0.1.0.Lifecycle Safety
sdk-erroris forwarded separately from protocolerrorValidation
bun install --frozen-lockfilebun run lintbun run typecheckbun run test(64 tests)bun run build