@agimon-ai/po-autocompact 0.0.0-alpha.2 → 0.0.0-alpha.20
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 +3 -3
- package/dist/apiContracts.cjs +1 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts +1 -1
- package/dist/apiContracts.mjs +1 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/{compactionPolicy-BIJJHcBP.cjs → compactionPolicy-C76UDULA.cjs} +20 -14
- package/dist/compactionPolicy-C76UDULA.cjs.map +1 -0
- package/dist/{compactionPolicy-CDCYTj2b.mjs → compactionPolicy-_WTvdEQ2.mjs} +15 -15
- package/dist/compactionPolicy-_WTvdEQ2.mjs.map +1 -0
- package/dist/extensions/server.cjs +288 -68
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +291 -71
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +1 -1
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -2
- package/package.json +12 -11
- package/dist/compactionPolicy-BIJJHcBP.cjs.map +0 -1
- package/dist/compactionPolicy-CDCYTj2b.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ asynchronous checkpoints and combines each checkpoint with subsequent messages.
|
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
20
|
-
`po init`
|
|
20
|
+
`po init` include Autocompact in `default.packages` in `.po/modes.yaml`.
|
|
21
21
|
Remove it or move it to a named layer to change which major modes load it.
|
|
22
|
-
The native
|
|
22
|
+
The native server plugin is `@agimon-ai/po-autocompact/extensions/server`.
|
|
23
23
|
This package does not provide a Pi extension or terminal UI.
|
|
24
24
|
|
|
25
25
|
## Checkpoint ladder
|
|
@@ -87,7 +87,7 @@ import { thresholdTokens } from '@agimon-ai/po-autocompact';
|
|
|
87
87
|
import type { AutocompactPass } from '@agimon-ai/po-autocompact';
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
The server host mounts the native
|
|
90
|
+
The server host mounts the native server plugin and owns its lifecycle. `thresholdTokens` exposes
|
|
91
91
|
the threshold policy for hosts that need to preview or test checkpoint boundaries.
|
|
92
92
|
|
|
93
93
|
## Development
|
package/dist/apiContracts.cjs
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
//#region src/schemas/apiContracts.ts
|
|
6
|
-
/** This
|
|
6
|
+
/** This server plugin contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
7
7
|
const apiContracts = (0, require("@agimon-ai/po-core/apiContracts").defineApiContract)({
|
|
8
8
|
version: 1,
|
|
9
9
|
http: [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This server plugin contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,4CAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
package/dist/apiContracts.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/schemas/apiContracts.d.ts
|
|
2
|
-
/** This
|
|
2
|
+
/** This server plugin contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
3
|
export declare const apiContracts: {
|
|
4
4
|
version: 1;
|
|
5
5
|
protocols?: Record<string, string> | undefined;
|
package/dist/apiContracts.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineApiContract } from "@agimon-ai/po-core/apiContracts";
|
|
2
2
|
//#region src/schemas/apiContracts.ts
|
|
3
|
-
/** This
|
|
3
|
+
/** This server plugin contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
4
4
|
const apiContracts = defineApiContract({
|
|
5
5
|
version: 1,
|
|
6
6
|
http: [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This server plugin contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
let _earendil_works_pi_coding_agent = require("@earendil-works/pi-coding-agent");
|
|
2
2
|
//#region src/constants/autocompact.ts
|
|
3
|
-
const STATE_CUSTOM_TYPE = "
|
|
4
|
-
const CHECKPOINT_MESSAGE_TYPE = "
|
|
5
|
-
const CONTEXT_MESSAGE_TYPE = "
|
|
6
|
-
const RESUME_MESSAGE_TYPE = "
|
|
7
|
-
const RUNTIME_STATE_MESSAGE_TYPE = "
|
|
3
|
+
const STATE_CUSTOM_TYPE = "po-autocompact-state";
|
|
4
|
+
const CHECKPOINT_MESSAGE_TYPE = "po-autocompact-checkpoint";
|
|
5
|
+
const CONTEXT_MESSAGE_TYPE = "po-autocompact-context";
|
|
6
|
+
const RESUME_MESSAGE_TYPE = "po-autocompact-resume";
|
|
7
|
+
const RUNTIME_STATE_MESSAGE_TYPE = "po-autocompact-runtime-state";
|
|
8
8
|
const COMPACTION_THRESHOLDS = {
|
|
9
9
|
1: {
|
|
10
10
|
ratio: .5,
|
|
@@ -57,14 +57,14 @@ function isAutocompactMessage(value) {
|
|
|
57
57
|
function contextDetailsFromUnknown(value) {
|
|
58
58
|
if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return void 0;
|
|
59
59
|
if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return void 0;
|
|
60
|
-
if (!isRecord(value.
|
|
61
|
-
const marker = value.
|
|
60
|
+
if (!isRecord(value.poAutocompact)) return void 0;
|
|
61
|
+
const marker = value.poAutocompact;
|
|
62
62
|
if (marker.version !== 2 || marker.pass !== 2 && marker.pass !== 3 || typeof marker.cycle !== "number" || typeof marker.requestId !== "string" || typeof marker.snapshotLeafId !== "string" || typeof marker.tokensBefore !== "number") return void 0;
|
|
63
63
|
return {
|
|
64
64
|
readFiles: [...value.readFiles],
|
|
65
65
|
modifiedFiles: [...value.modifiedFiles],
|
|
66
66
|
retainedMessages: [...value.retainedMessages],
|
|
67
|
-
|
|
67
|
+
poAutocompact: {
|
|
68
68
|
version: 2,
|
|
69
69
|
cycle: marker.cycle,
|
|
70
70
|
pass: marker.pass,
|
|
@@ -150,10 +150,10 @@ function effectiveThresholds(contextWindow, baselineTokens = 0, configured = {},
|
|
|
150
150
|
return thresholds;
|
|
151
151
|
}
|
|
152
152
|
function latestCheckpointArtifactEntry(branchEntries) {
|
|
153
|
-
return branchEntries.findLast((entry) => entry.type === "compaction" || entry.type === "custom" && entry.customType === "
|
|
153
|
+
return branchEntries.findLast((entry) => entry.type === "compaction" || entry.type === "custom" && entry.customType === "po-autocompact-checkpoint" || customMessage(entry)?.customType === "po-autocompact-checkpoint" || customMessage(entry)?.customType === "po-autocompact-context");
|
|
154
154
|
}
|
|
155
155
|
function baselineUsageIsSettled(branchEntries) {
|
|
156
|
-
const boundaryIndex = branchEntries.findLastIndex((entry) => entry.type === "compaction" || customMessage(entry)?.customType === "
|
|
156
|
+
const boundaryIndex = branchEntries.findLastIndex((entry) => entry.type === "compaction" || customMessage(entry)?.customType === "po-autocompact-context");
|
|
157
157
|
return branchEntries.slice(boundaryIndex + 1).some((entry) => {
|
|
158
158
|
if (entry.type !== "message" || entry.message.role !== "assistant") return false;
|
|
159
159
|
const { stopReason, usage } = entry.message;
|
|
@@ -176,7 +176,7 @@ function projectContextMessages(messages, branchEntries) {
|
|
|
176
176
|
invalidMarker: true,
|
|
177
177
|
retainedMessageCount: 0
|
|
178
178
|
};
|
|
179
|
-
const markerMessageIndex = messages.findLastIndex((message) => message.role === "custom" && message.customType === "
|
|
179
|
+
const markerMessageIndex = messages.findLastIndex((message) => message.role === "custom" && message.customType === "po-autocompact-context" && contextDetailsFromUnknown(message.details)?.poAutocompact.requestId === details.poAutocompact.requestId);
|
|
180
180
|
if (markerMessageIndex === -1) return {
|
|
181
181
|
messages,
|
|
182
182
|
invalidMarker: true,
|
|
@@ -187,13 +187,13 @@ function projectContextMessages(messages, branchEntries) {
|
|
|
187
187
|
{
|
|
188
188
|
role: "compactionSummary",
|
|
189
189
|
summary,
|
|
190
|
-
tokensBefore: details.
|
|
190
|
+
tokensBefore: details.poAutocompact.tokensBefore,
|
|
191
191
|
timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now()
|
|
192
192
|
},
|
|
193
193
|
...details.retainedMessages,
|
|
194
194
|
...messages.slice(markerMessageIndex + 1)
|
|
195
195
|
],
|
|
196
|
-
marker: details.
|
|
196
|
+
marker: details.poAutocompact,
|
|
197
197
|
retainedMessageCount: details.retainedMessages.length
|
|
198
198
|
};
|
|
199
199
|
}
|
|
@@ -389,6 +389,12 @@ Object.defineProperty(exports, "createRequestId", {
|
|
|
389
389
|
return createRequestId;
|
|
390
390
|
}
|
|
391
391
|
});
|
|
392
|
+
Object.defineProperty(exports, "customMessage", {
|
|
393
|
+
enumerable: true,
|
|
394
|
+
get: function() {
|
|
395
|
+
return customMessage;
|
|
396
|
+
}
|
|
397
|
+
});
|
|
392
398
|
Object.defineProperty(exports, "effectiveThresholds", {
|
|
393
399
|
enumerable: true,
|
|
394
400
|
get: function() {
|
|
@@ -456,4 +462,4 @@ Object.defineProperty(exports, "withCanonicalFileSections", {
|
|
|
456
462
|
}
|
|
457
463
|
});
|
|
458
464
|
|
|
459
|
-
//# sourceMappingURL=compactionPolicy-
|
|
465
|
+
//# sourceMappingURL=compactionPolicy-C76UDULA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compactionPolicy-C76UDULA.cjs","names":["DEFAULT_COMPACTION_SETTINGS"],"sources":["../src/constants/autocompact.ts","../src/services/compactionPolicy/index.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'po-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'po-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'po-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'po-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'po-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n","import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactRatioOverrides,\n AutocompactTokenOverrides,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/autocompact';\n\n/** V4 projections have numeric timestamps and store custom messages as message entries. */\nexport type NativePolicyEntry = { id: string; timestamp: number } & (\n | { type: 'message'; message: AutocompactMessage }\n | { type: 'custom'; customType: string; data?: unknown }\n | { type: 'compaction'; summary: string; tokensBefore: number; retainedTail: AutocompactMessage[] }\n | { type: 'branch_summary'; summary: string; fromId?: string | null }\n);\nexport type CompactionPolicyEntry = SessionEntry | NativePolicyEntry;\n\nexport function customMessage(\n entry: CompactionPolicyEntry,\n): Extract<SessionEntry, { type: 'custom_message' }> | Extract<AutocompactMessage, { role: 'custom' }> | undefined {\n if (entry.type === 'custom_message') return entry;\n if (entry.type === 'message' && entry.message.role === 'custom') return entry.message;\n return undefined;\n}\n\n/** Native entries are already projected messages, not Pi journal entries. */\nexport function policyEntryMessages(entry: CompactionPolicyEntry): AutocompactMessage[] {\n if (typeof entry.timestamp === 'string') return sessionEntryToContextMessages(entry as SessionEntry);\n if (entry.type === 'message') return [entry.message];\n if (entry.type === 'compaction' && 'retainedTail' in entry) {\n return [\n {\n role: 'compactionSummary',\n summary: entry.summary,\n tokensBefore: entry.tokensBefore,\n timestamp: entry.timestamp,\n },\n ...entry.retainedTail,\n ];\n }\n if (entry.type === 'branch_summary') {\n return [{ role: 'branchSummary', summary: entry.summary, fromId: entry.fromId ?? '', timestamp: entry.timestamp }];\n }\n return [];\n}\n\nconst SHOULD_COMPACT_PATTERN = /<shouldCompact>\\s*(true|false)\\s*<\\/shouldCompact>/i;\nconst FILE_SECTION_PATTERN = /\\n*<(?:read-files|modified-files)>[\\s\\S]*?<\\/(?:read-files|modified-files)>/g;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction isPass(value: unknown): value is AutocompactPass {\n return value === 1 || value === 2 || value === 3;\n}\n\nfunction assistantText(entry: CompactionPolicyEntry): string | undefined {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return undefined;\n const text = entry.message.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .trim();\n return text || undefined;\n}\n\nfunction isAutocompactMessage(value: unknown): value is AutocompactMessage {\n return isRecord(value) && typeof value.role === 'string';\n}\n\nexport function contextDetailsFromUnknown(value: unknown): AutocompactContextDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return undefined;\n if (!isRecord(value.poAutocompact)) return undefined;\n const marker = value.poAutocompact;\n if (\n marker.version !== STATE_VERSION ||\n (marker.pass !== 2 && marker.pass !== 3) ||\n typeof marker.cycle !== 'number' ||\n typeof marker.requestId !== 'string' ||\n typeof marker.snapshotLeafId !== 'string' ||\n typeof marker.tokensBefore !== 'number'\n )\n return undefined;\n return {\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n retainedMessages: [...value.retainedMessages],\n poAutocompact: {\n version: STATE_VERSION,\n cycle: marker.cycle,\n pass: marker.pass,\n requestId: marker.requestId,\n snapshotLeafId: marker.snapshotLeafId,\n tokensBefore: marker.tokensBefore,\n },\n };\n}\n\nexport function createInitialState(): AutocompactState {\n return {\n version: STATE_VERSION,\n cycle: 1,\n pass: 1,\n phase: 'waiting',\n checkpointQueue: [],\n exhaustedPasses: [],\n invalidAttempts: 0,\n baselineTokens: 0,\n baselinePending: false,\n readFiles: [],\n modifiedFiles: [],\n };\n}\n\n/**\n * The ratios each pass fires at, with configured values folded in.\n *\n * The ladder only works if it climbs, so a configured pass never sits below the\n * one before it: a file that says pass 2 fires earlier than pass 1 gets pass 1's\n * ratio for pass 2 rather than a pass that can never contribute.\n */\nexport function compactionRatios(configured: AutocompactRatioOverrides = {}): Record<AutocompactPass, number> {\n let previous = 0;\n const ratios = {} as Record<AutocompactPass, number>;\n for (const pass of [1, 2, 3] as const) {\n const ratio = Math.max(configured[pass] ?? COMPACTION_THRESHOLDS[pass].ratio, previous);\n ratios[pass] = ratio;\n previous = ratio;\n }\n return ratios;\n}\n\nexport function thresholdTokens(\n pass: AutocompactPass,\n contextWindow: number,\n baselineTokens = 0,\n configured: AutocompactRatioOverrides = {},\n): number {\n const threshold = COMPACTION_THRESHOLDS[pass];\n const ratio = compactionRatios(configured)[pass];\n const baseline = Math.max(0, Math.min(baselineTokens, contextWindow));\n const remaining = contextWindow - baseline;\n const staged = baseline + Math.min(Math.floor(remaining * ratio), threshold.capTokens);\n // Pi compacts natively above `contextWindow - reserveTokens`. A staged threshold above that\n // point can never fire, so the ladder would silently degrade into native compaction: on a\n // 200k window the raw pass 3 ratio lands at 190_000, while Pi already compacted at 183_616.\n const nativeTrigger = contextWindow - DEFAULT_COMPACTION_SETTINGS.reserveTokens;\n return nativeTrigger > baseline ? Math.min(staged, nativeTrigger) : staged;\n}\n\n/**\n * Where every pass fires, with a matching model's absolute token checkpoints folded in.\n *\n * A configured token count replaces the ratio only when it fires earlier, so an\n * override can bring a checkpoint forward on a very large window without ever\n * pushing one past the point Pi compacts natively.\n *\n * Two rules keep the ladder usable. A token count at or below the baseline is\n * ignored, because a compaction that lands above it would otherwise satisfy that\n * pass the moment the next cycle opens and re-fire it every turn. And a pass never\n * sits below the one before it, for the same reason {@link compactionRatios}\n * climbs: `evaluateUsage` skips any pass below the one already reached, so a later\n * pass that fires first does not merely reorder the ladder, it locks the earlier\n * passes out of the cycle and forces compaction with no summary ever written.\n */\nexport function effectiveThresholds(\n contextWindow: number,\n baselineTokens = 0,\n configured: AutocompactRatioOverrides = {},\n tokenOverrides: AutocompactTokenOverrides = {},\n): Record<AutocompactPass, number> {\n let previous = 0;\n const thresholds = {} as Record<AutocompactPass, number>;\n for (const pass of [1, 2, 3] as const) {\n const ratioTokens = thresholdTokens(pass, contextWindow, baselineTokens, configured);\n const absolute = tokenOverrides[pass];\n const staged = absolute !== undefined && absolute > baselineTokens ? Math.min(ratioTokens, absolute) : ratioTokens;\n thresholds[pass] = Math.max(staged, previous);\n previous = thresholds[pass];\n }\n return thresholds;\n}\nexport function latestCheckpointArtifactEntry(\n branchEntries: readonly CompactionPolicyEntry[],\n): CompactionPolicyEntry | undefined {\n return branchEntries.findLast(\n (entry) =>\n entry.type === 'compaction' ||\n // Staged checkpoints are plain entries so they stay out of the agent's LLM context.\n (entry.type === 'custom' && entry.customType === CHECKPOINT_MESSAGE_TYPE) ||\n // Legacy sessions staged checkpoints as custom messages; committed markers still are.\n customMessage(entry)?.customType === CHECKPOINT_MESSAGE_TYPE ||\n customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE,\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: readonly CompactionPolicyEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) => entry.type === 'compaction' || customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE,\n );\n return branchEntries.slice(boundaryIndex + 1).some((entry) => {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return false;\n const { stopReason, usage } = entry.message;\n if (stopReason === 'aborted' || stopReason === 'error' || !usage) return false;\n return (usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n });\n}\n\nexport function retainedMessagesAfterSnapshot(\n branchEntries: readonly CompactionPolicyEntry[],\n snapshotLeafId: string,\n): AutocompactMessage[] {\n const snapshotIndex = branchEntries.findIndex((entry) => entry.id === snapshotLeafId);\n if (snapshotIndex === -1) return [];\n return branchEntries\n .slice(snapshotIndex + 1)\n .filter((entry) => customMessage(entry)?.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap(policyEntryMessages);\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: readonly CompactionPolicyEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE);\n const markerMessage = markerEntry && customMessage(markerEntry);\n if (!markerEntry || !markerMessage) {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerMessage.details);\n const summary = checkpointSummaryFromEntry(markerEntry);\n if (!details || !summary) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const markerMessageIndex = messages.findLastIndex(\n (message) =>\n message.role === 'custom' &&\n message.customType === CONTEXT_MESSAGE_TYPE &&\n contextDetailsFromUnknown(message.details)?.poAutocompact.requestId === details.poAutocompact.requestId,\n );\n if (markerMessageIndex === -1) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const summaryMessage: AutocompactMessage = {\n role: 'compactionSummary',\n summary,\n tokensBefore: details.poAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.poAutocompact,\n retainedMessageCount: details.retainedMessages.length,\n };\n}\n\nexport function fileOperationsFromMessages(messages: AutocompactMessage[]): FileOperations {\n const fileOps: FileOperations = { read: new Set(), written: new Set(), edited: new Set() };\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const block of message.content) {\n if (block.type !== 'toolCall') continue;\n const path = typeof block.arguments.path === 'string' ? block.arguments.path : undefined;\n if (!path) continue;\n if (block.name === 'read') fileOps.read.add(path);\n else if (block.name === 'write') fileOps.written.add(path);\n else if (block.name === 'edit') fileOps.edited.add(path);\n }\n }\n return fileOps;\n}\n\nexport function parseState(value: unknown): AutocompactState | undefined {\n if (!isRecord(value)) return undefined;\n if (value.version !== STATE_VERSION || typeof value.cycle !== 'number' || !isPass(value.pass)) return undefined;\n if (\n value.phase !== 'waiting' &&\n value.phase !== 'checkpoint_pending' &&\n value.phase !== 'checkpoint_ready' &&\n value.phase !== 'compacting'\n )\n return undefined;\n const baselineTokens = value.baselineTokens ?? 0;\n if (typeof baselineTokens !== 'number' || baselineTokens < 0) return undefined;\n const baselinePending = value.baselinePending ?? false;\n if (typeof baselinePending !== 'boolean') return undefined;\n const checkpointQueue = value.checkpointQueue ?? [];\n if (\n !Array.isArray(checkpointQueue) ||\n !checkpointQueue.every(isPass) ||\n checkpointQueue.some((pass, index) => index > 0 && pass <= checkpointQueue[index - 1]!)\n )\n return undefined;\n // Sessions persisted before bounded retry landed simply have no attempt history to restore.\n const exhaustedPasses = value.exhaustedPasses ?? [];\n if (!Array.isArray(exhaustedPasses) || !exhaustedPasses.every(isPass)) return undefined;\n const invalidAttempts = value.invalidAttempts ?? 0;\n if (typeof invalidAttempts !== 'number' || invalidAttempts < 0) return undefined;\n if (!isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (value.requestId !== undefined && typeof value.requestId !== 'string') return undefined;\n if (value.compactionPass !== undefined && value.compactionPass !== 2 && value.compactionPass !== 3) return undefined;\n if ('latestCheckpointEntryId' in value) return undefined;\n if (value.latestCheckpointSnapshotLeafId !== undefined && typeof value.latestCheckpointSnapshotLeafId !== 'string')\n return undefined;\n if (value.lastAttemptLeafId !== undefined && typeof value.lastAttemptLeafId !== 'string') return undefined;\n if (value.snapshotLeafId !== undefined && typeof value.snapshotLeafId !== 'string') return undefined;\n if (value.snapshotTokens !== undefined && (typeof value.snapshotTokens !== 'number' || value.snapshotTokens < 0))\n return undefined;\n if (value.pendingCheckpoint !== undefined && typeof value.pendingCheckpoint !== 'string') return undefined;\n\n return {\n version: STATE_VERSION,\n cycle: value.cycle,\n pass: value.pass,\n phase: value.phase,\n checkpointQueue: [...checkpointQueue],\n exhaustedPasses: [...exhaustedPasses],\n invalidAttempts,\n baselineTokens,\n baselinePending,\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n ...(value.requestId ? { requestId: value.requestId } : {}),\n ...(value.compactionPass ? { compactionPass: value.compactionPass } : {}),\n ...(value.latestCheckpointSnapshotLeafId\n ? { latestCheckpointSnapshotLeafId: value.latestCheckpointSnapshotLeafId }\n : {}),\n ...(value.lastAttemptLeafId ? { lastAttemptLeafId: value.lastAttemptLeafId } : {}),\n ...(value.snapshotLeafId ? { snapshotLeafId: value.snapshotLeafId } : {}),\n ...(value.snapshotTokens !== undefined ? { snapshotTokens: value.snapshotTokens } : {}),\n ...(value.pendingCheckpoint ? { pendingCheckpoint: value.pendingCheckpoint } : {}),\n };\n}\n\nexport function checkpointSummaryFromEntry(entry: CompactionPolicyEntry | undefined): string | undefined {\n if (!entry) return undefined;\n if (entry.type === 'compaction') return entry.summary.trim() || undefined;\n if (entry.type === 'custom') {\n return isRecord(entry.data) && typeof entry.data.summary === 'string'\n ? entry.data.summary.trim() || undefined\n : undefined;\n }\n const marker = customMessage(entry);\n if (marker) {\n const content =\n typeof marker.content === 'string'\n ? marker.content\n : marker.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n');\n return content.trim() || undefined;\n }\n return assistantText(entry);\n}\n\nexport function parseCheckpointDecision(response: string): CheckpointDecision {\n const match = response.match(SHOULD_COMPACT_PATTERN);\n const summary = response.replace(SHOULD_COMPACT_PATTERN, '').trim();\n if (!match) return { summary };\n return { summary, shouldCompact: match[1]?.toLowerCase() === 'true' };\n}\n\nexport function isStructuredCheckpoint(summary: string): boolean {\n return CHECKPOINT_HEADINGS.every((heading) => summary.includes(heading));\n}\n\nexport function createRequestId(\n sessionId: string,\n cycle: number,\n pass: AutocompactPass,\n leafId: string | null,\n): string {\n return `${sessionId}:${cycle}:${pass}:${leafId ?? 'root'}`;\n}\n\nexport function checkpointRequestDetails(\n cycle: number,\n pass: AutocompactPass,\n requestId: string,\n): CheckpointRequestDetails {\n return { version: STATE_VERSION, cycle, pass, requestId };\n}\n\nexport function mergeFileDetails(\n current: AutocompactFileDetails,\n fileOps?: FileOperations,\n additional?: AutocompactFileDetails,\n): AutocompactFileDetails {\n const modified = new Set([\n ...current.modifiedFiles,\n ...(additional?.modifiedFiles ?? []),\n ...(fileOps ? [...fileOps.edited, ...fileOps.written] : []),\n ]);\n const read = new Set([...current.readFiles, ...(additional?.readFiles ?? []), ...(fileOps ? [...fileOps.read] : [])]);\n for (const path of modified) read.delete(path);\n return { readFiles: [...read].sort(), modifiedFiles: [...modified].sort() };\n}\n\nexport function fileDetailsFromUnknown(value: unknown): AutocompactFileDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n return { readFiles: value.readFiles, modifiedFiles: value.modifiedFiles };\n}\n\nexport function withCanonicalFileSections(summary: string, details: AutocompactFileDetails): string {\n const sections: string[] = [];\n if (details.readFiles.length > 0) sections.push(`<read-files>\\n${details.readFiles.join('\\n')}\\n</read-files>`);\n if (details.modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${details.modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n const normalized = summary.replace(FILE_SECTION_PATTERN, '').trim();\n return sections.length > 0 ? `${normalized}\\n\\n${sections.join('\\n\\n')}` : normalized;\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DEFAULT_COMPACTION_SETTINGS } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
//#region src/constants/autocompact.ts
|
|
3
|
-
const STATE_CUSTOM_TYPE = "
|
|
4
|
-
const CHECKPOINT_MESSAGE_TYPE = "
|
|
5
|
-
const CONTEXT_MESSAGE_TYPE = "
|
|
6
|
-
const RESUME_MESSAGE_TYPE = "
|
|
7
|
-
const RUNTIME_STATE_MESSAGE_TYPE = "
|
|
3
|
+
const STATE_CUSTOM_TYPE = "po-autocompact-state";
|
|
4
|
+
const CHECKPOINT_MESSAGE_TYPE = "po-autocompact-checkpoint";
|
|
5
|
+
const CONTEXT_MESSAGE_TYPE = "po-autocompact-context";
|
|
6
|
+
const RESUME_MESSAGE_TYPE = "po-autocompact-resume";
|
|
7
|
+
const RUNTIME_STATE_MESSAGE_TYPE = "po-autocompact-runtime-state";
|
|
8
8
|
const COMPACTION_THRESHOLDS = {
|
|
9
9
|
1: {
|
|
10
10
|
ratio: .5,
|
|
@@ -57,14 +57,14 @@ function isAutocompactMessage(value) {
|
|
|
57
57
|
function contextDetailsFromUnknown(value) {
|
|
58
58
|
if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return void 0;
|
|
59
59
|
if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return void 0;
|
|
60
|
-
if (!isRecord(value.
|
|
61
|
-
const marker = value.
|
|
60
|
+
if (!isRecord(value.poAutocompact)) return void 0;
|
|
61
|
+
const marker = value.poAutocompact;
|
|
62
62
|
if (marker.version !== 2 || marker.pass !== 2 && marker.pass !== 3 || typeof marker.cycle !== "number" || typeof marker.requestId !== "string" || typeof marker.snapshotLeafId !== "string" || typeof marker.tokensBefore !== "number") return void 0;
|
|
63
63
|
return {
|
|
64
64
|
readFiles: [...value.readFiles],
|
|
65
65
|
modifiedFiles: [...value.modifiedFiles],
|
|
66
66
|
retainedMessages: [...value.retainedMessages],
|
|
67
|
-
|
|
67
|
+
poAutocompact: {
|
|
68
68
|
version: 2,
|
|
69
69
|
cycle: marker.cycle,
|
|
70
70
|
pass: marker.pass,
|
|
@@ -150,10 +150,10 @@ function effectiveThresholds(contextWindow, baselineTokens = 0, configured = {},
|
|
|
150
150
|
return thresholds;
|
|
151
151
|
}
|
|
152
152
|
function latestCheckpointArtifactEntry(branchEntries) {
|
|
153
|
-
return branchEntries.findLast((entry) => entry.type === "compaction" || entry.type === "custom" && entry.customType === "
|
|
153
|
+
return branchEntries.findLast((entry) => entry.type === "compaction" || entry.type === "custom" && entry.customType === "po-autocompact-checkpoint" || customMessage(entry)?.customType === "po-autocompact-checkpoint" || customMessage(entry)?.customType === "po-autocompact-context");
|
|
154
154
|
}
|
|
155
155
|
function baselineUsageIsSettled(branchEntries) {
|
|
156
|
-
const boundaryIndex = branchEntries.findLastIndex((entry) => entry.type === "compaction" || customMessage(entry)?.customType === "
|
|
156
|
+
const boundaryIndex = branchEntries.findLastIndex((entry) => entry.type === "compaction" || customMessage(entry)?.customType === "po-autocompact-context");
|
|
157
157
|
return branchEntries.slice(boundaryIndex + 1).some((entry) => {
|
|
158
158
|
if (entry.type !== "message" || entry.message.role !== "assistant") return false;
|
|
159
159
|
const { stopReason, usage } = entry.message;
|
|
@@ -176,7 +176,7 @@ function projectContextMessages(messages, branchEntries) {
|
|
|
176
176
|
invalidMarker: true,
|
|
177
177
|
retainedMessageCount: 0
|
|
178
178
|
};
|
|
179
|
-
const markerMessageIndex = messages.findLastIndex((message) => message.role === "custom" && message.customType === "
|
|
179
|
+
const markerMessageIndex = messages.findLastIndex((message) => message.role === "custom" && message.customType === "po-autocompact-context" && contextDetailsFromUnknown(message.details)?.poAutocompact.requestId === details.poAutocompact.requestId);
|
|
180
180
|
if (markerMessageIndex === -1) return {
|
|
181
181
|
messages,
|
|
182
182
|
invalidMarker: true,
|
|
@@ -187,13 +187,13 @@ function projectContextMessages(messages, branchEntries) {
|
|
|
187
187
|
{
|
|
188
188
|
role: "compactionSummary",
|
|
189
189
|
summary,
|
|
190
|
-
tokensBefore: details.
|
|
190
|
+
tokensBefore: details.poAutocompact.tokensBefore,
|
|
191
191
|
timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now()
|
|
192
192
|
},
|
|
193
193
|
...details.retainedMessages,
|
|
194
194
|
...messages.slice(markerMessageIndex + 1)
|
|
195
195
|
],
|
|
196
|
-
marker: details.
|
|
196
|
+
marker: details.poAutocompact,
|
|
197
197
|
retainedMessageCount: details.retainedMessages.length
|
|
198
198
|
};
|
|
199
199
|
}
|
|
@@ -323,6 +323,6 @@ function withCanonicalFileSections(summary, details) {
|
|
|
323
323
|
return sections.length > 0 ? `${normalized}\n\n${sections.join("\n\n")}` : normalized;
|
|
324
324
|
}
|
|
325
325
|
//#endregion
|
|
326
|
-
export { STATE_CUSTOM_TYPE as S,
|
|
326
|
+
export { STATE_CUSTOM_TYPE as C, RUNTIME_STATE_MESSAGE_TYPE as S, thresholdTokens as _, createInitialState as a, CONTEXT_MESSAGE_TYPE as b, effectiveThresholds as c, isStructuredCheckpoint as d, latestCheckpointArtifactEntry as f, projectContextMessages as g, parseState as h, contextDetailsFromUnknown as i, fileDetailsFromUnknown as l, parseCheckpointDecision as m, checkpointRequestDetails as n, createRequestId as o, mergeFileDetails as p, checkpointSummaryFromEntry as r, customMessage as s, baselineUsageIsSettled as t, fileOperationsFromMessages as u, withCanonicalFileSections as v, RESUME_MESSAGE_TYPE as x, CHECKPOINT_MESSAGE_TYPE as y };
|
|
327
327
|
|
|
328
|
-
//# sourceMappingURL=compactionPolicy-
|
|
328
|
+
//# sourceMappingURL=compactionPolicy-_WTvdEQ2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compactionPolicy-_WTvdEQ2.mjs","names":[],"sources":["../src/constants/autocompact.ts","../src/services/compactionPolicy/index.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'po-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'po-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'po-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'po-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'po-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n","import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactRatioOverrides,\n AutocompactTokenOverrides,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/autocompact';\n\n/** V4 projections have numeric timestamps and store custom messages as message entries. */\nexport type NativePolicyEntry = { id: string; timestamp: number } & (\n | { type: 'message'; message: AutocompactMessage }\n | { type: 'custom'; customType: string; data?: unknown }\n | { type: 'compaction'; summary: string; tokensBefore: number; retainedTail: AutocompactMessage[] }\n | { type: 'branch_summary'; summary: string; fromId?: string | null }\n);\nexport type CompactionPolicyEntry = SessionEntry | NativePolicyEntry;\n\nexport function customMessage(\n entry: CompactionPolicyEntry,\n): Extract<SessionEntry, { type: 'custom_message' }> | Extract<AutocompactMessage, { role: 'custom' }> | undefined {\n if (entry.type === 'custom_message') return entry;\n if (entry.type === 'message' && entry.message.role === 'custom') return entry.message;\n return undefined;\n}\n\n/** Native entries are already projected messages, not Pi journal entries. */\nexport function policyEntryMessages(entry: CompactionPolicyEntry): AutocompactMessage[] {\n if (typeof entry.timestamp === 'string') return sessionEntryToContextMessages(entry as SessionEntry);\n if (entry.type === 'message') return [entry.message];\n if (entry.type === 'compaction' && 'retainedTail' in entry) {\n return [\n {\n role: 'compactionSummary',\n summary: entry.summary,\n tokensBefore: entry.tokensBefore,\n timestamp: entry.timestamp,\n },\n ...entry.retainedTail,\n ];\n }\n if (entry.type === 'branch_summary') {\n return [{ role: 'branchSummary', summary: entry.summary, fromId: entry.fromId ?? '', timestamp: entry.timestamp }];\n }\n return [];\n}\n\nconst SHOULD_COMPACT_PATTERN = /<shouldCompact>\\s*(true|false)\\s*<\\/shouldCompact>/i;\nconst FILE_SECTION_PATTERN = /\\n*<(?:read-files|modified-files)>[\\s\\S]*?<\\/(?:read-files|modified-files)>/g;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction isPass(value: unknown): value is AutocompactPass {\n return value === 1 || value === 2 || value === 3;\n}\n\nfunction assistantText(entry: CompactionPolicyEntry): string | undefined {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return undefined;\n const text = entry.message.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .trim();\n return text || undefined;\n}\n\nfunction isAutocompactMessage(value: unknown): value is AutocompactMessage {\n return isRecord(value) && typeof value.role === 'string';\n}\n\nexport function contextDetailsFromUnknown(value: unknown): AutocompactContextDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return undefined;\n if (!isRecord(value.poAutocompact)) return undefined;\n const marker = value.poAutocompact;\n if (\n marker.version !== STATE_VERSION ||\n (marker.pass !== 2 && marker.pass !== 3) ||\n typeof marker.cycle !== 'number' ||\n typeof marker.requestId !== 'string' ||\n typeof marker.snapshotLeafId !== 'string' ||\n typeof marker.tokensBefore !== 'number'\n )\n return undefined;\n return {\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n retainedMessages: [...value.retainedMessages],\n poAutocompact: {\n version: STATE_VERSION,\n cycle: marker.cycle,\n pass: marker.pass,\n requestId: marker.requestId,\n snapshotLeafId: marker.snapshotLeafId,\n tokensBefore: marker.tokensBefore,\n },\n };\n}\n\nexport function createInitialState(): AutocompactState {\n return {\n version: STATE_VERSION,\n cycle: 1,\n pass: 1,\n phase: 'waiting',\n checkpointQueue: [],\n exhaustedPasses: [],\n invalidAttempts: 0,\n baselineTokens: 0,\n baselinePending: false,\n readFiles: [],\n modifiedFiles: [],\n };\n}\n\n/**\n * The ratios each pass fires at, with configured values folded in.\n *\n * The ladder only works if it climbs, so a configured pass never sits below the\n * one before it: a file that says pass 2 fires earlier than pass 1 gets pass 1's\n * ratio for pass 2 rather than a pass that can never contribute.\n */\nexport function compactionRatios(configured: AutocompactRatioOverrides = {}): Record<AutocompactPass, number> {\n let previous = 0;\n const ratios = {} as Record<AutocompactPass, number>;\n for (const pass of [1, 2, 3] as const) {\n const ratio = Math.max(configured[pass] ?? COMPACTION_THRESHOLDS[pass].ratio, previous);\n ratios[pass] = ratio;\n previous = ratio;\n }\n return ratios;\n}\n\nexport function thresholdTokens(\n pass: AutocompactPass,\n contextWindow: number,\n baselineTokens = 0,\n configured: AutocompactRatioOverrides = {},\n): number {\n const threshold = COMPACTION_THRESHOLDS[pass];\n const ratio = compactionRatios(configured)[pass];\n const baseline = Math.max(0, Math.min(baselineTokens, contextWindow));\n const remaining = contextWindow - baseline;\n const staged = baseline + Math.min(Math.floor(remaining * ratio), threshold.capTokens);\n // Pi compacts natively above `contextWindow - reserveTokens`. A staged threshold above that\n // point can never fire, so the ladder would silently degrade into native compaction: on a\n // 200k window the raw pass 3 ratio lands at 190_000, while Pi already compacted at 183_616.\n const nativeTrigger = contextWindow - DEFAULT_COMPACTION_SETTINGS.reserveTokens;\n return nativeTrigger > baseline ? Math.min(staged, nativeTrigger) : staged;\n}\n\n/**\n * Where every pass fires, with a matching model's absolute token checkpoints folded in.\n *\n * A configured token count replaces the ratio only when it fires earlier, so an\n * override can bring a checkpoint forward on a very large window without ever\n * pushing one past the point Pi compacts natively.\n *\n * Two rules keep the ladder usable. A token count at or below the baseline is\n * ignored, because a compaction that lands above it would otherwise satisfy that\n * pass the moment the next cycle opens and re-fire it every turn. And a pass never\n * sits below the one before it, for the same reason {@link compactionRatios}\n * climbs: `evaluateUsage` skips any pass below the one already reached, so a later\n * pass that fires first does not merely reorder the ladder, it locks the earlier\n * passes out of the cycle and forces compaction with no summary ever written.\n */\nexport function effectiveThresholds(\n contextWindow: number,\n baselineTokens = 0,\n configured: AutocompactRatioOverrides = {},\n tokenOverrides: AutocompactTokenOverrides = {},\n): Record<AutocompactPass, number> {\n let previous = 0;\n const thresholds = {} as Record<AutocompactPass, number>;\n for (const pass of [1, 2, 3] as const) {\n const ratioTokens = thresholdTokens(pass, contextWindow, baselineTokens, configured);\n const absolute = tokenOverrides[pass];\n const staged = absolute !== undefined && absolute > baselineTokens ? Math.min(ratioTokens, absolute) : ratioTokens;\n thresholds[pass] = Math.max(staged, previous);\n previous = thresholds[pass];\n }\n return thresholds;\n}\nexport function latestCheckpointArtifactEntry(\n branchEntries: readonly CompactionPolicyEntry[],\n): CompactionPolicyEntry | undefined {\n return branchEntries.findLast(\n (entry) =>\n entry.type === 'compaction' ||\n // Staged checkpoints are plain entries so they stay out of the agent's LLM context.\n (entry.type === 'custom' && entry.customType === CHECKPOINT_MESSAGE_TYPE) ||\n // Legacy sessions staged checkpoints as custom messages; committed markers still are.\n customMessage(entry)?.customType === CHECKPOINT_MESSAGE_TYPE ||\n customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE,\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: readonly CompactionPolicyEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) => entry.type === 'compaction' || customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE,\n );\n return branchEntries.slice(boundaryIndex + 1).some((entry) => {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return false;\n const { stopReason, usage } = entry.message;\n if (stopReason === 'aborted' || stopReason === 'error' || !usage) return false;\n return (usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n });\n}\n\nexport function retainedMessagesAfterSnapshot(\n branchEntries: readonly CompactionPolicyEntry[],\n snapshotLeafId: string,\n): AutocompactMessage[] {\n const snapshotIndex = branchEntries.findIndex((entry) => entry.id === snapshotLeafId);\n if (snapshotIndex === -1) return [];\n return branchEntries\n .slice(snapshotIndex + 1)\n .filter((entry) => customMessage(entry)?.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap(policyEntryMessages);\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: readonly CompactionPolicyEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => customMessage(entry)?.customType === CONTEXT_MESSAGE_TYPE);\n const markerMessage = markerEntry && customMessage(markerEntry);\n if (!markerEntry || !markerMessage) {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerMessage.details);\n const summary = checkpointSummaryFromEntry(markerEntry);\n if (!details || !summary) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const markerMessageIndex = messages.findLastIndex(\n (message) =>\n message.role === 'custom' &&\n message.customType === CONTEXT_MESSAGE_TYPE &&\n contextDetailsFromUnknown(message.details)?.poAutocompact.requestId === details.poAutocompact.requestId,\n );\n if (markerMessageIndex === -1) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const summaryMessage: AutocompactMessage = {\n role: 'compactionSummary',\n summary,\n tokensBefore: details.poAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.poAutocompact,\n retainedMessageCount: details.retainedMessages.length,\n };\n}\n\nexport function fileOperationsFromMessages(messages: AutocompactMessage[]): FileOperations {\n const fileOps: FileOperations = { read: new Set(), written: new Set(), edited: new Set() };\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const block of message.content) {\n if (block.type !== 'toolCall') continue;\n const path = typeof block.arguments.path === 'string' ? block.arguments.path : undefined;\n if (!path) continue;\n if (block.name === 'read') fileOps.read.add(path);\n else if (block.name === 'write') fileOps.written.add(path);\n else if (block.name === 'edit') fileOps.edited.add(path);\n }\n }\n return fileOps;\n}\n\nexport function parseState(value: unknown): AutocompactState | undefined {\n if (!isRecord(value)) return undefined;\n if (value.version !== STATE_VERSION || typeof value.cycle !== 'number' || !isPass(value.pass)) return undefined;\n if (\n value.phase !== 'waiting' &&\n value.phase !== 'checkpoint_pending' &&\n value.phase !== 'checkpoint_ready' &&\n value.phase !== 'compacting'\n )\n return undefined;\n const baselineTokens = value.baselineTokens ?? 0;\n if (typeof baselineTokens !== 'number' || baselineTokens < 0) return undefined;\n const baselinePending = value.baselinePending ?? false;\n if (typeof baselinePending !== 'boolean') return undefined;\n const checkpointQueue = value.checkpointQueue ?? [];\n if (\n !Array.isArray(checkpointQueue) ||\n !checkpointQueue.every(isPass) ||\n checkpointQueue.some((pass, index) => index > 0 && pass <= checkpointQueue[index - 1]!)\n )\n return undefined;\n // Sessions persisted before bounded retry landed simply have no attempt history to restore.\n const exhaustedPasses = value.exhaustedPasses ?? [];\n if (!Array.isArray(exhaustedPasses) || !exhaustedPasses.every(isPass)) return undefined;\n const invalidAttempts = value.invalidAttempts ?? 0;\n if (typeof invalidAttempts !== 'number' || invalidAttempts < 0) return undefined;\n if (!isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (value.requestId !== undefined && typeof value.requestId !== 'string') return undefined;\n if (value.compactionPass !== undefined && value.compactionPass !== 2 && value.compactionPass !== 3) return undefined;\n if ('latestCheckpointEntryId' in value) return undefined;\n if (value.latestCheckpointSnapshotLeafId !== undefined && typeof value.latestCheckpointSnapshotLeafId !== 'string')\n return undefined;\n if (value.lastAttemptLeafId !== undefined && typeof value.lastAttemptLeafId !== 'string') return undefined;\n if (value.snapshotLeafId !== undefined && typeof value.snapshotLeafId !== 'string') return undefined;\n if (value.snapshotTokens !== undefined && (typeof value.snapshotTokens !== 'number' || value.snapshotTokens < 0))\n return undefined;\n if (value.pendingCheckpoint !== undefined && typeof value.pendingCheckpoint !== 'string') return undefined;\n\n return {\n version: STATE_VERSION,\n cycle: value.cycle,\n pass: value.pass,\n phase: value.phase,\n checkpointQueue: [...checkpointQueue],\n exhaustedPasses: [...exhaustedPasses],\n invalidAttempts,\n baselineTokens,\n baselinePending,\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n ...(value.requestId ? { requestId: value.requestId } : {}),\n ...(value.compactionPass ? { compactionPass: value.compactionPass } : {}),\n ...(value.latestCheckpointSnapshotLeafId\n ? { latestCheckpointSnapshotLeafId: value.latestCheckpointSnapshotLeafId }\n : {}),\n ...(value.lastAttemptLeafId ? { lastAttemptLeafId: value.lastAttemptLeafId } : {}),\n ...(value.snapshotLeafId ? { snapshotLeafId: value.snapshotLeafId } : {}),\n ...(value.snapshotTokens !== undefined ? { snapshotTokens: value.snapshotTokens } : {}),\n ...(value.pendingCheckpoint ? { pendingCheckpoint: value.pendingCheckpoint } : {}),\n };\n}\n\nexport function checkpointSummaryFromEntry(entry: CompactionPolicyEntry | undefined): string | undefined {\n if (!entry) return undefined;\n if (entry.type === 'compaction') return entry.summary.trim() || undefined;\n if (entry.type === 'custom') {\n return isRecord(entry.data) && typeof entry.data.summary === 'string'\n ? entry.data.summary.trim() || undefined\n : undefined;\n }\n const marker = customMessage(entry);\n if (marker) {\n const content =\n typeof marker.content === 'string'\n ? marker.content\n : marker.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n');\n return content.trim() || undefined;\n }\n return assistantText(entry);\n}\n\nexport function parseCheckpointDecision(response: string): CheckpointDecision {\n const match = response.match(SHOULD_COMPACT_PATTERN);\n const summary = response.replace(SHOULD_COMPACT_PATTERN, '').trim();\n if (!match) return { summary };\n return { summary, shouldCompact: match[1]?.toLowerCase() === 'true' };\n}\n\nexport function isStructuredCheckpoint(summary: string): boolean {\n return CHECKPOINT_HEADINGS.every((heading) => summary.includes(heading));\n}\n\nexport function createRequestId(\n sessionId: string,\n cycle: number,\n pass: AutocompactPass,\n leafId: string | null,\n): string {\n return `${sessionId}:${cycle}:${pass}:${leafId ?? 'root'}`;\n}\n\nexport function checkpointRequestDetails(\n cycle: number,\n pass: AutocompactPass,\n requestId: string,\n): CheckpointRequestDetails {\n return { version: STATE_VERSION, cycle, pass, requestId };\n}\n\nexport function mergeFileDetails(\n current: AutocompactFileDetails,\n fileOps?: FileOperations,\n additional?: AutocompactFileDetails,\n): AutocompactFileDetails {\n const modified = new Set([\n ...current.modifiedFiles,\n ...(additional?.modifiedFiles ?? []),\n ...(fileOps ? [...fileOps.edited, ...fileOps.written] : []),\n ]);\n const read = new Set([...current.readFiles, ...(additional?.readFiles ?? []), ...(fileOps ? [...fileOps.read] : [])]);\n for (const path of modified) read.delete(path);\n return { readFiles: [...read].sort(), modifiedFiles: [...modified].sort() };\n}\n\nexport function fileDetailsFromUnknown(value: unknown): AutocompactFileDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n return { readFiles: value.readFiles, modifiedFiles: value.modifiedFiles };\n}\n\nexport function withCanonicalFileSections(summary: string, details: AutocompactFileDetails): string {\n const sections: string[] = [];\n if (details.readFiles.length > 0) sections.push(`<read-files>\\n${details.readFiles.join('\\n')}\\n</read-files>`);\n if (details.modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${details.modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n const normalized = summary.replace(FILE_SECTION_PATTERN, '').trim();\n return sections.length > 0 ? `${normalized}\\n\\n${sections.join('\\n\\n')}` : normalized;\n}\n"],"mappings":"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"}
|