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}