use agentd::agentloop::action::SelfHandler;
use agentd::agentloop::runner::{LoopInput, run_loop};
use agentd::intel::client::IntelClient;
use agentd::mcp::client::McpClient;
use agentd::obs::log::{Comp, Level, LogCtx, Logger};
use agentd::wire::intel::ToolDef;
use serde_json::{Value, json};
use std::time::{Duration, Instant};
struct NoSelfTools;
impl SelfHandler for NoSelfTools {
fn tools(&self) -> Vec<ToolDef> {
Vec::new()
}
fn handle(&mut self, _name: &str, _args: &Value) -> Option<(String, bool)> {
None
}
}
fn main() {
agentd::tools::register(agentd::tools::CodeTool::new(
"word_count",
"Count the words in a text.",
json!({"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"]}),
|args| {
let text = args.get("text").and_then(Value::as_str).unwrap_or("");
Ok(json!({ "words": text.split_whitespace().count() }))
},
))
.expect("unique tool name");
let Ok(intel_uri) = std::env::var("AGENT_INTELLIGENCE") else {
eprintln!("set AGENT_INTELLIGENCE (and optionally AGENT_INTELLIGENCE_TOKEN,");
eprintln!("AGENT_MODEL, AGENT_MCP=name=https://…) to run this example");
return;
};
let intel = IntelClient::from_parts(&intel_uri, std::env::var("AGENT_INTELLIGENCE_TOKEN").ok())
.expect("intelligence endpoint");
let mut servers: Vec<McpClient> = Vec::new();
if let Ok(spec) = std::env::var("AGENT_MCP") {
let (name, endpoint) = spec.split_once('=').expect("AGENT_MCP=name=endpoint");
let server_spec = agentd::config::McpServerSpec {
name: name.into(),
endpoint: endpoint.into(),
..Default::default()
};
let mut client =
agentd::mcp::from_spec(&server_spec, Duration::from_secs(60)).expect("mcp connect");
client.initialize().expect("mcp initialize");
servers.push(client);
}
let log = Logger::new(
LogCtx {
run_id: "embedded-example".into(),
agent_id: "0".into(),
agent_path: "0".into(),
comp: Comp::Agent,
pid: std::process::id(),
trace_id: None,
},
Level::Info,
);
let input = LoopInput {
instruction: "How many words are in the sentence \
'the quick brown fox jumps over the lazy dog'? \
Use the word_count tool, then answer with just the number."
.into(),
output_contract: Some("Answer with a single integer.".into()),
seed: Vec::new(),
model: std::env::var("AGENT_MODEL").unwrap_or_default(),
max_steps: 10,
max_tokens: 20_000,
deadline: Instant::now() + Duration::from_secs(120),
cancel: None,
};
match run_loop(&intel, &servers, &input, &mut NoSelfTools, &log) {
Ok((outcome, usage)) => {
println!("status: {:?}", outcome.status);
println!("result: {}", outcome.result);
println!(
"tokens: {} in / {} out",
usage.input_tokens, usage.output_tokens
);
}
Err(abort) => eprintln!("infrastructure failure: {abort:?}"),
}
}