use serde_json::{Map, Value, json};
use uuid::Uuid;
use a2a_agents::agents::reimbursement::handler::ReimbursementHandler;
use a2a_rs::InMemoryStreamingHandler;
use a2a_rs::adapter::storage::InMemoryTaskStorage;
use a2a_rs::domain::{Message, Part, Role};
use a2a_rs::port::message_handler::AsyncMessageHandler;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let task_storage = InMemoryTaskStorage::new();
let push = task_storage.push_notifier();
let handler = ReimbursementHandler::new(task_storage, InMemoryStreamingHandler::new(), push);
println!("=== Example 1: Text with metadata ===");
let mut metadata1 = Map::new();
metadata1.insert(
"expense_type".to_string(),
Value::String("travel".to_string()),
);
metadata1.insert("currency".to_string(), Value::String("EUR".to_string()));
metadata1.insert("priority".to_string(), Value::String("high".to_string()));
let message1 = Message::builder()
.role(Role::User)
.message_id(Uuid::new_v4().to_string())
.parts(vec![
Part::text_builder(
"I need reimbursement for 150 euros spent on hotel in Paris on 2024-01-15"
.to_string(),
)
.with_metadata(serde_json::from_value(Value::Object(metadata1)).unwrap())
.build(),
])
.build();
let task1 = handler.process_message("task1", &message1, None).await?;
println!("Response: {:?}\n", task1.status.message);
println!("=== Example 2: Data with metadata ===");
let mut data2 = Map::new();
data2.insert("date".to_string(), Value::String("2024-01-20".to_string()));
data2.insert(
"amount".to_string(),
Value::Number(serde_json::Number::from(75)),
);
data2.insert(
"purpose".to_string(),
Value::String("Client dinner meeting".to_string()),
);
let mut metadata2 = Map::new();
metadata2.insert(
"category_hint".to_string(),
Value::String("meals".to_string()),
);
metadata2.insert("auto_approve".to_string(), Value::Bool(true));
let message2 = Message::builder()
.role(Role::User)
.message_id(Uuid::new_v4().to_string())
.parts(vec![
Part::data_builder(serde_json::from_value(Value::Object(data2)).unwrap())
.with_metadata(serde_json::from_value(Value::Object(metadata2)).unwrap())
.build(),
])
.build();
let task2 = handler.process_message("task2", &message2, None).await?;
println!("Response: {:?}\n", task2.status.message);
println!("=== Example 3: File with metadata ===");
let mut file_metadata = Map::new();
file_metadata.insert(
"file_name".to_string(),
Value::String("receipt_hotel.pdf".to_string()),
);
file_metadata.insert(
"size_bytes".to_string(),
Value::Number(serde_json::Number::from(12345)),
);
file_metadata.insert(
"uploaded_by".to_string(),
Value::String("john.doe@company.com".to_string()),
);
let mut data3 = Map::new();
data3.insert("date".to_string(), Value::String("2024-01-25".to_string()));
data3.insert(
"amount".to_string(),
json!({"amount": 250.0, "currency": "USD"}),
);
data3.insert(
"purpose".to_string(),
Value::String("Hotel stay for conference".to_string()),
);
data3.insert("category".to_string(), Value::String("travel".to_string()));
let file_metadata_struct: ::buffa_types::google::protobuf::Struct =
serde_json::from_value(Value::Object(file_metadata)).unwrap();
let file_part = Part::file_builder()
.name("receipt_hotel.pdf".to_string())
.mime_type("application/pdf".to_string())
.bytes(b"Hello World!".to_vec())
.with_metadata(file_metadata_struct)
.build()
.unwrap();
let data_val3: ::buffa_types::google::protobuf::Value =
serde_json::from_value(Value::Object(data3)).unwrap();
let data_part3 = Part::data(data_val3);
let message3 = Message::builder()
.role(Role::User)
.message_id(Uuid::new_v4().to_string())
.parts(vec![data_part3, file_part])
.build();
let task3 = handler.process_message("task3", &message3, None).await?;
println!("Response: {:?}\n", task3.status.message);
Ok(())
}