1use a2a::*;
5use futures::stream::BoxStream;
6use serde_json::Value;
7use std::collections::HashMap;
8
9use crate::middleware::{ServiceParams, User};
10
11pub struct ExecutorContext {
13 pub message: Option<Message>,
15 pub task_id: TaskId,
17 pub stored_task: Option<Task>,
19 pub context_id: String,
21 pub metadata: Option<HashMap<String, Value>>,
23 pub user: Option<User>,
25 pub service_params: ServiceParams,
27 pub tenant: Option<String>,
29}
30
31impl ExecutorContext {
32 pub fn task_info(&self) -> (TaskId, String) {
33 (self.task_id.clone(), self.context_id.clone())
34 }
35}
36
37#[async_trait::async_trait]
43pub trait AgentExecutor: Send + Sync + 'static {
44 fn execute(&self, ctx: ExecutorContext)
46 -> BoxStream<'static, Result<StreamResponse, A2AError>>;
47
48 fn cancel(&self, ctx: ExecutorContext) -> BoxStream<'static, Result<StreamResponse, A2AError>>;
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_executor_context_task_info() {
58 let ctx = ExecutorContext {
59 message: None,
60 task_id: "t1".into(),
61 stored_task: None,
62 context_id: "c1".into(),
63 metadata: None,
64 user: None,
65 service_params: HashMap::new(),
66 tenant: None,
67 };
68 let (tid, cid) = ctx.task_info();
69 assert_eq!(tid, "t1");
70 assert_eq!(cid, "c1");
71 }
72}