/** * cache-stack — official Pi 的工具发现与 active-tool policy 扩展。 * * session_start 建立小型初始工具集;模型通过 lazy search 发现工具, * lazy activate 以 additive setActiveTools() 加入工具。prompt cache、 * session affinity 和 deferred tool serialization 全部由官方 Pi/provider 负责。 * * 生命周期管线: * session_start → 建立/恢复 branch-local activation state * model_select → 按模型策略 reconcile * before_agent_start → 保留 activation 并 reconcile active-tool policy * session_tree/compact → 恢复当前 branch 的 activation snapshot * tool_execution_end → 刷新已知工具并 reconcile * session_shutdown → 丢弃扩展内存状态 * * 配置 (~/.pi/agent/cache-stack.json):见 config.ts 的 DEFAULT_CONFIG。 * * tool_result 输出限制 (toolOutput):在官方 tool_result 公共边界上把超过 * 字节/行数预算的文本结果截断(完整输出先落盘)后再进入模型上下文。 */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { loadConfig, resolveLazyToolsConfig, type CacheStackConfig, type EffectiveLazyToolsConfig, type ModelIdentity, } from "./config.ts"; import { setupLazyTools } from "./lazy-tools.ts"; import { createToolResultHandler } from "./tool-output-limit.ts"; export default function cacheStack(pi: ExtensionAPI): void { // 配置在 session_start 时惰性重载(编辑无需重启);模型切换时重新解析 // modelOverrides,不需要重启或新建会话。 let cfg: CacheStackConfig = loadConfig(); let currentModel: ModelIdentity | undefined; let effectiveLazyTools: EffectiveLazyToolsConfig = resolveLazyToolsConfig(cfg.lazyTools); const setCurrentModel = (model: ModelIdentity | undefined): void => { currentModel = model ? { provider: model.provider, id: model.id } : undefined; effectiveLazyTools = resolveLazyToolsConfig(cfg.lazyTools, currentModel); }; const lazyTools = setupLazyTools(pi, () => effectiveLazyTools); const toolResultHandler = createToolResultHandler(() => cfg.toolOutput); pi.on("tool_result", toolResultHandler); pi.on("session_start", async (event, ctx) => { // 每次新会话重载配置;模型规则按当前 ctx.model 解析。 cfg = loadConfig(); setCurrentModel(ctx.model); // pi 保证 session_start 先于首个 before_agent_start。 lazyTools.onSessionStart(ctx, event.reason); }); pi.on("model_select", (event) => { // 模型切换后立即应用该模型的 lazy policy;激活过的工具只在新 policy // 禁用/隐藏它们时才被移除。 setCurrentModel(event.model); lazyTools.onModelChange(); }); pi.on("before_agent_start", (_event, ctx) => { // 保险:某些启动路径(reload/重启后 resume)session_start 可能没送达扩展。 // 这里只 reconcile,不清空会话内已激活工具,也不修改 system prompt。 // 官方 Pi 根据 active tool set 生成当轮 Available tools/Guidelines。 setCurrentModel(ctx.model); lazyTools.onBeforeAgentStart(); }); pi.on("tool_execution_end", () => { lazyTools.onToolExecutionEnd(); }); pi.on("session_tree", (_event, ctx) => { lazyTools.onSessionTree(ctx); }); pi.on("session_compact", (_event, ctx) => { lazyTools.onSessionCompact(ctx); }); pi.on("session_shutdown", () => { lazyTools.onReset(); }); }