refactor(coding-agent): unify tool and event handler context creation

Tools now use ExtensionRunner.createContext() instead of a separate
inline context factory. This ensures tools and event handlers share
the same context, fixing ctx.shutdown() and other context methods.

- Made ExtensionRunner.createContext() public
- Changed wrapRegisteredTools to accept ExtensionRunner instead of getContext callback
- Create ExtensionRunner when SDK custom tools are present (not just extensions)
- Removed redundant inline context factory from sdk.ts
This commit is contained in:
Mario Zechner 2026-01-08 03:45:39 +01:00
parent cf0466d96c
commit b1fb910625
3 changed files with 23 additions and 49 deletions

View file

@ -296,7 +296,11 @@ export class ExtensionRunner {
this.shutdownHandler();
}
private createContext(): ExtensionContext {
/**
* Create an ExtensionContext for use in event handlers and tool execution.
* Context values are resolved at call time, so changes via initialize() are reflected.
*/
createContext(): ExtensionContext {
return {
ui: this.uiContext,
hasUI: this.hasUI(),

View file

@ -4,12 +4,13 @@
import type { AgentTool, AgentToolUpdateCallback } from "@mariozechner/pi-agent-core";
import type { ExtensionRunner } from "./runner.js";
import type { ExtensionContext, RegisteredTool, ToolCallEventResult, ToolResultEventResult } from "./types.js";
import type { RegisteredTool, ToolCallEventResult, ToolResultEventResult } from "./types.js";
/**
* Wrap a RegisteredTool into an AgentTool.
* Uses the runner's createContext() for consistent context across tools and event handlers.
*/
export function wrapRegisteredTool(registeredTool: RegisteredTool, getContext: () => ExtensionContext): AgentTool {
export function wrapRegisteredTool(registeredTool: RegisteredTool, runner: ExtensionRunner): AgentTool {
const { definition } = registeredTool;
return {
name: definition.name,
@ -17,18 +18,16 @@ export function wrapRegisteredTool(registeredTool: RegisteredTool, getContext: (
description: definition.description,
parameters: definition.parameters,
execute: (toolCallId, params, signal, onUpdate) =>
definition.execute(toolCallId, params, onUpdate, getContext(), signal),
definition.execute(toolCallId, params, onUpdate, runner.createContext(), signal),
};
}
/**
* Wrap all registered tools into AgentTools.
* Uses the runner's createContext() for consistent context across tools and event handlers.
*/
export function wrapRegisteredTools(
registeredTools: RegisteredTool[],
getContext: () => ExtensionContext,
): AgentTool[] {
return registeredTools.map((rt) => wrapRegisteredTool(rt, getContext));
export function wrapRegisteredTools(registeredTools: RegisteredTool[], runner: ExtensionRunner): AgentTool[] {
return registeredTools.map((rt) => wrapRegisteredTool(rt, runner));
}
/**