Skip to main content

deepgram-rust-voice-agent

Use when implementing a Deepgram Voice Agent from the Rust SDK, including the agent() WebSocket client, Settings/Update messages, typed AgentResponse events, function calling, and saved agent configurations.

소스 정보

저장소
deepgram/deepgram-rust-sdk
최근 소스 활동
2026년 10월 8일 12:56
감지된 SKILL.md 언어
영어
스타
67
포크
45

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
deepgram-rust-voice-agent
description
Use when implementing a Deepgram Voice Agent from the Rust SDK, including the agent() WebSocket client, Settings/Update messages, typed AgentResponse events, function calling, and saved agent configurations.
# Using Deepgram Voice Agent (Rust SDK) Use this skill when the user wants an end-to-end conversational voice agent — STT, LLM, and TTS orchestrated by Deepgram over one WebSocket. ## When to use this product - Building a full conversational agent (the server runs the turn loop, the LLM call, and speech synthesis). - Handling agent events: conversation text, function-call requests, latency reports, interruptions. - Changing a live session's model, prompt, or voice without reconnecting. Prefer conversational STT (`flux_request`) instead when the application only needs turn-based transcripts and drives its own LLM and TTS. ## Authentication The Voice Agent client is behind the `agent` feature (on by default). ```toml [dependencies] deepgram = { version = "0.12", default-features = false, features = ["agent"] } tokio = { version = "1", features = ["full"] } futures = "0.3" ``` `agent` is also part of the crate's default features, so a plain `cargo add deepgram` includes it. ```rust let dg = deepgram::Deepgram::new(std::env::var("DEEPGRAM_API_KEY")?)?; ``` The credential travels in the handshake's `Authorization` header. `start()` uses the SaaS endpoint; `start_at_url()` accepts a custom host but requires `wss://` (plain `ws://` is allowed only for loopback, so local mock servers work). Do not hand-roll a raw `tokio_tungstenite::connect_async` session: the SDK client also supplies the shared rustls connector (so `rustls-tls-native-roots` and `Deepgram::tls_config` apply), the correct `Host` authority for non-default ports, and `Debug` redaction of provider credentials. ## Quick start ```rust use deepgram::agent::{ audio::{AudioConfig, AudioInput, AudioInputEncoding}, listen::{AgentListenProvider, AgentListenSettings, DeepgramListenV2Provider}, settings::{AgentConfig, InlineAgentConfig, SettingsMessage}, speak::{DeepgramSpeakModel, DeepgramSpeakProvider, SpeakProvider, SpeakSettings}, think::{OpenAiModel, OpenAiThinkProvider, ThinkProvider, ThinkSettings}, AgentEvent, AgentResponse, }; use deepgram::{Deepgram, DeepgramError}; use futures::stream::StreamExt; #[tokio::main] async fn main() -> Result<(), DeepgramError> { let dg = Deepgram::new(std::env::var("DEEPGRAM_API_KEY").unwrap())?; let (mut handle, mut events) = dg.agent().start().await?; handle .send_settings(SettingsMessage::new( AudioConfig::new( Some(AudioInput::new(AudioInputEncoding::Linear16, 16_000)), None, ), AgentConfig::inline( InlineAgentConfig::from_parts( AgentListenSettings::new(AgentListenProvider::DeepgramV2( DeepgramListenV2Provider::new("flux-general-en"), )), ThinkSettings::new(ThinkProvider::OpenAi(OpenAiThinkProvider::new( OpenAiModel::Gpt4oMini, ))), SpeakSettings::new(SpeakProvider::Deepgram(DeepgramSpeakProvider::new( DeepgramSpeakModel::Aura2ThaliaEn, ))), ) .with_greeting("Hello! How can I help today?"), ), )) .await?; // Stream microphone audio with handle.send_data(pcm) from another task. while let Some(event) = events.next().await { match event? { AgentEvent::Json(AgentResponse::ConversationText(c)) => { println!("{:?}: {}", c.role, c.content) } AgentEvent::Json(AgentResponse::Error(e)) => { eprintln!("{}: {}", e.code, e.description); break; } AgentEvent::Json(AgentResponse::Unknown(value)) => println!("unmodeled: {value}"), AgentEvent::Audio(bytes) => println!("{} bytes of agent audio", bytes.len()), _ => {} // AgentEvent and AgentResponse are #[non_exhaustive] } } Ok(()) } ``` ## Key parameters - Entry points: `dg.agent().start()`, `dg.agent().start_at_url(url)`. Both return `(AgentHandle, AgentEventStream)`. - `AgentHandle` client messages: `send_settings`, `send_update_listen`, `send_update_speak`, `send_update_think`, `send_update_prompt`, `send_inject_user_message`, `send_inject_agent_message`, `send_function_call_response`, `send_data` (binary audio), `keep_alive`, `force_end_turn`, `close`, and `send_raw_json` as the escape hatch for messages the SDK has not typed yet. - `AgentEventStream` implements `futures::Stream<Item = Result<AgentEvent>>`; `AgentEvent` is `Json(AgentResponse)` or `Audio(Bytes)`, interleaved in protocol order. - Settings: `AgentConfig::inline(InlineAgentConfig…)` or `AgentConfig::saved(uuid)` for a saved configuration. Listen providers are Deepgram V1 (Nova) and V2 (Flux STT, with `language_hints`, `eot_threshold`, `eager_eot_threshold`, `eot_timeout_ms`, `keyterms`); Think providers are OpenAI, Anthropic, AWS Bedrock, Google, and Groq; Speak providers are Deepgram, ElevenLabs, Cartesia, OpenAI, and AWS Polly. - Request id: `handle.request_id()` / `events.request_id()` from the upgrade header, or `AgentResponse::Welcome`'s `request_id` when the header is absent. ## API reference (layered) 1. **In-repo** - `src/agent/websocket.rs` (client, handle, event stream) - `src/agent/settings.rs`, `src/agent/messages.rs`, `src/agent/response.rs` - `src/agent/{audio,listen,think,speak,history,endpoint,aws_credentials}.rs` - `examples/agent/websocket/simple_agent.rs`, `examples/agent/websocket/function_calling.rs` - `tests/agent_websocket_local.rs` 2. **OpenAPI** - Raw spec: `https://developers.deepgram.com/openapi.yaml` - Voice Agent reference page: `https://developers.deepgram.com/reference/voice-agent/voice-agent` 3. **AsyncAPI** - Raw spec: `https://developers.deepgram.com/asyncapi.yaml` - Voice Agent channel reference: `https://developers.deepgram.com/reference/voice-agent/voice-agent` 4. **Context7** - `/llmstxt/developers_deepgram_llms_txt` 5. **Product docs** - `https://developers.deepgram.com/docs/voice-agent` ## Gotchas 1. **Its own host.** Voice Agent runs on `agent.deepgram.com`, not `api.deepgram.com`. `Deepgram::with_base_url` does not redirect it; use `start_at_url` for a self-hosted deployment. 2. **`Settings` comes first.** Send it before any audio, and wait for `SettingsApplied` before assuming the configuration is live. `Update*` messages are confirmed by their own `ListenUpdated` / `SpeakUpdated` / `ThinkUpdated` / `PromptUpdated` events. 3. **KeepAlive while silent.** The server closes sessions that go quiet; send `keep_alive()` every 8 seconds during an idle period. It does not extend the 2-hour session cap. 4. **Drain the event stream.** The handle and the stream are bounded channels, so send audio and consume events from separate tasks rather than queueing audio without reading. 5. **Sends fail once the session ends.** After a peer close or a transport error, every `send_*` on a retained handle returns an error instead of silently dropping the message; `close()` on an ended session is a no-op. 6. **Unmodeled events are preserved; malformed known ones are not swallowed.** An event whose `type` the SDK does not model lands in `AgentResponse::Unknown(serde_json::Value)` rather than breaking the stream — including the production `{"type":"EndOfTurn","trigger":"model"|"timeout"}` message from Flux STT listen providers, which is not in the published spec yet. An event whose `type` *is* modeled but whose payload does not fit its schema arrives as an `Err` item naming the event type, so a malformed `Error` event is never mistaken for an ignorable `Unknown`. A modeled event carrying an *unmodeled value* is neither: a `role` the SDK does not name arrives as `ConversationRole::Unknown(String)` holding the wire string, and a `History` entry matching neither modeled shape as `HistoryMessage::Unknown(serde_json::Value)`, so a new server enum value never ends the session. 7. **`force_end_turn` needs Flux STT.** With any other listen provider the server answers `FORCE_END_TURN_UNSUPPORTED` as a `Warning` and the turn does not end. 8. **Do not answer `FunctionCallCancelled`.** It reports calls the server abandoned; only `FunctionCallRequest` expects a `send_function_call_response`. ## Example files in this repo - `examples/agent/websocket/simple_agent.rs` — connect, configure, print events, close. - `examples/agent/websocket/function_calling.rs` — client-side function execution and `FunctionCallResponse`. ## Central product skills For cross-language Deepgram product knowledge — the consolidated API reference, documentation finder, focused runnable recipes, third-party integration examples, and MCP setup — install the central skills: ```bash npx skills add deepgram/skills ``` This SDK ships language-idiomatic code skills; `deepgram/skills` ships cross-language product knowledge (see `api`, `docs`, `recipes`, `examples`, `starters`, `setup-mcp`).
GitHub에서 보기