use std::env;
use std::time::Duration;
use futures::stream::StreamExt;
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};
static SESSION_DURATION: Duration = Duration::from_secs(30);
static KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(8);
#[tokio::main]
async fn main() -> Result<(), DeepgramError> {
let api_key = env::var("DEEPGRAM_API_KEY").expect("DEEPGRAM_API_KEY environment variable");
let dg = Deepgram::new(&api_key)?;
let (mut handle, mut events) = dg.agent().start().await?;
println!(
"Connected. dg-request-id from upgrade headers: {:?}",
handle.request_id()
);
let 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?"),
),
);
handle.send_settings(settings).await?;
let timeout = tokio::time::sleep(SESSION_DURATION);
tokio::pin!(timeout);
let mut keep_alive = tokio::time::interval(KEEP_ALIVE_INTERVAL);
keep_alive.tick().await;
loop {
tokio::select! {
_ = &mut timeout => {
println!("\nSession duration reached, closing.");
break;
}
_ = keep_alive.tick() => {
handle.keep_alive().await?;
}
event = events.next() => {
match event {
Some(Ok(AgentEvent::Json(response))) => match response {
AgentResponse::Welcome(w) => {
println!("Welcome event request_id: {}", w.request_id);
}
AgentResponse::SettingsApplied(_) => {
println!("Settings applied");
}
AgentResponse::AgentThinking(t) => {
println!("Agent thinking: {}", t.content);
}
AgentResponse::ConversationText(c) => {
println!("Conversation ({:?}): {}", c.role, c.content);
}
AgentResponse::UserStartedSpeaking(_) => {
println!("User started speaking");
}
AgentResponse::AgentStartedSpeaking(s) => {
println!(
"Agent started speaking (total_latency={:.3}s)",
s.total_latency
);
}
AgentResponse::AgentAudioDone(_) => {
println!("Agent audio done");
}
AgentResponse::Warning(w) => {
println!("Warning [{}]: {}", w.code, w.description);
}
AgentResponse::Error(e) => {
eprintln!("Error [{}]: {}", e.code, e.description);
break;
}
other => println!("Other event: {:?}", other),
},
Some(Ok(AgentEvent::Audio(bytes))) => {
println!("Audio chunk: {} bytes", bytes.len());
}
Some(Ok(_)) => {}
Some(Err(err)) => {
eprintln!("Stream error: {}", err);
break;
}
None => {
println!("Server closed connection.");
break;
}
}
}
}
}
handle.close().await?;
Ok(())
}