use agentsdk::core::Tool;
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use agentsdk::core::{LanguageModelRequest, LanguageModelStreamChunkType};
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use agentsdk::integrations::vercel_agentsdk_ui::VercelUIStreamOptions;
#[cfg(feature = "anthropic")]
use agentsdk::providers::anthropic::Anthropic;
#[cfg(feature = "google")]
use agentsdk::providers::google::Google;
#[cfg(feature = "openai")]
use agentsdk::providers::openai::OpenAI;
use agentsdk::tool;
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use futures::StreamExt;
#[tool]
fn get_username(user_id: String) -> Tool {
match user_id.as_str() {
"123" => Ok("sura".to_string()),
_ => Ok("invalid".to_string()),
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv::dotenv().ok();
let args: Vec<String> = std::env::args().collect();
let provider = args.get(1).map(String::as_str).unwrap_or("openai");
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
let mode = args.get(2).map(String::as_str).unwrap_or("both");
match provider {
"openai" => {
#[cfg(feature = "openai")]
{
return run_openai(mode).await;
}
#[cfg(not(feature = "openai"))]
{
return Err("openai feature is not enabled".into());
}
}
"anthropic" => {
#[cfg(feature = "anthropic")]
{
return run_anthropic(mode).await;
}
#[cfg(not(feature = "anthropic"))]
{
return Err("anthropic feature is not enabled".into());
}
}
"google" => {
#[cfg(feature = "google")]
{
return run_google(mode).await;
}
#[cfg(not(feature = "google"))]
{
return Err("google feature is not enabled".into());
}
}
_ => Err("provider must be one of: openai | anthropic | google".into()),
}
}
#[cfg(feature = "openai")]
async fn run_openai(mode: &str) -> Result<(), Box<dyn std::error::Error>> {
if mode == "core" || mode == "both" {
println!("=== OPENAI core stream ===");
let response = LanguageModelRequest::builder()
.model(OpenAI::gpt_5_nano())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut stream = response.stream;
while let Some(chunk) = stream.next().await {
match chunk {
LanguageModelStreamChunkType::ToolCallDelta { id, delta } => {
println!("ToolCallDelta id={id} delta={delta}");
}
LanguageModelStreamChunkType::ToolCallStart(details) => {
println!("ToolCallStart id={} name={}", details.id, details.name);
}
LanguageModelStreamChunkType::ToolCallEnd(info) => {
println!(
"ToolCallEnd id={} name={} output={:?}",
info.tool.id, info.tool.name, info.output
);
}
other => println!("{other:?}"),
}
}
}
if mode == "vercel" || mode == "both" {
println!("=== OPENAI vercel ui stream ===");
let response = LanguageModelRequest::builder()
.model(OpenAI::gpt_5_nano())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut ui = response.into_vercel_ui_stream(VercelUIStreamOptions {
send_reasoning: true,
send_start: true,
send_finish: true,
..Default::default()
});
while let Some(item) = ui.next().await {
println!("{:?}", item?);
}
}
Ok(())
}
#[cfg(feature = "anthropic")]
async fn run_anthropic(mode: &str) -> Result<(), Box<dyn std::error::Error>> {
if mode == "core" || mode == "both" {
println!("=== ANTHROPIC core stream ===");
let response = LanguageModelRequest::builder()
.model(Anthropic::claude_haiku_4_5())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut stream = response.stream;
while let Some(chunk) = stream.next().await {
match chunk {
LanguageModelStreamChunkType::ToolCallDelta { id, delta } => {
println!("ToolCallDelta id={id} delta={delta}");
}
LanguageModelStreamChunkType::ToolCallStart(details) => {
println!("ToolCallStart id={} name={}", details.id, details.name);
}
LanguageModelStreamChunkType::ToolCallEnd(info) => {
println!(
"ToolCallEnd id={} name={} output={:?}",
info.tool.id, info.tool.name, info.output
);
}
other => println!("{other:?}"),
}
}
}
if mode == "vercel" || mode == "both" {
println!("=== ANTHROPIC vercel ui stream ===");
let response = LanguageModelRequest::builder()
.model(Anthropic::claude_haiku_4_5())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut ui = response.into_vercel_ui_stream(VercelUIStreamOptions {
send_reasoning: true,
send_start: true,
send_finish: true,
..Default::default()
});
while let Some(item) = ui.next().await {
println!("{:?}", item?);
}
}
Ok(())
}
#[cfg(feature = "google")]
async fn run_google(mode: &str) -> Result<(), Box<dyn std::error::Error>> {
if mode == "core" || mode == "both" {
println!("=== GOOGLE core stream ===");
let response = LanguageModelRequest::builder()
.model(Google::gemini_3_flash_preview())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut stream = response.stream;
while let Some(chunk) = stream.next().await {
match chunk {
LanguageModelStreamChunkType::ToolCallDelta { id, delta } => {
println!("ToolCallDelta id={id} delta={delta}");
}
LanguageModelStreamChunkType::ToolCallStart(details) => {
println!("ToolCallStart id={} name={}", details.id, details.name);
}
LanguageModelStreamChunkType::ToolCallEnd(info) => {
println!(
"ToolCallEnd id={} name={} output={:?}",
info.tool.id, info.tool.name, info.output
);
}
other => println!("{other:?}"),
}
}
}
if mode == "vercel" || mode == "both" {
println!("=== GOOGLE vercel ui stream ===");
let response = LanguageModelRequest::builder()
.model(Google::gemini_3_flash_preview())
.system("You must call tool get_username with user_id = '123'. After tool result, respond with only the username.")
.prompt("What is the username for user id 123?")
.with_tool(get_username())
.build()
.stream_text()
.await?;
let mut ui = response.into_vercel_ui_stream(VercelUIStreamOptions {
send_reasoning: true,
send_start: true,
send_finish: true,
..Default::default()
});
while let Some(item) = ui.next().await {
println!("{:?}", item?);
}
}
Ok(())
}