第五章停在一项已经完成的模型输出上:
FunctionCall(
call_id="call_17",
name="exec_command",
arguments={"cmd": "npm test"}
)
这还不是一次命令执行。它只是模型提出的结构化意图。真正改变文件、启动进程或访问网络之前,Codex 还必须回答四个问题:
- 模型调用的工具,是否就是这个 Step 曾经展示给它的那一个;
- 工具名称和参数应交给哪个执行器;
- 这次操作是否需要审批,最终允许接触哪些资源;
- 执行结果怎样成为下一次模型采样可以读取的事实。
这四个问题共同构成工具执行链。它不是一个巨大的 if name == ...,也不是“用户允许后直接运行命令”。Codex 把工具描述、路由、生命周期、命令策略、审批、权限和沙箱分成不同层,再用同一份 Step 快照把它们接起来。
工具有给模型看的一面,也有给 Runtime 用的一面
模型不会直接持有 Rust 函数。它看到的是 ToolSpec:工具名称、说明和参数格式。当前实现支持几种不同形状:
| ToolSpec | 模型怎样提交调用 | 典型用途 |
|---|---|---|
Function | 按 JSON Schema 生成参数 | exec_command、write_stdin |
Freeform | 生成一段自定义语法文本 | apply_patch |
Namespace | 在命名空间内选择具体工具 | MCP、扩展工具和多工具分组 |
ToolSearch | 搜索暂未直接展示的工具 | Deferred Tool 发现 |
WebSearch | 由 Responses 服务执行 | Hosted Tool |
Runtime 需要的是另一面:哪个名字由谁处理,能否并行,怎样执行。ToolExecutor 把两面绑在同一个接口里:
tool_name() 精确路由名称
spec() 模型可见定义
exposure() 在什么界面暴露
supports_parallel_tool_calls() 是否允许并行
handle(invocation) 真正的执行入口
这个绑定很重要。如果工具规格和执行函数由两套互不相关的注册表维护,规格更新而执行器没更新时,模型可能生成 Runtime 无法解释的参数;执行器换了语义而规格仍旧时,副作用会比模型理解的更大。当前源码在 codex-rs/tools/src/tool_executor.rs::ToolExecutor 的注释中直接把“规格与可执行 Runtime 保持绑定”写成接口目标。
不是每个已经注册的工具都要立刻塞进 Prompt。ToolExposure 规定了四种暴露方式:
| 暴露方式 | 初始工具列表 | 可被本地 Registry 调度 | Code Mode 中的含义 |
|---|---|---|---|
Direct | 有 | 有 | 可作为嵌套工具 |
Deferred | 无 | 有 | 先经 Tool Search 发现 |
DirectModelOnly | 有 | 有 | 只保留普通模型调用入口 |
Hidden | 无 | 有 | 仅供内部兼容或间接调度 |
还有一类 Hosted Tool 只有模型可见规格,没有本地 Handler,因为副作用由 Responses 服务完成。由此可见,“模型看得见”和“客户端注册了”是两个集合,不能用一张工具名称列表代替。
Deferred Tool 解决的是 Prompt 体积问题。工具数量较多时,Runtime 可以只展示 tool_search,把带搜索元数据的工具留在 Registry 中;模型找到所需工具后再调用它。Hidden Tool 则不允许模型发现,只保留内部调度能力。两者虽然都不在初始列表中,安全含义完全不同。
同一个 Step 同时生成规格和执行表
第四章介绍过 StepContext:它冻结一次模型采样实际使用的环境、MCP Binding、能力发现结果和 AGENTS.md。第六章最关键的字段是 tool_router。源码注释把它定义为:
为这一次采样请求展示并执行的最终工具计划。
建立 Step 时,capture_step_context_with_required_mcp_servers 先刷新已选环境的就绪状态,再捕获 MCP 和扩展能力,最后调用 built_tools。工具规划器从同一批 ToolExecutor 生成两个结果:
ToolRouter
├── model_visible_specs: Vec<ToolSpec>
└── registry: ToolRegistry
└── ToolName → CoreToolRuntime
build_prompt 从这个 Router 读取 model_visible_specs;ToolCallRuntime 则保存同一个 Router 和整个 Arc<StepContext>,以后用其中的 Registry 执行调用。即使工具 Future 稍后才运行,它也不会偷偷改用下一次采样刚生成的工具表。
这条约束解决了一个真实的时序问题。假设一次 Turn 中,远程环境在第一轮采样时仍未就绪,第二轮才变成可用:
Step A:只展示本地 exec_command
Step B:展示带 environment_id 的多环境 exec_command
Step A 返回的调用必须按 Step A 的参数合同解析,不能因为执行发生得晚,就拿 Step B 的环境和 Schema 解释它。下一次采样可以采用新的计划,已经发出的调用不能跨快照漂移。
完整 ResponseItem 才进入工具路由
工具执行从 OutputItemDone 开始,而不是从参数 Delta 开始。handle_output_item_done 收到完整 ResponseItem 后调用 ToolRouter::build_tool_call,当前客户端执行路径主要处理三种输入:
FunctionCall变成 JSON 参数形状的ToolPayload::Function;CustomToolCall变成自由文本形状的ToolPayload::Custom;execution == "client"的ToolSearchCall变成ToolPayload::ToolSearch。
Hosted Tool Search 不进入本地调度。工具名也不是一个扁平字符串:Namespace 和 Name 一起组成规范的 ToolName。因此 mcp__calendar / create_event 不会与本地同名函数碰撞。
解析成功后,Runtime 先把模型生成的 Tool Call Item 写入 History 和 Rollout,再创建工具 Future,并把 needs_follow_up 设为真。这里的顺序保证即使用户随后取消 Turn,历史里仍保留“模型曾经请求了什么”,不会只剩一个来历不明的工具结果。
工具 Future 经过 ToolRegistry 时还有几道结构检查:
- Registry 按完整
ToolName查找 Handler; - 未注册的名称变成模型可读的“unsupported call”结果;
- Handler 检查 Payload 形状是否匹配;
- 名称存在但 Function/Custom 形状不兼容,被视为 Runtime 内部契约错误;
- 检查通过后才发送 Tool Start 生命周期事件。
“工具不存在”和“程序把错误 Payload 交给了已存在工具”性质不同。前者可能是模型使用了过期或错误的工具名,返回结果后模型还能改正;后者意味着规格、解析器和 Registry 之间出现了程序错误,不能假装成普通命令失败。
Hooks 包围执行,但执行后的阻断不能回滚副作用
Registry 不会一查到 Handler 就立刻调用。它先运行 PreToolUse Hook。Hook 可以:
- 继续使用原参数;
- 返回新输入,让 Handler 重建
ToolInvocation; - 阻断调用,并把原因反馈给模型。
Handler 成功后,Registry 再运行 PostToolUse Hook。Post Hook 可以补充上下文、把反馈文字替换成模型可见结果,或阻断结果继续返回。不过此时真实操作已经发生。源码在 registry.rs 中专门提醒:PostToolUse 阻断的是结果,不是已经完成的工具执行。
例如 apply_patch 已经修改文件后,Post Hook 决定不把原结果交给模型,并不会自动恢复旧文件。需要事务语义的工具必须由自己的 Runtime 提供提交、补偿或回滚机制,不能把生命周期 Hook 当成数据库事务。
多个工具可以并行执行,但结果仍按调用顺序回灌
一次模型响应可以完成多个 Tool Call。Codex 把对应 Future 放进 FuturesOrdered,并通过一个共享 RwLock 控制执行:
- 声明支持并行的工具取得读锁,可以与其他并行工具同时运行;
- 不支持并行的工具取得写锁,会等待已有并行调用结束,并阻止其他调用进入;
- 即使实际完成时间不同,
FuturesOrdered仍按模型发出调用的顺序交付结果。
因此需要区分“执行顺序”和“History 顺序”。两个只读搜索可能并行,第二个先完成,但结果仍按调用次序与各自的 call_id 写入历史。这样既缩短等待,又给下一次采样一个稳定转录。
当前流程还有一个容易误读的细节:OutputItemDone 只是把 Future 排入队列。采样事件循环结束后,drain_in_flight 才轮询并等待这些 Future。工具不会在参数还没完成时抢跑,也不会把执行输出插进同一个尚未 Completed 的模型响应。
取消同样沿这层传播。每次调用获得子 CancellationToken。普通 Handler 可被直接中止;声明需要 Runtime 清理的 Handler 会先得到机会终止进程或释放资源。最终 Runtime 生成带失败语义的 Aborted Tool Output,让下一次模型采样知道操作没有正常完成,而不是让调用在 History 中永久悬空。
exec_command 不只是“一次 shell 调用”
命令工具最容易把工具路由、安全策略和进程生命周期同时暴露出来。当前 Unified Exec 组合通常向模型展示:
exec_command:启动命令,等待一小段时间并返回当前输出;write_stdin:向仍存活的会话写入字符,或空写入以继续轮询。
旧的 shell_command 可以继续注册为 Hidden 兼容入口,但具体暴露仍受模型能力、Feature 和 Tool Mode 影响,不能把某一套工具表写成所有会话的固定常量。
exec_command 的 Handler 先从原 Step 的环境快照选择目标环境。没有 environment_id 时使用主环境;指定 ID 时只允许选择该 Step 中已经就绪的环境。工作目录相对环境自身的 cwd 解析,远程环境还使用它报告的 Shell 类型,而不是假定远端与 Codex 宿主机相同。
接下来命令被交给 Unified Exec Process Manager。短命令在初始等待窗口内结束时,结果直接带回退出码;仍在运行时,Manager 会先把进程存入 Session 级 Process Store,再返回 process_id:
exec_command
├── 已退出 → output + exit_code
└── 仍运行 → output snapshot + process_id
│
└── write_stdin / 空轮询
write_stdin 使用工具参数名 session_id 接收这个进程 ID。对同一终端的读写会取得会话级交互锁,避免两个轮询同时抽走同一个输出缓冲区;不同终端仍可并行。空字符表示只等待新输出,非空字符写入 TTY。非 TTY 进程不能任意续写,只保留有限的中断处理。
write_stdin 也不会再次运行命令级 PreToolUse Hook,因为它只是已经批准并启动的命令的传输通道。当一次轮询观察到原命令最终结束时,PostToolUse 仍使用原 exec_command 的调用 ID 和命令内容,保持生命周期配对。
这套设计的代价是状态明显增加:Process Store、输出缓冲、交互锁、超时、终止、网络审批和清理都要跨多次工具调用保持一致。收益则是编译、测试服务器和交互式程序不必被伪装成一个超长的同步函数调用。
命令策略先判断“是否应该执行”,沙箱再约束“执行时能碰什么”
命令到达进程创建之前,ExecPolicyManager 会把 Shell 命令尽量拆成可判断的命令片段,然后同时参考显式 Exec Policy、危险命令启发式、已知安全命令和当前审批模式。结果被规整为三类:
| 结果 | 含义 |
|---|---|
Skip | 不需要弹出审批;是否绕过沙箱由额外字段和权限策略决定 |
NeedsApproval | 需要 Hook、自动 Reviewer 或用户给出决定 |
Forbidden | 当前策略不允许执行,也不能通过询问来改变 |
例如审批模式为 Never 时,Runtime 不会询问用户,但这不代表所有命令都被允许:危险命令可以直接变成 Forbidden,普通命令则可以依赖受限沙箱运行。OnRequest 配合受限文件系统时,普通且未请求升级的命令通常直接进入沙箱;只有请求越过边界或命中策略时才需要审批。
显式 Allow 规则也有严格条件。只有解析出的每个命令片段都被 Exec Policy 明确允许,Skip 才可以携带 bypass_sandbox=true。模型给出的 prefix_rule 只是一个建议:Runtime 会拒绝过宽或不能覆盖整条命令的前缀,不能靠 ["bash"] 这类泛化规则把任意脚本变成可信命令。
这里至少有四个不能合并的概念:
| 层 | 回答的问题 | 典型数据或组件 |
|---|---|---|
| 命令策略 | 这条命令应允许、询问还是禁止 | Exec Policy、危险/安全启发式 |
| 审批流程 | 这一次具体动作由谁决定 | Permission Hook、Guardian、User |
| 权限配置 | 如果运行,允许读写和联网到哪里 | PermissionProfile、附加权限 |
| 沙箱执行 | 怎样在操作系统或目标环境强制落实边界 | SandboxManager、Exec Server |
用户批准一次命令,是审批流程的结果,不会自动删除 Permission Profile;沙箱是执行机制,也不负责决定什么时候应该弹窗。
ToolOrchestrator 把审批、沙箱和升级组织成两次有界尝试
Shell、Unified Exec 和 Apply Patch 都把高风险执行交给 ToolOrchestrator。其正常顺序如下:
- 用当前 Workspace Roots 物化 Permission Profile;
- 计算
Skip、NeedsApproval或Forbidden; - 需要决定时,先运行 PermissionRequest Hook,再路由到 Guardian 或用户;
- 根据文件、网络策略和工具偏好选择首个 Sandbox Attempt;
- 执行并收集成功、普通错误或 Sandbox Denied;
- 只有工具允许升级且策略允许时,才审批并执行第二次尝试。
SandboxManager 在当前平台选择具体实现:macOS 使用 Seatbelt,Linux 路径在类型中名为 LinuxSeccomp 并由 Codex Linux Sandbox 根据权限配置构造启动参数,Windows 可使用 Restricted Token;不需要或无法选择平台沙箱时为 None。
本地执行会把命令转换成平台对应的启动请求。远程执行不能让 Codex 宿主机用自己的路径和 Sandbox Wrapper 包住另一台机器的命令,因此 env_for_exec_server 保留原生命令,把 Permission Profile、Workspace Roots、cwd 和沙箱请求作为上下文发给 Exec Server,由目标环境落实边界。
Sandbox Denied 也不等于“自动去掉沙箱再跑一次”。Orchestrator 先检查:
- 该工具是否允许失败升级;
- 当前审批模式是否允许无沙箱审批;
- 拒绝是否来自可解释的网络策略;
- 文件策略是否含有 denied-read 限制;
- 首轮批准能否覆盖权限更大的第二轮。
denied-read 尤其关键。这类限制只能由文件系统沙箱执行。如果为了升级直接无沙箱重跑,原本禁止读取的路径反而全部暴露。因此只要存在 denied-read,Runtime 就认为无沙箱执行不能表示当前权限策略;即使命令规则允许或调用明确请求升级,也必须保留沙箱和拒读边界。
严格自动审查下,首轮的 Guardian 批准只覆盖沙箱内执行,改成无沙箱的第二轮需要新审核。其他模式可以在动作已经获得适当批准且没有网络升级时复用决定。无论哪种情况,当前 Orchestrator 的升级都是一次有界的第二次尝试,不会无限循环“失败—放宽—再失败”。
apply_patch 是结构化文件操作,不是把文本丢给 Shell
apply_patch 使用 Freeform Tool,因为补丁语法比嵌套 JSON 更适合模型生成:
*** Begin Patch
*** Update File: src/app.py
@@
-old_value = 1
+new_value = 2
*** End Patch
Handler 首先解析语法,再针对同一个 Step 选中的文件系统验证补丁。验证会确认目标文件、上下文和移动操作等信息,之后才评估权限并委托 Runtime 执行。直接工具调用和 exec_command 中识别出的 apply_patch 命令最终都会进入这条专用路径,后者不会真的启动一个 Shell 子进程来修改文件。
补丁审批按原子目标建立 Key:
ApplyPatchApprovalKey = environment_id + path
一次补丁可能有多个 Key;移动文件还会同时加入源路径和目标路径。只有所有 Key 都已经获得 Session 级批准,后续补丁才可跳过询问。若用户选择“本会话允许”,Runtime 分别缓存每个路径,因此以后只修改其中一个已批准文件也能命中缓存。
在 Workspace 内本来可写的目录不需要额外权限。目标父目录不在当前可写范围时,Handler 才构造附加写权限请求。真正应用补丁时,ApplyPatchRuntime 仍使用 Orchestrator 选定的 Sandbox Attempt 和环境文件系统;远程文件也通过同一抽象处理。
这种实现比 echo ... > file 复杂,但它知道“将修改哪些路径”,可以提前展示 Diff、按路径审批、追踪已提交 Delta,并在部分失败时把已经发生的变化交给生命周期事件。通用 Shell 无法可靠提供这些语义。
工具结果不是日志,它是下一次采样的输入
Handler 返回的是实现 ToolOutput 的类型,而不是随意向标准输出打印一段文字。不同工具会生成对应的 ResponseInputItem:
| 调用形状 | 回灌形状 |
|---|---|
| Function Tool | FunctionCallOutput |
| Freeform Custom Tool | CustomToolCallOutput |
| Client Tool Search | ToolSearchOutput |
结果保留原 call_id,模型因此能把输出与此前的调用配对。普通可恢复错误也会转成失败结果,例如不支持的工具、审批拒绝或参数错误;只有破坏 Runtime 契约的 Fatal Error 才终止整个采样链。
命令输出在进入模型上下文前还会受双重限制:Process Manager 先限制采集缓冲,ToolOutput 再按模型截断策略生成上下文文本。返回值可以携带原始 Token 估计、被省略的字节数、Chunk ID、退出码和仍存活的进程 ID。遥测预览也有独立上限,不能把“日志里只看到一小段”误判为 Handler 只产生了这一小段。
采样结束后,drain_in_flight 把每个结果转换成 ResponseItem,按调用顺序写入 History。外层 run_turn 看到 needs_follow_up=true 后,不是复用旧 Step,而是重新捕获 StepContext,再用已经包含 Tool Call 和 Tool Result 的 History 发起下一次采样。
用接近 Python 的伪代码表示,主循环是:
async def run_agent_step(session: Session) -> bool:
step = await session.capture_step_context()
prompt = build_prompt(
history=session.history.for_prompt(),
tools=step.tool_router.model_visible_specs,
)
ordered_calls: list[Awaitable[ToolResult]] = []
needs_follow_up = False
async for event in model.stream(prompt):
if isinstance(event, OutputItemDone):
await session.history.append(event.item)
call = step.tool_router.try_parse(event.item)
if call is not None:
ordered_calls.append(
step.tool_runtime.execute(call, session.cancel_token)
)
needs_follow_up = True
for result in await_in_call_order(ordered_calls):
await session.history.append(result.to_response_item())
return needs_follow_up
这段伪代码省略了界面事件、Hooks、网络审批和错误分类,但保留了三个不变量:使用同一 Step 的规格和 Registry,调用项先于结果进入 History,工具结果只在下一次模型采样中生效。
调试工具链要先判断失败发生在哪一层
“命令没执行”不是一个足够精确的故障描述。可以按下面的信号定位:
| 现象 | 优先检查 |
|---|---|
| 模型始终不调用某工具 | 它是否为 Deferred、Hidden,或被 Code Mode/Feature Gate 隐藏 |
| 模型生成了工具名但提示 unsupported | 调用是否来自旧 Step,Namespace 是否匹配 Registry |
| 参数看似正确却触发 Fatal | ToolPayload 是 Function 还是 Custom,Handler 的 matches_kind 是否一致 |
| 调用在执行前被挡住 | PreToolUse Hook、Exec Policy、审批模式与 Reviewer 决定 |
| 用户批准后仍被拒绝 | Permission Profile 是否仍限制路径或网络,Sandbox 是否正确落实 |
| 沙箱拒绝后没有无沙箱重试 | 工具是否允许升级,审批策略和 denied-read 是否允许绕过 |
命令返回 process_id 但无退出码 | 进程仍存活,应通过 write_stdin 继续轮询或输入 |
| 第二个并行工具先完成却后出现 | 执行并行,但 FuturesOrdered 按调用顺序交付 |
| Patch 移动目标没有获批 | 审批 Key 是否同时包含源路径与目标路径 |
| 模型只看到部分命令输出 | 区分采集上限、模型上下文截断和遥测预览 |
观察日志时还应把 tool_name、namespace、call_id、Step/Turn ID、环境 ID、审批来源、Sandbox Type、退出码和原始输出大小放在同一条 Trace 中。只记录 Shell 文本,无法解释它为什么走到了某个远程环境,也无法区分“策略拒绝”和“操作系统拒绝”。
Agent 的行动能力来自受控闭环
到这里,第五章留下的 Tool Call 已经走完整条链:
模型可见规格
→ 完整 Tool Call
→ 同 Step 路由
→ Hook 与 Handler
→ 命令策略和审批
→ Permission Profile 与 Sandbox
→ 本地或远程副作用
→ 类型化 Tool Result
→ History
→ 下一次采样
这条链的核心不是工具数量,而是四个边界始终可核对:规格与执行器来自同一 Step,副作用发生前有明确决策,批准和强制权限没有混为一谈,结果与原调用一起进入历史。
下一章会沿另一种工具继续向外扩展:当工具不再只操作文件和进程,而是创建子 Agent、发送消息和等待其他任务时,Codex 怎样保持父子关系、上下文继承、并发上限与终止语义。
延伸阅读
- ToolExecutor 与 ToolExposure
- ToolRouter 的工具调用解析与调度
- 工具规格与 Registry 的共同规划
- ToolRegistry 的 Hooks 与生命周期
- ToolOrchestrator 的审批、沙箱和升级
- Unified Exec Process Manager
- Apply Patch Handler
第六章细节导航
第六章的总览只负责建立地图。下面 82 个细节单元按真实执行链展开;每节都包含源码索引、机制伪代码、失败分支和两张可复现技术图。
工具协议与规划
- 6.2
ToolSpec::Namespace的合并与 Provider 能力门控 - 6.3
ToolSpec::Freeform与自定义 Grammar - 6.4
ToolSpec::ToolSearch的客户端执行协议 - 6.5
ToolSpec::WebSearch的 Hosted Tool 参数 - 6.6 ToolName、Namespace 和名称冲突规则
- 6.7 Direct、Deferred、DirectModelOnly 与 Hidden Exposure
- 6.8
build_tool_specs_and_registry的工具来源汇总 - 6.9 Feature、模型能力、环境数量与账户类型门控
- 6.10 同一 Step 的 Model-visible Specs 与 Runtime Registry
- 6.11 ToolRouter 怎样把 ResponseItem 解析为 ToolCall
- 6.12 Function、Custom、ToolSearch 三种 ToolPayload
- 6.13 CoreToolRuntime 与通用 ToolExecutor 契约
- 6.14 PreToolUse/PostToolUse Hook 与输入改写
- 6.15 Tool Start/Finish Event、Telemetry 与 Dispatch Trace
- 6.16 并行工具的分组、顺序保持和终态竞争
- 6.17 ToolOutput 到 ResponseInputItem 的编码
- 6.18 输出 Token 截断、Head/Tail 截断与遥测预览
- 6.19 取消、Aborted Output 和 Call/Output 配对
Shell 与进程工具
- 6.20
shell_command的模型规格和命令数组语义 - 6.21 Shell 参数解析、登录 Shell 与平台差异
- 6.22 ShellCommandHandler 的审批、执行和输出
- 6.23 Shell Runtime 的 Sandbox 选择与升级重试
- 6.24 Zsh Fork Backend 的会话复用机制
- 6.25
exec_command的规格、yield time 和 session ID - 6.26 Unified Exec ProcessManager 的进程注册表
- 6.27 子进程启动、stdout/stderr 异步读取和 HeadTailBuffer
- 6.28 命令首次 Yield、后台化与退出事件
- 6.29
write_stdin写入、空轮询和会话关闭 - 6.30 Unified Exec 的超时、取消和进程回收
- 6.31 User Shell Command 为什么不经过模型 Tool Call
Apply Patch
- 6.32 Apply Patch Freeform Tool Spec 和 Lark Grammar
- 6.33 Patch 文本的 Add、Update、Delete 与 Move 语法
- 6.34 Parser 怎样定位 Hunk、上下文和文件操作
- 6.35 路径规范化、工作区边界和符号链接风险
- 6.36 ApplyPatchHandler 的审批和直接执行路径
- 6.37 Shell 中
apply_patch命令的识别与截获 - 6.38 Patch 的文件写入顺序、失败原子性和错误报告
- 6.39 TurnDiffTracker 怎样记录改动并生成 Turn Diff
- 6.40 Apply Patch 流式参数预览和完成事件
图像、计划和交互工具
- 6.41
view_image的路径/环境选择与 MIME 解码 - 6.42 原图 Detail 能力、尺寸限制和模型内容项
- 6.43
update_plan的状态约束与 Event 更新 - 6.44
request_user_input的模式门控、问题 Schema 和等待器 - 6.45
request_permissions的权限请求、响应和 TurnContext 更新 - 6.46
wait_for_environment的环境状态观察和超时 - 6.47
current_time与时间提醒注入 - 6.48
sleep的取消和时间范围限制 - 6.49
new_context怎样触发新上下文窗口 - 6.50
get_context_remaining怎样读取 Token Budget
Tool Search、Code Mode 与扩展工具
- 6.51 Deferred Tool 的 SearchInfo 和延迟暴露
- 6.52
tool_search的查询匹配、来源分组和返回规格 - 6.53 Tool Search Result 怎样进入下一次模型请求
- 6.54 Code Mode 的启用条件和工具面重写
- 6.55 Code Mode Execute 的 JavaScript Cell 生命周期
- 6.56 Code Mode Nested Tool 的名称规范化和桥接
- 6.57 Code Mode Wait 的 Cell 等待、取消与结果
- 6.58 Code Mode 与 DirectModelOnly/Excluded Namespace
- 6.59 Dynamic Function/Namespace Tool 的注册和执行
- 6.60 Extension ToolContributor 到 Core Runtime Adapter
- 6.61 Hosted Web Search 与 Standalone
web.run的选择 - 6.62 Image Generation Extension 的能力和账户门控
MCP 与插件工具
- 6.63 MCP Server 的工具目录、命名空间和旧名称兼容
- 6.64 MCP Function Call 的参数解析、审批和执行
- 6.65 MCP 结果中的文本、图片、资源和错误编码
- 6.66 MCP 输出截断、耗时信息和 Hook Payload
- 6.67
list_mcp_resources的分页和 Server 过滤 - 6.68
list_mcp_resource_templates的模板目录 - 6.69
read_mcp_resource的 URI 路由和内容转换 - 6.70
list_available_plugins_to_install的候选来源 - 6.71
request_plugin_install的批准、安装和能力刷新
安全策略与系统沙箱
- 6.72 Permission Profile 从配置到 TurnContext 的解析
- 6.73 Approval Policy 的 Never、OnRequest 和升级语义
- 6.74 Exec Policy 怎样解析命令风险和保存前缀规则
- 6.75 Guardian 审查请求、策略 Prompt 与判定
- 6.76 SandboxPolicy、SandboxType 与执行器选择
- 6.77 macOS Seatbelt Profile 的文件和网络规则
- 6.78 Linux Landlock、Seccomp 与网络命名空间
- 6.79 Windows Sandbox Token、ACL 和进程限制
- 6.80 Network Proxy、域名审批和运行期网络规则
- 6.81 Sandbox Denied 的识别、升级和重试
- 6.82 审批、策略、沙箱和 Hook 各自能防住什么
评论
登录后即可评论