feat(extensions): add ctx.invokeTool for native built-in delegation
A tool's execute context now carries invokeTool(name, params, options?), which runs the native built-in of `name` and returns its result. A tool that re-registers a built-in (e.g. wrapping write to add logging or a policy check) can delegate to the original instead of reimplementing it. The native implementation is captured before extension re-registration replaces the registry entry and before the ExtensionToolWrapper pass, so invokeTool reaches the unwrapped native execute: it does not recurse into the caller's own wrapper, and it inherits the caller's already-granted approval rather than re-running the gate. Delegation depth is guarded against accidental self-recursion, and it resolves to undefined when no native tool of that name exists. Wired through ToolContextStore with a lazy native-tool resolver, so it is coding-agent-only (no agent-loop change) and sees the fully-assembled built-in set at call time.
This commit is contained in:
@@ -312,6 +312,25 @@ execute(
|
||||
): Promise<AgentToolResult>
|
||||
```
|
||||
|
||||
### Delegating to a native built-in (`ctx.invokeTool`)
|
||||
|
||||
A tool that re-registers a built-in name (e.g. wrapping `write` to add logging or a policy check) can
|
||||
run the original instead of reimplementing it. The `ctx` passed to `execute` carries:
|
||||
|
||||
```ts
|
||||
ctx.invokeTool?<TDetails>(
|
||||
name: string,
|
||||
params: Record<string, unknown>,
|
||||
options?: { signal?: AbortSignal; onUpdate?: AgentToolUpdateCallback },
|
||||
): Promise<AgentToolResult<TDetails> | undefined>
|
||||
```
|
||||
|
||||
It runs the **native** built-in of `name` (bypassing your own re-registration, so it does not recurse
|
||||
into your wrapper) and returns its result, including the native tool's own side effects and internal
|
||||
bookkeeping. It resolves to `undefined` when there is no native tool of that name. The invoked tool's
|
||||
approval gate is not re-run — your call already passed approval — and delegation depth is guarded
|
||||
against accidental self-recursion.
|
||||
|
||||
Template:
|
||||
|
||||
```ts
|
||||
|
||||
Reference in New Issue
Block a user