1use serde::{Deserialize, Serialize};
4
5use crate::error::Result;
6use crate::DakeraClient;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct KnowledgeGraphRequest {
15 pub agent_id: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub memory_id: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub depth: Option<u32>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub min_similarity: Option<f32>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct KnowledgeNode {
27 pub id: String,
28 pub content: String,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub memory_type: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub importance: Option<f32>,
33 #[serde(default)]
34 pub metadata: serde_json::Value,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct KnowledgeEdge {
40 pub source: String,
41 pub target: String,
42 pub similarity: f32,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub relationship: Option<String>,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct KnowledgeGraphResponse {
50 pub nodes: Vec<KnowledgeNode>,
51 pub edges: Vec<KnowledgeEdge>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub clusters: Option<Vec<Vec<String>>>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct FullKnowledgeGraphRequest {
59 pub agent_id: String,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub max_nodes: Option<u32>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub min_similarity: Option<f32>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub cluster_threshold: Option<f32>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub max_edges_per_node: Option<u32>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct SummarizeRequest {
73 pub agent_id: String,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub memory_ids: Option<Vec<String>>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub target_type: Option<String>,
78 #[serde(default)]
79 pub dry_run: bool,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct SummarizeResponse {
85 pub summary: String,
86 pub source_count: usize,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub new_memory_id: Option<String>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct DeduplicateRequest {
94 pub agent_id: String,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub threshold: Option<f32>,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub memory_type: Option<String>,
99 #[serde(default)]
100 pub dry_run: bool,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct DeduplicateResponse {
106 pub duplicates_found: usize,
107 pub removed_count: usize,
108 pub groups: Vec<Vec<String>>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct CrossAgentNetworkRequest {
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub agent_ids: Option<Vec<String>>,
121 pub min_similarity: f32,
123 pub max_nodes_per_agent: usize,
125 pub min_importance: f32,
127 pub max_cross_edges: usize,
129}
130
131impl Default for CrossAgentNetworkRequest {
132 fn default() -> Self {
133 Self {
134 agent_ids: None,
135 min_similarity: 0.3,
136 max_nodes_per_agent: 50,
137 min_importance: 0.0,
138 max_cross_edges: 200,
139 }
140 }
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct AgentNetworkInfo {
146 pub agent_id: String,
147 pub memory_count: usize,
148 pub avg_importance: f32,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct AgentNetworkNode {
154 pub id: String,
155 pub agent_id: String,
156 pub content: String,
157 pub importance: f32,
158 pub tags: Vec<String>,
159 pub memory_type: String,
160 pub created_at: u64,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct AgentNetworkEdge {
167 pub source: String,
168 pub target: String,
169 pub source_agent: String,
170 pub target_agent: String,
171 pub similarity: f32,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct AgentNetworkStats {
177 pub total_agents: usize,
178 pub total_nodes: usize,
179 pub total_cross_edges: usize,
180 pub density: f32,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct CrossAgentNetworkResponse {
186 pub agents: Vec<AgentNetworkInfo>,
187 pub nodes: Vec<AgentNetworkNode>,
188 pub edges: Vec<AgentNetworkEdge>,
189 pub stats: AgentNetworkStats,
190 #[serde(default)]
192 pub node_count: usize,
193}
194
195impl DakeraClient {
200 pub async fn knowledge_graph(
202 &self,
203 request: KnowledgeGraphRequest,
204 ) -> Result<KnowledgeGraphResponse> {
205 let url = format!("{}/v1/knowledge/graph", self.base_url);
206 let response = self.client.post(&url).json(&request).send().await?;
207 self.handle_response(response).await
208 }
209
210 pub async fn full_knowledge_graph(
212 &self,
213 request: FullKnowledgeGraphRequest,
214 ) -> Result<KnowledgeGraphResponse> {
215 let url = format!("{}/v1/knowledge/graph/full", self.base_url);
216 let response = self.client.post(&url).json(&request).send().await?;
217 self.handle_response(response).await
218 }
219
220 pub async fn summarize(&self, request: SummarizeRequest) -> Result<SummarizeResponse> {
222 let url = format!("{}/v1/knowledge/summarize", self.base_url);
223 let response = self.client.post(&url).json(&request).send().await?;
224 self.handle_response(response).await
225 }
226
227 pub async fn deduplicate(&self, request: DeduplicateRequest) -> Result<DeduplicateResponse> {
229 let url = format!("{}/v1/knowledge/deduplicate", self.base_url);
230 let response = self.client.post(&url).json(&request).send().await?;
231 self.handle_response(response).await
232 }
233
234 pub async fn cross_agent_network(
239 &self,
240 request: CrossAgentNetworkRequest,
241 ) -> Result<CrossAgentNetworkResponse> {
242 let url = format!("{}/v1/knowledge/network/cross-agent", self.base_url);
243 let response = self.client.post(&url).json(&request).send().await?;
244 self.handle_response(response).await
245 }
246}