a2a_agents/traits/plugin.rs
1//! Core plugin trait for A2A agents.
2//!
3//! The `AgentPlugin` trait defines the interface that all agents should implement
4//! to integrate with the framework. It provides metadata, skill definitions, and
5//! lifecycle hooks.
6
7use a2a_rs::domain::A2AError;
8use a2a_rs::port::AsyncMessageHandler;
9use async_trait::async_trait;
10use serde::{Deserialize, Serialize};
11
12/// Skill definition for agent capabilities.
13///
14/// Skills describe what an agent can do, including keywords for intent matching,
15/// examples for documentation, and supported input/output formats.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct SkillDefinition {
18 /// Unique identifier for the skill
19 pub id: String,
20 /// Human-readable name
21 pub name: String,
22 /// Description of what this skill does
23 pub description: String,
24 /// Keywords for intent classification
25 pub keywords: Vec<String>,
26 /// Example queries that trigger this skill
27 pub examples: Vec<String>,
28 /// Supported input formats (e.g., "text", "file", "data")
29 pub input_formats: Vec<String>,
30 /// Supported output formats (e.g., "text", "file", "data")
31 pub output_formats: Vec<String>,
32}
33
34/// Plugin trait that all agents should implement.
35///
36/// This trait extends `AsyncMessageHandler` with metadata and capability discovery.
37/// Agents implementing this trait can be automatically configured and discovered
38/// by the framework.
39///
40/// # Example
41///
42/// ```rust
43/// use a2a_agents::traits::{AgentPlugin, SkillDefinition};
44/// use a2a_rs::port::AsyncMessageHandler;
45/// use a2a_rs::domain::{A2AError, Message, Task};
46/// use async_trait::async_trait;
47///
48/// #[derive(Clone)]
49/// struct MyAgent;
50///
51/// impl AgentPlugin for MyAgent {
52/// fn name(&self) -> &str {
53/// "My Agent"
54/// }
55///
56/// fn description(&self) -> &str {
57/// "A simple example agent"
58/// }
59///
60/// fn skills(&self) -> Vec<SkillDefinition> {
61/// vec![
62/// SkillDefinition {
63/// id: "hello".to_string(),
64/// name: "Say Hello".to_string(),
65/// description: "Greets the user".to_string(),
66/// keywords: vec!["hello".into(), "hi".into()],
67/// examples: vec!["Hello!".into()],
68/// input_formats: vec!["text".into()],
69/// output_formats: vec!["text".into()],
70/// }
71/// ]
72/// }
73/// }
74///
75/// #[async_trait]
76/// impl AsyncMessageHandler for MyAgent {
77/// async fn process_message(
78/// &self,
79/// task_id: &str,
80/// message: &Message,
81/// session_id: Option<&str>,
82/// ) -> Result<Task, A2AError> {
83/// // Implementation
84/// todo!()
85/// }
86///
87/// async fn validate_message(&self, message: &Message) -> Result<(), A2AError> {
88/// Ok(())
89/// }
90/// }
91/// ```
92#[async_trait]
93pub trait AgentPlugin: AsyncMessageHandler + Clone + Send + Sync + 'static {
94 /// Agent name (displayed to users)
95 fn name(&self) -> &str;
96
97 /// Agent description
98 fn description(&self) -> &str;
99
100 /// Version of the agent
101 fn version(&self) -> &str {
102 "1.0.0"
103 }
104
105 /// Skills provided by this agent
106 fn skills(&self) -> Vec<SkillDefinition>;
107
108 /// Optional: Initialize the agent (load models, connect to services, etc.)
109 async fn initialize(&mut self) -> Result<(), A2AError> {
110 Ok(())
111 }
112
113 /// Optional: Cleanup resources
114 async fn shutdown(&mut self) -> Result<(), A2AError> {
115 Ok(())
116 }
117
118 /// Optional: Health check
119 async fn health_check(&self) -> Result<(), A2AError> {
120 Ok(())
121 }
122}