Skip to main content

soma_codemode/
broker.rs

1use std::sync::Arc;
2
3use crate::execute::{
4    runner::{execute_in_subprocess, SubprocessExecution},
5    CodeModeExecutionOutcome,
6};
7use crate::host::CodeModeHost;
8use crate::pool::{PoolConfig, RunnerPool, RunnerSpawn};
9use crate::types::{CodeModeCaller, CodeModeExecutionResponse, CodeModeSurface, ToolScope, UiLink};
10use crate::{CodeModeConfig, ToolError};
11
12pub struct CodeModeBroker<'a, H: CodeModeHost> {
13    pub(crate) host: Option<&'a H>,
14    pub(crate) ui_capture: Arc<std::sync::Mutex<Option<UiLink>>>,
15    runner_pool: tokio::sync::OnceCell<Arc<RunnerPool>>,
16}
17
18impl<'a, H: CodeModeHost> CodeModeBroker<'a, H> {
19    #[must_use]
20    pub fn new(host: Option<&'a H>) -> Self {
21        Self {
22            host,
23            ui_capture: Arc::new(std::sync::Mutex::new(None)),
24            runner_pool: tokio::sync::OnceCell::new(),
25        }
26    }
27
28    pub async fn execute(
29        &self,
30        code: &str,
31        caller: CodeModeCaller,
32        surface: CodeModeSurface,
33        config: CodeModeConfig,
34        scope: ToolScope,
35        execution_id: Option<Arc<str>>,
36    ) -> Result<CodeModeExecutionResponse, ToolError> {
37        Ok(self
38            .execute_with_raw_response(code, caller, surface, config, scope, execution_id)
39            .await?
40            .display_response)
41    }
42
43    pub async fn execute_with_raw_response(
44        &self,
45        code: &str,
46        caller: CodeModeCaller,
47        surface: CodeModeSurface,
48        config: CodeModeConfig,
49        scope: ToolScope,
50        execution_id: Option<Arc<str>>,
51    ) -> Result<CodeModeExecutionOutcome, ToolError> {
52        let runner_pool = self
53            .runner_pool
54            .get_or_try_init(|| async {
55                Ok::<_, ToolError>(Arc::new(RunnerPool::new(
56                    PoolConfig::from_env(),
57                    RunnerSpawn::current_exe()?,
58                )))
59            })
60            .await?;
61        execute_in_subprocess(SubprocessExecution {
62            host: self.host,
63            runner_pool: Some(runner_pool.as_ref()),
64            code,
65            caller,
66            surface,
67            config,
68            scope,
69            execution_id,
70            ui_capture: self.ui_capture.clone(),
71        })
72        .await
73    }
74}
75
76pub fn code_mode_unknown_tool_hint() -> String {
77    "Use codemode.search or codemode.describe to find an available tool id.".to_string()
78}