- 首页
- Documentation
- 运行时工具
- Resolve 工具运行时内部机制
Resolve 工具运行时内部机制
本文档介绍了 coding-agent 中预览/应用工作流的建模方式,以及自定义工具如何通过 pushPendingAction 参与该流程。
范围和关键文件
Section titled “范围和关键文件”src/tools/resolve.tssrc/tools/pending-action.tssrc/tools/ast-edit.tssrc/extensibility/custom-tools/types.tssrc/extensibility/custom-tools/loader.tssrc/sdk.ts
resolve 的作用
Section titled “resolve 的作用”resolve 是一个隐藏工具,用于最终确认待处理的预览操作。
action: "apply"在待处理操作上执行apply(reason)并持久化变更。action: "discard"如果提供了reject(reason)则调用该方法;否则使用默认的 “Discarded” 消息丢弃该操作。
如果不存在待处理操作,resolve 将失败并返回:
No pending action to resolve. Nothing to apply or discard.
待处理操作是一个栈(后进先出)
Section titled “待处理操作是一个栈(后进先出)”待处理操作以推入/弹出栈的形式存储在 PendingActionStore 中:
push(action)将新的待处理操作添加到栈顶。peek()查看当前栈顶操作。pop()移除并返回栈顶操作。hasPending指示栈是否非空。
resolve 总是先消费最顶部的待处理操作(pop()),因此多个产生预览的工具按注册的逆序解析。
内置生产者示例(ast_edit)
Section titled “内置生产者示例(ast_edit)”ast_edit 首先预览结构替换。当预览包含替换内容且尚未应用时,它会推入一个待处理操作,其中包含:
- label(人类可读的摘要)
sourceToolName(ast_edit)apply(reason: string)回调函数,以dryRun: false重新运行 AST 编辑
resolve(action="apply", reason="...") 将 reason 传递给此回调函数。
自定义工具:pushPendingAction
Section titled “自定义工具:pushPendingAction”自定义工具可以通过 CustomToolAPI.pushPendingAction(...) 注册与 resolve 兼容的待处理操作。
CustomToolPendingAction:
label: string(必需)apply(reason: string): Promise<AgentToolResult<unknown>>(必需)— 应用时调用;reason是传递给resolve的字符串reject?(reason: string): Promise<AgentToolResult<unknown> | undefined>(可选)— 丢弃时调用;如果提供了返回值,则替换默认的 “Discarded” 消息details?: unknown(可选)sourceToolName?: string(可选,默认为"custom_tool")
最小使用示例
Section titled “最小使用示例”import type { CustomToolFactory } from "@f5-sales-demo/xcsh";
const factory: CustomToolFactory = pi => ({ name: "batch_rename_preview", label: "Batch Rename Preview", description: "Previews renames and defers commit to resolve", parameters: pi.typebox.Type.Object({ files: pi.typebox.Type.Array(pi.typebox.Type.String()), }),
async execute(_toolCallId, params) { const previewSummary = `Prepared rename plan for ${params.files.length} files`;
pi.pushPendingAction({ label: `Batch rename: ${params.files.length} files`, sourceToolName: "batch_rename_preview", apply: async (reason) => { // apply writes here return { content: [{ type: "text", text: `Applied batch rename. Reason: ${reason}` }], }; }, reject: async (reason) => { // optional: cleanup or notify on discard return { content: [{ type: "text", text: `Discarded batch rename. Reason: ${reason}` }], }; }, });
return { content: [{ type: "text", text: `${previewSummary}. Call resolve to apply or discard.` }], }; },});
export default factory;运行时可用性与故障
Section titled “运行时可用性与故障”pushPendingAction 由自定义工具加载器使用活动会话的 PendingActionStore 进行连接。
如果运行时没有待处理操作存储,pushPendingAction 将抛出异常:
Pending action store unavailable for custom tools in this runtime.
工具选择行为
Section titled “工具选择行为”当 PendingActionStore.hasPending 为 true 时,代理运行时会偏向选择 resolve 工具,以确保在正常工具流程继续之前,待处理的预览被显式地最终确认。
- 仅对需要支持显式应用/丢弃的破坏性或高影响操作使用待处理操作。
- 保持
label简洁且具体;它会在 resolve 渲染器输出中显示。 - 确保
apply(reason)具有确定性且足够幂等以支持一次性执行;reason仅用于信息说明,不应改变行为。 - 当丢弃操作需要清理(临时状态、锁、通知)时实现
reject(reason);对于默认消息即可满足需求的无状态预览,可以省略它。 - 如果您的工具可以暂存多个预览,请记住后进先出语义:最后推入的操作最先解析。