use std::sync::Arc;
use std::time::Instant;
use anyhow::Result;
use clap::Parser;
use colored::Colorize;
use log::info;
use neuromance_agent::AgentTask;
use neuromance_client::LLMClient;
use neuromance_client::openai::client::OpenAIClient;
use neuromance_common::client::Config;
use neuromance_tools::generic::CurrentTimeTool;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(long, default_value = "http://localhost:8080/v1")]
base_url: String,
#[arg(long, default_value = "dummy")]
api_key: String,
#[arg(long, default_value = "ggml-org/gpt-oss-120b-GGUF")]
model: String,
#[arg(long)]
mcp_config: Option<std::path::PathBuf>,
}
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
let args = Args::parse();
info!("Agent Task Demo: Vampire Time Teller");
info!("=====================================");
info!("Base URL: {}", args.base_url);
info!("Model: {}", args.model);
let config = Config::new("openai", &args.model)
.with_base_url(&args.base_url)
.with_api_key(&args.api_key);
info!("Config model: {}", config.model);
let start_time = Instant::now();
let client = OpenAIClient::new(config)?;
info!("Client config model: {}", client.config().model);
let mut task = AgentTask::new(
"vampire-time-task",
"Tell me the current time like a vampire from Transylvania would",
client,
);
if let Some(mcp_config_path) = args.mcp_config {
info!("Loading MCP configuration from {:?}", mcp_config_path);
use neuromance_tools::mcp::{McpConfig, McpManager};
let mcp_config = McpConfig::from_file(&mcp_config_path)?;
let mcp_manager = McpManager::new(mcp_config).await?;
let tools = mcp_manager.get_all_tools().await?;
info!("Connected to MCP servers and loaded {} tools", tools.len());
for tool in tools.iter() {
task.add_tool_arc(Arc::clone(tool));
}
println!(
"{}",
format!("✓ Loaded {} MCP tools", tools.len()).bright_green()
);
}
task.add_tool(CurrentTimeTool);
task.verifier_agent.agent.core.client = task
.verifier_agent
.agent
.core
.client
.with_model("gpt-oss:120b".to_string());
info!("\n=== Phase 1: Context Agent ===");
let context_response = task.gather_context().await?;
info!("Context Analysis:\n{}", context_response.content.content);
info!("\n=== Phase 2: Action Agent ===");
let action_response = task.take_action().await?;
info!("Vampire says:\n{}", action_response.content.content);
info!("\n=== Phase 3: Verifier Agent ===");
let verify_response = task.verify().await?;
info!("Task Result:\n\n {}", action_response.content.content);
info!(
"Verification Result: {}",
if task.state.verified {
"SUCCESS ✓"
} else {
"FAILED ✗"
}
);
if let Some(reasoning) = &verify_response.reasoning {
info!("Reasoning: {}", reasoning);
}
let total_duration = start_time.elapsed();
info!("\n=====================================");
info!("Total execution time: {:.2}s", total_duration.as_secs_f64());
info!("Task verified: {}", task.state.verified);
Ok(())
}