执行后端与沙箱命令运行时
这一阶段是系统把外部命令真正跑起来的中段,也负责给运行加护栏。上层接住 shell、改文件、启动应用等请求,补好目录、环境、超时和审批;统一执行引擎用本机终端、管道或远端 exec-server 开进程、收输出、喂输入、停进程。补丁通道先查格式和权限再改文件。各平台沙箱和提权像门禁,限制文件、网络和越权;文件系统服务让远端读写也走安全通道。sleep 工具可短暂停顿,有新输入就提前醒。
子阶段
执行后端与沙箱命令运行时
core/src/tools/handlers/sleep.rs源码 ↗
这个文件像一个“可打断的闹钟”。模型调用 sleep 时,会传进来要等多久,单位是毫秒。文件先定义这个工具长什么样:名字叫 sleep,需要一个 duration_ms 参数,并告诉外部这个数必须在安全范围内。真正执行时,SleepHandler 会检查传入内容是不是函数调用,再把参数解析出来,并限制最长只能睡一小时,防止有人让系统卡太久。开始等待前,它会向会话里发一条“睡眠开始”的记录;等待期间,它一边计时,一边监听当前轮次有没有新输入。如果新输入来了,就提前结束;如果没有,就等满指定时间。最后它发出“睡眠完成”的记录,并返回实际经过了多少秒,以及是正常完成还是被新输入打断。
create_sleep_tool31–52 ↗
fn create_sleep_tool() -> ToolSpec
作用:这个函数说明 sleep 工具对外长什么样,包括工具名、用途说明、需要哪些参数,以及参数格式。别人要把这个工具登记到系统里时,会用到这份说明书。
数据流:进去时不需要外部输入 → 它创建一个参数表,说明 duration_ms 是数字、必须填写、不能有额外字段,并把这些包装成一个工具规格 → 出来的是 ToolSpec,也就是系统能理解的“工具说明书”。
调用关系:它是 SleepHandler::spec 背后的具体制作者。外部问 SleepHandler“你的工具规格是什么”时,spec 会转头调用它,把完整的 sleep 工具说明交出去。
调用图:调用 2 个内部函数(number, object);被 1 处调用(spec);外部调用 4 个(from, format!, Function, vec!)。
SleepHandler::tool_name55–57 ↗
fn tool_name(&self) -> ToolName
作用:这个函数告诉系统:这个处理器对应的工具名字叫 sleep。这样当模型请求 sleep 工具时,系统才能把请求送到正确的人手里。
数据流:进去时只需要这个处理器本身 → 它把固定字符串 sleep 包装成系统使用的 ToolName → 出来的是一个标准化的工具名。
调用关系:它是工具注册和匹配时用的小标签。运行框架会用这个名字判断某个工具调用该不该交给 SleepHandler。
调用图:调用 1 个内部函数(plain)。
SleepHandler::spec59–61 ↗
fn spec(&self) -> ToolSpec
作用:这个函数把 sleep 工具的完整说明交给系统,包括它能做什么、要什么参数。没有它,外部就不知道该怎样正确调用 sleep。
数据流:进去时只需要这个处理器本身 → 它调用 create_sleep_tool 生成工具规格 → 出来的是 sleep 工具的说明书。
调用关系:它是 ToolExecutor 接口的一部分。系统登记工具或向模型暴露可用工具时,会调用它;它本身不拼细节,而是把活交给 create_sleep_tool。
调用图:调用 1 个内部函数(create_sleep_tool)。
SleepHandler::handle63–128 ↗
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_>
作用:这个函数是真正执行 sleep 工具的地方:按请求等待一段时间,但如果当前对话来了新输入,就提前结束。它还会返回实际等了多久,让调用方知道结果。
数据流:进去的是一次工具调用,里面有会话、当前轮次、调用编号和参数 → 它确认载荷是函数参数,解析 duration_ms,检查范围,然后记录开始时间,发出“睡眠开始”事件;接着同时等待计时器和新输入通知,谁先到就按谁结束 → 出来的是一段文本结果,包含实际墙钟时间和“完成”或“被新输入打断”的提示,同时会话里也多了开始和完成两条状态记录。
调用关系:当运行框架发现模型调用 sleep 时,会把请求交给它。它会借助 parse_arguments 读懂参数,用系统的输入队列监听新活动,用 tokio 的异步计时等待时间,再用 boxed_tool_output 和 FunctionToolOutput::from_text 把结果包装成工具输出交回去。
调用图:调用 3 个内部函数(from_text, boxed_tool_output, parse_arguments);外部调用 9 个(pin, from_millis, now, Sleep, format!, pin!, select!, sleep, RespondToModel)。