use std::{error::Error, sync::Arc};
use async_trait::async_trait;
use langchain_rust::{
agent::{AgentExecutor, OpenAiToolAgentBuilder},
chain::Chain,
llm::openai::OpenAI,
prompt_args,
tools::Tool,
};
use serde_json::Value;
use tracing_subscriber::{fmt::format::FmtSpan, EnvFilter};
struct Weather;
#[async_trait]
impl Tool for Weather {
fn name(&self) -> String {
"weather".into()
}
fn description(&self) -> String {
"Current weather for a city".into()
}
async fn run(&self, input: Value) -> Result<String, Box<dyn Error>> {
Ok(format!("Sunny, 22°C in {}", input.as_str().unwrap_or("?")))
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("langchain_rust=info")),
)
.with_span_events(FmtSpan::CLOSE)
.init();
let tools: Vec<Arc<dyn Tool>> = vec![Arc::new(Weather)];
let agent = OpenAiToolAgentBuilder::new()
.tools(&tools)
.build(OpenAI::default())
.unwrap();
let executor = AgentExecutor::from_agent(agent);
let answer = executor
.invoke(prompt_args! {"input" => "What's the weather in Lima?"})
.await
.unwrap();
println!("{answer}");
}