use enki_next::agent::AgentDefinition;
use enki_next::runtime::MultiAgentRuntime;
use std::env;
use std::io::{self, Write};
use std::path::PathBuf;
fn usage(program: &str) {
eprintln!(
"Usage: {program} <prompt>\n\
Optional env vars:\n\
- ENKI_MODEL=provider::model\n\
- ENKI_WORKSPACE=path"
);
}
#[tokio::main]
async fn main() {
let mut args = env::args();
let program = args.next().unwrap_or_else(|| "multi_agent".to_string());
let prompt = args.collect::<Vec<_>>().join(" ");
if prompt.trim().is_empty() {
usage(&program);
std::process::exit(1);
}
let workspace_home = env::var("ENKI_WORKSPACE")
.ok()
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("crates/core/examples/.agent-workspace"));
let model = env::var("ENKI_MODEL").unwrap_or_else(|_| "ollama::qwen3.5".to_string());
let coordinator_def = AgentDefinition {
name: "Coordinator".to_string(),
system_prompt_preamble: "\
You are a coordinator agent. You can use `discover_agents` to find \
peer agents and `delegate_task` to send work to them. \
Prefer delegating research tasks to a peer with the 'research' \
capability whenever appropriate."
.to_string(),
model: model.clone(),
max_iterations: 50,
};
let researcher_def = AgentDefinition {
name: "Researcher".to_string(),
system_prompt_preamble: "\
You are a research agent. You read files, run commands, and \
synthesize concise answers. Focus on factual, well-structured \
responses."
.to_string(),
model: model.clone(),
max_iterations: 50,
};
let runtime = match MultiAgentRuntime::builder()
.add_agent(
"coordinator",
coordinator_def,
vec!["orchestration".into(), "planning".into()],
)
.add_agent(
"researcher",
researcher_def,
vec!["research".into(), "analysis".into()],
)
.with_workspace_home(workspace_home)
.build()
.await
{
Ok(rt) => rt,
Err(err) => {
eprintln!("Failed to build multi-agent runtime: {err}");
std::process::exit(1);
}
};
println!("=== Registered Agents ===");
for card in runtime.registry().list_all().await {
println!(
" - {} (id={}, capabilities={:?}, status={})",
card.name, card.agent_id, card.capabilities, card.status
);
}
println!();
println!("Prompt: {prompt}");
print!("Running coordinator agent...");
let _ = io::stdout().flush();
let response = runtime
.process("coordinator", "demo-session", &prompt)
.await;
match response {
Ok(content) => println!("\n\nResponse:\n{content}"),
Err(err) => eprintln!("\n\nError: {err}"),
}
}