opencode_rs

Crates.ioopencode_rs
lib.rsopencode_rs
version0.1.1
created_at2026-01-04 20:22:35.426624+00
updated_at2026-01-04 21:22:43.733072+00
descriptionRust SDK for OpenCode (HTTP-first hybrid with SSE streaming)
homepagehttps://github.com/allisoneer/agentic_auxilary
repositoryhttps://github.com/allisoneer/agentic_auxilary
max_upload_size
id2022420
size347,328
Allison Durham (allisoneer)

documentation

https://docs.rs/opencode_rs

README

opencode_rs

Rust SDK for OpenCode (HTTP-first hybrid with SSE streaming). Provides an async client for HTTP endpoints and Server-Sent Events (SSE) subscriptions, with optional helpers for managing a local server and CLI integration.

Platform: Unix-like systems (Linux/macOS). Windows is currently not supported.

Table of Contents

Installation

Add the crate to your Cargo.toml:

[dependencies]
opencode_rs = "0.1.0"

Feature flags:

  • Default: http, sse
  • Optional: server, cli
  • Convenience: full = http + sse + server + cli

Examples:

# Minimal (HTTP + SSE)
cargo build

# Explicitly choose features
cargo build --no-default-features --features http
cargo build --features "http sse"
cargo build --features full

Usage

All examples assume an OpenCode server is running locally:

opencode serve
# Default URL: http://127.0.0.1:4096

Basic Session

Create a session and send a prompt via HTTP:

use opencode_rs::ClientBuilder;
use opencode_rs::types::message::{PromptPart, PromptRequest};
use opencode_rs::types::session::CreateSessionRequest;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Build client connecting to default localhost:4096
    let client = ClientBuilder::new().build()?;

    // Create a new session
    let session = client
        .sessions()
        .create(&CreateSessionRequest::default())
        .await?;
    println!("Created session: {}", session.id);

    // Send a prompt
    client
        .messages()
        .prompt(
            &session.id,
            &PromptRequest {
                parts: vec![PromptPart::Text {
                    text: "Hello OpenCode! What can you help me with?".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 successfully!");

    // Clean up session to avoid accumulating dangling sessions
    client.sessions().delete(&session.id).await?;
    println!("Session deleted");

    Ok(())
}

Streaming Events

Subscribe to SSE and stream events in real time:

use opencode_rs::ClientBuilder;
use opencode_rs::types::event::Event;
use opencode_rs::types::message::{PromptPart, PromptRequest};
use opencode_rs::types::session::CreateSessionRequest;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize tracing for debug output
    tracing_subscriber::fmt::init();

    // Build client
    let client = ClientBuilder::new().build()?;

    // Create session
    let session = client
        .sessions()
        .create(&CreateSessionRequest::default())
        .await?;
    println!("Created session: {}", session.id);

    // Subscribe to session events BEFORE sending prompt
    let mut subscription = client.subscribe_session(&session.id).await?;
    println!("Subscribed to events");

    // Send prompt
    client
        .messages()
        .prompt(
            &session.id,
            &PromptRequest {
                parts: vec![PromptPart::Text {
                    text: "Write a haiku about Rust programming".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, streaming events...\n");

    // Stream events until session is idle or error
    loop {
        match subscription.recv().await {
            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);
                }
            }
            Some(Event::ServerHeartbeat { .. }) => {
                // Heartbeat received, connection alive
            }
            Some(event) => {
                println!("[Event: {:?}]", event);
            }
            None => {
                println!("[Stream closed]");
                break;
            }
        }
    }

    // Cleanup
    client.sessions().delete(&session.id).await?;
    println!("Session deleted");

    Ok(())
}

Features

  • HTTP-first design for creating sessions and sending prompts
  • SSE streaming with heartbeat and retry/backoff (via reqwest-eventsource + backoff)
  • Async API built on Tokio
  • Optional managed server launcher and CLI integration (feature flags)
  • Strongly-typed request/response and event enums

Configuration

Use ClientBuilder to construct a client. Defaults connect to http://127.0.0.1:4096. Builder options allow customizing base URL, timeouts, and SSE behavior (e.g., retry/backoff). See docs.rs for full builder options.

Example (defaults):

let client = opencode_rs::ClientBuilder::new().build()?;

Error Handling

Most operations return Result<T, opencode_rs::Error>. Common error categories include HTTP status errors, JSON (de)serialization errors, SSE connection/stream errors, and timeouts.

match client.sessions().delete(&session.id).await {
    Ok(_) => println!("Session deleted"),
    Err(e) => eprintln!("Failed to delete session: {e}"),
}

Examples

Run the included examples (requires a local OpenCode server):

# Basic HTTP example
cargo run --example basic

# SSE streaming example
cargo run --example streaming

License

Licensed under the Apache-2.0 License. See the crate's Cargo.toml for details.

Commit count: 493

cargo fmt