Skip to main content

dakera_client/
knowledge.rs

1//! Knowledge graph operations for the Dakera client.
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::Result;
6use crate::DakeraClient;
7
8// ============================================================================
9// Knowledge Graph Types
10// ============================================================================
11
12/// Request to build a knowledge graph
13#[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/// A node in the knowledge graph
25#[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/// An edge in the knowledge graph
38#[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/// Response from knowledge graph operations
48#[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/// Request to build a full knowledge graph
57#[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/// Request to summarize memories
71#[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/// Response from summarization
83#[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/// Request to deduplicate memories
92#[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/// Response from deduplication
104#[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// ============================================================================
112// Knowledge Graph Client Methods
113// ============================================================================
114
115impl DakeraClient {
116    /// Build a knowledge graph from a seed memory
117    pub async fn knowledge_graph(
118        &self,
119        request: KnowledgeGraphRequest,
120    ) -> Result<KnowledgeGraphResponse> {
121        let url = format!("{}/v1/knowledge/graph", self.base_url);
122        let response = self.client.post(&url).json(&request).send().await?;
123        self.handle_response(response).await
124    }
125
126    /// Build a full knowledge graph for an agent
127    pub async fn full_knowledge_graph(
128        &self,
129        request: FullKnowledgeGraphRequest,
130    ) -> Result<KnowledgeGraphResponse> {
131        let url = format!("{}/v1/knowledge/graph/full", self.base_url);
132        let response = self.client.post(&url).json(&request).send().await?;
133        self.handle_response(response).await
134    }
135
136    /// Summarize memories
137    pub async fn summarize(&self, request: SummarizeRequest) -> Result<SummarizeResponse> {
138        let url = format!("{}/v1/knowledge/summarize", self.base_url);
139        let response = self.client.post(&url).json(&request).send().await?;
140        self.handle_response(response).await
141    }
142
143    /// Deduplicate memories
144    pub async fn deduplicate(&self, request: DeduplicateRequest) -> Result<DeduplicateResponse> {
145        let url = format!("{}/v1/knowledge/deduplicate", self.base_url);
146        let response = self.client.post(&url).json(&request).send().await?;
147        self.handle_response(response).await
148    }
149}