use io_harness::{
run_tree, ApproveAll, Containment, Policy, RunOutcome, Store, TaskContract, Verification,
};
#[tokio::main]
async fn main() -> io_harness::Result<()> {
let provider = io_harness::OpenRouter::from_env()?;
let dir = tempfile::tempdir()?;
let contract = TaskContract::workspace(
"You are a coordinator. Do NOT write files yourself. Use the spawn_agent \
tool twice: spawn one sub-agent whose goal is to create the file a.txt \
containing the word ALPHA (verify_file a.txt, verify_contains ALPHA), \
and another whose goal is to create b.txt containing BETA (verify_file \
b.txt, verify_contains BETA). After both sub-agents finish, write \
summary.txt containing the word DONE.",
dir.path(),
Verification::WorkspaceFileContains { file: "summary.txt".into(), needle: "DONE".into() },
)
.with_max_steps(8);
let policy = Policy::permissive();
let containment = Containment::new(3, 2, 1, 200_000);
let store = Store::open(dir.path().join("runs.db"))?;
let result = run_tree(&contract, &provider, &store, &policy, &ApproveAll, &containment).await?;
println!("outcome: {:?}", result.outcome);
println!("\ntree:");
for child in store.children(result.run_id)? {
println!(" child run {child}: depth {}", store.depth(child)?);
}
for e in store.agent_events(result.run_id)? {
match e.kind.as_str() {
"spawn" => println!(" spawn -> run {:?} ({:?})", e.child_run_id, e.detail),
"spawn_refused" => println!(" spawn REFUSED (cap: {:?})", e.detail),
"budget_draw" => println!(" drew {:?} tokens, {:?} left", e.tokens, e.remaining),
_ => {}
}
}
for f in ["a.txt", "b.txt", "summary.txt"] {
let p = dir.path().join(f);
println!(" {f}: {}", if p.exists() { "present" } else { "absent" });
}
if !matches!(result.outcome, RunOutcome::Success { .. }) {
eprintln!("note: the parent did not reach success; see the trace above");
}
Ok(())
}