import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import type { Runtime } from "../runtime.js"; import { buildCompactionProjection, renderSummary, type Entry } from "../session-ledger/index.js"; const DEFAULT_OBSERVATIONS_POOL_MAX_TOKENS = 20_000; function observationsPoolMaxTokens(runtime: Runtime): number { const value = (runtime.config as { observationsPoolMaxTokens?: unknown }).observationsPoolMaxTokens; return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_OBSERVATIONS_POOL_MAX_TOKENS; } export function registerCompactionHook(pi: ExtensionAPI, runtime: Runtime): void { pi.on("session_before_compact", async (event: any, ctx: any) => { if (runtime.compactHookInFlight) { if (ctx.hasUI) { ctx.ui.notify( "Observational memory: another compaction is already in progress; cancelling duplicate", "warning", ); } return { cancel: true }; } runtime.compactHookInFlight = true; try { runtime.ensureConfig(ctx.cwd); const { preparation, branchEntries } = event; const { firstKeptEntryId, tokensBefore } = preparation; const projection = buildCompactionProjection( branchEntries as Entry[], firstKeptEntryId, { observationsPoolMaxTokens: observationsPoolMaxTokens(runtime) }, ); const summary = renderSummary(projection.reflections, projection.observations); return { compaction: { summary, firstKeptEntryId, tokensBefore, details: projection.details, }, }; } finally { runtime.compactHookInFlight = false; } }); }