From 222976aa236c5d59cbacb2b325e3344f92f6f152 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 30 May 2026 22:00:00 +0300 Subject: fix(reload-runtime): remove broken lastCtx.reload() call from tool Tools receive ExtensionContext, which does not have a reload() method. Only ExtensionCommandContext (command handlers) has reload(). The tool now always queues /reload-runtime as a follow-up command, matching the upstream example pattern. This fixes: lastCtx.reload is not a function --- pi/agent/extensions/reload-runtime/index.ts | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'pi/agent') diff --git a/pi/agent/extensions/reload-runtime/index.ts b/pi/agent/extensions/reload-runtime/index.ts index aceeddc..e2eec33 100644 --- a/pi/agent/extensions/reload-runtime/index.ts +++ b/pi/agent/extensions/reload-runtime/index.ts @@ -1,24 +1,19 @@ -import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; +import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; import { Type } from "@sinclair/typebox"; export default function (pi: ExtensionAPI) { - // Capture ctx so the tool can call ctx.reload() directly, avoiding a - // follow-up user message that would re-trigger the AI and cause a reload loop. - let lastCtx: ExtensionContext | undefined; - - pi.on("session_start", async (_event, ctx) => { - lastCtx = ctx; - }); - + // Command entrypoint for reload. + // Treat reload as terminal for this handler. pi.registerCommand("reload-runtime", { description: "Reload extensions, skills, prompts, and themes", handler: async (_args, ctx) => { - lastCtx = ctx; await ctx.reload(); return; }, }); + // LLM-callable tool. Tools get ExtensionContext, so they cannot call ctx.reload() directly. + // Instead, queue a follow-up user command that executes the command above. pi.registerTool({ name: "reload_runtime", label: "Reload Runtime", @@ -26,16 +21,6 @@ export default function (pi: ExtensionAPI) { description: "Reload extensions, skills, prompts, and themes. Call this once after editing extension files. Do not call it again in the same turn.", parameters: Type.Object({}), async execute() { - if (lastCtx) { - // Direct reload via ctx avoids injecting a follow-up user message, - // which would start a new AI turn and risk a reload loop. - await lastCtx.reload(); - return { - content: [{ type: "text", text: "Runtime reloaded." }], - details: {}, - }; - } - // Fallback if ctx is not yet available (should not happen in practice). pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" }); return { content: [{ type: "text", text: "Queued /reload-runtime as a follow-up command." }], -- cgit v1.2.3