Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Thanks for your interest in contributing to `@deepgram/react`!
## Setup

```bash
# Clone the agent SDK (required -- @deepgram/react depends on it via file: pointer)
# Clone and build the sibling agent SDK used by the local TypeScript path mapping
git clone git@github.com:deepgram/agent.git ../agent
cd ../agent && bun install && bun run build
cd -
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function App() {
<AgentProvider
config={{
auth: { tokenFactory: () => fetch('/api/deepgram-token').then(r => r.text()) },
agent: { think: { provider: { type: 'open_ai' }, model: 'gpt-4o-mini' } },
agent: { think: { provider: { type: 'open_ai', model: 'gpt-4o-mini' } } },
}}
>
<VoiceAgent />
Expand All @@ -47,16 +47,18 @@ function VoiceAgent() {
}
```

`config`, `playerSampleRate`, and the initial `autoStart` value establish the provider session for that component lifetime. Use the runtime update methods for supported listen, think, speak, and prompt changes rather than changing `config` in place.

## Hooks

| Hook | Purpose |
|------|---------|
| `useAgentState` | Connection state (`idle`, `connecting`, `connected`, etc.) and `start`/`stop` controls |
| `useAgentMode` | Speaking/listening mode tracking |
| `useAgentConversation` | Conversation transcript and `sendUserMessage` |
| `useAgentMode` | Listening/thinking/speaking mode tracking |
| `useAgentConversation` | Conversation transcript plus user and agent messages |
| `useAgentMicrophone` | Mic state, mute controls, input volume |
| `useAgentPlayer` | Audio playback state, mute controls, output volume |
| `useAgentControls` | Stable action methods (never change identity) |
| `useAgentControls` | Grouped lifecycle, messaging, settings, and mute controls |
| `useAgentClientTool` | Register client-side function call handlers scoped to component lifecycle |
| `useAgentSession` | Direct access to the underlying `AgentSession` (escape hatch) |
| `useDeepgramAgent` | Standalone hook -- no provider needed |
Expand All @@ -81,7 +83,7 @@ See the [package README](packages/react/README.md) for full API documentation.

