use dakera_client::{
DakeraClient, FullKnowledgeGraphRequest, KnowledgeGraphRequest, MemoryType, StoreMemoryRequest,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url =
std::env::var("DAKERA_API_URL").unwrap_or_else(|_| "http://localhost:3300".to_string());
let api_key = std::env::var("DAKERA_API_KEY").unwrap_or_else(|_| "dk-mykey".to_string());
let client = DakeraClient::builder(&url).api_key(&api_key).build()?;
let health = client.health().await?;
println!(
"Server: {} (healthy: {})",
health.version.as_deref().unwrap_or("unknown"),
health.healthy
);
let agent_id = "kg-example-agent";
println!("\n--- Storing memories for knowledge graph ---");
let memories = vec![
StoreMemoryRequest::new(
agent_id,
"Rust provides memory safety without garbage collection",
)
.with_type(MemoryType::Semantic)
.with_importance(0.9)
.with_tags(vec!["rust".into(), "memory-safety".into()]),
StoreMemoryRequest::new(
agent_id,
"HNSW is an efficient algorithm for approximate nearest neighbor search",
)
.with_type(MemoryType::Semantic)
.with_importance(0.8)
.with_tags(vec!["algorithms".into(), "search".into()]),
StoreMemoryRequest::new(
agent_id,
"Vector databases use embeddings to represent semantic similarity",
)
.with_type(MemoryType::Semantic)
.with_importance(0.85)
.with_tags(vec!["vectors".into(), "embeddings".into()]),
StoreMemoryRequest::new(
agent_id,
"Knowledge graphs connect related concepts through typed edges",
)
.with_type(MemoryType::Semantic)
.with_importance(0.9)
.with_tags(vec!["knowledge-graph".into(), "relationships".into()]),
StoreMemoryRequest::new(
agent_id,
"BM25 scoring ranks documents by term frequency and inverse document frequency",
)
.with_type(MemoryType::Semantic)
.with_importance(0.7)
.with_tags(vec!["search".into(), "ranking".into()]),
];
let mut memory_ids = Vec::new();
for mem in memories {
let resp = client.store_memory(mem).await?;
println!(" Stored: {}", resp.memory_id);
memory_ids.push(resp.memory_id);
}
assert_eq!(memory_ids.len(), 5, "expected 5 memories stored");
println!("\n--- Knowledge Graph (from seed) ---");
let kg = client
.knowledge_graph(KnowledgeGraphRequest {
agent_id: agent_id.to_string(),
memory_id: Some(memory_ids[0].clone()),
depth: Some(2),
min_similarity: Some(0.1),
})
.await?;
println!("Graph: {} nodes, {} edges", kg.nodes.len(), kg.edges.len());
for node in &kg.nodes {
println!(" Node: {} — {:.50}...", node.id, node.content);
}
assert!(
!kg.nodes.is_empty(),
"expected non-empty knowledge graph nodes"
);
println!("\n--- Full Knowledge Graph ---");
let full_kg = client
.full_knowledge_graph(FullKnowledgeGraphRequest {
agent_id: agent_id.to_string(),
max_nodes: Some(50),
min_similarity: Some(0.1),
cluster_threshold: Some(0.5),
max_edges_per_node: Some(5),
})
.await?;
println!(
"Full graph: {} nodes, {} edges, {} clusters",
full_kg.nodes.len(),
full_kg.edges.len(),
full_kg.clusters.as_ref().map_or(0, |c| c.len())
);
println!("\n--- KG Query ---");
let query_resp = client
.knowledge_query(
agent_id,
None, None, Some(0.1), None, Some(20), )
.await?;
println!(
"Query: {} nodes, {} edges",
query_resp.node_count, query_resp.edge_count
);
if memory_ids.len() >= 2 {
println!("\n--- KG Path ---");
let path_resp = client
.knowledge_path(agent_id, &memory_ids[0], &memory_ids[3])
.await?;
println!(
"Path from {} to {}: {} hops",
path_resp.from_id,
path_resp.to_id,
path_resp.path.len().saturating_sub(1)
);
for node_id in &path_resp.path {
println!(" -> {}", node_id);
}
}
println!("\n--- KG Export (JSON) ---");
let export = client.knowledge_export(agent_id, Some("json")).await?;
println!(
"Exported graph: {} nodes, {} edges (format: {})",
export.node_count, export.edge_count, export.format
);
assert!(export.node_count > 0, "expected non-empty export");
println!("\nKnowledge graph example completed successfully.");
Ok(())
}