Add exec-server MVP startup and surface seams

This commit is contained in:
starr-openai
2026-04-04 14:32:43 -07:00
parent 4fd5c35c4f
commit e4cc738a5c
14 changed files with 610 additions and 69 deletions

View File

@@ -85,6 +85,9 @@ pub use responses_api::dynamic_tool_to_responses_api_tool;
pub use responses_api::mcp_tool_to_deferred_responses_api_tool;
pub use responses_api::mcp_tool_to_responses_api_tool;
pub use responses_api::tool_definition_to_responses_api_tool;
pub use tool_config::BuiltinToolCoverage;
pub use tool_config::BuiltinToolName;
pub use tool_config::BuiltinToolSurface;
pub use tool_config::ShellCommandBackendConfig;
pub use tool_config::ToolUserShellType;
pub use tool_config::ToolsConfig;

View File

@@ -37,6 +37,52 @@ pub enum UnifiedExecShellMode {
ZshFork(ZshForkConfig),
}
/// Phase-1 exec-server seam: a small typed summary of where a builtin tool
/// logically executes today. This is descriptive only and does not change tool
/// routing yet.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum BuiltinToolSurface {
RemoteExecution,
LocalExecution,
WorkspaceFileAccess,
UserInteraction,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum BuiltinToolName {
ApplyPatch,
ExecCommand,
RequestUserInput,
ShellCommand,
ViewImage,
WriteStdin,
}
impl BuiltinToolName {
pub const fn as_str(self) -> &'static str {
match self {
Self::ApplyPatch => "apply_patch",
Self::ExecCommand => "exec_command",
Self::RequestUserInput => "request_user_input",
Self::ShellCommand => "shell_command",
Self::ViewImage => "view_image",
Self::WriteStdin => "write_stdin",
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct BuiltinToolCoverage {
pub tool: BuiltinToolName,
pub surface: BuiltinToolSurface,
}
impl BuiltinToolCoverage {
pub const fn new(tool: BuiltinToolName, surface: BuiltinToolSurface) -> Self {
Self { tool, surface }
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ZshForkConfig {
pub shell_zsh_path: AbsolutePathBuf,
@@ -264,6 +310,55 @@ impl ToolsConfig {
self
}
/// Descriptive coverage that future exec-server negotiation can inspect
/// without coupling to the concrete handler map.
pub fn builtin_tool_coverage(&self) -> Vec<BuiltinToolCoverage> {
let mut coverage = Vec::with_capacity(5);
match self.shell_type {
ConfigShellToolType::UnifiedExec => {
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::ExecCommand,
BuiltinToolSurface::RemoteExecution,
));
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::WriteStdin,
BuiltinToolSurface::RemoteExecution,
));
}
ConfigShellToolType::ShellCommand => {
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::ShellCommand,
BuiltinToolSurface::LocalExecution,
));
}
ConfigShellToolType::Default
| ConfigShellToolType::Disabled
| ConfigShellToolType::Local => {}
}
if self.apply_patch_tool_type.is_some() {
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::ApplyPatch,
BuiltinToolSurface::WorkspaceFileAccess,
));
}
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::ViewImage,
BuiltinToolSurface::WorkspaceFileAccess,
));
if self.request_user_input {
coverage.push(BuiltinToolCoverage::new(
BuiltinToolName::RequestUserInput,
BuiltinToolSurface::UserInteraction,
));
}
coverage
}
pub fn for_code_mode_nested_tools(&self) -> Self {
let mut nested = self.clone();
nested.code_mode_enabled = false;

View File

@@ -69,6 +69,11 @@ pub fn build_tool_registry_plan(
let mut plan = ToolRegistryPlan::new();
let exec_permission_approvals_enabled = config.exec_permission_approvals_enabled;
// Phase-1 exec-server seam: keep a typed builtin surface summary next to
// tool registration so later hosted/exec-server work can reason about the
// same builtin set without changing handler wiring in this slice.
plan.set_builtin_tool_coverage(config.builtin_tool_coverage());
if config.code_mode_enabled {
let nested_config = config.for_code_mode_nested_tools();
let nested_plan = build_tool_registry_plan(

View File

@@ -1,3 +1,4 @@
use crate::BuiltinToolCoverage;
use crate::ConfiguredToolSpec;
use crate::DiscoverableTool;
use crate::ToolSpec;
@@ -53,6 +54,9 @@ pub struct ToolHandlerSpec {
pub struct ToolRegistryPlan {
pub specs: Vec<ConfiguredToolSpec>,
pub handlers: Vec<ToolHandlerSpec>,
/// Phase-1 exec-server seam: a typed builtin coverage summary that can be
/// inspected alongside the registry plan before transport/runtime changes.
pub builtin_tool_coverage: Vec<BuiltinToolCoverage>,
}
#[derive(Debug, Clone, Copy)]
@@ -80,6 +84,7 @@ impl ToolRegistryPlan {
Self {
specs: Vec::new(),
handlers: Vec::new(),
builtin_tool_coverage: Vec::new(),
}
}
@@ -104,6 +109,13 @@ impl ToolRegistryPlan {
kind,
});
}
pub(crate) fn set_builtin_tool_coverage(
&mut self,
builtin_tool_coverage: Vec<BuiltinToolCoverage>,
) {
self.builtin_tool_coverage = builtin_tool_coverage;
}
}
pub(crate) fn agent_type_description(