**Prerequisites:** [Bun](https://bun.sh/) 1.3+

This package depends on `@deepgram/agents` via a `file:` pointer. Clone the agent repo as a sibling:
The published package depends on the npm release of `@deepgram/agents`. For coordinated local development, this repository's TypeScript config maps `@deepgram/agents` to a built sibling checkout:

```bash
git clone git@github.com:deepgram/agent.git ../agent
Expand Down
33 changes: 25 additions & 8 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/basic/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const config = {
tokenFactory: () => fetch("/api/deepgram-token").then((r) => r.text()),
},
agent: {
think: { provider: { type: "open_ai" as const }, model: "gpt-4o-mini" },
think: { provider: { type: "open_ai" as const, model: "gpt-4o-mini" } },
},
};

Expand Down
2 changes: 1 addition & 1 deletion examples/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ This example is a standalone React component. To use it in your project:
- Wrapping your app with `AgentProvider`
- Using `useAgentState` for connection lifecycle (`start`/`stop`)
- Using `useAgentConversation` for transcript display and text messaging
- Using `useAgentMode` for speaking/listening state
- Using `useAgentMode` for listening, thinking, and speaking mode tracking
56 changes: 41 additions & 15 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function App() {
<AgentProvider
config={{
auth: { tokenFactory: () => fetch('/api/deepgram-token').then(r => r.text()) },
agent: { think: { provider: { type: 'open_ai' }, model: 'gpt-4o-mini' } },
agent: { think: { provider: { type: 'open_ai', model: 'gpt-4o-mini' } } },
}}
>
<VoiceAgent />
Expand Down Expand Up @@ -58,14 +58,23 @@ Wraps your component tree with agent state management. Creates and manages an `A
playerSampleRate={24_000} // Agent audio sample rate (default: 24_000)
autoStart={false} // Auto-connect on mount (default: false)
onFunctionCall={handler} // Fallback function call handler
onError={handleError} // Protocol Error notification
onSdkError={handleSdkError} // Connection or transport failure
onWarning={handleWarning} // Protocol Warning notification
onLatencyReport={handleLatency}
onInjectionRefused={handleRefusal}
onListenUpdated={handleListenUpdate}
onHistory={handleHistory}
>
{children}
</AgentProvider>
```

`config`, `playerSampleRate`, and the initial `autoStart` value establish resources for the provider's lifetime. Changing those props does not reconstruct or automatically restart the session. Use `updateListen`, `updateThink`, `updateSpeak`, and `updatePrompt` for supported mid-session changes; remount the provider when a new session config or player sample rate is required.

### Mode Tracking

The provider tracks three agent modes: `"idle"`, `"listening"`, and `"speaking"`.
The provider tracks four agent modes: `"idle"`, `"listening"`, `"thinking"`, and `"speaking"`.

The speaking-to-listening transition is **playback-aware** -- when the server fires `AgentAudioDone`, the provider waits until `AgentPlayer.getRemainingPlaybackTime()` reaches zero before switching to `"listening"`. This prevents premature mode changes while audio is still playing.

Expand All @@ -91,13 +100,14 @@ const {

### useAgentMode

Speaking/listening mode.
Speaking/listening/thinking mode.

```ts
const {
mode, // "idle" | "listening" | "speaking"
isSpeaking, // boolean
isListening, // boolean
mode, // "idle" | "listening" | "thinking" | "speaking"
isSpeaking, // boolean
isListening, // boolean
isThinking, // boolean
} = useAgentMode();
```

Expand All @@ -110,6 +120,7 @@ const {
conversation, // ConversationEntry[] -- { id, role, content, timestamp }
clearConversation, // () => void
sendUserMessage, // (text: string) => void
sendAgentMessage, // (message: string, behavior?) => void
} = useAgentConversation();
```

Expand Down Expand Up @@ -144,13 +155,18 @@ const {

### useAgentControls

Stable action methods that never change identity. Use in components that trigger actions but do not display state.
Lifecycle, messaging, runtime settings, and mute actions grouped in one hook. Like the other focused hooks, it consumes `AgentContext`, so consumers still re-render when the provider value changes.

```ts
const {
start,
stop,
sendUserMessage,
sendAgentMessage,
updateListen,
updateThink,
updateSpeak,
updatePrompt,
clearConversation,
setMicMuted,
setOutputMuted,
Expand All @@ -164,7 +180,7 @@ Register a client-side function call handler scoped to the component's lifecycle
```tsx
function WeatherPanel() {
useAgentClientTool("getWeather", async (fn) => {
const { city } = JSON.parse(fn.input);
const { city } = JSON.parse(fn.arguments);
const data = await fetchWeather(city);
return JSON.stringify(data);
});
Expand All @@ -186,21 +202,28 @@ session.on("warning", (msg) => console.warn(msg));

### useAgentContext

Raw context value (escape hatch). Returns the full `AgentContextValue`. Prefer focused hooks for better render performance.
Raw context value (escape hatch). Returns the full `AgentContextValue`. Prefer focused hooks for a smaller, purpose-specific API surface.

### useDeepgramAgent (standalone)

Self-contained hook that does not require `AgentProvider`. Creates and manages its own session, microphone, and player. Useful for simple integrations or when you don't need the provider/context pattern.

The initial `config` and `playerSampleRate` similarly apply for the hook's lifetime. Use the returned update methods for supported runtime settings changes.

```ts
const {
state, micActive, outputMuted, conversation,
start, stop, setMicMuted, setOutputMuted, sendUserMessage, interrupt,
state, mode, micActive, micMuted, outputMuted, conversation,
start, stop, setMicMuted, setOutputMuted,
sendUserMessage, sendAgentMessage,
updateListen, updateThink, updateSpeak, updatePrompt,
clearConversation, interrupt,
} = useDeepgramAgent({
config: {
auth: { tokenFactory: () => fetch('/api/token').then(r => r.text()) },
agent: { think: { provider: { type: 'open_ai' }, model: 'gpt-4o-mini' } },
agent: { think: { provider: { type: 'open_ai', model: 'gpt-4o-mini' } } },
},
onWarning: (message) => console.warn(message),
onLatencyReport: (report) => console.debug(report),
});
```

Expand All @@ -211,7 +234,7 @@ All hooks, the provider, context types, and common SDK types (re-exported from `
```ts
// Provider
export { AgentProvider };
export type { AgentProviderProps };
export type { AgentNotificationCallbacks, AgentProviderProps };

// Hooks
export {
Expand All @@ -235,8 +258,11 @@ export type { AgentContextValue, ConversationEntry, AgentMode };
// SDK types (re-exported from @deepgram/agents)
export type {
AgentSessionConfig, AuthConfig, TokenFactory,
AgentSettingsObject, ThinkSettings, SpeakSettings,
MicrophoneOptions,
AgentSettingsObject, AgentMessageBehavior, ListenSettings,
ThinkSettings, SpeakSettings, MicrophoneOptions,
AgentThinkingMessage, ListenUpdatedMessage, LatencyReportMessage,
HistoryMessage, InjectionRefusedMessage,
AgentErrorMessage, AgentWarningMessage,
};
```

Expand Down
8 changes: 5 additions & 3 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@
"typecheck": "tsc --noEmit",
"dev": "vite build --watch",
"test": "bun test",
"test:watch": "bun test --watch"
"test:watch": "bun test --watch",
"lint": "biome lint src/index.ts src/context.ts src/provider.tsx src/hooks --error-on-warnings"
},
"dependencies": {
"@deepgram/agents": "^0.1.1"
"@deepgram/agents": "^0.1.2"
},
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
},
"devDependencies": {
"@biomejs/biome": "2.4.10",
"@testing-library/react": "16.3.2",
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3",
Expand All @@ -49,7 +51,7 @@
"react": "19.2.5",
"react-dom": "19.2.5",
"terser": "5.46.2",
"typescript": "6.0.2",
"typescript": "5.9.3",
"vite": "8.0.10",
"vite-plugin-dts": "4.5.4"
},
Expand Down
Loading