synaps_cli/extensions/runtime/
mod.rs1pub mod process;
4pub mod restart;
5
6pub use restart::RestartPolicy;
7
8use async_trait::async_trait;
9use serde_json::Value;
10use crate::extensions::hooks::events::{HookEvent, HookResult};
11use self::process::{ProviderCompleteParams, ProviderCompleteResult, ProviderStreamEvent};
12use crate::extensions::info::PluginInfo;
13use crate::extensions::commands::CommandOutputEvent;
14use crate::extensions::tasks::TaskEvent;
15
16#[derive(Debug, Clone, PartialEq)]
18pub enum InvokeCommandEvent {
19 Output(CommandOutputEvent),
21 Task(TaskEvent),
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum ExtensionHealth {
28 Loaded,
30 FailedValidation,
32 FailedInitialize,
34 Running,
36 Restarting,
38 Degraded,
40 Failed,
42}
43
44impl ExtensionHealth {
45 pub fn as_str(self) -> &'static str {
46 match self {
47 Self::Loaded => "loaded",
48 Self::FailedValidation => "failed_validation",
49 Self::FailedInitialize => "failed_initialize",
50 Self::Running => "running",
51 Self::Restarting => "restarting",
52 Self::Degraded => "degraded",
53 Self::Failed => "failed",
54 }
55 }
56}
57
58#[cfg(test)]
59mod health_tests {
60 use super::ExtensionHealth;
61
62 #[test]
63 fn as_str_covers_all_variants() {
64 assert_eq!(ExtensionHealth::Loaded.as_str(), "loaded");
65 assert_eq!(ExtensionHealth::FailedValidation.as_str(), "failed_validation");
66 assert_eq!(ExtensionHealth::FailedInitialize.as_str(), "failed_initialize");
67 assert_eq!(ExtensionHealth::Running.as_str(), "running");
68 assert_eq!(ExtensionHealth::Restarting.as_str(), "restarting");
69 assert_eq!(ExtensionHealth::Degraded.as_str(), "degraded");
70 assert_eq!(ExtensionHealth::Failed.as_str(), "failed");
71 }
72}
73
74#[async_trait]
76pub trait ExtensionHandler: Send + Sync {
77 fn id(&self) -> &str;
79
80 async fn handle(&self, event: &HookEvent) -> HookResult;
82
83 async fn call_tool(&self, _name: &str, _input: Value) -> Result<Value, String> {
85 Err("extension runtime does not support tool.call".to_string())
86 }
87
88 async fn provider_complete(&self, _params: ProviderCompleteParams) -> Result<ProviderCompleteResult, String> {
90 Err("extension runtime does not support provider.complete".to_string())
91 }
92
93 async fn provider_stream(
101 &self,
102 _params: ProviderCompleteParams,
103 _sink: tokio::sync::mpsc::UnboundedSender<ProviderStreamEvent>,
104 ) -> Result<ProviderCompleteResult, String> {
105 Err("provider.stream is not supported by this extension".to_string())
106 }
107
108 async fn invoke_command(
112 &self,
113 _command: &str,
114 _args: Vec<String>,
115 _request_id: &str,
116 _sink: tokio::sync::mpsc::UnboundedSender<InvokeCommandEvent>,
117 ) -> Result<Value, String> {
118 Err("extension runtime does not support command.invoke".to_string())
119 }
120
121 async fn get_info(&self) -> Result<PluginInfo, String> {
123 Err("extension runtime does not support info.get".to_string())
124 }
125
126 async fn sidecar_spawn_args(&self) -> Result<crate::sidecar::spawn::SidecarSpawnArgs, String> {
132 Err("extension runtime does not support sidecar.spawn_args".to_string())
133 }
134
135 async fn settings_editor_open(&self, _category: &str, _field: &str) -> Result<Value, String> {
137 Err("extension runtime does not support settings.editor.open".to_string())
138 }
139
140 async fn settings_editor_key(&self, _category: &str, _field: &str, _key: &str) -> Result<Value, String> {
142 Err("extension runtime does not support settings.editor.key".to_string())
143 }
144
145 async fn settings_editor_commit(&self, _category: &str, _field: &str, _value: Value) -> Result<Value, String> {
147 Err("extension runtime does not support settings.editor.commit".to_string())
148 }
149
150 async fn shutdown(&self);
152
153 async fn health(&self) -> ExtensionHealth {
155 ExtensionHealth::Running
156 }
157
158 async fn restart_count(&self) -> usize {
160 0
161 }
162}