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