1use serde::{Deserialize, Serialize};
4
5use crate::error::Result;
6use crate::types::{KgExportResponse, KgPathResponse, KgQueryResponse};
7use crate::DakeraClient;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct KnowledgeGraphRequest {
16 pub agent_id: String,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub memory_id: Option<String>,
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub depth: Option<u32>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub min_similarity: Option<f32>,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct KnowledgeNode {
28 pub id: String,
29 pub content: String,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub memory_type: Option<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub importance: Option<f32>,
34 #[serde(default)]
35 pub metadata: serde_json::Value,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct KnowledgeEdge {
41 pub source: String,
42 pub target: String,
43 pub similarity: f32,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub relationship: Option<String>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct KnowledgeGraphResponse {
51 pub nodes: Vec<KnowledgeNode>,
52 pub edges: Vec<KnowledgeEdge>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub clusters: Option<Vec<Vec<String>>>,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct FullKnowledgeGraphRequest {
60 pub agent_id: String,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub max_nodes: Option<u32>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub min_similarity: Option<f32>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub cluster_threshold: Option<f32>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub max_edges_per_node: Option<u32>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct SummarizeRequest {
74 pub agent_id: String,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub memory_ids: Option<Vec<String>>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub target_type: Option<String>,
79 #[serde(default)]
80 pub dry_run: bool,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct SummarizeResponse {
86 pub summary: String,
87 pub source_count: usize,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub new_memory_id: Option<String>,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct DeduplicateRequest {
95 pub agent_id: String,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub threshold: Option<f32>,
98 #[serde(skip_serializing_if = "Option::is_none")]
99 pub memory_type: Option<String>,
100 #[serde(default)]
101 pub dry_run: bool,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct DeduplicateResponse {
107 pub duplicates_found: usize,
108 pub removed_count: usize,
109 pub groups: Vec<Vec<String>>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct CrossAgentNetworkRequest {
119 #[serde(skip_serializing_if = "Option::is_none")]
121 pub agent_ids: Option<Vec<String>>,
122 pub min_similarity: f32,
124 pub max_nodes_per_agent: usize,
126 pub min_importance: f32,
128 pub max_cross_edges: usize,
130}
131
132impl Default for CrossAgentNetworkRequest {
133 fn default() -> Self {
134 Self {
135 agent_ids: None,
136 min_similarity: 0.3,
137 max_nodes_per_agent: 50,
138 min_importance: 0.0,
139 max_cross_edges: 200,
140 }
141 }
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct AgentNetworkInfo {
147 pub agent_id: String,
148 pub memory_count: usize,
149 pub avg_importance: f32,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct AgentNetworkNode {
155 pub id: String,
156 pub agent_id: String,
157 pub content: String,
158 pub importance: f32,
159 pub tags: Vec<String>,
160 pub memory_type: String,
161 pub created_at: u64,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct AgentNetworkEdge {
168 pub source: String,
169 pub target: String,
170 pub source_agent: String,
171 pub target_agent: String,
172 pub similarity: f32,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct AgentNetworkStats {
178 pub total_agents: usize,
179 pub total_nodes: usize,
180 pub total_cross_edges: usize,
181 pub density: f32,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct CrossAgentNetworkResponse {
187 pub agents: Vec<AgentNetworkInfo>,
188 pub nodes: Vec<AgentNetworkNode>,
189 pub edges: Vec<AgentNetworkEdge>,
190 pub stats: AgentNetworkStats,
191 #[serde(default)]
193 pub node_count: usize,
194}
195
196impl DakeraClient {
201 pub async fn knowledge_graph(
203 &self,
204 request: KnowledgeGraphRequest,
205 ) -> Result<KnowledgeGraphResponse> {
206 let url = format!("{}/v1/knowledge/graph", self.base_url);
207 let response = self.client.post(&url).json(&request).send().await?;
208 self.handle_response(response).await
209 }
210
211 pub async fn full_knowledge_graph(
213 &self,
214 request: FullKnowledgeGraphRequest,
215 ) -> Result<KnowledgeGraphResponse> {
216 let url = format!("{}/v1/knowledge/graph/full", self.base_url);
217 let response = self.client.post(&url).json(&request).send().await?;
218 self.handle_response(response).await
219 }
220
221 pub async fn summarize(&self, request: SummarizeRequest) -> Result<SummarizeResponse> {
223 let url = format!("{}/v1/knowledge/summarize", self.base_url);
224 let response = self.client.post(&url).json(&request).send().await?;
225 self.handle_response(response).await
226 }
227
228 pub async fn deduplicate(&self, request: DeduplicateRequest) -> Result<DeduplicateResponse> {
230 let url = format!("{}/v1/knowledge/deduplicate", self.base_url);
231 let response = self.client.post(&url).json(&request).send().await?;
232 self.handle_response(response).await
233 }
234
235 pub async fn cross_agent_network(
240 &self,
241 request: CrossAgentNetworkRequest,
242 ) -> Result<CrossAgentNetworkResponse> {
243 let url = format!("{}/v1/knowledge/network/cross-agent", self.base_url);
244 let response = self.client.post(&url).json(&request).send().await?;
245 self.handle_response(response).await
246 }
247
248 pub async fn knowledge_query(
264 &self,
265 agent_id: &str,
266 root_id: Option<&str>,
267 edge_type: Option<&str>,
268 min_weight: Option<f32>,
269 max_depth: Option<u32>,
270 limit: Option<usize>,
271 ) -> Result<KgQueryResponse> {
272 let mut url = format!("{}/v1/knowledge/query?agent_id={}", self.base_url, agent_id);
273 if let Some(v) = root_id {
274 url.push_str(&format!("&root_id={}", v));
275 }
276 if let Some(v) = edge_type {
277 url.push_str(&format!("&edge_type={}", v));
278 }
279 if let Some(v) = min_weight {
280 url.push_str(&format!("&min_weight={}", v));
281 }
282 if let Some(v) = max_depth {
283 url.push_str(&format!("&max_depth={}", v));
284 }
285 if let Some(v) = limit {
286 url.push_str(&format!("&limit={}", v));
287 }
288 let response = self.client.get(&url).send().await?;
289 self.handle_response(response).await
290 }
291
292 pub async fn knowledge_path(
298 &self,
299 agent_id: &str,
300 from_id: &str,
301 to_id: &str,
302 ) -> Result<KgPathResponse> {
303 let url = format!(
304 "{}/v1/knowledge/path?agent_id={}&from={}&to={}",
305 self.base_url, agent_id, from_id, to_id
306 );
307 let response = self.client.get(&url).send().await?;
308 self.handle_response(response).await
309 }
310
311 pub async fn knowledge_export(
318 &self,
319 agent_id: &str,
320 format: Option<&str>,
321 ) -> Result<KgExportResponse> {
322 let fmt = format.unwrap_or("json");
323 let url = format!(
324 "{}/v1/knowledge/export?agent_id={}&format={}",
325 self.base_url, agent_id, fmt
326 );
327 let response = self.client.get(&url).send().await?;
328 self.handle_response(response).await
329 }
330}