Skip to main content

vtcode_a2a/
cli.rs

1//! A2A Protocol CLI commands
2//!
3//! Provides command-line interface for:
4//! - Serving VT Code as an A2A agent
5//! - Discovering remote A2A agents
6//! - Sending tasks to other agents
7//! - Managing A2A agent connections
8
9use clap::{Parser, Subcommand};
10
11/// A2A Protocol commands
12#[derive(Debug, Subcommand, Clone)]
13pub enum A2aCommands {
14    /// Serve VT Code as an A2A agent (requires a2a-server feature)
15    ///
16    /// Starts an HTTP server exposing A2A endpoints:
17    /// - /.well-known/agent-card.json - Agent discovery
18    /// - /a2a - JSON-RPC endpoint for task management
19    /// - /a2a/stream - Server-Sent Events streaming
20    ///
21    /// Examples:
22    ///   vtcode a2a serve --port 8080
23    ///   vtcode a2a serve --host 0.0.0.0 --port 8080
24    ///
25    /// Set VTCODE_A2A_TOKEN to use a managed token; otherwise one is generated
26    /// and printed when the server starts.
27    Serve {
28        /// Host to bind the server to
29        #[arg(long, default_value = "127.0.0.1")]
30        host: String,
31
32        /// Port to listen on
33        #[arg(long, default_value_t = 8080)]
34        port: u16,
35
36        /// Base URL for the agent (used in agent card)
37        #[arg(long)]
38        base_url: Option<String>,
39
40        /// Enable push notifications via webhooks
41        #[arg(long)]
42        enable_push: bool,
43    },
44
45    /// Discover and display information about a remote A2A agent
46    ///
47    /// Fetches and displays the agent card from the remote agent,
48    /// showing capabilities, skills, and supported features.
49    ///
50    /// Examples:
51    ///   vtcode a2a discover <https://agent.example.com>
52    ///   vtcode a2a discover <https://localhost:8080>
53    Discover {
54        /// URL of the remote A2A agent
55        agent_url: String,
56    },
57
58    /// Send a task to a remote A2A agent
59    ///
60    /// Sends a message to a remote agent and returns the task result.
61    /// The agent will process the request and return structured results.
62    ///
63    /// Examples:
64    ///   vtcode a2a send-task <https://agent.example.com> "Help me refactor this code"
65    ///   vtcode a2a send-task <https://localhost:8080> "Explain this error message"
66    SendTask {
67        /// URL of the remote A2A agent
68        agent_url: String,
69
70        /// The task/message to send to the agent
71        message: String,
72
73        /// Wait for task completion and stream progress
74        #[arg(long)]
75        stream: bool,
76
77        /// Optional context ID for conversation tracking
78        #[arg(long)]
79        context_id: Option<String>,
80    },
81
82    /// List active tasks in a running A2A agent
83    ///
84    /// Queries a remote A2A agent for its current and recent tasks.
85    ///
86    /// Examples:
87    ///   vtcode a2a list-tasks <https://agent.example.com>
88    ///   vtcode a2a list-tasks <https://localhost:8080> --context-id my-conversation
89    ListTasks {
90        /// URL of the remote A2A agent
91        agent_url: String,
92
93        /// Filter by context ID
94        #[arg(long)]
95        context_id: Option<String>,
96
97        /// Maximum number of tasks to return
98        #[arg(long, default_value_t = 50)]
99        limit: u32,
100    },
101
102    /// Get details about a specific task
103    ///
104    /// Retrieves the current status, artifacts, and history of a task.
105    ///
106    /// Examples:
107    ///   vtcode a2a get-task <https://agent.example.com> task-123
108    ///   vtcode a2a get-task <https://localhost:8080> task-456
109    GetTask {
110        /// URL of the remote A2A agent
111        agent_url: String,
112
113        /// Task ID to retrieve
114        task_id: String,
115    },
116
117    /// Cancel a running task
118    ///
119    /// Requests cancellation of a task that is currently being processed.
120    ///
121    /// Examples:
122    ///   vtcode a2a cancel-task <https://agent.example.com> task-123
123    CancelTask {
124        /// URL of the remote A2A agent
125        agent_url: String,
126
127        /// Task ID to cancel
128        task_id: String,
129    },
130}
131
132/// A2A CLI configuration options
133#[derive(Debug, Parser)]
134pub struct A2aServeConfig {
135    /// Host to bind the server to
136    #[arg(long, default_value = "127.0.0.1")]
137    host: String,
138
139    /// Port to listen on
140    #[arg(long, default_value_t = 8080)]
141    port: u16,
142
143    /// Base URL for the agent (used in agent card)
144    #[arg(long)]
145    base_url: Option<String>,
146
147    /// Enable push notifications via webhooks
148    #[arg(long)]
149    enable_push: bool,
150}
151
152#[cfg(test)]
153mod tests {
154    use super::*;
155
156    #[test]
157    fn test_cli_serve_command() {
158        let cmd = A2aCommands::Serve {
159            host: "127.0.0.1".to_string(),
160            port: 8080,
161            base_url: Some("http://localhost:8080".to_string()),
162            enable_push: false,
163        };
164        match cmd {
165            A2aCommands::Serve { port, .. } => assert_eq!(port, 8080),
166            _ => panic!("Wrong command type"),
167        }
168    }
169
170    #[test]
171    fn test_cli_discover_command() {
172        let cmd = A2aCommands::Discover { agent_url: "https://example.com".to_string() };
173        match cmd {
174            A2aCommands::Discover { agent_url } => {
175                assert_eq!(agent_url, "https://example.com")
176            }
177            _ => panic!("Wrong command type"),
178        }
179    }
180}