Add code_mode experimental feature (#13418)

A much narrower and more isolated (no node features) version of js_repl
This commit is contained in:
pakrym-oai
2026-03-09 20:56:27 -07:00
committed by GitHub
parent a3cd9f16f5
commit da616136cc
14 changed files with 958 additions and 0 deletions
+57
View File
@@ -67,6 +67,7 @@ pub(crate) struct ToolsConfig {
pub search_tool: bool,
pub request_permission_enabled: bool,
pub request_permissions_tool_enabled: bool,
pub code_mode_enabled: bool,
pub js_repl_enabled: bool,
pub js_repl_tools_only: bool,
pub collab_tools: bool,
@@ -94,6 +95,7 @@ impl ToolsConfig {
session_source,
} = params;
let include_apply_patch_tool = features.enabled(Feature::ApplyPatchFreeform);
let include_code_mode = features.enabled(Feature::CodeMode);
let include_js_repl = features.enabled(Feature::JsRepl);
let include_js_repl_tools_only =
include_js_repl && features.enabled(Feature::JsReplToolsOnly);
@@ -170,6 +172,7 @@ impl ToolsConfig {
search_tool: include_search_tool,
request_permission_enabled,
request_permissions_tool_enabled,
code_mode_enabled: include_code_mode,
js_repl_enabled: include_js_repl,
js_repl_tools_only: include_js_repl_tools_only,
collab_tools: include_collab_tools,
@@ -196,6 +199,12 @@ impl ToolsConfig {
self.web_search_config = web_search_config;
self
}
pub fn for_code_mode_nested_tools(&self) -> Self {
let mut nested = self.clone();
nested.code_mode_enabled = false;
nested
}
}
fn supports_image_generation(model_info: &ModelInfo) -> bool {
@@ -1523,6 +1532,32 @@ fn create_js_repl_reset_tool() -> ToolSpec {
})
}
fn create_code_mode_tool(enabled_tool_names: &[String]) -> ToolSpec {
const CODE_MODE_FREEFORM_GRAMMAR: &str = r#"
start: source
source: /[\s\S]+/
"#;
let enabled_list = if enabled_tool_names.is_empty() {
"none".to_string()
} else {
enabled_tool_names.join(", ")
};
let description = format!(
"Runs JavaScript in a Node-backed `node:vm` context. This is a freeform tool: send raw JavaScript source text (no JSON/quotes/markdown fences). Direct tool calls remain available while `code_mode` is enabled. Inside JavaScript, call nested tools with `await tools[name](args)` or identifier wrappers like `await shell(args)` when the tool name is a valid JS identifier. Nested tool calls resolve to arrays of content items. Function tools require JSON object arguments. Freeform tools require raw strings. Use synchronous `add_content(value)` with a content item or content-item array, including `add_content(await exec_command(...))`, to return the same content items a direct tool call would expose to the model. Only content passed to `add_content(value)` is surfaced back to the model. Enabled nested tools: {enabled_list}."
);
ToolSpec::Freeform(FreeformTool {
name: "code_mode".to_string(),
description,
format: FreeformToolFormat {
r#type: "grammar".to_string(),
syntax: "lark".to_string(),
definition: CODE_MODE_FREEFORM_GRAMMAR.to_string(),
},
})
}
fn create_list_mcp_resources_tool() -> ToolSpec {
let properties = BTreeMap::from([
(
@@ -1829,6 +1864,7 @@ pub(crate) fn build_specs(
) -> ToolRegistryBuilder {
use crate::tools::handlers::ApplyPatchHandler;
use crate::tools::handlers::ArtifactsHandler;
use crate::tools::handlers::CodeModeHandler;
use crate::tools::handlers::DynamicToolHandler;
use crate::tools::handlers::GrepFilesHandler;
use crate::tools::handlers::JsReplHandler;
@@ -1865,11 +1901,32 @@ pub(crate) fn build_specs(
default_mode_request_user_input: config.default_mode_request_user_input,
});
let search_tool_handler = Arc::new(SearchToolBm25Handler);
let code_mode_handler = Arc::new(CodeModeHandler);
let js_repl_handler = Arc::new(JsReplHandler);
let js_repl_reset_handler = Arc::new(JsReplResetHandler);
let artifacts_handler = Arc::new(ArtifactsHandler);
let request_permission_enabled = config.request_permission_enabled;
if config.code_mode_enabled {
let nested_config = config.for_code_mode_nested_tools();
let (nested_specs, _) = build_specs(
&nested_config,
mcp_tools.clone(),
app_tools.clone(),
dynamic_tools,
)
.build();
let mut enabled_tool_names = nested_specs
.into_iter()
.map(|spec| spec.spec.name().to_string())
.filter(|name| name != "code_mode")
.collect::<Vec<_>>();
enabled_tool_names.sort();
enabled_tool_names.dedup();
builder.push_spec(create_code_mode_tool(&enabled_tool_names));
builder.register_handler("code_mode", code_mode_handler);
}
match &config.shell_type {
ConfigShellToolType::Default => {
builder.push_spec_with_parallel_support(