Skip to main content

tap_cli/commands/
agent.rs

1use crate::error::{Error, Result};
2use crate::output::{print_success, OutputFormat};
3use crate::tap_integration::TapIntegration;
4use clap::Subcommand;
5use serde::Serialize;
6use std::sync::Arc;
7use tap_agent::agent_key_manager::AgentKeyManagerBuilder;
8use tap_agent::config::AgentConfig;
9use tap_agent::did::{DIDGenerationOptions, KeyType};
10use tap_agent::key_manager::KeyManager;
11use tap_agent::storage::KeyStorage;
12use tap_agent::TapAgent;
13use tracing::info;
14
15#[derive(Subcommand, Debug)]
16pub enum AgentCommands {
17    /// Create a new agent with a generated DID
18    Create {
19        /// Label for the agent
20        #[arg(long)]
21        label: Option<String>,
22    },
23    /// List all registered agents
24    List,
25}
26
27#[derive(Debug, Serialize)]
28struct AgentCreatedResponse {
29    did: String,
30    label: Option<String>,
31}
32
33pub async fn handle(
34    cmd: &AgentCommands,
35    format: OutputFormat,
36    tap_integration: &TapIntegration,
37) -> Result<()> {
38    match cmd {
39        AgentCommands::Create { label } => {
40            handle_create(label.clone(), format, tap_integration).await
41        }
42        AgentCommands::List => handle_list(format, tap_integration).await,
43    }
44}
45
46async fn handle_create(
47    label: Option<String>,
48    format: OutputFormat,
49    tap_integration: &TapIntegration,
50) -> Result<()> {
51    let default_key_path = KeyStorage::default_key_path()
52        .ok_or_else(|| Error::configuration("Could not determine default key path"))?;
53    let key_manager_builder = AgentKeyManagerBuilder::new().load_from_path(default_key_path);
54    let key_manager = key_manager_builder
55        .build()
56        .map_err(|e| Error::configuration(format!("Failed to build key manager: {}", e)))?;
57
58    let generated_key = key_manager
59        .generate_key(DIDGenerationOptions {
60            key_type: KeyType::Ed25519,
61        })
62        .map_err(|e| Error::command_failed(format!("Failed to generate key: {}", e)))?;
63
64    // Set label if provided
65    if let Some(ref label) = label {
66        let mut storage = KeyStorage::load_default().unwrap_or_else(|_| KeyStorage::new());
67        if let Some(key) = storage.keys.get_mut(&generated_key.did) {
68            key.label = label.clone();
69            let _ = storage.save_default();
70        }
71    }
72
73    info!("Generated new agent with DID: {}", generated_key.did);
74
75    // Register with the TapNode
76    let config = AgentConfig::new(generated_key.did.clone()).with_debug(true);
77    let new_key_manager = AgentKeyManagerBuilder::new()
78        .load_from_default_storage()
79        .build()
80        .map_err(|e| Error::configuration(format!("Failed to reload key manager: {}", e)))?;
81    let agent = TapAgent::new(config, Arc::new(new_key_manager));
82    tap_integration
83        .node()
84        .register_agent(Arc::new(agent))
85        .await
86        .map_err(|e| Error::command_failed(format!("Failed to register agent: {}", e)))?;
87
88    let response = AgentCreatedResponse {
89        did: generated_key.did,
90        label,
91    };
92    print_success(format, &response);
93    Ok(())
94}
95
96async fn handle_list(format: OutputFormat, tap_integration: &TapIntegration) -> Result<()> {
97    let agents = tap_integration.list_agents().await?;
98    print_success(format, &agents);
99    Ok(())
100}