@caupulican/pi-agent-core 0.81.39 → 0.81.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +77 -89
- package/dist/agent-loop.js.map +1 -1
- package/dist/compaction/branch-summarization.d.ts +4 -2
- package/dist/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/compaction/branch-summarization.js +4 -0
- package/dist/compaction/branch-summarization.js.map +1 -1
- package/dist/compaction/compaction.d.ts +32 -1
- package/dist/compaction/compaction.d.ts.map +1 -1
- package/dist/compaction/compaction.js +172 -101
- package/dist/compaction/compaction.js.map +1 -1
- package/dist/compaction/extraction.d.ts.map +1 -1
- package/dist/compaction/extraction.js +1 -1
- package/dist/compaction/extraction.js.map +1 -1
- package/dist/compaction/loop.d.ts +1 -1
- package/dist/compaction/loop.d.ts.map +1 -1
- package/dist/compaction/loop.js +24 -7
- package/dist/compaction/loop.js.map +1 -1
- package/dist/compaction/utils.d.ts.map +1 -1
- package/dist/compaction/utils.js +3 -1
- package/dist/compaction/utils.js.map +1 -1
- package/dist/compaction/verification.d.ts +11 -0
- package/dist/compaction/verification.d.ts.map +1 -1
- package/dist/compaction/verification.js +93 -11
- package/dist/compaction/verification.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +1 -0
- package/dist/proxy.js.map +1 -1
- package/dist/reliability/classifier.d.ts.map +1 -1
- package/dist/reliability/classifier.js +3 -3
- package/dist/reliability/classifier.js.map +1 -1
- package/dist/session/session-manager.d.ts +18 -6
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +68 -61
- package/dist/session/session-manager.js.map +1 -1
- package/dist/tool-failure-memory.d.ts +35 -0
- package/dist/tool-failure-memory.d.ts.map +1 -0
- package/dist/tool-failure-memory.js +290 -0
- package/dist/tool-failure-memory.js.map +1 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/usage.d.ts +5 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +32 -0
- package/dist/usage.js.map +1 -1
- package/dist/uuid.d.ts +1 -1
- package/dist/uuid.d.ts.map +1 -1
- package/dist/uuid.js +1 -49
- package/dist/uuid.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.js","sourceRoot":"","sources":["../../src/compaction/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry } from \"../session/session-manager.ts\";\nimport type { AgentMessage } from \"../types.ts\";\n\nexport interface CompactionFileFact {\n\tpath: string;\n\tkind: \"modified\" | \"created\" | \"read\";\n\tnote: string;\n}\n\nexport interface CompactionErrorFact {\n\toperation: string;\n\terror: string;\n}\n\nexport interface CompactionDelegatedWorkerFact {\n\t/** Worker-authored text is evidence for the parent, never a verified decision or completion claim. */\n\ttrust: \"UNTRUSTED\";\n\ttask: string;\n\tsummary: string;\n}\n\nexport interface CompactionFacts {\n\tfiles: CompactionFileFact[];\n\tworkingSet: CompactionFileFact[];\n\tactions: string[];\n\terrorFacts: CompactionErrorFact[];\n\tprohibitions: string[];\n\tcancelledText: string;\n\tactiveTaskSource: string;\n\t/** Latest-first worker evidence retained only by deterministic checkpoints. */\n\tdelegatedWorkerFacts?: CompactionDelegatedWorkerFact[];\n}\n\ninterface ToolCallFact {\n\tid: string | undefined;\n\tname: string;\n\tpath: string | undefined;\n\tbaseKind: \"modified\" | \"created\" | \"read\" | null;\n\tfinalKind: \"modified\" | \"created\" | \"read\" | null;\n\tverb: string;\n\tresolved: boolean;\n\tfailed: boolean;\n}\n\nconst PROHIBITION_PATTERN = /\\b(do not|don't|never|stop (?:doing|using|changing)|no more)\\b/i;\n// Deliberately narrow: a bare \"stop\" (\"stop the server and rerun\") is everyday phrasing, not a\n// reversal of the prior work — matching it marked whole turns cancelled and made the\n// cancelled-work gate fight the recall gates (2026-07-06 incident).\nconst REVERSAL_PATTERN =\n\t/\\b(undo|revert|roll back|never mind|scrap that|forget (?:it|that)|stop (?:that|this|it|everything|working on))\\b/i;\n\n/** User messages longer than this are documents/pastes, not spoken prohibitions. */\nconst PROHIBITION_SOURCE_MAX_CHARS = 1_500;\n/** Upper bound on gate-demanded rules; most recent win (same bounding rationale as Done carry-over). */\nconst MAX_PROHIBITIONS = 8;\n/** Upper bound on gate-demanded actions; mirrors the prompt's \"15 most recent Done items\" rule. */\nconst MAX_ACTIONS = 15;\nconst MAX_WORKING_SET_FILES = 8;\nconst MAX_ERROR_FACTS = 5;\nconst ERROR_LINE_MAX_CHARS = 160;\nconst COMMAND_PREFIX_MAX_CHARS = 80;\nconst MAX_DELEGATED_WORKER_FACTS = 4;\nconst DELEGATED_WORKER_TASK_MAX_CHARS = 240;\nconst DELEGATED_WORKER_SUMMARY_MAX_CHARS = 600;\n/** Shared clamp for the active-task text because verification can only demand what the prompt receives. */\nexport const ACTIVE_TASK_SOURCE_MAX_CHARS = 4_000;\n\nconst FILE_KIND_PRIORITY: Record<NonNullable<ToolCallFact[\"finalKind\"]>, number> = {\n\tread: 1,\n\tcreated: 2,\n\tmodified: 3,\n};\n\nconst TOOL_KIND_BY_NAME: Record<string, \"modified\" | \"created\" | \"read\" | null> = {\n\tread: \"read\",\n\tgrep: \"read\",\n\tfind: \"read\",\n\twrite: \"modified\",\n\tedit: \"modified\",\n\tbash: null,\n};\n\nconst TOOL_VERB_BY_NAME: Record<string, string> = {\n\twrite: \"WRITE\",\n\tedit: \"EDIT\",\n\tbash: \"RUN\",\n\tread: \"READ\",\n\tgrep: \"READ\",\n\tfind: \"READ\",\n};\n\nfunction messageToText(message: AgentMessage): string {\n\tconst rawContent = (message as { content?: unknown }).content;\n\tif (typeof rawContent === \"string\") {\n\t\treturn rawContent;\n\t}\n\tif (!Array.isArray(rawContent)) {\n\t\treturn \"\";\n\t}\n\n\tconst parts: string[] = [];\n\tfor (const block of rawContent) {\n\t\tif (!block || typeof block !== \"object\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((block as { type?: unknown }).type === \"text\" && typeof (block as { text?: unknown }).text === \"string\") {\n\t\t\tparts.push((block as { text: string }).text);\n\t\t}\n\t}\n\treturn (parts.length === 1 ? parts[0] : parts.join(\" \")).trim();\n}\n\nfunction assistantToolCallTarget(name: string, rawArgs: unknown): string | undefined {\n\tif (!rawArgs || typeof rawArgs !== \"object\") {\n\t\treturn undefined;\n\t}\n\tconst args = rawArgs as Record<string, unknown>;\n\n\tif (\n\t\t(name === \"read\" || name === \"grep\" || name === \"find\" || name === \"write\" || name === \"edit\") &&\n\t\ttypeof args.path === \"string\" &&\n\t\targs.path.length > 0\n\t) {\n\t\treturn args.path;\n\t}\n\n\tif (name === \"bash\" && typeof args.command === \"string\" && args.command.length > 0) {\n\t\treturn args.command;\n\t}\n\n\treturn undefined;\n}\n\nfunction clampText(text: string, maxLen: number): string {\n\treturn text.length > maxLen ? text.slice(0, maxLen) : text;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction normalizeDelegatedWorkerText(text: string, maxLen: number): string {\n\tlet normalized = \"\";\n\tfor (const match of text.matchAll(/\\S+/g)) {\n\t\tconst separator = normalized.length > 0 ? \" \" : \"\";\n\t\tconst remaining = maxLen - normalized.length - separator.length;\n\t\tif (remaining <= 0) break;\n\t\tnormalized += `${separator}${match[0].slice(0, remaining)}`;\n\t\tif (match[0].length >= remaining) break;\n\t}\n\treturn normalized;\n}\n\nfunction extractDelegatedWorkerFact(entry: SessionEntry): CompactionDelegatedWorkerFact | undefined {\n\tif (entry.type !== \"custom\" || entry.customType !== \"worker_result\" || !isPlainRecord(entry.data)) {\n\t\treturn undefined;\n\t}\n\tif (entry.data.version !== 1 || !isPlainRecord(entry.data.result)) return undefined;\n\n\tconst result = entry.data.result;\n\tif (typeof result.requestId !== \"string\" || typeof result.summary !== \"string\") return undefined;\n\tif (typeof result.status !== \"string\" || ![\"completed\", \"blocked\", \"failed\", \"cancelled\"].includes(result.status)) {\n\t\treturn undefined;\n\t}\n\tif (!Array.isArray(result.changedFiles) || !result.changedFiles.every((file) => typeof file === \"string\")) {\n\t\treturn undefined;\n\t}\n\n\tconst request = entry.data.request;\n\tconst instructions =\n\t\tisPlainRecord(request) && typeof request.instructions === \"string\" ? request.instructions : undefined;\n\tconst task = normalizeDelegatedWorkerText(\n\t\tinstructions ?? `Worker request ${result.requestId}`,\n\t\tDELEGATED_WORKER_TASK_MAX_CHARS,\n\t);\n\tconst summary = normalizeDelegatedWorkerText(result.summary, DELEGATED_WORKER_SUMMARY_MAX_CHARS);\n\n\treturn {\n\t\ttrust: \"UNTRUSTED\",\n\t\ttask: task || \"(empty task)\",\n\t\tsummary: summary || \"(empty summary)\",\n\t};\n}\n\nfunction extractDelegatedWorkerFacts(\n\tentries: readonly SessionEntry[],\n\tstart: number,\n\tend: number,\n): CompactionDelegatedWorkerFact[] {\n\tconst facts: CompactionDelegatedWorkerFact[] = [];\n\tfor (let i = end - 1; i >= start && facts.length < MAX_DELEGATED_WORKER_FACTS; i--) {\n\t\tconst fact = extractDelegatedWorkerFact(entries[i]);\n\t\tif (fact) facts.push(fact);\n\t}\n\treturn facts;\n}\n\nfunction appearsCreated(message: AgentMessage): boolean {\n\tif (message.role !== \"toolResult\") {\n\t\treturn false;\n\t}\n\n\tconst text = messageToText(message).toLowerCase();\n\tif (/(\\bnew file\\b|\\bcreated\\b|\\bcreated file\\b)/.test(text)) {\n\t\treturn true;\n\t}\n\n\tconst details = (message as { details?: unknown }).details;\n\tif (!details || typeof details !== \"object\") {\n\t\treturn false;\n\t}\n\n\tif (typeof (details as { created?: unknown }).created === \"boolean\") {\n\t\treturn (details as { created: boolean }).created;\n\t}\n\tif (typeof (details as { isCreated?: unknown }).isCreated === \"boolean\") {\n\t\treturn (details as { isCreated: boolean }).isCreated;\n\t}\n\tif (typeof (details as { isNewFile?: unknown }).isNewFile === \"boolean\") {\n\t\treturn (details as { isNewFile: boolean }).isNewFile;\n\t}\n\n\treturn false;\n}\n\nfunction splitSentenceLines(text: string): string[] {\n\treturn text\n\t\t.split(/(?<=[.!?])\\s+|\\n+/)\n\t\t.map((line) => line.trim().replace(/[.!?]+$/, \"\"))\n\t\t.filter(Boolean);\n}\n\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn entry.message;\n\t\tcase \"custom_message\":\n\t\t\treturn {\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: entry.customType,\n\t\t\t\tcontent: entry.content,\n\t\t\t\tdetails: entry.details,\n\t\t\t\tdisplay: entry.display,\n\t\t\t\ttimestamp: new Date(entry.timestamp).getTime(),\n\t\t\t};\n\t\tcase \"branch_summary\":\n\t\t\treturn {\n\t\t\t\trole: \"branchSummary\",\n\t\t\t\tsummary: entry.summary,\n\t\t\t\tfromId: entry.fromId,\n\t\t\t\ttimestamp: new Date(entry.timestamp).getTime(),\n\t\t\t};\n\t\tcase \"compaction\":\n\t\t\treturn undefined;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction isToolCallBlock(block: unknown): block is { type: \"toolCall\"; id?: string; name: string; arguments: unknown } {\n\tif (!block || typeof block !== \"object\") {\n\t\treturn false;\n\t}\n\tif ((block as { type?: unknown }).type !== \"toolCall\") {\n\t\treturn false;\n\t}\n\tif (typeof (block as { name?: unknown }).name !== \"string\") {\n\t\treturn false;\n\t}\n\tif (!(block as { arguments?: unknown }).arguments) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction toolCallVerb(name: string): string {\n\treturn TOOL_VERB_BY_NAME[name] ?? name.toUpperCase();\n}\n\nfunction isHarnessPlumbingTarget(target: string | undefined): boolean {\n\tif (!target) return false;\n\treturn (\n\t\ttarget.includes(\"/.pi/agent/context-gc/\") ||\n\t\ttarget.includes(\"~/.pi/agent/context-gc/\") ||\n\t\t/\\/tmp\\/pi-bash-[^\\s]+\\.log\\b/.test(target)\n\t);\n}\n\nfunction normalizeOperationTarget(toolName: string, path: string | undefined): string {\n\tif (!path) return \"(unknown)\";\n\tif (toolName !== \"bash\") return path;\n\treturn clampText(path.replace(/\\s+/g, \" \").trim(), COMMAND_PREFIX_MAX_CHARS);\n}\n\nfunction operationKey(toolName: string, path: string | undefined): string {\n\treturn `${toolName}:${normalizeOperationTarget(toolName, path)}`;\n}\n\nfunction operationLabel(toolName: string, path: string | undefined): string {\n\treturn `${toolCallVerb(toolName)} ${normalizeOperationTarget(toolName, path)}`;\n}\n\nfunction resultExitCode(message: AgentMessage): number | undefined {\n\tconst details = (message as { details?: unknown }).details;\n\tif (!details || typeof details !== \"object\") return undefined;\n\tconst raw = (details as { exitCode?: unknown }).exitCode;\n\tif (typeof raw === \"number\" && Number.isFinite(raw)) return raw;\n\tif (typeof raw === \"string\" && /^\\d+$/.test(raw)) return Number(raw);\n\treturn undefined;\n}\n\nfunction isOutcomeBearingTool(toolName: string | undefined): boolean {\n\treturn toolName === \"bash\";\n}\n\nfunction isOpenProblemTool(toolName: string | undefined): boolean {\n\treturn toolName === \"bash\" || toolName === \"edit\" || toolName === \"write\";\n}\n\nfunction failureSignalLine(text: string): string | undefined {\n\treturn text\n\t\t.split(/\\r?\\n/)\n\t\t.map((part) => part.trim())\n\t\t.find((line) => /exited with code [1-9]\\d*/i.test(line) || /^(error|fatal|✗|FAIL)\\b/i.test(line));\n}\n\nfunction firstErrorLine(text: string): string {\n\tconst line =\n\t\tfailureSignalLine(text) ??\n\t\ttext\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.map((part) => part.trim())\n\t\t\t.find(Boolean);\n\treturn clampText(line ?? \"failed\", ERROR_LINE_MAX_CHARS);\n}\n\nfunction isFailureToolResult(message: AgentMessage, text: string): boolean {\n\tif (message.role !== \"toolResult\") return false;\n\tif ((message as { isError?: unknown }).isError === true) return true;\n\tconst exitCode = resultExitCode(message);\n\tif (exitCode !== undefined) return exitCode !== 0;\n\tconst toolName = (message as { toolName?: unknown }).toolName;\n\treturn typeof toolName === \"string\" && isOutcomeBearingTool(toolName) && failureSignalLine(text) !== undefined;\n}\n\nexport function extractCompactionFacts(entries: SessionEntry[], start: number, end: number): CompactionFacts {\n\tconst rangeStart = Math.max(0, start);\n\tconst rangeEnd = Math.min(entries.length, Math.max(rangeStart, end));\n\n\tif (rangeStart >= rangeEnd) {\n\t\treturn {\n\t\t\tfiles: [],\n\t\t\tworkingSet: [],\n\t\t\tactions: [],\n\t\t\terrorFacts: [],\n\t\t\tprohibitions: [],\n\t\t\tcancelledText: \"\",\n\t\t\tactiveTaskSource: \"\",\n\t\t\tdelegatedWorkerFacts: [],\n\t\t};\n\t}\n\tconst delegatedWorkerFacts = extractDelegatedWorkerFacts(entries, rangeStart, rangeEnd);\n\n\tconst filesByPath = new Map<string, CompactionFileFact & { lastTouch: number }>();\n\tconst filesNotes = new Map<string, string>();\n\tconst seenProhibitions = new Set<string>();\n\tconst actionFacts: ToolCallFact[] = [];\n\tconst pendingById = new Map<string, number[]>();\n\tconst pendingByOrder: number[] = [];\n\n\tconst actions: string[] = [];\n\tconst openErrors = new Map<string, CompactionErrorFact & { lastTouch: number }>();\n\tconst prohibitions: string[] = [];\n\tlet activeTaskSource = \"\";\n\tconst cancelledParts: string[] = [];\n\tconst sinceLastUser: string[] = [];\n\n\tfor (let i = rangeStart; i < rangeEnd; i++) {\n\t\tconst message = getMessageFromEntry(entries[i]);\n\t\tif (!message) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (message.role === \"user\") {\n\t\t\tconst userText = messageToText(message);\n\t\t\tif (REVERSAL_PATTERN.test(userText)) {\n\t\t\t\tcancelledParts.push(...sinceLastUser);\n\t\t\t}\n\t\t\tsinceLastUser.length = 0;\n\n\t\t\tif (userText) {\n\t\t\t\tactiveTaskSource = clampText(userText, ACTIVE_TASK_SOURCE_MAX_CHARS);\n\t\t\t\t// Mandatory Rules exist for SPOKEN durable prohibitions (\"do not touch X\"), not for\n\t\t\t\t// documents. A long pasted text (plan, instruction file) can contain dozens of\n\t\t\t\t// \"never/do not\" lines; harvesting them makes the verification gate demand the\n\t\t\t\t// checkpoint reproduce the document (2026-07-06 field incident: 13 fragment rules\n\t\t\t\t// extracted from one pasted instruction). Documents live on disk; skip them here.\n\t\t\t\tif (userText.length <= PROHIBITION_SOURCE_MAX_CHARS) {\n\t\t\t\t\tfor (const sentence of splitSentenceLines(userText)) {\n\t\t\t\t\t\tif (!PROHIBITION_PATTERN.test(sentence)) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst normalized = clampText(sentence, 160);\n\t\t\t\t\t\tconst dedupeKey = normalized.toLowerCase();\n\t\t\t\t\t\tif (!seenProhibitions.has(dedupeKey)) {\n\t\t\t\t\t\t\tseenProhibitions.add(dedupeKey);\n\t\t\t\t\t\t\tprohibitions.push(normalized);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (message.role === \"assistant\" || message.role === \"toolResult\") {\n\t\t\tconst messageText = messageToText(message);\n\t\t\tif (messageText) {\n\t\t\t\tsinceLastUser.push(messageText);\n\t\t\t}\n\t\t}\n\n\t\tif (message.role === \"assistant\" && Array.isArray(message.content)) {\n\t\t\tfor (const block of message.content) {\n\t\t\t\tif (!isToolCallBlock(block)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst name = block.name;\n\t\t\t\tconst verb = toolCallVerb(name);\n\t\t\t\tconst path = assistantToolCallTarget(name, block.arguments);\n\t\t\t\tconst baseKind = TOOL_KIND_BY_NAME[name] ?? null;\n\t\t\t\tconst fact: ToolCallFact = {\n\t\t\t\t\tid: block.id,\n\t\t\t\t\tname,\n\t\t\t\t\tpath,\n\t\t\t\t\tbaseKind,\n\t\t\t\t\tfinalKind: baseKind,\n\t\t\t\t\tverb,\n\t\t\t\t\tresolved: false,\n\t\t\t\t\tfailed: false,\n\t\t\t\t};\n\t\t\t\tactionFacts.push(fact);\n\t\t\t\tconst index = actionFacts.length - 1;\n\t\t\t\tpendingByOrder.push(index);\n\t\t\t\tif (fact.id) {\n\t\t\t\t\tconst bucket = pendingById.get(fact.id) ?? [];\n\t\t\t\t\tbucket.push(index);\n\t\t\t\t\tpendingById.set(fact.id, bucket);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (message.role === \"toolResult\") {\n\t\t\tconst toolCallId = (message as { toolCallId?: string }).toolCallId;\n\t\t\tconst toolName = (message as { toolName?: string }).toolName;\n\t\t\tlet matchedIndex: number | undefined;\n\n\t\t\tif (toolCallId) {\n\t\t\t\tconst bucket = pendingById.get(toolCallId);\n\t\t\t\tif (bucket && bucket.length > 0) {\n\t\t\t\t\tmatchedIndex = bucket.shift();\n\t\t\t\t\tif (bucket.length === 0) {\n\t\t\t\t\t\tpendingById.delete(toolCallId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchedIndex === undefined && toolName) {\n\t\t\t\tfor (const index of pendingByOrder) {\n\t\t\t\t\tconst candidate = actionFacts[index];\n\t\t\t\t\tif (!candidate.resolved && candidate.name === toolName) {\n\t\t\t\t\t\tmatchedIndex = index;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchedIndex !== undefined) {\n\t\t\t\tconst fact = actionFacts[matchedIndex];\n\t\t\t\tconst resultText = messageToText(message);\n\t\t\t\tconst failed = isFailureToolResult(message, resultText);\n\t\t\t\tfact.resolved = true;\n\t\t\t\tfact.failed = failed;\n\t\t\t\tif (!failed && fact.baseKind === \"modified\" && appearsCreated(message)) {\n\t\t\t\t\tfact.finalKind = \"created\";\n\t\t\t\t}\n\n\t\t\t\tif (!failed && fact.path && fact.finalKind && !isHarnessPlumbingTarget(fact.path)) {\n\t\t\t\t\tconst existing = filesByPath.get(fact.path);\n\t\t\t\t\tconst nextKind = fact.finalKind;\n\t\t\t\t\tconst note = fact.verb;\n\t\t\t\t\tif (!existing || FILE_KIND_PRIORITY[nextKind] > FILE_KIND_PRIORITY[existing.kind]) {\n\t\t\t\t\t\tfilesByPath.set(fact.path, { path: fact.path, kind: nextKind, note, lastTouch: i });\n\t\t\t\t\t} else if (existing.kind === nextKind) {\n\t\t\t\t\t\texisting.note = note;\n\t\t\t\t\t\texisting.lastTouch = i;\n\t\t\t\t\t} else {\n\t\t\t\t\t\texisting.lastTouch = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst key = operationKey(fact.name, fact.path);\n\t\t\t\tif (failed && isOpenProblemTool(fact.name)) {\n\t\t\t\t\topenErrors.set(key, {\n\t\t\t\t\t\toperation: operationLabel(fact.name, fact.path),\n\t\t\t\t\t\terror: firstErrorLine(resultText),\n\t\t\t\t\t\tlastTouch: i,\n\t\t\t\t\t});\n\t\t\t\t} else if (!failed) {\n\t\t\t\t\topenErrors.delete(key);\n\t\t\t\t}\n\n\t\t\t\tconst pendingPos = pendingByOrder.indexOf(matchedIndex);\n\t\t\t\tif (pendingPos >= 0) {\n\t\t\t\t\tpendingByOrder.splice(pendingPos, 1);\n\t\t\t\t}\n\t\t\t\tif (toolCallId) {\n\t\t\t\t\tconst bucket = pendingById.get(toolCallId);\n\t\t\t\t\tif (bucket) {\n\t\t\t\t\t\tconst pos = bucket.indexOf(matchedIndex);\n\t\t\t\t\t\tif (pos >= 0) {\n\t\t\t\t\t\t\tbucket.splice(pos, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (bucket.length === 0) {\n\t\t\t\t\t\t\tpendingById.delete(toolCallId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const action of actionFacts) {\n\t\tif (isHarnessPlumbingTarget(action.path)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (action.resolved && action.failed && action.name !== \"bash\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif ((!action.resolved || !action.failed) && action.finalKind && action.path && !filesByPath.has(action.path)) {\n\t\t\tfilesByPath.set(action.path, {\n\t\t\t\tpath: action.path,\n\t\t\t\tkind: action.finalKind,\n\t\t\t\tnote: action.verb,\n\t\t\t\tlastTouch: actionFacts.indexOf(action),\n\t\t\t});\n\t\t}\n\n\t\tactions.push(`${action.verb} ${action.path ?? \"(unknown)\"}`);\n\t}\n\n\tfor (const file of filesByPath.values()) {\n\t\tif (!file.note && filesNotes.has(file.path)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (file.note && filesNotes.get(file.path) === file.note) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (file.note) {\n\t\t\tfilesNotes.set(file.path, file.note);\n\t\t}\n\t}\n\n\tfor (const file of filesByPath.values()) {\n\t\tconst suffix = filesNotes.get(file.path);\n\t\tif (suffix) {\n\t\t\tfile.note = suffix;\n\t\t}\n\t}\n\n\tconst files = Array.from(filesByPath.values())\n\t\t.sort(\n\t\t\t(a, b) =>\n\t\t\t\tb.lastTouch - a.lastTouch ||\n\t\t\t\tFILE_KIND_PRIORITY[b.kind] - FILE_KIND_PRIORITY[a.kind] ||\n\t\t\t\ta.path.localeCompare(b.path),\n\t\t)\n\t\t.map(({ lastTouch: _lastTouch, ...file }) => file);\n\n\treturn {\n\t\tfiles,\n\t\tworkingSet: files.slice(0, MAX_WORKING_SET_FILES),\n\t\tactions: dedupeMostRecent(actions).slice(-MAX_ACTIONS),\n\t\terrorFacts: Array.from(openErrors.values())\n\t\t\t.sort((a, b) => a.lastTouch - b.lastTouch)\n\t\t\t.slice(-MAX_ERROR_FACTS)\n\t\t\t.map(({ lastTouch: _lastTouch, ...error }) => error),\n\t\tprohibitions: prohibitions.slice(-MAX_PROHIBITIONS),\n\t\tcancelledText: cancelledParts.join(\"\\n\"),\n\t\tactiveTaskSource,\n\t\tdelegatedWorkerFacts,\n\t};\n}\n\nfunction dedupeMostRecent(values: string[]): string[] {\n\tconst seen = new Set<string>();\n\tconst kept: string[] = [];\n\tfor (let i = values.length - 1; i >= 0; i--) {\n\t\tconst value = values[i];\n\t\tif (seen.has(value)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(value);\n\t\tkept.push(value);\n\t}\n\treturn kept.reverse();\n}\n\nexport function renderFactsBlock(facts: CompactionFacts): string {\n\tconst lines: string[] = [\"verification demands:\"];\n\tlines.push(\"files-modified-recall (must appear in ## Files):\");\n\tfor (const file of facts.files.filter((file) => file.kind !== \"read\")) {\n\t\tlines.push(file.path);\n\t}\n\tlines.push(\"files-read-recall (must appear in ## Files, containment threshold applies):\");\n\tfor (const file of facts.files.filter((file) => file.kind === \"read\")) {\n\t\tlines.push(file.path);\n\t}\n\tlines.push(\"working-set-recall (must appear in ## Working Set):\");\n\tfor (const file of facts.workingSet) {\n\t\tlines.push(`${file.path} — ${file.note || file.kind}`);\n\t}\n\tlines.push(\"open-errors-recall (must appear in ## Open Problems):\");\n\tfor (const error of facts.errorFacts) {\n\t\tlines.push(`${error.operation}: ${error.error}`);\n\t}\n\tlines.push(\"actions-recall (must appear in ## Done):\");\n\tfor (const action of facts.actions) {\n\t\tlines.push(action);\n\t}\n\tlines.push(\"mandatory-rules-recall (must appear in ### Mandatory Rules):\");\n\tfor (const prohibition of facts.prohibitions) {\n\t\tlines.push(prohibition);\n\t}\n\t// The active-task gate demands near-verbatim recall of this text, but the conversation the\n\t// summarizer sees may be pre-digested or truncated — the facts block is the one channel\n\t// guaranteed to reach the prompt, so the gated text must ride in it (bounded).\n\tlines.push(\"active-task-containment (must appear in ## Active Task):\");\n\tif (facts.activeTaskSource) {\n\t\tlines.push(clampText(facts.activeTaskSource, ACTIVE_TASK_SOURCE_MAX_CHARS));\n\t}\n\tlines.push(\"cancelled-work-dropped (must NOT appear outside ### Mandatory Rules):\");\n\tif (facts.cancelledText) {\n\t\tlines.push(facts.cancelledText);\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extraction.js","sourceRoot":"","sources":["../../src/compaction/extraction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry } from \"../session/session-manager.ts\";\nimport type { AgentMessage } from \"../types.ts\";\n\nexport interface CompactionFileFact {\n\tpath: string;\n\tkind: \"modified\" | \"created\" | \"read\";\n\tnote: string;\n}\n\nexport interface CompactionErrorFact {\n\toperation: string;\n\terror: string;\n}\n\nexport interface CompactionDelegatedWorkerFact {\n\t/** Worker-authored text is evidence for the parent, never a verified decision or completion claim. */\n\ttrust: \"UNTRUSTED\";\n\ttask: string;\n\tsummary: string;\n}\n\nexport interface CompactionFacts {\n\tfiles: CompactionFileFact[];\n\tworkingSet: CompactionFileFact[];\n\tactions: string[];\n\terrorFacts: CompactionErrorFact[];\n\tprohibitions: string[];\n\tcancelledText: string;\n\tactiveTaskSource: string;\n\t/** Latest-first worker evidence retained only by deterministic checkpoints. */\n\tdelegatedWorkerFacts?: CompactionDelegatedWorkerFact[];\n}\n\ninterface ToolCallFact {\n\tid: string | undefined;\n\tname: string;\n\tpath: string | undefined;\n\tbaseKind: \"modified\" | \"created\" | \"read\" | null;\n\tfinalKind: \"modified\" | \"created\" | \"read\" | null;\n\tverb: string;\n\tresolved: boolean;\n\tfailed: boolean;\n}\n\nconst PROHIBITION_PATTERN = /\\b(do not|don't|never|stop (?:doing|using|changing)|no more)\\b/i;\n// Deliberately narrow: a bare \"stop\" (\"stop the server and rerun\") is everyday phrasing, not a\n// reversal of the prior work — matching it marked whole turns cancelled and made the\n// cancelled-work gate fight the recall gates (2026-07-06 incident).\nconst REVERSAL_PATTERN =\n\t/\\b(undo|revert|roll back|never mind|scrap that|forget (?:it|that)|stop (?:that|this|it|everything|working on))\\b/i;\n\n/** User messages longer than this are documents/pastes, not spoken prohibitions. */\nconst PROHIBITION_SOURCE_MAX_CHARS = 1_500;\n/** Upper bound on gate-demanded rules; most recent win (same bounding rationale as Done carry-over). */\nconst MAX_PROHIBITIONS = 8;\n/** Upper bound on gate-demanded actions; mirrors the prompt's \"15 most recent Done items\" rule. */\nconst MAX_ACTIONS = 15;\nconst MAX_WORKING_SET_FILES = 8;\nconst MAX_ERROR_FACTS = 5;\nconst ERROR_LINE_MAX_CHARS = 160;\nconst COMMAND_PREFIX_MAX_CHARS = 80;\nconst MAX_DELEGATED_WORKER_FACTS = 4;\nconst DELEGATED_WORKER_TASK_MAX_CHARS = 240;\nconst DELEGATED_WORKER_SUMMARY_MAX_CHARS = 600;\n/** Shared clamp for the active-task text because verification can only demand what the prompt receives. */\nexport const ACTIVE_TASK_SOURCE_MAX_CHARS = 4_000;\n\nconst FILE_KIND_PRIORITY: Record<NonNullable<ToolCallFact[\"finalKind\"]>, number> = {\n\tread: 1,\n\tcreated: 2,\n\tmodified: 3,\n};\n\nconst TOOL_KIND_BY_NAME: Record<string, \"modified\" | \"created\" | \"read\" | null> = {\n\tread: \"read\",\n\tgrep: \"read\",\n\tfind: \"read\",\n\twrite: \"modified\",\n\tedit: \"modified\",\n\tbash: null,\n};\n\nconst TOOL_VERB_BY_NAME: Record<string, string> = {\n\twrite: \"WRITE\",\n\tedit: \"EDIT\",\n\tbash: \"RUN\",\n\tread: \"READ\",\n\tgrep: \"READ\",\n\tfind: \"READ\",\n};\n\nfunction messageToText(message: AgentMessage): string {\n\tconst rawContent = (message as { content?: unknown }).content;\n\tif (typeof rawContent === \"string\") {\n\t\treturn rawContent;\n\t}\n\tif (!Array.isArray(rawContent)) {\n\t\treturn \"\";\n\t}\n\n\tconst parts: string[] = [];\n\tfor (const block of rawContent) {\n\t\tif (!block || typeof block !== \"object\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((block as { type?: unknown }).type === \"text\" && typeof (block as { text?: unknown }).text === \"string\") {\n\t\t\tparts.push((block as { text: string }).text);\n\t\t}\n\t}\n\treturn (parts.length === 1 ? parts[0] : parts.join(\" \")).trim();\n}\n\nfunction assistantToolCallTarget(name: string, rawArgs: unknown): string | undefined {\n\tif (!rawArgs || typeof rawArgs !== \"object\") {\n\t\treturn undefined;\n\t}\n\tconst args = rawArgs as Record<string, unknown>;\n\n\tif (\n\t\t(name === \"read\" || name === \"grep\" || name === \"find\" || name === \"write\" || name === \"edit\") &&\n\t\ttypeof args.path === \"string\" &&\n\t\targs.path.length > 0\n\t) {\n\t\treturn args.path;\n\t}\n\n\tif (name === \"bash\" && typeof args.command === \"string\" && args.command.length > 0) {\n\t\treturn args.command;\n\t}\n\n\treturn undefined;\n}\n\nfunction clampText(text: string, maxLen: number): string {\n\treturn text.length > maxLen ? text.slice(0, maxLen) : text;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction normalizeDelegatedWorkerText(text: string, maxLen: number): string {\n\tlet normalized = \"\";\n\tfor (const match of text.matchAll(/\\S+/g)) {\n\t\tconst separator = normalized.length > 0 ? \" \" : \"\";\n\t\tconst remaining = maxLen - normalized.length - separator.length;\n\t\tif (remaining <= 0) break;\n\t\tnormalized += `${separator}${match[0].slice(0, remaining)}`;\n\t\tif (match[0].length >= remaining) break;\n\t}\n\treturn normalized;\n}\n\nfunction extractDelegatedWorkerFact(entry: SessionEntry): CompactionDelegatedWorkerFact | undefined {\n\tif (entry.type !== \"custom\" || entry.customType !== \"worker_result\" || !isPlainRecord(entry.data)) {\n\t\treturn undefined;\n\t}\n\tif (entry.data.version !== 1 || !isPlainRecord(entry.data.result)) return undefined;\n\n\tconst result = entry.data.result;\n\tif (typeof result.requestId !== \"string\" || typeof result.summary !== \"string\") return undefined;\n\tif (typeof result.status !== \"string\" || ![\"completed\", \"blocked\", \"failed\", \"cancelled\"].includes(result.status)) {\n\t\treturn undefined;\n\t}\n\tif (!Array.isArray(result.changedFiles) || !result.changedFiles.every((file) => typeof file === \"string\")) {\n\t\treturn undefined;\n\t}\n\n\tconst request = entry.data.request;\n\tconst instructions =\n\t\tisPlainRecord(request) && typeof request.instructions === \"string\" ? request.instructions : undefined;\n\tconst task = normalizeDelegatedWorkerText(\n\t\tinstructions ?? `Worker request ${result.requestId}`,\n\t\tDELEGATED_WORKER_TASK_MAX_CHARS,\n\t);\n\tconst summary = normalizeDelegatedWorkerText(result.summary, DELEGATED_WORKER_SUMMARY_MAX_CHARS);\n\n\treturn {\n\t\ttrust: \"UNTRUSTED\",\n\t\ttask: task || \"(empty task)\",\n\t\tsummary: summary || \"(empty summary)\",\n\t};\n}\n\nfunction extractDelegatedWorkerFacts(\n\tentries: readonly SessionEntry[],\n\tstart: number,\n\tend: number,\n): CompactionDelegatedWorkerFact[] {\n\tconst facts: CompactionDelegatedWorkerFact[] = [];\n\tfor (let i = end - 1; i >= start && facts.length < MAX_DELEGATED_WORKER_FACTS; i--) {\n\t\tconst fact = extractDelegatedWorkerFact(entries[i]);\n\t\tif (fact) facts.push(fact);\n\t}\n\treturn facts;\n}\n\nfunction appearsCreated(message: AgentMessage): boolean {\n\tif (message.role !== \"toolResult\") {\n\t\treturn false;\n\t}\n\n\tconst text = messageToText(message).toLowerCase();\n\tif (/(\\bnew file\\b|\\bcreated\\b|\\bcreated file\\b)/.test(text)) {\n\t\treturn true;\n\t}\n\n\tconst details = (message as { details?: unknown }).details;\n\tif (!details || typeof details !== \"object\") {\n\t\treturn false;\n\t}\n\n\tif (typeof (details as { created?: unknown }).created === \"boolean\") {\n\t\treturn (details as { created: boolean }).created;\n\t}\n\tif (typeof (details as { isCreated?: unknown }).isCreated === \"boolean\") {\n\t\treturn (details as { isCreated: boolean }).isCreated;\n\t}\n\tif (typeof (details as { isNewFile?: unknown }).isNewFile === \"boolean\") {\n\t\treturn (details as { isNewFile: boolean }).isNewFile;\n\t}\n\n\treturn false;\n}\n\nfunction splitSentenceLines(text: string): string[] {\n\treturn text\n\t\t.split(/(?<=[.!?])\\s+|\\n+/)\n\t\t.map((line) => line.trim().replace(/[.!?]+$/, \"\"))\n\t\t.filter(Boolean);\n}\n\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn entry.message;\n\t\tcase \"custom_message\":\n\t\t\treturn {\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: entry.customType,\n\t\t\t\tcontent: entry.content,\n\t\t\t\tdetails: entry.details,\n\t\t\t\tdisplay: entry.display,\n\t\t\t\ttimestamp: new Date(entry.timestamp).getTime(),\n\t\t\t};\n\t\tcase \"branch_summary\":\n\t\t\treturn {\n\t\t\t\trole: \"branchSummary\",\n\t\t\t\tsummary: entry.summary,\n\t\t\t\tfromId: entry.fromId,\n\t\t\t\ttimestamp: new Date(entry.timestamp).getTime(),\n\t\t\t};\n\t\tcase \"compaction\":\n\t\t\treturn undefined;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction isToolCallBlock(block: unknown): block is { type: \"toolCall\"; id?: string; name: string; arguments: unknown } {\n\tif (!block || typeof block !== \"object\") {\n\t\treturn false;\n\t}\n\tif ((block as { type?: unknown }).type !== \"toolCall\") {\n\t\treturn false;\n\t}\n\tif (typeof (block as { name?: unknown }).name !== \"string\") {\n\t\treturn false;\n\t}\n\tif (!(block as { arguments?: unknown }).arguments) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction toolCallVerb(name: string): string {\n\treturn TOOL_VERB_BY_NAME[name] ?? name.toUpperCase();\n}\n\nfunction isHarnessPlumbingTarget(target: string | undefined): boolean {\n\tif (!target) return false;\n\treturn (\n\t\ttarget.includes(\"/.pi/agent/context-gc/\") ||\n\t\ttarget.includes(\"~/.pi/agent/context-gc/\") ||\n\t\t/\\/tmp\\/pi-bash-[^\\s]+\\.log\\b/.test(target)\n\t);\n}\n\nfunction normalizeOperationTarget(toolName: string, path: string | undefined): string {\n\tif (!path) return \"(unknown)\";\n\tif (toolName !== \"bash\") return path;\n\treturn clampText(path.replace(/\\s+/g, \" \").trim(), COMMAND_PREFIX_MAX_CHARS);\n}\n\nfunction operationKey(toolName: string, path: string | undefined): string {\n\treturn `${toolName}:${normalizeOperationTarget(toolName, path)}`;\n}\n\nfunction operationLabel(toolName: string, path: string | undefined): string {\n\treturn `${toolCallVerb(toolName)} ${normalizeOperationTarget(toolName, path)}`;\n}\n\nfunction resultExitCode(message: AgentMessage): number | undefined {\n\tconst details = (message as { details?: unknown }).details;\n\tif (!details || typeof details !== \"object\") return undefined;\n\tconst raw = (details as { exitCode?: unknown }).exitCode;\n\tif (typeof raw === \"number\" && Number.isFinite(raw)) return raw;\n\tif (typeof raw === \"string\" && /^\\d+$/.test(raw)) return Number(raw);\n\treturn undefined;\n}\n\nfunction isOutcomeBearingTool(toolName: string | undefined): boolean {\n\treturn toolName === \"bash\";\n}\n\nfunction isOpenProblemTool(toolName: string | undefined): boolean {\n\treturn toolName === \"bash\" || toolName === \"edit\" || toolName === \"write\";\n}\n\nfunction failureSignalLine(text: string): string | undefined {\n\treturn text\n\t\t.split(/\\r?\\n/)\n\t\t.map((part) => part.trim())\n\t\t.find((line) => /exited with code [1-9]\\d*/i.test(line) || /^(error|fatal|✗|FAIL)\\b/i.test(line));\n}\n\nfunction firstErrorLine(text: string): string {\n\tconst line =\n\t\tfailureSignalLine(text) ??\n\t\ttext\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.map((part) => part.trim())\n\t\t\t.find(Boolean);\n\treturn clampText(line ?? \"failed\", ERROR_LINE_MAX_CHARS);\n}\n\nfunction isFailureToolResult(message: AgentMessage, text: string): boolean {\n\tif (message.role !== \"toolResult\") return false;\n\tif ((message as { isError?: unknown }).isError === true) return true;\n\tconst exitCode = resultExitCode(message);\n\tif (exitCode !== undefined) return exitCode !== 0;\n\tconst toolName = (message as { toolName?: unknown }).toolName;\n\treturn typeof toolName === \"string\" && isOutcomeBearingTool(toolName) && failureSignalLine(text) !== undefined;\n}\n\nexport function extractCompactionFacts(entries: SessionEntry[], start: number, end: number): CompactionFacts {\n\tconst rangeStart = Math.max(0, start);\n\tconst rangeEnd = Math.min(entries.length, Math.max(rangeStart, end));\n\n\tif (rangeStart >= rangeEnd) {\n\t\treturn {\n\t\t\tfiles: [],\n\t\t\tworkingSet: [],\n\t\t\tactions: [],\n\t\t\terrorFacts: [],\n\t\t\tprohibitions: [],\n\t\t\tcancelledText: \"\",\n\t\t\tactiveTaskSource: \"\",\n\t\t\tdelegatedWorkerFacts: [],\n\t\t};\n\t}\n\tconst delegatedWorkerFacts = extractDelegatedWorkerFacts(entries, rangeStart, rangeEnd);\n\n\tconst filesByPath = new Map<string, CompactionFileFact & { lastTouch: number }>();\n\tconst filesNotes = new Map<string, string>();\n\tconst seenProhibitions = new Set<string>();\n\tconst actionFacts: ToolCallFact[] = [];\n\tconst pendingById = new Map<string, number[]>();\n\tconst pendingByOrder: number[] = [];\n\n\tconst actions: string[] = [];\n\tconst openErrors = new Map<string, CompactionErrorFact & { lastTouch: number }>();\n\tconst prohibitions: string[] = [];\n\tlet activeTaskSource = \"\";\n\tconst cancelledParts: string[] = [];\n\tconst sinceLastUser: string[] = [];\n\n\tfor (let i = rangeStart; i < rangeEnd; i++) {\n\t\tconst message = getMessageFromEntry(entries[i]);\n\t\tif (!message) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (message.role === \"user\") {\n\t\t\tconst userText = messageToText(message);\n\t\t\tif (REVERSAL_PATTERN.test(userText)) {\n\t\t\t\tcancelledParts.push(...sinceLastUser);\n\t\t\t}\n\t\t\tsinceLastUser.length = 0;\n\n\t\t\tif (userText) {\n\t\t\t\tactiveTaskSource = clampText(userText, ACTIVE_TASK_SOURCE_MAX_CHARS);\n\t\t\t\t// Mandatory Rules exist for SPOKEN durable prohibitions (\"do not touch X\"), not for\n\t\t\t\t// documents. A long pasted text (plan, instruction file) can contain dozens of\n\t\t\t\t// \"never/do not\" lines; harvesting them makes the verification gate demand the\n\t\t\t\t// checkpoint reproduce the document (2026-07-06 field incident: 13 fragment rules\n\t\t\t\t// extracted from one pasted instruction). Documents live on disk; skip them here.\n\t\t\t\tif (userText.length <= PROHIBITION_SOURCE_MAX_CHARS) {\n\t\t\t\t\tfor (const sentence of splitSentenceLines(userText)) {\n\t\t\t\t\t\tif (!PROHIBITION_PATTERN.test(sentence)) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst normalized = clampText(sentence, 160);\n\t\t\t\t\t\tconst dedupeKey = normalized.toLowerCase();\n\t\t\t\t\t\tif (!seenProhibitions.has(dedupeKey)) {\n\t\t\t\t\t\t\tseenProhibitions.add(dedupeKey);\n\t\t\t\t\t\t\tprohibitions.push(normalized);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (message.role === \"assistant\" || message.role === \"toolResult\") {\n\t\t\tconst messageText = messageToText(message);\n\t\t\tif (messageText) {\n\t\t\t\tsinceLastUser.push(messageText);\n\t\t\t}\n\t\t}\n\n\t\tif (message.role === \"assistant\" && Array.isArray(message.content)) {\n\t\t\tfor (const block of message.content) {\n\t\t\t\tif (!isToolCallBlock(block)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst name = block.name;\n\t\t\t\tconst verb = toolCallVerb(name);\n\t\t\t\tconst path = assistantToolCallTarget(name, block.arguments);\n\t\t\t\tconst baseKind = TOOL_KIND_BY_NAME[name] ?? null;\n\t\t\t\tconst fact: ToolCallFact = {\n\t\t\t\t\tid: block.id,\n\t\t\t\t\tname,\n\t\t\t\t\tpath,\n\t\t\t\t\tbaseKind,\n\t\t\t\t\tfinalKind: baseKind,\n\t\t\t\t\tverb,\n\t\t\t\t\tresolved: false,\n\t\t\t\t\tfailed: false,\n\t\t\t\t};\n\t\t\t\tactionFacts.push(fact);\n\t\t\t\tconst index = actionFacts.length - 1;\n\t\t\t\tpendingByOrder.push(index);\n\t\t\t\tif (fact.id) {\n\t\t\t\t\tconst bucket = pendingById.get(fact.id) ?? [];\n\t\t\t\t\tbucket.push(index);\n\t\t\t\t\tpendingById.set(fact.id, bucket);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (message.role === \"toolResult\") {\n\t\t\tconst toolCallId = (message as { toolCallId?: string }).toolCallId;\n\t\t\tconst toolName = (message as { toolName?: string }).toolName;\n\t\t\tlet matchedIndex: number | undefined;\n\n\t\t\tif (toolCallId) {\n\t\t\t\tconst bucket = pendingById.get(toolCallId);\n\t\t\t\tif (bucket && bucket.length > 0) {\n\t\t\t\t\tmatchedIndex = bucket.shift();\n\t\t\t\t\tif (bucket.length === 0) {\n\t\t\t\t\t\tpendingById.delete(toolCallId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchedIndex === undefined && toolName) {\n\t\t\t\tfor (const index of pendingByOrder) {\n\t\t\t\t\tconst candidate = actionFacts[index];\n\t\t\t\t\tif (!candidate.resolved && candidate.name === toolName) {\n\t\t\t\t\t\tmatchedIndex = index;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (matchedIndex !== undefined) {\n\t\t\t\tconst fact = actionFacts[matchedIndex];\n\t\t\t\tconst resultText = messageToText(message);\n\t\t\t\tconst failed = isFailureToolResult(message, resultText);\n\t\t\t\tfact.resolved = true;\n\t\t\t\tfact.failed = failed;\n\t\t\t\tif (!failed && fact.baseKind === \"modified\" && appearsCreated(message)) {\n\t\t\t\t\tfact.finalKind = \"created\";\n\t\t\t\t}\n\n\t\t\t\tif (!failed && fact.path && fact.finalKind && !isHarnessPlumbingTarget(fact.path)) {\n\t\t\t\t\tconst existing = filesByPath.get(fact.path);\n\t\t\t\t\tconst nextKind = fact.finalKind;\n\t\t\t\t\tconst note = fact.verb;\n\t\t\t\t\tif (!existing || FILE_KIND_PRIORITY[nextKind] > FILE_KIND_PRIORITY[existing.kind]) {\n\t\t\t\t\t\tfilesByPath.set(fact.path, { path: fact.path, kind: nextKind, note, lastTouch: i });\n\t\t\t\t\t} else if (existing.kind === nextKind) {\n\t\t\t\t\t\texisting.note = note;\n\t\t\t\t\t\texisting.lastTouch = i;\n\t\t\t\t\t} else {\n\t\t\t\t\t\texisting.lastTouch = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst key = operationKey(fact.name, fact.path);\n\t\t\t\tif (failed && isOpenProblemTool(fact.name)) {\n\t\t\t\t\topenErrors.set(key, {\n\t\t\t\t\t\toperation: operationLabel(fact.name, fact.path),\n\t\t\t\t\t\terror: firstErrorLine(resultText),\n\t\t\t\t\t\tlastTouch: i,\n\t\t\t\t\t});\n\t\t\t\t} else if (!failed) {\n\t\t\t\t\topenErrors.delete(key);\n\t\t\t\t}\n\n\t\t\t\tconst pendingPos = pendingByOrder.indexOf(matchedIndex);\n\t\t\t\tif (pendingPos >= 0) {\n\t\t\t\t\tpendingByOrder.splice(pendingPos, 1);\n\t\t\t\t}\n\t\t\t\tif (toolCallId) {\n\t\t\t\t\tconst bucket = pendingById.get(toolCallId);\n\t\t\t\t\tif (bucket) {\n\t\t\t\t\t\tconst pos = bucket.indexOf(matchedIndex);\n\t\t\t\t\t\tif (pos >= 0) {\n\t\t\t\t\t\t\tbucket.splice(pos, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (bucket.length === 0) {\n\t\t\t\t\t\t\tpendingById.delete(toolCallId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const action of actionFacts) {\n\t\tif (isHarnessPlumbingTarget(action.path)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (action.resolved && action.failed && action.name !== \"bash\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif ((!action.resolved || !action.failed) && action.finalKind && action.path && !filesByPath.has(action.path)) {\n\t\t\tfilesByPath.set(action.path, {\n\t\t\t\tpath: action.path,\n\t\t\t\tkind: action.finalKind,\n\t\t\t\tnote: action.verb,\n\t\t\t\tlastTouch: actionFacts.indexOf(action),\n\t\t\t});\n\t\t}\n\n\t\tactions.push(`${action.verb} ${action.path ?? \"(unknown)\"}`);\n\t}\n\n\tfor (const file of filesByPath.values()) {\n\t\tif (!file.note && filesNotes.has(file.path)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (file.note && filesNotes.get(file.path) === file.note) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (file.note) {\n\t\t\tfilesNotes.set(file.path, file.note);\n\t\t}\n\t}\n\n\tfor (const file of filesByPath.values()) {\n\t\tconst suffix = filesNotes.get(file.path);\n\t\tif (suffix) {\n\t\t\tfile.note = suffix;\n\t\t}\n\t}\n\n\tconst files = Array.from(filesByPath.values())\n\t\t.sort(\n\t\t\t(a, b) =>\n\t\t\t\tb.lastTouch - a.lastTouch ||\n\t\t\t\tFILE_KIND_PRIORITY[b.kind] - FILE_KIND_PRIORITY[a.kind] ||\n\t\t\t\ta.path.localeCompare(b.path),\n\t\t)\n\t\t.map(({ lastTouch: _lastTouch, ...file }) => file);\n\n\treturn {\n\t\tfiles,\n\t\tworkingSet: files.slice(0, MAX_WORKING_SET_FILES),\n\t\tactions: dedupeMostRecent(actions).slice(-MAX_ACTIONS),\n\t\terrorFacts: Array.from(openErrors.values())\n\t\t\t.sort((a, b) => a.lastTouch - b.lastTouch)\n\t\t\t.slice(-MAX_ERROR_FACTS)\n\t\t\t.map(({ lastTouch: _lastTouch, ...error }) => error),\n\t\tprohibitions: prohibitions.slice(-MAX_PROHIBITIONS),\n\t\tcancelledText: cancelledParts.join(\"\\n\"),\n\t\tactiveTaskSource,\n\t\tdelegatedWorkerFacts,\n\t};\n}\n\nfunction dedupeMostRecent(values: string[]): string[] {\n\tconst seen = new Set<string>();\n\tconst kept: string[] = [];\n\tfor (let i = values.length - 1; i >= 0; i--) {\n\t\tconst value = values[i];\n\t\tif (seen.has(value)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(value);\n\t\tkept.push(value);\n\t}\n\treturn kept.reverse();\n}\n\nexport function renderFactsBlock(facts: CompactionFacts): string {\n\tconst lines: string[] = [\"verification demands:\"];\n\tlines.push(\"files-modified-recall (must appear in ## Files):\");\n\tfor (const file of facts.files.filter((file) => file.kind !== \"read\")) {\n\t\tlines.push(file.path);\n\t}\n\tlines.push(\"files-read-recall (must appear as exact paths in ## Files, path recall threshold applies):\");\n\tfor (const file of facts.files.filter((file) => file.kind === \"read\")) {\n\t\tlines.push(file.path);\n\t}\n\tlines.push(\"working-set-recall (must appear in ## Working Set):\");\n\tfor (const file of facts.workingSet) {\n\t\tlines.push(`${file.path} — ${file.note || file.kind}`);\n\t}\n\tlines.push(\"open-errors-recall (must appear in ## Open Problems):\");\n\tfor (const error of facts.errorFacts) {\n\t\tlines.push(`${error.operation}: ${error.error}`);\n\t}\n\tlines.push(\"actions-recall (must appear in ## Done):\");\n\tfor (const action of facts.actions) {\n\t\tlines.push(action);\n\t}\n\tlines.push(\"mandatory-rules-recall (must appear in ### Mandatory Rules):\");\n\tfor (const prohibition of facts.prohibitions) {\n\t\tlines.push(prohibition);\n\t}\n\t// The active-task gate demands near-verbatim recall of this text, but the conversation the\n\t// summarizer sees may be pre-digested or truncated — the facts block is the one channel\n\t// guaranteed to reach the prompt, so the gated text must ride in it (bounded).\n\tlines.push(\"active-task-containment (must appear in ## Active Task):\");\n\tif (facts.activeTaskSource) {\n\t\tlines.push(clampText(facts.activeTaskSource, ACTIVE_TASK_SOURCE_MAX_CHARS));\n\t}\n\tlines.push(\"cancelled-work-dropped (must NOT appear outside ### Mandatory Rules):\");\n\tif (facts.cancelledText) {\n\t\tlines.push(facts.cancelledText);\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Model } from "@caupulican/pi-ai";
|
|
2
2
|
import type { SessionEntry } from "../session/session-manager.ts";
|
|
3
|
-
import type
|
|
3
|
+
import { type CompactionResult } from "./compaction.ts";
|
|
4
4
|
export interface CompactionCycleParams {
|
|
5
5
|
modelTier: "cheap" | "session";
|
|
6
6
|
keepRecentTokens: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/compaction/loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAC5B,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kBAAkB,IAAI,MAAM,CAAC;IAC7B,SAAS,IAAI,YAAY,EAAE,CAAC;IAC5B,mBAAmB,CAAC,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1F,kBAAkB,CACjB,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,MAAM,EAAE,YAAY,EAAE,GACpB,OAAO,CAAC;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;IACzC,4BAA4B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,GAAG;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACrG,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtD,YAAY,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1F,uBAAuB,CAAC,IAAI,MAAM,CAAC;IACnC,qBAAqB,CAAC,IAAI,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMtD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6IhG","sourcesContent":["import type { Model } from \"@caupulican/pi-ai\";\nimport type { SessionEntry } from \"../session/session-manager.ts\";\nimport type { CompactionResult } from \"./compaction.ts\";\n\nexport interface CompactionCycleParams {\n\tmodelTier: \"cheap\" | \"session\";\n\tkeepRecentTokens: number;\n\tchunked: boolean;\n\tdeterministicOnly: boolean;\n}\n\nexport interface ModelAndAuth {\n\tmodel: Model<any>;\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tfailure?: string;\n}\n\nexport interface CompactionLoopDeps {\n\tmeasureLiveTokens(): number;\n\tshouldCompact(tokens: number): boolean;\n\tgetPostApplyMargin(): number;\n\tgetBranch(): SessionEntry[];\n\tresolveModelAndAuth(modelTier: CompactionCycleParams[\"modelTier\"]): Promise<ModelAndAuth>;\n\tsummarizeAndVerify(\n\t\tparams: CompactionCycleParams,\n\t\tmodel: Model<any>,\n\t\tapiKey: string | undefined,\n\t\theaders: Record<string, string> | undefined,\n\t\tbranch: SessionEntry[],\n\t): Promise<{ result: CompactionResult }>;\n\tbuildDeterministicCheckpoint(): Promise<{ result: CompactionResult }> | { result: CompactionResult };\n\tapply(result: CompactionResult): Promise<void> | void;\n\tonTransition(info: { cycle: number; from: string; cause: string; detail?: string }): void;\n\tgetBaseKeepRecentTokens?(): number;\n\tverifyPostApplyEffect?(): boolean;\n\tsignal?: AbortSignal;\n}\n\nexport type CompactionLoopOutcome =\n\t| { kind: \"success\"; result: CompactionResult; cycles: number }\n\t| { kind: \"skip\"; reason: string }\n\t| { kind: \"failed\"; reason: string; cycles: number };\n\nconst MAX_CYCLES = 4;\nconst MAX_LLM_CYCLES = 3;\nconst DEFAULT_KEEP_RECENT = 20_000;\n\nexport async function runCompactionLoop(deps: CompactionLoopDeps): Promise<CompactionLoopOutcome> {\n\tlet lastCause = \"start\";\n\tlet lastParams: CompactionCycleParams | undefined;\n\tlet lastObservedTokens: number | undefined;\n\tlet appliedResult: CompactionResult | undefined;\n\tlet lastModelKey: string | undefined;\n\tlet ownTrailingCompactionId: string | undefined;\n\tlet ownTrailingCompactionNeedsRetry = false;\n\tlet baseKeepRecent = deps.getBaseKeepRecentTokens ? deps.getBaseKeepRecentTokens() : DEFAULT_KEEP_RECENT;\n\tif (!Number.isFinite(baseKeepRecent) || baseKeepRecent <= 0) {\n\t\tbaseKeepRecent = DEFAULT_KEEP_RECENT;\n\t}\n\n\tfor (let cycle = 1; cycle <= MAX_CYCLES; cycle++) {\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t}\n\n\t\tconst branch = deps.getBranch();\n\t\tconst trailingEntry = branch[branch.length - 1];\n\t\tif (branch.length > 0 && trailingEntry?.type === \"compaction\") {\n\t\t\tif (appliedResult && trailingEntry.id === ownTrailingCompactionId) {\n\t\t\t\tif (!ownTrailingCompactionNeedsRetry) return { kind: \"success\", result: appliedResult, cycles: cycle - 1 };\n\t\t\t} else {\n\t\t\t\treturn { kind: \"skip\", reason: \"already compacted\" };\n\t\t\t}\n\t\t}\n\n\t\tconst observedTokens = deps.measureLiveTokens();\n\t\tif (cycle === 1 && !deps.shouldCompact(observedTokens)) {\n\t\t\treturn {\n\t\t\t\tkind: \"skip\",\n\t\t\t\treason:\n\t\t\t\t\tbranch.length > 0 && branch[branch.length - 1]?.type === \"compaction\"\n\t\t\t\t\t\t? \"already compacted\"\n\t\t\t\t\t\t: \"within threshold\",\n\t\t\t};\n\t\t}\n\n\t\tconst selectedParams = selectCycleParams(cycle, lastCause, lastParams, baseKeepRecent);\n\t\tlet params = enforceMonotonicProgress(selectedParams, lastParams, observedTokens, lastObservedTokens, lastCause);\n\t\tlastObservedTokens = observedTokens;\n\n\t\tif (params.deterministicOnly || cycle > MAX_LLM_CYCLES) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { result } = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\tawait deps.apply(result);\n\t\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t\t} catch (error) {\n\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(error).cause, cycles: cycle };\n\t\t\t}\n\t\t}\n\n\t\tlet modelInfo: ModelAndAuth;\n\t\ttry {\n\t\t\tmodelInfo = await deps.resolveModelAndAuth(params.modelTier);\n\t\t} catch {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tif (modelInfo.failure) {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tconst currentModelKey = modelKey(modelInfo.model);\n\t\tif (\n\t\t\t(lastCause === \"gate-failed\" || lastCause === \"length-stop\") &&\n\t\t\tlastParams &&\n\t\t\tparams.modelTier !== lastParams.modelTier &&\n\t\t\tlastModelKey === currentModelKey\n\t\t) {\n\t\t\tparams = { ...params, modelTier: lastParams.modelTier };\n\t\t}\n\t\tlastParams = params;\n\t\tlastModelKey = currentModelKey;\n\n\t\tlet result: CompactionResult;\n\t\ttry {\n\t\t\t({ result } = await deps.summarizeAndVerify(\n\t\t\t\tparams,\n\t\t\t\tmodelInfo.model,\n\t\t\t\tmodelInfo.apiKey,\n\t\t\t\tmodelInfo.headers,\n\t\t\t\tbranch,\n\t\t\t));\n\t\t} catch (error) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t\t}\n\t\t\tconst failure = mapFailureCause(error);\n\t\t\tlastCause = failure.cause;\n\t\t\tif (lastCause === \"aborted\") {\n\t\t\t\treturn { kind: \"failed\", reason: lastCause, cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"provider-failure\") {\n\t\t\t\treturn { kind: \"failed\", reason: error instanceof Error ? error.message : String(error), cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"deterministic-required\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { result: deterministicResult } = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\t\tawait deps.apply(deterministicResult);\n\t\t\t\t\treturn { kind: \"success\", result: deterministicResult, cycles: cycle };\n\t\t\t\t} catch (deterministicError) {\n\t\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(deterministicError).cause, cycles: cycle };\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step3\", cause: lastCause, detail: failure.detail });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t}\n\t\tawait deps.apply(result);\n\t\tappliedResult = result;\n\t\tconst branchAfterApply = deps.getBranch();\n\t\tconst trailingAfterApply = branchAfterApply[branchAfterApply.length - 1];\n\t\townTrailingCompactionId = trailingAfterApply?.type === \"compaction\" ? trailingAfterApply.id : undefined;\n\n\t\tif (deps.verifyPostApplyEffect?.() === false) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\tconst measuredAfter = deps.measureLiveTokens();\n\t\tif (!deps.shouldCompact(measuredAfter + deps.getPostApplyMargin())) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\townTrailingCompactionNeedsRetry = true;\n\t\tlastCause = \"effect-not-restored\";\n\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step5\", cause: lastCause });\n\t}\n\n\treturn { kind: \"failed\", reason: \"exhausted-compaction-cycles\", cycles: MAX_CYCLES };\n}\n\nfunction selectCycleParams(\n\tcycle: number,\n\tcause: string,\n\tlastParams: CompactionCycleParams | undefined,\n\tbaseKeepRecent: number,\n): CompactionCycleParams {\n\tif (cycle >= MAX_CYCLES) {\n\t\treturn {\n\t\t\tmodelTier: lastParams?.modelTier ?? \"session\",\n\t\t\tkeepRecentTokens: Math.max(1, Math.floor((lastParams?.keepRecentTokens ?? baseKeepRecent) / 2)),\n\t\t\tchunked: true,\n\t\t\tdeterministicOnly: true,\n\t\t};\n\t}\n\n\tif (!lastParams) {\n\t\treturn {\n\t\t\tmodelTier: \"cheap\",\n\t\t\tkeepRecentTokens: Math.max(1, baseKeepRecent),\n\t\t\tchunked: false,\n\t\t\tdeterministicOnly: false,\n\t\t};\n\t}\n\n\tconst params: CompactionCycleParams = {\n\t\t...lastParams,\n\t\tdeterministicOnly: false,\n\t};\n\n\tif (cause === \"gate-failed\" || cause === \"auth-failed\" || cause === \"length-stop\") {\n\t\tparams.modelTier = \"session\";\n\t} else if (cause === \"input-overflow\") {\n\t\tparams.chunked = true;\n\t} else if (cause === \"effect-not-restored\") {\n\t\tparams.chunked = true;\n\t\tparams.keepRecentTokens = Math.max(1, Math.floor(lastParams.keepRecentTokens / 2));\n\t}\n\n\treturn params;\n}\n\nfunction enforceMonotonicProgress(\n\tparams: CompactionCycleParams,\n\tlastParams: CompactionCycleParams | undefined,\n\tobservedTokens: number,\n\tlastObservedTokens: number | undefined,\n\tlastCause: string,\n): CompactionCycleParams {\n\tif (\n\t\t!lastParams ||\n\t\tparams.deterministicOnly ||\n\t\t(lastObservedTokens !== undefined && observedTokens < lastObservedTokens)\n\t) {\n\t\treturn params;\n\t}\n\tif (!sameParams(params, lastParams)) {\n\t\treturn params;\n\t}\n\tif (lastCause === \"gate-failed\") {\n\t\treturn params;\n\t}\n\n\tconst keepRecentTokens = Math.max(1, Math.floor(params.keepRecentTokens / 2));\n\tif (keepRecentTokens !== params.keepRecentTokens) {\n\t\treturn { ...params, chunked: true, keepRecentTokens };\n\t}\n\tif (!params.chunked) {\n\t\treturn { ...params, chunked: true };\n\t}\n\treturn { ...params, modelTier: params.modelTier === \"cheap\" ? \"session\" : \"cheap\" };\n}\n\nfunction modelKey(model: Model<any>): string {\n\treturn `${model.provider}:${model.id}:${model.api}:${model.baseUrl ?? \"\"}`;\n}\n\nfunction sameParams(a: CompactionCycleParams, b: CompactionCycleParams): boolean {\n\treturn (\n\t\ta.modelTier === b.modelTier &&\n\t\ta.keepRecentTokens === b.keepRecentTokens &&\n\t\ta.chunked === b.chunked &&\n\t\ta.deterministicOnly === b.deterministicOnly\n\t);\n}\n\nfunction mapFailureCause(error: unknown): { cause: string; detail?: string } {\n\tconst message = error instanceof Error ? error.message : typeof error === \"string\" ? error : \"\";\n\tif (message.includes(\"gate-failed\")) return { cause: \"gate-failed\", detail: boundedDetail(message) };\n\tif (message.includes(\"summary-demand-exceeds-reserve\"))\n\t\treturn { cause: \"deterministic-required\", detail: boundedDetail(message) };\n\tif (message.includes(\"input-overflow\")) return { cause: \"input-overflow\", detail: boundedDetail(message) };\n\t// A length-stopped summary lost gated sections; escalating the tier buys a larger output cap.\n\tif (message.includes(\"summary-length-stop\")) return { cause: \"length-stop\", detail: boundedDetail(message) };\n\tif (\n\t\t/stream stalled|overloaded|rate.?limit|too many requests|service.?unavailable|server.?error|network.?error|fetch failed|timeout|timed out/i.test(\n\t\t\tmessage,\n\t\t)\n\t)\n\t\treturn { cause: \"provider-failure\", detail: boundedDetail(message) };\n\tif (message.includes(\"auto-compaction-cancelled\")) return { cause: \"aborted\", detail: boundedDetail(message) };\n\tif (message.includes(\"auth\") || message.includes(\"api key\") || message.includes(\"not compacted\"))\n\t\treturn { cause: \"auth-failed\", detail: boundedDetail(message) };\n\treturn { cause: \"unknown-failure\", detail: boundedDetail(message) };\n}\n\nfunction boundedDetail(message: string): string | undefined {\n\tif (!message) return undefined;\n\treturn message.length > 500 ? `${message.slice(0, 500)}…` : message;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/compaction/loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,KAAK,gBAAgB,EAAsC,MAAM,iBAAiB,CAAC;AAG5F,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAC5B,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kBAAkB,IAAI,MAAM,CAAC;IAC7B,SAAS,IAAI,YAAY,EAAE,CAAC;IAC5B,mBAAmB,CAAC,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1F,kBAAkB,CACjB,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,MAAM,EAAE,YAAY,EAAE,GACpB,OAAO,CAAC;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;IACzC,4BAA4B,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,GAAG;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACrG,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtD,YAAY,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1F,uBAAuB,CAAC,IAAI,MAAM,CAAC;IACnC,qBAAqB,CAAC,IAAI,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMtD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAuJhG","sourcesContent":["import type { Model } from \"@caupulican/pi-ai\";\nimport { classifyFailure } from \"../reliability/classifier.ts\";\nimport type { SessionEntry } from \"../session/session-manager.ts\";\nimport { type CompactionResult, mergeCompactionVerificationReports } from \"./compaction.ts\";\nimport { CompactionVerificationError, type VerificationReport } from \"./verification.ts\";\n\nexport interface CompactionCycleParams {\n\tmodelTier: \"cheap\" | \"session\";\n\tkeepRecentTokens: number;\n\tchunked: boolean;\n\tdeterministicOnly: boolean;\n}\n\nexport interface ModelAndAuth {\n\tmodel: Model<any>;\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tfailure?: string;\n}\n\nexport interface CompactionLoopDeps {\n\tmeasureLiveTokens(): number;\n\tshouldCompact(tokens: number): boolean;\n\tgetPostApplyMargin(): number;\n\tgetBranch(): SessionEntry[];\n\tresolveModelAndAuth(modelTier: CompactionCycleParams[\"modelTier\"]): Promise<ModelAndAuth>;\n\tsummarizeAndVerify(\n\t\tparams: CompactionCycleParams,\n\t\tmodel: Model<any>,\n\t\tapiKey: string | undefined,\n\t\theaders: Record<string, string> | undefined,\n\t\tbranch: SessionEntry[],\n\t): Promise<{ result: CompactionResult }>;\n\tbuildDeterministicCheckpoint(): Promise<{ result: CompactionResult }> | { result: CompactionResult };\n\tapply(result: CompactionResult): Promise<void> | void;\n\tonTransition(info: { cycle: number; from: string; cause: string; detail?: string }): void;\n\tgetBaseKeepRecentTokens?(): number;\n\tverifyPostApplyEffect?(): boolean;\n\tsignal?: AbortSignal;\n}\n\nexport type CompactionLoopOutcome =\n\t| { kind: \"success\"; result: CompactionResult; cycles: number }\n\t| { kind: \"skip\"; reason: string }\n\t| { kind: \"failed\"; reason: string; cycles: number };\n\nconst MAX_CYCLES = 4;\nconst MAX_LLM_CYCLES = 3;\nconst DEFAULT_KEEP_RECENT = 20_000;\n\nexport async function runCompactionLoop(deps: CompactionLoopDeps): Promise<CompactionLoopOutcome> {\n\tlet lastCause = \"start\";\n\tlet lastParams: CompactionCycleParams | undefined;\n\tlet lastObservedTokens: number | undefined;\n\tlet appliedResult: CompactionResult | undefined;\n\tlet lastModelKey: string | undefined;\n\tlet ownTrailingCompactionId: string | undefined;\n\tlet ownTrailingCompactionNeedsRetry = false;\n\tconst pendingVerificationReports: VerificationReport[] = [];\n\tlet baseKeepRecent = deps.getBaseKeepRecentTokens ? deps.getBaseKeepRecentTokens() : DEFAULT_KEEP_RECENT;\n\tif (!Number.isFinite(baseKeepRecent) || baseKeepRecent <= 0) {\n\t\tbaseKeepRecent = DEFAULT_KEEP_RECENT;\n\t}\n\n\tfor (let cycle = 1; cycle <= MAX_CYCLES; cycle++) {\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t}\n\n\t\tconst branch = deps.getBranch();\n\t\tconst trailingEntry = branch[branch.length - 1];\n\t\tif (branch.length > 0 && trailingEntry?.type === \"compaction\") {\n\t\t\tif (appliedResult && trailingEntry.id === ownTrailingCompactionId) {\n\t\t\t\tif (!ownTrailingCompactionNeedsRetry) return { kind: \"success\", result: appliedResult, cycles: cycle - 1 };\n\t\t\t} else {\n\t\t\t\treturn { kind: \"skip\", reason: \"already compacted\" };\n\t\t\t}\n\t\t}\n\n\t\tconst observedTokens = deps.measureLiveTokens();\n\t\tif (cycle === 1 && !deps.shouldCompact(observedTokens)) {\n\t\t\treturn {\n\t\t\t\tkind: \"skip\",\n\t\t\t\treason:\n\t\t\t\t\tbranch.length > 0 && branch[branch.length - 1]?.type === \"compaction\"\n\t\t\t\t\t\t? \"already compacted\"\n\t\t\t\t\t\t: \"within threshold\",\n\t\t\t};\n\t\t}\n\n\t\tconst selectedParams = selectCycleParams(cycle, lastCause, lastParams, baseKeepRecent);\n\t\tlet params = enforceMonotonicProgress(selectedParams, lastParams, observedTokens, lastObservedTokens, lastCause);\n\t\tlastObservedTokens = observedTokens;\n\n\t\tif (params.deterministicOnly || cycle > MAX_LLM_CYCLES) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst built = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\tconst result = mergeCompactionVerificationReports(built.result, pendingVerificationReports);\n\t\t\t\tpendingVerificationReports.length = 0;\n\t\t\t\tawait deps.apply(result);\n\t\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t\t} catch (error) {\n\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(error).cause, cycles: cycle };\n\t\t\t}\n\t\t}\n\n\t\tlet modelInfo: ModelAndAuth;\n\t\ttry {\n\t\t\tmodelInfo = await deps.resolveModelAndAuth(params.modelTier);\n\t\t} catch {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tif (modelInfo.failure) {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tconst currentModelKey = modelKey(modelInfo.model);\n\t\tif (\n\t\t\t(lastCause === \"gate-failed\" || lastCause === \"length-stop\") &&\n\t\t\tlastParams &&\n\t\t\tparams.modelTier !== lastParams.modelTier &&\n\t\t\tlastModelKey === currentModelKey\n\t\t) {\n\t\t\tparams = { ...params, modelTier: lastParams.modelTier };\n\t\t}\n\t\tlastParams = params;\n\t\tlastModelKey = currentModelKey;\n\n\t\tlet result: CompactionResult;\n\t\ttry {\n\t\t\t({ result } = await deps.summarizeAndVerify(\n\t\t\t\tparams,\n\t\t\t\tmodelInfo.model,\n\t\t\t\tmodelInfo.apiKey,\n\t\t\t\tmodelInfo.headers,\n\t\t\t\tbranch,\n\t\t\t));\n\t\t} catch (error) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t\t}\n\t\t\tif (error instanceof CompactionVerificationError) {\n\t\t\t\tpendingVerificationReports.push(...error.reports);\n\t\t\t}\n\t\t\tconst failure = mapFailureCause(error, modelInfo.model.provider);\n\t\t\tlastCause = failure.cause;\n\t\t\tif (lastCause === \"aborted\") {\n\t\t\t\treturn { kind: \"failed\", reason: lastCause, cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"provider-failure\") {\n\t\t\t\treturn { kind: \"failed\", reason: error instanceof Error ? error.message : String(error), cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"deterministic-required\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst built = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\t\tconst deterministicResult = mergeCompactionVerificationReports(built.result, pendingVerificationReports);\n\t\t\t\t\tpendingVerificationReports.length = 0;\n\t\t\t\t\tawait deps.apply(deterministicResult);\n\t\t\t\t\treturn { kind: \"success\", result: deterministicResult, cycles: cycle };\n\t\t\t\t} catch (deterministicError) {\n\t\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(deterministicError).cause, cycles: cycle };\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step3\", cause: lastCause, detail: failure.detail });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t}\n\t\tmergeCompactionVerificationReports(result, pendingVerificationReports);\n\t\tpendingVerificationReports.length = 0;\n\t\tawait deps.apply(result);\n\t\tappliedResult = result;\n\t\tconst branchAfterApply = deps.getBranch();\n\t\tconst trailingAfterApply = branchAfterApply[branchAfterApply.length - 1];\n\t\townTrailingCompactionId = trailingAfterApply?.type === \"compaction\" ? trailingAfterApply.id : undefined;\n\n\t\tif (deps.verifyPostApplyEffect?.() === false) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\tconst measuredAfter = deps.measureLiveTokens();\n\t\tif (!deps.shouldCompact(measuredAfter + deps.getPostApplyMargin())) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\townTrailingCompactionNeedsRetry = true;\n\t\tlastCause = \"effect-not-restored\";\n\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step5\", cause: lastCause });\n\t}\n\n\treturn { kind: \"failed\", reason: \"exhausted-compaction-cycles\", cycles: MAX_CYCLES };\n}\n\nfunction selectCycleParams(\n\tcycle: number,\n\tcause: string,\n\tlastParams: CompactionCycleParams | undefined,\n\tbaseKeepRecent: number,\n): CompactionCycleParams {\n\tif (cycle >= MAX_CYCLES) {\n\t\treturn {\n\t\t\tmodelTier: lastParams?.modelTier ?? \"session\",\n\t\t\tkeepRecentTokens: Math.max(1, Math.floor((lastParams?.keepRecentTokens ?? baseKeepRecent) / 2)),\n\t\t\tchunked: true,\n\t\t\tdeterministicOnly: true,\n\t\t};\n\t}\n\n\tif (!lastParams) {\n\t\treturn {\n\t\t\tmodelTier: \"cheap\",\n\t\t\tkeepRecentTokens: Math.max(1, baseKeepRecent),\n\t\t\tchunked: false,\n\t\t\tdeterministicOnly: false,\n\t\t};\n\t}\n\n\tconst params: CompactionCycleParams = {\n\t\t...lastParams,\n\t\tdeterministicOnly: false,\n\t};\n\n\tif (cause === \"gate-failed\" || cause === \"auth-failed\" || cause === \"length-stop\") {\n\t\tparams.modelTier = \"session\";\n\t} else if (cause === \"input-overflow\") {\n\t\tparams.chunked = true;\n\t} else if (cause === \"effect-not-restored\") {\n\t\tparams.chunked = true;\n\t\tparams.keepRecentTokens = Math.max(1, Math.floor(lastParams.keepRecentTokens / 2));\n\t}\n\n\treturn params;\n}\n\nfunction enforceMonotonicProgress(\n\tparams: CompactionCycleParams,\n\tlastParams: CompactionCycleParams | undefined,\n\tobservedTokens: number,\n\tlastObservedTokens: number | undefined,\n\tlastCause: string,\n): CompactionCycleParams {\n\tif (\n\t\t!lastParams ||\n\t\tparams.deterministicOnly ||\n\t\t(lastObservedTokens !== undefined && observedTokens < lastObservedTokens)\n\t) {\n\t\treturn params;\n\t}\n\tif (!sameParams(params, lastParams)) {\n\t\treturn params;\n\t}\n\tif (lastCause === \"gate-failed\") {\n\t\treturn params;\n\t}\n\n\tconst keepRecentTokens = Math.max(1, Math.floor(params.keepRecentTokens / 2));\n\tif (keepRecentTokens !== params.keepRecentTokens) {\n\t\treturn { ...params, chunked: true, keepRecentTokens };\n\t}\n\tif (!params.chunked) {\n\t\treturn { ...params, chunked: true };\n\t}\n\treturn { ...params, modelTier: params.modelTier === \"cheap\" ? \"session\" : \"cheap\" };\n}\n\nfunction modelKey(model: Model<any>): string {\n\treturn `${model.provider}:${model.id}:${model.api}:${model.baseUrl ?? \"\"}`;\n}\n\nfunction sameParams(a: CompactionCycleParams, b: CompactionCycleParams): boolean {\n\treturn (\n\t\ta.modelTier === b.modelTier &&\n\t\ta.keepRecentTokens === b.keepRecentTokens &&\n\t\ta.chunked === b.chunked &&\n\t\ta.deterministicOnly === b.deterministicOnly\n\t);\n}\n\nfunction mapFailureCause(error: unknown, provider?: string): { cause: string; detail?: string } {\n\tconst message = error instanceof Error ? error.message : typeof error === \"string\" ? error : \"\";\n\tif (message.includes(\"gate-failed\")) return { cause: \"gate-failed\", detail: boundedDetail(message) };\n\tif (message.includes(\"summary-demand-exceeds-reserve\"))\n\t\treturn { cause: \"deterministic-required\", detail: boundedDetail(message) };\n\tif (message.includes(\"input-overflow\")) return { cause: \"input-overflow\", detail: boundedDetail(message) };\n\t// A length-stopped summary lost gated sections; escalating the tier buys a larger output cap.\n\tif (message.includes(\"summary-length-stop\")) return { cause: \"length-stop\", detail: boundedDetail(message) };\n\tif (message.includes(\"auto-compaction-cancelled\")) return { cause: \"aborted\", detail: boundedDetail(message) };\n\tconst classified = classifyFailure({ message, provider });\n\tif (classified.retryable) return { cause: \"provider-failure\", detail: boundedDetail(message) };\n\tif (\n\t\tclassified.reason === \"auth\" ||\n\t\tclassified.reason === \"billing_or_quota\" ||\n\t\tmessage.includes(\"api key\") ||\n\t\tmessage.includes(\"not compacted\")\n\t)\n\t\treturn { cause: \"auth-failed\", detail: boundedDetail(message) };\n\treturn { cause: \"unknown-failure\", detail: boundedDetail(message) };\n}\n\nfunction boundedDetail(message: string): string | undefined {\n\tif (!message) return undefined;\n\treturn message.length > 500 ? `${message.slice(0, 500)}…` : message;\n}\n"]}
|
package/dist/compaction/loop.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { classifyFailure } from "../reliability/classifier.js";
|
|
2
|
+
import { mergeCompactionVerificationReports } from "./compaction.js";
|
|
3
|
+
import { CompactionVerificationError } from "./verification.js";
|
|
1
4
|
const MAX_CYCLES = 4;
|
|
2
5
|
const MAX_LLM_CYCLES = 3;
|
|
3
6
|
const DEFAULT_KEEP_RECENT = 20_000;
|
|
@@ -9,6 +12,7 @@ export async function runCompactionLoop(deps) {
|
|
|
9
12
|
let lastModelKey;
|
|
10
13
|
let ownTrailingCompactionId;
|
|
11
14
|
let ownTrailingCompactionNeedsRetry = false;
|
|
15
|
+
const pendingVerificationReports = [];
|
|
12
16
|
let baseKeepRecent = deps.getBaseKeepRecentTokens ? deps.getBaseKeepRecentTokens() : DEFAULT_KEEP_RECENT;
|
|
13
17
|
if (!Number.isFinite(baseKeepRecent) || baseKeepRecent <= 0) {
|
|
14
18
|
baseKeepRecent = DEFAULT_KEEP_RECENT;
|
|
@@ -45,7 +49,9 @@ export async function runCompactionLoop(deps) {
|
|
|
45
49
|
return { kind: "failed", reason: "aborted", cycles: cycle - 1 };
|
|
46
50
|
}
|
|
47
51
|
try {
|
|
48
|
-
const
|
|
52
|
+
const built = await Promise.resolve(deps.buildDeterministicCheckpoint());
|
|
53
|
+
const result = mergeCompactionVerificationReports(built.result, pendingVerificationReports);
|
|
54
|
+
pendingVerificationReports.length = 0;
|
|
49
55
|
await deps.apply(result);
|
|
50
56
|
return { kind: "success", result, cycles: cycle };
|
|
51
57
|
}
|
|
@@ -84,7 +90,10 @@ export async function runCompactionLoop(deps) {
|
|
|
84
90
|
if (deps.signal?.aborted) {
|
|
85
91
|
return { kind: "failed", reason: "aborted", cycles: cycle };
|
|
86
92
|
}
|
|
87
|
-
|
|
93
|
+
if (error instanceof CompactionVerificationError) {
|
|
94
|
+
pendingVerificationReports.push(...error.reports);
|
|
95
|
+
}
|
|
96
|
+
const failure = mapFailureCause(error, modelInfo.model.provider);
|
|
88
97
|
lastCause = failure.cause;
|
|
89
98
|
if (lastCause === "aborted") {
|
|
90
99
|
return { kind: "failed", reason: lastCause, cycles: cycle };
|
|
@@ -94,7 +103,9 @@ export async function runCompactionLoop(deps) {
|
|
|
94
103
|
}
|
|
95
104
|
if (lastCause === "deterministic-required") {
|
|
96
105
|
try {
|
|
97
|
-
const
|
|
106
|
+
const built = await Promise.resolve(deps.buildDeterministicCheckpoint());
|
|
107
|
+
const deterministicResult = mergeCompactionVerificationReports(built.result, pendingVerificationReports);
|
|
108
|
+
pendingVerificationReports.length = 0;
|
|
98
109
|
await deps.apply(deterministicResult);
|
|
99
110
|
return { kind: "success", result: deterministicResult, cycles: cycle };
|
|
100
111
|
}
|
|
@@ -108,6 +119,8 @@ export async function runCompactionLoop(deps) {
|
|
|
108
119
|
if (deps.signal?.aborted) {
|
|
109
120
|
return { kind: "failed", reason: "aborted", cycles: cycle };
|
|
110
121
|
}
|
|
122
|
+
mergeCompactionVerificationReports(result, pendingVerificationReports);
|
|
123
|
+
pendingVerificationReports.length = 0;
|
|
111
124
|
await deps.apply(result);
|
|
112
125
|
appliedResult = result;
|
|
113
126
|
const branchAfterApply = deps.getBranch();
|
|
@@ -191,7 +204,7 @@ function sameParams(a, b) {
|
|
|
191
204
|
a.chunked === b.chunked &&
|
|
192
205
|
a.deterministicOnly === b.deterministicOnly);
|
|
193
206
|
}
|
|
194
|
-
function mapFailureCause(error) {
|
|
207
|
+
function mapFailureCause(error, provider) {
|
|
195
208
|
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
196
209
|
if (message.includes("gate-failed"))
|
|
197
210
|
return { cause: "gate-failed", detail: boundedDetail(message) };
|
|
@@ -202,11 +215,15 @@ function mapFailureCause(error) {
|
|
|
202
215
|
// A length-stopped summary lost gated sections; escalating the tier buys a larger output cap.
|
|
203
216
|
if (message.includes("summary-length-stop"))
|
|
204
217
|
return { cause: "length-stop", detail: boundedDetail(message) };
|
|
205
|
-
if (/stream stalled|overloaded|rate.?limit|too many requests|service.?unavailable|server.?error|network.?error|fetch failed|timeout|timed out/i.test(message))
|
|
206
|
-
return { cause: "provider-failure", detail: boundedDetail(message) };
|
|
207
218
|
if (message.includes("auto-compaction-cancelled"))
|
|
208
219
|
return { cause: "aborted", detail: boundedDetail(message) };
|
|
209
|
-
|
|
220
|
+
const classified = classifyFailure({ message, provider });
|
|
221
|
+
if (classified.retryable)
|
|
222
|
+
return { cause: "provider-failure", detail: boundedDetail(message) };
|
|
223
|
+
if (classified.reason === "auth" ||
|
|
224
|
+
classified.reason === "billing_or_quota" ||
|
|
225
|
+
message.includes("api key") ||
|
|
226
|
+
message.includes("not compacted"))
|
|
210
227
|
return { cause: "auth-failed", detail: boundedDetail(message) };
|
|
211
228
|
return { cause: "unknown-failure", detail: boundedDetail(message) };
|
|
212
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/compaction/loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Model } from \"@caupulican/pi-ai\";\nimport type { SessionEntry } from \"../session/session-manager.ts\";\nimport type { CompactionResult } from \"./compaction.ts\";\n\nexport interface CompactionCycleParams {\n\tmodelTier: \"cheap\" | \"session\";\n\tkeepRecentTokens: number;\n\tchunked: boolean;\n\tdeterministicOnly: boolean;\n}\n\nexport interface ModelAndAuth {\n\tmodel: Model<any>;\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tfailure?: string;\n}\n\nexport interface CompactionLoopDeps {\n\tmeasureLiveTokens(): number;\n\tshouldCompact(tokens: number): boolean;\n\tgetPostApplyMargin(): number;\n\tgetBranch(): SessionEntry[];\n\tresolveModelAndAuth(modelTier: CompactionCycleParams[\"modelTier\"]): Promise<ModelAndAuth>;\n\tsummarizeAndVerify(\n\t\tparams: CompactionCycleParams,\n\t\tmodel: Model<any>,\n\t\tapiKey: string | undefined,\n\t\theaders: Record<string, string> | undefined,\n\t\tbranch: SessionEntry[],\n\t): Promise<{ result: CompactionResult }>;\n\tbuildDeterministicCheckpoint(): Promise<{ result: CompactionResult }> | { result: CompactionResult };\n\tapply(result: CompactionResult): Promise<void> | void;\n\tonTransition(info: { cycle: number; from: string; cause: string; detail?: string }): void;\n\tgetBaseKeepRecentTokens?(): number;\n\tverifyPostApplyEffect?(): boolean;\n\tsignal?: AbortSignal;\n}\n\nexport type CompactionLoopOutcome =\n\t| { kind: \"success\"; result: CompactionResult; cycles: number }\n\t| { kind: \"skip\"; reason: string }\n\t| { kind: \"failed\"; reason: string; cycles: number };\n\nconst MAX_CYCLES = 4;\nconst MAX_LLM_CYCLES = 3;\nconst DEFAULT_KEEP_RECENT = 20_000;\n\nexport async function runCompactionLoop(deps: CompactionLoopDeps): Promise<CompactionLoopOutcome> {\n\tlet lastCause = \"start\";\n\tlet lastParams: CompactionCycleParams | undefined;\n\tlet lastObservedTokens: number | undefined;\n\tlet appliedResult: CompactionResult | undefined;\n\tlet lastModelKey: string | undefined;\n\tlet ownTrailingCompactionId: string | undefined;\n\tlet ownTrailingCompactionNeedsRetry = false;\n\tlet baseKeepRecent = deps.getBaseKeepRecentTokens ? deps.getBaseKeepRecentTokens() : DEFAULT_KEEP_RECENT;\n\tif (!Number.isFinite(baseKeepRecent) || baseKeepRecent <= 0) {\n\t\tbaseKeepRecent = DEFAULT_KEEP_RECENT;\n\t}\n\n\tfor (let cycle = 1; cycle <= MAX_CYCLES; cycle++) {\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t}\n\n\t\tconst branch = deps.getBranch();\n\t\tconst trailingEntry = branch[branch.length - 1];\n\t\tif (branch.length > 0 && trailingEntry?.type === \"compaction\") {\n\t\t\tif (appliedResult && trailingEntry.id === ownTrailingCompactionId) {\n\t\t\t\tif (!ownTrailingCompactionNeedsRetry) return { kind: \"success\", result: appliedResult, cycles: cycle - 1 };\n\t\t\t} else {\n\t\t\t\treturn { kind: \"skip\", reason: \"already compacted\" };\n\t\t\t}\n\t\t}\n\n\t\tconst observedTokens = deps.measureLiveTokens();\n\t\tif (cycle === 1 && !deps.shouldCompact(observedTokens)) {\n\t\t\treturn {\n\t\t\t\tkind: \"skip\",\n\t\t\t\treason:\n\t\t\t\t\tbranch.length > 0 && branch[branch.length - 1]?.type === \"compaction\"\n\t\t\t\t\t\t? \"already compacted\"\n\t\t\t\t\t\t: \"within threshold\",\n\t\t\t};\n\t\t}\n\n\t\tconst selectedParams = selectCycleParams(cycle, lastCause, lastParams, baseKeepRecent);\n\t\tlet params = enforceMonotonicProgress(selectedParams, lastParams, observedTokens, lastObservedTokens, lastCause);\n\t\tlastObservedTokens = observedTokens;\n\n\t\tif (params.deterministicOnly || cycle > MAX_LLM_CYCLES) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { result } = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\tawait deps.apply(result);\n\t\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t\t} catch (error) {\n\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(error).cause, cycles: cycle };\n\t\t\t}\n\t\t}\n\n\t\tlet modelInfo: ModelAndAuth;\n\t\ttry {\n\t\t\tmodelInfo = await deps.resolveModelAndAuth(params.modelTier);\n\t\t} catch {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tif (modelInfo.failure) {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tconst currentModelKey = modelKey(modelInfo.model);\n\t\tif (\n\t\t\t(lastCause === \"gate-failed\" || lastCause === \"length-stop\") &&\n\t\t\tlastParams &&\n\t\t\tparams.modelTier !== lastParams.modelTier &&\n\t\t\tlastModelKey === currentModelKey\n\t\t) {\n\t\t\tparams = { ...params, modelTier: lastParams.modelTier };\n\t\t}\n\t\tlastParams = params;\n\t\tlastModelKey = currentModelKey;\n\n\t\tlet result: CompactionResult;\n\t\ttry {\n\t\t\t({ result } = await deps.summarizeAndVerify(\n\t\t\t\tparams,\n\t\t\t\tmodelInfo.model,\n\t\t\t\tmodelInfo.apiKey,\n\t\t\t\tmodelInfo.headers,\n\t\t\t\tbranch,\n\t\t\t));\n\t\t} catch (error) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t\t}\n\t\t\tconst failure = mapFailureCause(error);\n\t\t\tlastCause = failure.cause;\n\t\t\tif (lastCause === \"aborted\") {\n\t\t\t\treturn { kind: \"failed\", reason: lastCause, cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"provider-failure\") {\n\t\t\t\treturn { kind: \"failed\", reason: error instanceof Error ? error.message : String(error), cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"deterministic-required\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { result: deterministicResult } = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\t\tawait deps.apply(deterministicResult);\n\t\t\t\t\treturn { kind: \"success\", result: deterministicResult, cycles: cycle };\n\t\t\t\t} catch (deterministicError) {\n\t\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(deterministicError).cause, cycles: cycle };\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step3\", cause: lastCause, detail: failure.detail });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t}\n\t\tawait deps.apply(result);\n\t\tappliedResult = result;\n\t\tconst branchAfterApply = deps.getBranch();\n\t\tconst trailingAfterApply = branchAfterApply[branchAfterApply.length - 1];\n\t\townTrailingCompactionId = trailingAfterApply?.type === \"compaction\" ? trailingAfterApply.id : undefined;\n\n\t\tif (deps.verifyPostApplyEffect?.() === false) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\tconst measuredAfter = deps.measureLiveTokens();\n\t\tif (!deps.shouldCompact(measuredAfter + deps.getPostApplyMargin())) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\townTrailingCompactionNeedsRetry = true;\n\t\tlastCause = \"effect-not-restored\";\n\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step5\", cause: lastCause });\n\t}\n\n\treturn { kind: \"failed\", reason: \"exhausted-compaction-cycles\", cycles: MAX_CYCLES };\n}\n\nfunction selectCycleParams(\n\tcycle: number,\n\tcause: string,\n\tlastParams: CompactionCycleParams | undefined,\n\tbaseKeepRecent: number,\n): CompactionCycleParams {\n\tif (cycle >= MAX_CYCLES) {\n\t\treturn {\n\t\t\tmodelTier: lastParams?.modelTier ?? \"session\",\n\t\t\tkeepRecentTokens: Math.max(1, Math.floor((lastParams?.keepRecentTokens ?? baseKeepRecent) / 2)),\n\t\t\tchunked: true,\n\t\t\tdeterministicOnly: true,\n\t\t};\n\t}\n\n\tif (!lastParams) {\n\t\treturn {\n\t\t\tmodelTier: \"cheap\",\n\t\t\tkeepRecentTokens: Math.max(1, baseKeepRecent),\n\t\t\tchunked: false,\n\t\t\tdeterministicOnly: false,\n\t\t};\n\t}\n\n\tconst params: CompactionCycleParams = {\n\t\t...lastParams,\n\t\tdeterministicOnly: false,\n\t};\n\n\tif (cause === \"gate-failed\" || cause === \"auth-failed\" || cause === \"length-stop\") {\n\t\tparams.modelTier = \"session\";\n\t} else if (cause === \"input-overflow\") {\n\t\tparams.chunked = true;\n\t} else if (cause === \"effect-not-restored\") {\n\t\tparams.chunked = true;\n\t\tparams.keepRecentTokens = Math.max(1, Math.floor(lastParams.keepRecentTokens / 2));\n\t}\n\n\treturn params;\n}\n\nfunction enforceMonotonicProgress(\n\tparams: CompactionCycleParams,\n\tlastParams: CompactionCycleParams | undefined,\n\tobservedTokens: number,\n\tlastObservedTokens: number | undefined,\n\tlastCause: string,\n): CompactionCycleParams {\n\tif (\n\t\t!lastParams ||\n\t\tparams.deterministicOnly ||\n\t\t(lastObservedTokens !== undefined && observedTokens < lastObservedTokens)\n\t) {\n\t\treturn params;\n\t}\n\tif (!sameParams(params, lastParams)) {\n\t\treturn params;\n\t}\n\tif (lastCause === \"gate-failed\") {\n\t\treturn params;\n\t}\n\n\tconst keepRecentTokens = Math.max(1, Math.floor(params.keepRecentTokens / 2));\n\tif (keepRecentTokens !== params.keepRecentTokens) {\n\t\treturn { ...params, chunked: true, keepRecentTokens };\n\t}\n\tif (!params.chunked) {\n\t\treturn { ...params, chunked: true };\n\t}\n\treturn { ...params, modelTier: params.modelTier === \"cheap\" ? \"session\" : \"cheap\" };\n}\n\nfunction modelKey(model: Model<any>): string {\n\treturn `${model.provider}:${model.id}:${model.api}:${model.baseUrl ?? \"\"}`;\n}\n\nfunction sameParams(a: CompactionCycleParams, b: CompactionCycleParams): boolean {\n\treturn (\n\t\ta.modelTier === b.modelTier &&\n\t\ta.keepRecentTokens === b.keepRecentTokens &&\n\t\ta.chunked === b.chunked &&\n\t\ta.deterministicOnly === b.deterministicOnly\n\t);\n}\n\nfunction mapFailureCause(error: unknown): { cause: string; detail?: string } {\n\tconst message = error instanceof Error ? error.message : typeof error === \"string\" ? error : \"\";\n\tif (message.includes(\"gate-failed\")) return { cause: \"gate-failed\", detail: boundedDetail(message) };\n\tif (message.includes(\"summary-demand-exceeds-reserve\"))\n\t\treturn { cause: \"deterministic-required\", detail: boundedDetail(message) };\n\tif (message.includes(\"input-overflow\")) return { cause: \"input-overflow\", detail: boundedDetail(message) };\n\t// A length-stopped summary lost gated sections; escalating the tier buys a larger output cap.\n\tif (message.includes(\"summary-length-stop\")) return { cause: \"length-stop\", detail: boundedDetail(message) };\n\tif (\n\t\t/stream stalled|overloaded|rate.?limit|too many requests|service.?unavailable|server.?error|network.?error|fetch failed|timeout|timed out/i.test(\n\t\t\tmessage,\n\t\t)\n\t)\n\t\treturn { cause: \"provider-failure\", detail: boundedDetail(message) };\n\tif (message.includes(\"auto-compaction-cancelled\")) return { cause: \"aborted\", detail: boundedDetail(message) };\n\tif (message.includes(\"auth\") || message.includes(\"api key\") || message.includes(\"not compacted\"))\n\t\treturn { cause: \"auth-failed\", detail: boundedDetail(message) };\n\treturn { cause: \"unknown-failure\", detail: boundedDetail(message) };\n}\n\nfunction boundedDetail(message: string): string | undefined {\n\tif (!message) return undefined;\n\treturn message.length > 500 ? `${message.slice(0, 500)}…` : message;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/compaction/loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Model } from \"@caupulican/pi-ai\";\nimport { classifyFailure } from \"../reliability/classifier.ts\";\nimport type { SessionEntry } from \"../session/session-manager.ts\";\nimport { type CompactionResult, mergeCompactionVerificationReports } from \"./compaction.ts\";\nimport { CompactionVerificationError, type VerificationReport } from \"./verification.ts\";\n\nexport interface CompactionCycleParams {\n\tmodelTier: \"cheap\" | \"session\";\n\tkeepRecentTokens: number;\n\tchunked: boolean;\n\tdeterministicOnly: boolean;\n}\n\nexport interface ModelAndAuth {\n\tmodel: Model<any>;\n\tapiKey?: string;\n\theaders?: Record<string, string>;\n\tfailure?: string;\n}\n\nexport interface CompactionLoopDeps {\n\tmeasureLiveTokens(): number;\n\tshouldCompact(tokens: number): boolean;\n\tgetPostApplyMargin(): number;\n\tgetBranch(): SessionEntry[];\n\tresolveModelAndAuth(modelTier: CompactionCycleParams[\"modelTier\"]): Promise<ModelAndAuth>;\n\tsummarizeAndVerify(\n\t\tparams: CompactionCycleParams,\n\t\tmodel: Model<any>,\n\t\tapiKey: string | undefined,\n\t\theaders: Record<string, string> | undefined,\n\t\tbranch: SessionEntry[],\n\t): Promise<{ result: CompactionResult }>;\n\tbuildDeterministicCheckpoint(): Promise<{ result: CompactionResult }> | { result: CompactionResult };\n\tapply(result: CompactionResult): Promise<void> | void;\n\tonTransition(info: { cycle: number; from: string; cause: string; detail?: string }): void;\n\tgetBaseKeepRecentTokens?(): number;\n\tverifyPostApplyEffect?(): boolean;\n\tsignal?: AbortSignal;\n}\n\nexport type CompactionLoopOutcome =\n\t| { kind: \"success\"; result: CompactionResult; cycles: number }\n\t| { kind: \"skip\"; reason: string }\n\t| { kind: \"failed\"; reason: string; cycles: number };\n\nconst MAX_CYCLES = 4;\nconst MAX_LLM_CYCLES = 3;\nconst DEFAULT_KEEP_RECENT = 20_000;\n\nexport async function runCompactionLoop(deps: CompactionLoopDeps): Promise<CompactionLoopOutcome> {\n\tlet lastCause = \"start\";\n\tlet lastParams: CompactionCycleParams | undefined;\n\tlet lastObservedTokens: number | undefined;\n\tlet appliedResult: CompactionResult | undefined;\n\tlet lastModelKey: string | undefined;\n\tlet ownTrailingCompactionId: string | undefined;\n\tlet ownTrailingCompactionNeedsRetry = false;\n\tconst pendingVerificationReports: VerificationReport[] = [];\n\tlet baseKeepRecent = deps.getBaseKeepRecentTokens ? deps.getBaseKeepRecentTokens() : DEFAULT_KEEP_RECENT;\n\tif (!Number.isFinite(baseKeepRecent) || baseKeepRecent <= 0) {\n\t\tbaseKeepRecent = DEFAULT_KEEP_RECENT;\n\t}\n\n\tfor (let cycle = 1; cycle <= MAX_CYCLES; cycle++) {\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t}\n\n\t\tconst branch = deps.getBranch();\n\t\tconst trailingEntry = branch[branch.length - 1];\n\t\tif (branch.length > 0 && trailingEntry?.type === \"compaction\") {\n\t\t\tif (appliedResult && trailingEntry.id === ownTrailingCompactionId) {\n\t\t\t\tif (!ownTrailingCompactionNeedsRetry) return { kind: \"success\", result: appliedResult, cycles: cycle - 1 };\n\t\t\t} else {\n\t\t\t\treturn { kind: \"skip\", reason: \"already compacted\" };\n\t\t\t}\n\t\t}\n\n\t\tconst observedTokens = deps.measureLiveTokens();\n\t\tif (cycle === 1 && !deps.shouldCompact(observedTokens)) {\n\t\t\treturn {\n\t\t\t\tkind: \"skip\",\n\t\t\t\treason:\n\t\t\t\t\tbranch.length > 0 && branch[branch.length - 1]?.type === \"compaction\"\n\t\t\t\t\t\t? \"already compacted\"\n\t\t\t\t\t\t: \"within threshold\",\n\t\t\t};\n\t\t}\n\n\t\tconst selectedParams = selectCycleParams(cycle, lastCause, lastParams, baseKeepRecent);\n\t\tlet params = enforceMonotonicProgress(selectedParams, lastParams, observedTokens, lastObservedTokens, lastCause);\n\t\tlastObservedTokens = observedTokens;\n\n\t\tif (params.deterministicOnly || cycle > MAX_LLM_CYCLES) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle - 1 };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst built = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\tconst result = mergeCompactionVerificationReports(built.result, pendingVerificationReports);\n\t\t\t\tpendingVerificationReports.length = 0;\n\t\t\t\tawait deps.apply(result);\n\t\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t\t} catch (error) {\n\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(error).cause, cycles: cycle };\n\t\t\t}\n\t\t}\n\n\t\tlet modelInfo: ModelAndAuth;\n\t\ttry {\n\t\t\tmodelInfo = await deps.resolveModelAndAuth(params.modelTier);\n\t\t} catch {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tif (modelInfo.failure) {\n\t\t\tlastCause = \"auth-failed\";\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step0\", cause: lastCause });\n\t\t\tcontinue;\n\t\t}\n\t\tconst currentModelKey = modelKey(modelInfo.model);\n\t\tif (\n\t\t\t(lastCause === \"gate-failed\" || lastCause === \"length-stop\") &&\n\t\t\tlastParams &&\n\t\t\tparams.modelTier !== lastParams.modelTier &&\n\t\t\tlastModelKey === currentModelKey\n\t\t) {\n\t\t\tparams = { ...params, modelTier: lastParams.modelTier };\n\t\t}\n\t\tlastParams = params;\n\t\tlastModelKey = currentModelKey;\n\n\t\tlet result: CompactionResult;\n\t\ttry {\n\t\t\t({ result } = await deps.summarizeAndVerify(\n\t\t\t\tparams,\n\t\t\t\tmodelInfo.model,\n\t\t\t\tmodelInfo.apiKey,\n\t\t\t\tmodelInfo.headers,\n\t\t\t\tbranch,\n\t\t\t));\n\t\t} catch (error) {\n\t\t\tif (deps.signal?.aborted) {\n\t\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t\t}\n\t\t\tif (error instanceof CompactionVerificationError) {\n\t\t\t\tpendingVerificationReports.push(...error.reports);\n\t\t\t}\n\t\t\tconst failure = mapFailureCause(error, modelInfo.model.provider);\n\t\t\tlastCause = failure.cause;\n\t\t\tif (lastCause === \"aborted\") {\n\t\t\t\treturn { kind: \"failed\", reason: lastCause, cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"provider-failure\") {\n\t\t\t\treturn { kind: \"failed\", reason: error instanceof Error ? error.message : String(error), cycles: cycle };\n\t\t\t}\n\t\t\tif (lastCause === \"deterministic-required\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst built = await Promise.resolve(deps.buildDeterministicCheckpoint());\n\t\t\t\t\tconst deterministicResult = mergeCompactionVerificationReports(built.result, pendingVerificationReports);\n\t\t\t\t\tpendingVerificationReports.length = 0;\n\t\t\t\t\tawait deps.apply(deterministicResult);\n\t\t\t\t\treturn { kind: \"success\", result: deterministicResult, cycles: cycle };\n\t\t\t\t} catch (deterministicError) {\n\t\t\t\t\treturn { kind: \"failed\", reason: mapFailureCause(deterministicError).cause, cycles: cycle };\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step3\", cause: lastCause, detail: failure.detail });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (deps.signal?.aborted) {\n\t\t\treturn { kind: \"failed\", reason: \"aborted\", cycles: cycle };\n\t\t}\n\t\tmergeCompactionVerificationReports(result, pendingVerificationReports);\n\t\tpendingVerificationReports.length = 0;\n\t\tawait deps.apply(result);\n\t\tappliedResult = result;\n\t\tconst branchAfterApply = deps.getBranch();\n\t\tconst trailingAfterApply = branchAfterApply[branchAfterApply.length - 1];\n\t\townTrailingCompactionId = trailingAfterApply?.type === \"compaction\" ? trailingAfterApply.id : undefined;\n\n\t\tif (deps.verifyPostApplyEffect?.() === false) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\tconst measuredAfter = deps.measureLiveTokens();\n\t\tif (!deps.shouldCompact(measuredAfter + deps.getPostApplyMargin())) {\n\t\t\townTrailingCompactionNeedsRetry = false;\n\t\t\treturn { kind: \"success\", result, cycles: cycle };\n\t\t}\n\n\t\townTrailingCompactionNeedsRetry = true;\n\t\tlastCause = \"effect-not-restored\";\n\t\tdeps.onTransition({ cycle: cycle + 1, from: \"step5\", cause: lastCause });\n\t}\n\n\treturn { kind: \"failed\", reason: \"exhausted-compaction-cycles\", cycles: MAX_CYCLES };\n}\n\nfunction selectCycleParams(\n\tcycle: number,\n\tcause: string,\n\tlastParams: CompactionCycleParams | undefined,\n\tbaseKeepRecent: number,\n): CompactionCycleParams {\n\tif (cycle >= MAX_CYCLES) {\n\t\treturn {\n\t\t\tmodelTier: lastParams?.modelTier ?? \"session\",\n\t\t\tkeepRecentTokens: Math.max(1, Math.floor((lastParams?.keepRecentTokens ?? baseKeepRecent) / 2)),\n\t\t\tchunked: true,\n\t\t\tdeterministicOnly: true,\n\t\t};\n\t}\n\n\tif (!lastParams) {\n\t\treturn {\n\t\t\tmodelTier: \"cheap\",\n\t\t\tkeepRecentTokens: Math.max(1, baseKeepRecent),\n\t\t\tchunked: false,\n\t\t\tdeterministicOnly: false,\n\t\t};\n\t}\n\n\tconst params: CompactionCycleParams = {\n\t\t...lastParams,\n\t\tdeterministicOnly: false,\n\t};\n\n\tif (cause === \"gate-failed\" || cause === \"auth-failed\" || cause === \"length-stop\") {\n\t\tparams.modelTier = \"session\";\n\t} else if (cause === \"input-overflow\") {\n\t\tparams.chunked = true;\n\t} else if (cause === \"effect-not-restored\") {\n\t\tparams.chunked = true;\n\t\tparams.keepRecentTokens = Math.max(1, Math.floor(lastParams.keepRecentTokens / 2));\n\t}\n\n\treturn params;\n}\n\nfunction enforceMonotonicProgress(\n\tparams: CompactionCycleParams,\n\tlastParams: CompactionCycleParams | undefined,\n\tobservedTokens: number,\n\tlastObservedTokens: number | undefined,\n\tlastCause: string,\n): CompactionCycleParams {\n\tif (\n\t\t!lastParams ||\n\t\tparams.deterministicOnly ||\n\t\t(lastObservedTokens !== undefined && observedTokens < lastObservedTokens)\n\t) {\n\t\treturn params;\n\t}\n\tif (!sameParams(params, lastParams)) {\n\t\treturn params;\n\t}\n\tif (lastCause === \"gate-failed\") {\n\t\treturn params;\n\t}\n\n\tconst keepRecentTokens = Math.max(1, Math.floor(params.keepRecentTokens / 2));\n\tif (keepRecentTokens !== params.keepRecentTokens) {\n\t\treturn { ...params, chunked: true, keepRecentTokens };\n\t}\n\tif (!params.chunked) {\n\t\treturn { ...params, chunked: true };\n\t}\n\treturn { ...params, modelTier: params.modelTier === \"cheap\" ? \"session\" : \"cheap\" };\n}\n\nfunction modelKey(model: Model<any>): string {\n\treturn `${model.provider}:${model.id}:${model.api}:${model.baseUrl ?? \"\"}`;\n}\n\nfunction sameParams(a: CompactionCycleParams, b: CompactionCycleParams): boolean {\n\treturn (\n\t\ta.modelTier === b.modelTier &&\n\t\ta.keepRecentTokens === b.keepRecentTokens &&\n\t\ta.chunked === b.chunked &&\n\t\ta.deterministicOnly === b.deterministicOnly\n\t);\n}\n\nfunction mapFailureCause(error: unknown, provider?: string): { cause: string; detail?: string } {\n\tconst message = error instanceof Error ? error.message : typeof error === \"string\" ? error : \"\";\n\tif (message.includes(\"gate-failed\")) return { cause: \"gate-failed\", detail: boundedDetail(message) };\n\tif (message.includes(\"summary-demand-exceeds-reserve\"))\n\t\treturn { cause: \"deterministic-required\", detail: boundedDetail(message) };\n\tif (message.includes(\"input-overflow\")) return { cause: \"input-overflow\", detail: boundedDetail(message) };\n\t// A length-stopped summary lost gated sections; escalating the tier buys a larger output cap.\n\tif (message.includes(\"summary-length-stop\")) return { cause: \"length-stop\", detail: boundedDetail(message) };\n\tif (message.includes(\"auto-compaction-cancelled\")) return { cause: \"aborted\", detail: boundedDetail(message) };\n\tconst classified = classifyFailure({ message, provider });\n\tif (classified.retryable) return { cause: \"provider-failure\", detail: boundedDetail(message) };\n\tif (\n\t\tclassified.reason === \"auth\" ||\n\t\tclassified.reason === \"billing_or_quota\" ||\n\t\tmessage.includes(\"api key\") ||\n\t\tmessage.includes(\"not compacted\")\n\t)\n\t\treturn { cause: \"auth-failed\", detail: boundedDetail(message) };\n\treturn { cause: \"unknown-failure\", detail: boundedDetail(message) };\n}\n\nfunction boundedDetail(message: string): string | undefined {\n\tif (!message) return undefined;\n\treturn message.length > 500 ? `${message.slice(0, 500)}…` : message;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/compaction/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,wBAAgB,aAAa,IAAI,cAAc,CAM9C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CA2B9F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAK1G;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAUzF;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/compaction/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,wBAAgB,aAAa,IAAI,cAAc,CAM9C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CA2B9F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAK1G;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAUzF;AAuBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAuDjE;AAMD,eAAO,MAAM,2BAA2B,uvFAoDkL,CAAC","sourcesContent":["/**\n * Shared utilities for compaction and branch summarization.\n */\n\nimport type { Message } from \"@caupulican/pi-ai\";\nimport type { AgentMessage } from \"../types.ts\";\n\n// ============================================================================\n// File Operation Tracking\n// ============================================================================\n\nexport interface FileOperations {\n\tread: Set<string>;\n\twritten: Set<string>;\n\tedited: Set<string>;\n}\n\nexport function createFileOps(): FileOperations {\n\treturn {\n\t\tread: new Set(),\n\t\twritten: new Set(),\n\t\tedited: new Set(),\n\t};\n}\n\n/**\n * Extract file operations from tool calls in an assistant message.\n */\nexport function extractFileOpsFromMessage(message: AgentMessage, fileOps: FileOperations): void {\n\tif (message.role !== \"assistant\") return;\n\tif (!(\"content\" in message) || !Array.isArray(message.content)) return;\n\n\tfor (const block of message.content) {\n\t\tif (typeof block !== \"object\" || block === null) continue;\n\t\tif (!(\"type\" in block) || block.type !== \"toolCall\") continue;\n\t\tif (!(\"arguments\" in block) || !(\"name\" in block)) continue;\n\n\t\tconst args = block.arguments as Record<string, unknown> | undefined;\n\t\tif (!args) continue;\n\n\t\tconst path = typeof args.path === \"string\" ? args.path : undefined;\n\t\tif (!path) continue;\n\n\t\tswitch (block.name) {\n\t\t\tcase \"read\":\n\t\t\t\tfileOps.read.add(path);\n\t\t\t\tbreak;\n\t\t\tcase \"write\":\n\t\t\t\tfileOps.written.add(path);\n\t\t\t\tbreak;\n\t\t\tcase \"edit\":\n\t\t\t\tfileOps.edited.add(path);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Compute final file lists from file operations.\n * Returns readFiles (files only read, not modified) and modifiedFiles.\n */\nexport function computeFileLists(fileOps: FileOperations): { readFiles: string[]; modifiedFiles: string[] } {\n\tconst modified = new Set([...fileOps.edited, ...fileOps.written]);\n\tconst readOnly = [...fileOps.read].filter((f) => !modified.has(f)).sort();\n\tconst modifiedFiles = [...modified].sort();\n\treturn { readFiles: readOnly, modifiedFiles };\n}\n\n/**\n * Format file operations as XML tags for summary.\n */\nexport function formatFileOperations(readFiles: string[], modifiedFiles: string[]): string {\n\tconst sections: string[] = [];\n\tif (readFiles.length > 0) {\n\t\tsections.push(`<read-files>\\n${readFiles.join(\"\\n\")}\\n</read-files>`);\n\t}\n\tif (modifiedFiles.length > 0) {\n\t\tsections.push(`<modified-files>\\n${modifiedFiles.join(\"\\n\")}\\n</modified-files>`);\n\t}\n\tif (sections.length === 0) return \"\";\n\treturn `\\n\\n${sections.join(\"\\n\\n\")}`;\n}\n\n// ============================================================================\n// Message Serialization\n// ============================================================================\n\n/** Maximum characters for a tool result in serialized summaries. */\nconst TOOL_RESULT_MAX_CHARS = 2000;\n/** Maximum characters for non-gated assistant thinking in serialized summaries. */\nconst ASSISTANT_THINKING_MAX_CHARS = 2000;\n/** Maximum characters for one tool call's arguments in serialized summaries. */\nconst TOOL_CALL_ARGUMENTS_MAX_CHARS = 2000;\n\n/**\n * Truncate text to a maximum character length for summarization.\n * Keeps the beginning and appends a truncation marker.\n */\nfunction truncateForSummary(text: string, maxChars: number): string {\n\tif (text.length <= maxChars) return text;\n\tconst truncatedChars = text.length - maxChars;\n\treturn `${text.slice(0, maxChars)}\\n\\n[... ${truncatedChars} more characters truncated]`;\n}\n\n/**\n * Serialize LLM messages to text for summarization.\n * This prevents the model from treating it as a conversation to continue.\n * Call convertToLlm() first to handle custom message types.\n *\n * Tool results are truncated to keep the summarization request within\n * reasonable token budgets. Full content is not needed for summarization.\n */\nexport function serializeConversation(messages: Message[]): string {\n\tconst parts: string[] = [];\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tconst content =\n\t\t\t\ttypeof msg.content === \"string\"\n\t\t\t\t\t? msg.content\n\t\t\t\t\t: msg.content\n\t\t\t\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t\t\t.join(\"\");\n\t\t\tif (content) parts.push(`[User]: ${content}`);\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst textParts: string[] = [];\n\t\t\tconst thinkingParts: string[] = [];\n\t\t\tconst toolCalls: string[] = [];\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\ttextParts.push(block.text);\n\t\t\t\t} else if (block.type === \"thinking\") {\n\t\t\t\t\tthinkingParts.push(block.thinking);\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst args = block.arguments as Record<string, unknown>;\n\t\t\t\t\tconst argsStr = Object.entries(args)\n\t\t\t\t\t\t.map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n\t\t\t\t\t\t.join(\", \");\n\t\t\t\t\ttoolCalls.push(`${block.name}(${truncateForSummary(argsStr, TOOL_CALL_ARGUMENTS_MAX_CHARS)})`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (thinkingParts.length > 0) {\n\t\t\t\tparts.push(\n\t\t\t\t\t`[Assistant thinking]: ${truncateForSummary(thinkingParts.join(\"\\n\"), ASSISTANT_THINKING_MAX_CHARS)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (textParts.length > 0) {\n\t\t\t\tparts.push(`[Assistant]: ${textParts.join(\"\\n\")}`);\n\t\t\t}\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tparts.push(`[Assistant tool calls]: ${toolCalls.join(\"; \")}`);\n\t\t\t}\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst content = msg.content\n\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\");\n\t\t\tif (content) {\n\t\t\t\tparts.push(`[Tool result]: ${truncateForSummary(content, TOOL_RESULT_MAX_CHARS)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\\n\");\n}\n\n// ============================================================================\n// Summarization System Prompt\n// ============================================================================\n\nexport const SUMMARIZATION_SYSTEM_PROMPT = `You are a context checkpointer. Input: a serialized agent conversation. Output: ONLY the checkpoint, exactly in the format below. No preamble. No commentary. Same language as the user. Never include secrets/keys/tokens — write [REDACTED].\n\nRULES:\n- Recent turns weigh heaviest. Old turns contribute only rules, decisions, and file knowledge.\n- ## Active Task: the user's most recent UNFULFILLED input, near-verbatim. A question awaiting an answer IS an active task. If the user's last signal cancels earlier work (stop/undo/never mind), record the cancellation and DROP the cancelled work everywhere.\n- ### Mandatory Rules: every user prohibition (\"do not X\", \"never Y\", \"stop doing Z\") as one bullet each, imperative, with source turn if known. PRESERVE existing rules verbatim. A user-corrected mistake appears ONLY here as \"DO NOT <mistake>\" — the mistaken work itself must not survive.\n- ## Working Set: the currently active/recent files — path — why they matter.\n- ## Files: bare paths only; modified files must all appear, read files should be recalled when relevant.\n- ## Open Problems: unresolved errors only — command/operation plus first error line. Drop resolved/transient errors.\n- ## Done: numbered caveman log — \"N. VERB target — outcome\". Exact paths, commands, line numbers, error strings.\n- Do NOT carry resolved/transient errors, superseded approaches, or file contents. Record paths and intent, never bodies.\n- Sections with nothing: write \"(none)\".\n\nEXAMPLE INPUT (excerpt):\n[user]: add retry to the fetcher, and do not touch the legacy client\n[assistant]: (edits src/fetcher.ts, adds retry loop)\n[tool write src/fetcher.ts]: ok\n[tool bash npm test]: 2 failed: fetcher.test.ts\n[assistant]: (tries wrapping legacy client instead)\n[user]: no — stop changing the legacy client, I said don't touch it. Fix the two tests instead.\n\nEXAMPLE OUTPUT:\n## Active Task\nUser: \"Fix the two failing tests\" (fetcher.test.ts) — retry work continues, legacy-client changes cancelled.\n\n### Mandatory Rules\n- DO NOT touch the legacy client (user, twice)\n\n## Working Set\n- test/fetcher.test.ts — 2 failing, current focus\n- src/fetcher.ts — retry loop added\n\n## Files\n- src/fetcher.ts\n- test/fetcher.test.ts\n\n## Open Problems\n- TEST npm test: 2 failed: fetcher.test.ts\n\n## Done\n1. EDIT src/fetcher.ts — added retry loop\n2. TEST npm test — 2 failed: fetcher.test.ts\n\n## Key Decisions\n(none)\n\n## Constraints & Preferences\n(none)\n\n## Critical Context\n(none)\n\nNote what the example TEACHES (not just shows): the legacy-client wrapping attempt (cancelled work) appears nowhere except as the DO-NOT rule; the Active Task is the tail, near-verbatim; Done lines are caveman-format.`;\n"]}
|
package/dist/compaction/utils.js
CHANGED
|
@@ -74,6 +74,8 @@ export function formatFileOperations(readFiles, modifiedFiles) {
|
|
|
74
74
|
const TOOL_RESULT_MAX_CHARS = 2000;
|
|
75
75
|
/** Maximum characters for non-gated assistant thinking in serialized summaries. */
|
|
76
76
|
const ASSISTANT_THINKING_MAX_CHARS = 2000;
|
|
77
|
+
/** Maximum characters for one tool call's arguments in serialized summaries. */
|
|
78
|
+
const TOOL_CALL_ARGUMENTS_MAX_CHARS = 2000;
|
|
77
79
|
/**
|
|
78
80
|
* Truncate text to a maximum character length for summarization.
|
|
79
81
|
* Keeps the beginning and appends a truncation marker.
|
|
@@ -121,7 +123,7 @@ export function serializeConversation(messages) {
|
|
|
121
123
|
const argsStr = Object.entries(args)
|
|
122
124
|
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
123
125
|
.join(", ");
|
|
124
|
-
toolCalls.push(`${block.name}(${argsStr})`);
|
|
126
|
+
toolCalls.push(`${block.name}(${truncateForSummary(argsStr, TOOL_CALL_ARGUMENTS_MAX_CHARS)})`);
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
if (thinkingParts.length > 0) {
|