- Inicio
- Documentation
- Herramientas de ejecución
- Aspectos internos del tiempo de ejecución de la herramienta Resolve
Aspectos internos del tiempo de ejecución de la herramienta Resolve
Este documento explica cómo se modelan los flujos de trabajo de vista previa/aplicación en el agente de codificación y cómo las herramientas personalizadas pueden participar mediante pushPendingAction.
Alcance y archivos clave
Sección titulada «Alcance y archivos clave»src/tools/resolve.tssrc/tools/pending-action.tssrc/tools/ast-edit.tssrc/extensibility/custom-tools/types.tssrc/extensibility/custom-tools/loader.tssrc/sdk.ts
Qué hace resolve
Sección titulada «Qué hace resolve»resolve es una herramienta oculta que finaliza una acción de vista previa pendiente.
action: "apply"ejecutaapply(reason)sobre la acción pendiente y persiste los cambios.action: "discard"invocareject(reason)si se proporciona; de lo contrario, descarta la acción con un mensaje predeterminado “Discarded”.
Si no existe ninguna acción pendiente, resolve falla con:
No pending action to resolve. Nothing to apply or discard.
Las acciones pendientes forman una pila (LIFO)
Sección titulada «Las acciones pendientes forman una pila (LIFO)»Las acciones pendientes se almacenan en PendingActionStore como una pila de tipo push/pop:
push(action)añade una nueva acción pendiente en la cima.peek()inspecciona la acción actual en la cima.pop()elimina y devuelve la acción en la cima.hasPendingindica si la pila no está vacía.
resolve siempre consume la acción pendiente más reciente primero (pop()), por lo que las herramientas que producen múltiples vistas previas se resuelven en orden inverso al de su registro.
Ejemplo de productor integrado (ast_edit)
Sección titulada «Ejemplo de productor integrado (ast_edit)»ast_edit previsualiza primero los reemplazos estructurales. Cuando la vista previa tiene reemplazos y aún no se ha aplicado, agrega una acción pendiente que contiene:
- etiqueta (resumen legible por humanos)
sourceToolName(ast_edit)- callback
apply(reason: string)que vuelve a ejecutar la edición AST condryRun: false
resolve(action="apply", reason="...") pasa reason a este callback.
Herramientas personalizadas: pushPendingAction
Sección titulada «Herramientas personalizadas: pushPendingAction»Las herramientas personalizadas pueden registrar acciones pendientes compatibles con resolve mediante CustomToolAPI.pushPendingAction(...).
CustomToolPendingAction:
label: string(obligatorio)apply(reason: string): Promise<AgentToolResult<unknown>>(obligatorio) — se invoca al aplicar;reasones la cadena pasada aresolvereject?(reason: string): Promise<AgentToolResult<unknown> | undefined>(opcional) — se invoca al descartar; el valor de retorno reemplaza el mensaje predeterminado “Discarded” si se proporcionadetails?: unknown(opcional)sourceToolName?: string(opcional, por defecto"custom_tool")
Ejemplo de uso mínimo
Sección titulada «Ejemplo de uso mínimo»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;Disponibilidad en tiempo de ejecución y fallos
Sección titulada «Disponibilidad en tiempo de ejecución y fallos»pushPendingAction es conectado por el cargador de herramientas personalizadas mediante el PendingActionStore de la sesión activa.
Si el tiempo de ejecución no dispone de un almacén de acciones pendientes, pushPendingAction lanza:
Pending action store unavailable for custom tools in this runtime.
Comportamiento de selección de herramientas
Sección titulada «Comportamiento de selección de herramientas»Cuando PendingActionStore.hasPending es verdadero, el tiempo de ejecución del agente inclina la selección de herramientas hacia resolve, de modo que las vistas previas pendientes se finalicen explícitamente antes de que continúe el flujo normal de herramientas.
Orientación para desarrolladores
Sección titulada «Orientación para desarrolladores»- Utilice acciones pendientes únicamente para operaciones destructivas o de alto impacto que deban admitir aplicación/descarte explícito.
- Mantenga
labelconciso y específico; se muestra en la salida del renderizador de resolve. - Asegúrese de que
apply(reason)sea determinista e idempotente para una ejecución de un solo disparo;reasones informativo y no debe modificar el comportamiento. - Implemente
reject(reason)cuando el descarte requiera limpieza (estado temporal, bloqueos, notificaciones); omítalo en vistas previas sin estado donde el mensaje predeterminado sea suficiente. - Si su herramienta puede preparar múltiples vistas previas, recuerde la semántica LIFO: la última acción enviada se resuelve primero.