Skip to main content

reimbursement_builder/
reimbursement_builder.rs

1//! Reimbursement agent using the new declarative builder API
2//!
3//! This example shows how to create a full-featured agent using TOML configuration
4//! with much less boilerplate than the traditional approach.
5
6use a2a_agents::{
7    agents::reimbursement::ReimbursementHandler,
8    core::{AgentBuilder, BuildError},
9};
10use a2a_rs::adapter::storage::SqlxTaskStorage;
11use std::env;
12
13#[tokio::main]
14async fn main() -> Result<(), Box<dyn std::error::Error>> {
15    // Load environment variables from .env file
16    dotenvy::dotenv().ok();
17
18    // Initialize logging
19    tracing_subscriber::fmt()
20        .with_env_filter(
21            tracing_subscriber::EnvFilter::from_default_env()
22                .add_directive(tracing::Level::INFO.into()),
23        )
24        .init();
25
26    println!("🚀 Starting Reimbursement Agent with Builder API");
27    println!();
28
29    // Get database URL from environment or use default
30    let database_url =
31        env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite:reimbursement_tasks.db".to_string());
32
33    // Create storage with custom migrations
34    let migrations = &[include_str!("../migrations/001_create_reimbursements.sql")];
35    let storage = SqlxTaskStorage::with_migrations(&database_url, migrations)
36        .await
37        .map_err(|e| format!("Failed to create storage: {}", e))?;
38
39    // Create the handler
40    let handler = ReimbursementHandler::new(storage.clone());
41
42    // Build and run the agent - this is where the magic happens!
43    // The configuration file defines all the metadata, skills, and features
44    // The builder wires everything together automatically
45    AgentBuilder::from_file("reimbursement.toml")?
46        .with_config(|config| {
47            // Override config from environment if needed
48            if let Ok(port) = env::var("HTTP_PORT") {
49                if let Ok(port_num) = port.parse() {
50                    config.server.http_port = port_num;
51                }
52            }
53            if let Ok(port) = env::var("WS_PORT") {
54                if let Ok(port_num) = port.parse() {
55                    config.server.ws_port = port_num;
56                }
57            }
58        })
59        .with_handler(handler)
60        .with_storage(storage)
61        .build()?
62        .run()
63        .await
64        .map_err(|e| BuildError::RuntimeError(e.to_string()))?;
65
66    Ok(())
67}