Skip to main content

relay_knowledge/api/operations/
service_runtime.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    api::{AgentProtocolStatus, ApiMetadata, RuntimeStatus, WatcherDiagnostics},
5    domain::{
6        CodeRepositoryTotals, IndexKind, IndexStatus, ServiceDefinitionPlan, ServiceOperatorStatus,
7        WorkerStatus,
8    },
9    storage::{FileIndexDiagnostics, GraphInspection, IndexCursor, IndexRefreshDiagnostics},
10};
11
12use super::{AuditSinkStatus, CodeIndexWorkerStatus};
13
14/// Service manager status surfaced without exposing platform-specific handles.
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub struct ServiceStatusResponse {
17    pub metadata: ApiMetadata,
18    pub service_name: String,
19    pub mode: String,
20    pub background_enabled: bool,
21    pub silent_updates_enabled: bool,
22    pub service_definition_path: String,
23    pub storage: StorageTopologyDiagnostics,
24    pub index_refresh: IndexRefreshDiagnostics,
25    pub file_index: FileIndexDiagnostics,
26    pub agent_protocols: AgentProtocolStatus,
27    pub operator: ServiceOperatorStatus,
28    pub workers: Vec<WorkerStatus>,
29    pub code_index_workers: CodeIndexWorkerStatus,
30    pub proposal_backlog: usize,
31    pub audit_sink: AuditSinkStatus,
32    #[serde(default = "WatcherDiagnostics::default_disabled")]
33    pub watcher: WatcherDiagnostics,
34}
35
36/// Storage topology and shard-catalog diagnostics surfaced by the control plane.
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub struct StorageTopologyDiagnostics {
39    pub topology: String,
40    pub control_database_path: String,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub repository_shards_dir: Option<String>,
43    pub shard_catalog_active: bool,
44    pub active_shard_count: usize,
45    pub staged_shard_count: usize,
46    pub missing_shard_count: usize,
47    pub runtime_state_paths: Vec<String>,
48    pub shards: Vec<StorageShardDiagnostics>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub degraded_reason: Option<String>,
51}
52
53/// One partitioned SQLite shard reported through storage diagnostics.
54#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
55pub struct StorageShardDiagnostics {
56    pub repository_id: String,
57    pub state: String,
58    pub shard_locator: String,
59    pub resolved_path: String,
60    pub source_scope_count: usize,
61    pub exists: bool,
62    pub updated_at_ms: u64,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub degraded_reason: Option<String>,
65}
66
67/// Control-plane storage topology response.
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
69pub struct StorageTopologyResponse {
70    pub metadata: ApiMetadata,
71    pub storage: StorageTopologyDiagnostics,
72}
73
74/// Service definition write response.
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
76pub struct ServiceDefinitionWriteResponse {
77    pub metadata: ApiMetadata,
78    pub plan: ServiceDefinitionPlan,
79    pub written: bool,
80}
81
82/// Service silent-update operator response.
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
84pub struct ServiceOperatorResponse {
85    pub metadata: ApiMetadata,
86    pub operator: ServiceOperatorStatus,
87}
88
89/// Startup recovery report for resident service mode.
90#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
91pub struct ServiceRecoveryReport {
92    pub metadata: ApiMetadata,
93    pub graph_version: u64,
94    pub stale_index_kinds: Vec<IndexKind>,
95    pub refreshed_index_kinds: Vec<IndexKind>,
96    pub index_lag_max: u64,
97    pub task_queue_depth: usize,
98    pub dead_letter_count: usize,
99    pub heartbeat_state: String,
100}
101
102/// Aggregated health response for CLI/Web/service diagnostics.
103#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
104pub struct HealthResponse {
105    pub metadata: ApiMetadata,
106    pub healthy: bool,
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub degraded_reason: Option<String>,
109    pub storage: StorageTopologyDiagnostics,
110    pub graph: GraphInspection,
111    pub repository_code_totals: CodeRepositoryTotals,
112    pub indexes: Vec<IndexStatus>,
113    pub index_cursors: Vec<IndexCursor>,
114    pub index_refresh: IndexRefreshDiagnostics,
115    pub file_index: FileIndexDiagnostics,
116    pub runtime: RuntimeStatus,
117}
118
119/// Remote embedding provider probe response with secret-free diagnostics.
120#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
121pub struct EmbeddingProviderProbeResponse {
122    pub metadata: ApiMetadata,
123    pub ok: bool,
124    pub provider: Option<String>,
125    pub model: String,
126    pub dimension: u32,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub latency_ms: Option<u64>,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub error_code: Option<String>,
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub error_message: Option<String>,
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub retryable: Option<bool>,
135}