relay_knowledge/api/operations/
graph_canvas.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::api::ApiMetadata;
6
7pub const GRAPH_CANVAS_DEFAULT_LIMIT: usize = 250;
8pub const GRAPH_CANVAS_MAX_LIMIT: usize = 1000;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum GraphCanvasKind {
14 Knowledge,
15 Code,
16 Mixed,
17}
18
19impl GraphCanvasKind {
20 pub fn parse(value: &str) -> Result<Self, String> {
22 match value {
23 "knowledge" => Ok(Self::Knowledge),
24 "code" => Ok(Self::Code),
25 "mixed" => Ok(Self::Mixed),
26 _ => Err(format!("unsupported graph canvas kind '{value}'")),
27 }
28 }
29
30 pub const fn as_str(self) -> &'static str {
32 match self {
33 Self::Knowledge => "knowledge",
34 Self::Code => "code",
35 Self::Mixed => "mixed",
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42pub struct GraphCanvasRequest {
43 pub kind: GraphCanvasKind,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub source_scope: Option<String>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub query: Option<String>,
48 pub limit: usize,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct GraphCanvasNode {
54 pub id: String,
55 pub kind: String,
56 pub label: String,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub subtitle: Option<String>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub source_scope: Option<String>,
61 pub graph_version: u64,
62 pub weight: u32,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub status: Option<String>,
65 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
66 pub details: BTreeMap<String, String>,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct GraphCanvasEdge {
72 pub id: String,
73 pub kind: String,
74 pub source: String,
75 pub target: String,
76 pub label: String,
77 pub graph_version: u64,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub confidence_basis_points: Option<u16>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub evidence_count: Option<usize>,
82 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
83 pub details: BTreeMap<String, String>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88pub struct GraphCanvasSummary {
89 pub kind: GraphCanvasKind,
90 pub node_count: usize,
91 pub edge_count: usize,
92 pub truncated: bool,
93 pub available_kinds: Vec<String>,
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
98pub struct GraphCanvasResponse {
99 pub metadata: ApiMetadata,
100 pub nodes: Vec<GraphCanvasNode>,
101 pub edges: Vec<GraphCanvasEdge>,
102 pub summary: GraphCanvasSummary,
103}
104
105#[cfg(test)]
106#[path = "graph_canvas_tests.rs"]
107mod tests;