codetether_agent/knowledge_graph/
graph.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct CodeNode {
9 pub id: String,
10 pub name: String,
11 pub kind: CodeNodeKind,
12 pub file_path: String,
13 pub line: u32,
14 pub embedding: Option<Vec<f32>>,
15 pub last_modified: chrono::DateTime<chrono::Utc>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19#[serde(rename_all = "snake_case")]
20pub enum CodeNodeKind {
21 Function,
22 Struct,
23 Enum,
24 Trait,
25 Module,
26 Const,
27 TypeAlias,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct CodeEdge {
33 pub source_id: String,
34 pub target_id: String,
35 pub kind: EdgeKind,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39#[serde(rename_all = "snake_case")]
40pub enum EdgeKind {
41 Calls,
42 Imports,
43 Implements,
44 Contains,
45 References,
46}
47
48#[derive(Debug, Default, Serialize, Deserialize)]
50pub struct KnowledgeGraph {
51 pub nodes: HashMap<String, CodeNode>,
52 pub edges: Vec<CodeEdge>,
53}
54
55impl KnowledgeGraph {
56 pub fn callers_of(&self, node_id: &str) -> Vec<&CodeNode> {
57 self.edges
58 .iter()
59 .filter(|e| e.target_id == node_id && e.kind == EdgeKind::Calls)
60 .filter_map(|e| self.nodes.get(&e.source_id))
61 .collect()
62 }
63
64 pub fn symbols_in_file(&self, path: &str) -> Vec<&CodeNode> {
65 self.nodes
66 .values()
67 .filter(|n| n.file_path == path)
68 .collect()
69 }
70}