tap_cli/
tap_integration.rs1use crate::error::{Error, Result};
2use std::path::PathBuf;
3use std::sync::Arc;
4use tap_agent::TapAgent;
5use tap_node::{NodeConfig, TapNode};
6use tracing::{debug, error, info};
7
8pub struct TapIntegration {
10 node: Arc<TapNode>,
11 storage_path: Option<PathBuf>,
12}
13
14impl TapIntegration {
15 pub async fn new(
17 agent_did: Option<&str>,
18 tap_root: Option<&str>,
19 agent: Option<Arc<TapAgent>>,
20 ) -> Result<Self> {
21 let mut config = NodeConfig::default();
22
23 if let Some(did) = agent_did {
24 config.agent_did = Some(did.to_string());
25 }
26
27 if let Some(root) = tap_root {
28 config.tap_root = Some(PathBuf::from(root));
29 }
30
31 config.enable_message_logging = true;
32 config.log_message_content = true;
33
34 let mut node = TapNode::new(config);
35
36 node.init_storage().await.map_err(|e| {
37 Error::configuration(format!("Failed to initialize TAP node storage: {}", e))
38 })?;
39
40 info!("Initialized TAP integration with DID-based storage");
41
42 let node_arc = Arc::new(node);
43
44 if let Some(agent) = agent {
45 node_arc
46 .register_agent(agent)
47 .await
48 .map_err(|e| Error::configuration(format!("Failed to register agent: {}", e)))?;
49 info!("Registered primary agent with TAP Node");
50 }
51
52 match tap_agent::storage::KeyStorage::load_default() {
54 Ok(storage) => {
55 let stored_dids: Vec<String> = storage.keys.keys().cloned().collect();
56 info!("Found {} total keys in storage", stored_dids.len());
57
58 for stored_did in &stored_dids {
59 if agent_did.is_some_and(|did| stored_did == did) {
60 continue;
61 }
62
63 info!("Registering additional agent: {}", stored_did);
64 match TapAgent::from_stored_keys(Some(stored_did.clone()), true).await {
65 Ok(additional_agent) => {
66 let additional_agent_arc = Arc::new(additional_agent);
67 if let Err(e) = node_arc.register_agent(additional_agent_arc).await {
68 error!("Failed to register additional agent {}: {}", stored_did, e);
69 } else {
70 info!("Successfully registered additional agent: {}", stored_did);
71 }
72 }
73 Err(e) => {
74 error!("Failed to load additional agent {}: {}", stored_did, e);
75 }
76 }
77 }
78 }
79 Err(e) => {
80 debug!("Could not load additional keys from storage: {}", e);
81 }
82 }
83
84 Ok(Self {
85 node: node_arc,
86 storage_path: None,
87 })
88 }
89
90 #[allow(dead_code)]
92 pub async fn new_for_testing(tap_root: Option<&str>, agent_did: &str) -> Result<Self> {
93 let mut config = NodeConfig::default();
94
95 if let Some(root) = tap_root {
96 config.tap_root = Some(PathBuf::from(root));
97 }
98
99 config.agent_did = Some(agent_did.to_string());
100 config.enable_message_logging = true;
101 config.log_message_content = true;
102
103 let mut node = TapNode::new(config);
104 node.init_storage().await.map_err(|e| {
105 Error::configuration(format!("Failed to initialize TAP node storage: {}", e))
106 })?;
107
108 let storage_path = tap_root.map(|root| PathBuf::from(root).join("keys.json"));
109
110 let (test_agent, _) = TapAgent::from_ephemeral_key()
111 .await
112 .map_err(|e| Error::configuration(format!("Failed to create test agent: {}", e)))?;
113
114 let node_arc = Arc::new(node);
115 node_arc
116 .register_agent(Arc::new(test_agent))
117 .await
118 .map_err(|e| Error::configuration(format!("Failed to register test agent: {}", e)))?;
119
120 Ok(Self {
121 node: node_arc,
122 storage_path,
123 })
124 }
125
126 pub fn node(&self) -> &Arc<TapNode> {
127 &self.node
128 }
129
130 #[allow(dead_code)]
131 pub fn storage_path(&self) -> Option<&PathBuf> {
132 self.storage_path.as_ref()
133 }
134
135 pub async fn storage_for_agent(
136 &self,
137 agent_did: &str,
138 ) -> Result<Arc<tap_node::storage::Storage>> {
139 if let Some(storage_manager) = self.node.agent_storage_manager() {
140 storage_manager
141 .get_agent_storage(agent_did)
142 .await
143 .map_err(|e| {
144 Error::configuration(format!(
145 "Failed to get storage for agent {}: {}",
146 agent_did, e
147 ))
148 })
149 } else {
150 Err(Error::configuration(
151 "Agent storage manager not available".to_string(),
152 ))
153 }
154 }
155
156 pub async fn list_agents(&self) -> Result<Vec<AgentInfo>> {
157 let mut agents = Vec::new();
158
159 use tap_agent::storage::KeyStorage;
160 let key_storage = if let Some(ref storage_path) = self.storage_path {
161 KeyStorage::load_from_path(storage_path)
162 } else {
163 KeyStorage::load_default()
164 };
165
166 match key_storage {
167 Ok(storage) => {
168 for (did, stored_key) in &storage.keys {
169 let mut metadata = std::collections::HashMap::new();
170
171 if !stored_key.label.is_empty() {
172 metadata.insert("label".to_string(), stored_key.label.clone());
173 }
174
175 for (key, value) in &stored_key.metadata {
176 metadata.insert(key.clone(), value.clone());
177 }
178
179 agents.push(AgentInfo {
180 id: did.clone(),
181 label: if stored_key.label.is_empty() {
182 None
183 } else {
184 Some(stored_key.label.clone())
185 },
186 metadata,
187 });
188 }
189 }
190 Err(e) => {
191 debug!("Could not load key storage: {}", e);
192 }
193 }
194
195 let node_agent_dids = self.node.list_agents();
197 for did in node_agent_dids {
198 if !agents.iter().any(|a| a.id == did) {
199 agents.push(AgentInfo {
200 id: did,
201 label: None,
202 metadata: std::collections::HashMap::new(),
203 });
204 }
205 }
206
207 Ok(agents)
208 }
209}
210
211#[derive(Debug, Clone, serde::Serialize)]
212pub struct AgentInfo {
213 pub id: String,
214 pub label: Option<String>,
215 pub metadata: std::collections::HashMap<String, String>,
216}