use std::sync::Arc;
use serde_json::json;
use tinyagents::Result;
use tinyagents::harness::providers::openai::OpenAiModel;
use tinyagents::registry::CapabilityRegistry;
use tinyagents::rlm::{RlmConfig, RlmRunner};
#[tokio::main]
async fn main() -> Result<()> {
dotenvy::dotenv().ok();
let model = OpenAiModel::from_env()?;
let mut registry: CapabilityRegistry<()> = CapabilityRegistry::new();
registry.register_model("openai", Arc::new(model))?;
let config = RlmConfig::from_json(
r#"{
"interpreter": {"kind": "rhai"},
"driver_model": "openai",
"template": "context-explorer",
"policy": {"max_cells": 8, "max_llm_calls": 16, "cell_timeout": 90000}
}"#,
)?;
let mut runner = RlmRunner::from_config(config, Arc::new(registry), Arc::new(()))?;
let mut records = Vec::new();
for i in 0..200usize {
let team = ["platform", "growth", "ops"][i % 3];
let amount = 40 + (i * 7) % 60;
records.push(json!({
"id": i,
"team": team,
"amount_usd": amount,
"memo": format!("routine cloud spend, invoice {i}"),
}));
}
records[57] = json!({"id": 57, "team": "growth", "amount_usd": 18400,
"memo": "annual conference sponsorship paid twice, needs review"});
records[121] = json!({"id": 121, "team": "ops", "amount_usd": 9750,
"memo": "emergency hardware replacement after flood damage"});
records[188] = json!({"id": 188, "team": "platform", "amount_usd": 12300,
"memo": "contractor invoice with mismatched PO number"});
runner.set_context(json!(records)).await?;
println!("── system prompt ──\n{}\n", runner.system_prompt());
let outcome = runner
.run(
"The `context` variable holds 200 expense records. Find every anomalous record \
(unusual amount or memo), and summarize each anomaly in one line.",
)
.await?;
for (i, step) in outcome.steps.iter().enumerate() {
println!("── cell {} ──\n{}\n", i + 1, step.code);
if !step.outcome.stdout.is_empty() {
println!("stdout:\n{}", step.outcome.stdout);
}
if let Some(error) = &step.outcome.error {
println!("error: {error}");
}
}
println!("── answer ({:?}) ──", outcome.stop_reason);
println!("{}", outcome.answer.as_deref().unwrap_or("(none)"));
println!(
"\ndriver calls: {}, sub-llm calls: {}, tool calls: {}, agent calls: {}",
outcome.driver_calls, outcome.sub_llm_calls, outcome.tool_calls, outcome.agent_calls
);
Ok(())
}