From 5bde9de32f73cfd0d49ed9637932373bdab94c8b Mon Sep 17 00:00:00 2001 From: "Grace (Clawdbot)" Date: Tue, 27 Jan 2026 14:18:20 +0100 Subject: [PATCH] feat(exec-events): bead-4 - wrap tools with exec context --- src/agents/pi-tools.ts | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/agents/pi-tools.ts b/src/agents/pi-tools.ts index 2047da4af..349a80c05 100644 --- a/src/agents/pi-tools.ts +++ b/src/agents/pi-tools.ts @@ -19,6 +19,7 @@ import { listChannelAgentTools } from "./channel-tools.js"; import { createMoltbotTools } from "./moltbot-tools.js"; import type { ModelAuthMode } from "./model-auth.js"; import { wrapToolWithAbortSignal } from "./pi-tools.abort.js"; +import { runWithExecEventContext } from "../infra/exec-events-context.js"; import { filterToolsByPolicy, isToolAllowedByPolicies, @@ -96,6 +97,28 @@ function resolveExecConfig(cfg: MoltbotConfig | undefined) { }; } +function wrapToolWithExecEventContext( + tool: AnyAgentTool, + context: { runId?: string; sessionKey?: string }, +): AnyAgentTool { + const execute = tool.execute; + if (!execute) return tool; + const runId = context.runId?.trim() || undefined; + const sessionKey = context.sessionKey?.trim() || undefined; + return { + ...tool, + execute: (toolCallId, params, signal, onUpdate) => + runWithExecEventContext( + { + runId, + toolCallId, + sessionKey, + }, + () => execute(toolCallId, params, signal, onUpdate), + ), + }; +} + export const __testing = { cleanToolSchemaForGemini, normalizeToolParams, @@ -411,9 +434,15 @@ export function createMoltbotCodingTools(options?: { // Always normalize tool JSON Schemas before handing them to pi-agent/pi-ai. // Without this, some providers (notably OpenAI) will reject root-level union schemas. const normalized = subagentFiltered.map(normalizeToolParameters); + const withExecContext = normalized.map((tool) => + wrapToolWithExecEventContext(tool, { + runId: options?.runId, + sessionKey: options?.sessionKey, + }), + ); const withAbort = options?.abortSignal - ? normalized.map((tool) => wrapToolWithAbortSignal(tool, options.abortSignal)) - : normalized; + ? withExecContext.map((tool) => wrapToolWithAbortSignal(tool, options.abortSignal)) + : withExecContext; // NOTE: Keep canonical (lowercase) tool names here. // pi-ai's Anthropic OAuth transport remaps tool names to Claude Code-style names