soma_provider_adapters/
codemode.rs1use std::sync::{Arc, Mutex};
18
19use async_trait::async_trait;
20use serde_json::json;
21use soma_codemode::{execute::execute_inline, CodeModeConfig, UiLink};
22use soma_provider_core::{Provider, ProviderCall, ProviderCatalog, ProviderError, ProviderOutput};
23
24#[derive(Clone)]
29pub struct CodeModeSnippetProvider {
30 catalog: ProviderCatalog,
31 code: String,
32 config: CodeModeConfig,
33}
34
35impl CodeModeSnippetProvider {
36 pub fn new(catalog: ProviderCatalog, code: impl Into<String>, config: CodeModeConfig) -> Self {
37 Self {
38 catalog,
39 code: code.into(),
40 config,
41 }
42 }
43
44 pub fn arc(
45 catalog: ProviderCatalog,
46 code: impl Into<String>,
47 config: CodeModeConfig,
48 ) -> Arc<Self> {
49 Arc::new(Self::new(catalog, code, config))
50 }
51}
52
53#[async_trait]
54impl Provider for CodeModeSnippetProvider {
55 fn catalog(&self) -> ProviderCatalog {
56 self.catalog.clone()
57 }
58
59 async fn call(&self, call: ProviderCall) -> Result<ProviderOutput, ProviderError> {
60 let ui_capture: Arc<Mutex<Option<UiLink>>> = Arc::new(Mutex::new(None));
61 let outcome = execute_inline(&self.code, self.config.clone(), ui_capture)
62 .await
63 .map_err(|error| {
64 ProviderError::execution(&self.catalog.provider.name, call.action.clone(), error)
65 .with_provider_kind("codemode")
66 })?;
67 Ok(ProviderOutput::json(json!({
68 "result": outcome.display_response.result,
69 "logs": outcome.display_response.logs,
70 })))
71 }
72}
73
74#[cfg(test)]
75#[path = "codemode_tests.rs"]
76mod tests;