Skip to main content

run_prompt/
run_prompt.rs

1//! Run a prompt against a harness and stream the normalized events.
2//!
3//! `cargo run --example run_prompt`
4//! (requires the `claude` CLI installed + signed in; swap `Claude` for
5//! `Bob` / `Codex` to drive a different agent).
6
7use harness::{Claude, Harness, HarnessError, RunEvent, RunMode, RunRequest, RunTuning};
8
9fn main() -> Result<(), HarnessError> {
10    // Pick a harness. `Claude` drives the `claude` CLI (must be installed +
11    // signed in). Swap for `harness::Bob::new()` or `harness::Codex::new()`.
12    let claude = Claude::new();
13
14    // `run_channel()` starts the run and hands back the events on a channel,
15    // so there's no callback/`Sender` plumbing to write by hand. It returns
16    // immediately; events arrive on background threads. (`run()` is still
17    // there for push semantics — forwarding straight onto a Tauri Channel or
18    // SSE sink from inside a callback.)
19    let (_handle, rx) = claude.run_channel(RunRequest {
20        run_id: "demo".into(),
21        prompt: "In one sentence, what is a Markdown heading?".into(),
22        cwd: None,                    // working dir for the agent's tool calls
23        mode: RunMode::Ask,           // Ask = answer only; Edit = may edit files
24        tuning: RunTuning::default(), // optional: model / effort / max_turns
25        resume: None,                 // Some(session_id) to continue a prior run
26    })?; // keep `_handle` to `.cancel()`; dropping it does NOT stop the run
27
28    // ONE normalized event stream, regardless of the backing CLI. `rx` hangs
29    // up on its own when the run ends, so this loop terminates without
30    // touching the handle:
31    for ev in rx {
32        match ev {
33            RunEvent::Text { delta, .. } => print!("{delta}"), // the answer
34            RunEvent::Thinking { delta, .. } => eprint!("{delta}"), // model reasoning
35            RunEvent::ToolStart { name, .. } => eprintln!("\n[tool] {name}"),
36            RunEvent::Error { message, .. } => eprintln!("\n[error] {message}"),
37            RunEvent::Exited { .. } => break,
38            _ => {}
39        }
40    }
41    Ok(())
42}