use opencode_rs::ClientBuilder;
use opencode_rs::types::event::Event;
use opencode_rs::types::message::PromptPart;
use opencode_rs::types::message::PromptRequest;
use opencode_rs::types::session::CreateSessionRequest;
use opencode_rs::types::session::UpdateSessionRequest;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("=== OpenCode Rust SDK Full Workflow Example ===\n");
println!("1. Creating client...");
let client = ClientBuilder::new()
.base_url("http://127.0.0.1:4096")
.directory(std::env::current_dir()?.to_string_lossy())
.timeout_secs(300)
.build()?;
println!("2. Checking server health...");
let health = client.misc().health().await?;
println!(" Server healthy: {}", health.healthy);
if let Some(version) = &health.version {
println!(" Server version: {version}");
}
println!("\n3. Creating session...");
let session = client
.sessions()
.create(&CreateSessionRequest {
title: Some("SDK Full Workflow Example".into()),
..Default::default()
})
.await?;
println!(" Created session: {}", session.id);
println!(" Title: {}", session.title);
println!("\n4. Subscribing to session events...");
let mut subscription = client.subscribe_session(&session.id)?;
println!(" Subscribed successfully");
println!("\n5. Sending prompt...");
let prompt_text = "Write a short haiku about programming";
client
.messages()
.prompt(
&session.id,
&PromptRequest {
parts: vec![PromptPart::Text {
text: prompt_text.into(),
synthetic: None,
ignored: None,
metadata: None,
}],
message_id: None,
model: None,
agent: None,
no_reply: None,
system: None,
variant: None,
},
)
.await?;
println!(" Prompt sent: \"{prompt_text}\"");
println!("\n6. Streaming response...\n");
let mut response_text = String::new();
let timeout = Duration::from_secs(60);
let start = std::time::Instant::now();
loop {
if start.elapsed() > timeout {
println!("\n [Timeout reached]");
break;
}
tokio::select! {
event = subscription.recv() => {
match event {
Some(Event::SessionIdle { .. }) => {
println!("\n [Session completed]");
break;
}
Some(Event::SessionError { properties }) => {
eprintln!("\n [Session error: {:?}]", properties.error);
break;
}
Some(Event::MessagePartUpdated { properties }) => {
if let Some(delta) = &properties.delta {
print!("{delta}");
response_text.push_str(delta);
}
}
Some(_) => {
}
None => {
println!("\n [Stream closed]");
break;
}
}
}
() = tokio::time::sleep(Duration::from_millis(100)) => {
}
}
}
println!("\n7. Updating session title...");
let updated = client
.sessions()
.update(
&session.id,
&UpdateSessionRequest {
title: Some("Completed Haiku Session".into()),
},
)
.await?;
println!(" New title: {}", updated.title);
println!("\n8. Getting session diff...");
let diff = client.sessions().diff(&session.id).await?;
println!(" Files changed: {}", diff.len());
for file_diff in &diff {
println!(
" - {} (+{}, -{})",
file_diff.file, file_diff.additions, file_diff.deletions
);
}
println!("\n9. Checking todos...");
let todos = client.sessions().todo(&session.id).await?;
println!(" Todos: {}", todos.len());
for todo in &todos {
println!(
" - [{}] {}",
if todo.completed { "x" } else { " " },
todo.content
);
}
println!("\n10. Listing messages...");
let messages = client.messages().list(&session.id).await?;
println!(" Total messages: {}", messages.len());
for msg in &messages {
println!(" - {} (parts: {})", msg.role(), msg.parts.len());
}
println!("\n11. Cleaning up - deleting session...");
client.sessions().delete(&session.id).await?;
println!(" Session deleted");
println!("\n=== Workflow Complete ===");
println!("\nResponse received:\n{response_text}");
Ok(())
}