@agimon-ai/doompi-autocompact 0.0.1-alpha.26 → 0.0.1-alpha.28
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/dist/checkpointWorker.cjs +1 -1
- package/dist/checkpointWorker.cjs.map +1 -1
- package/dist/checkpointWorker.d.cts +1 -1
- package/dist/checkpointWorker.d.mts +1 -1
- package/dist/checkpointWorker.mjs.map +1 -1
- package/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/src/adapters/compaction/policy.cjs +3 -3
- package/dist/src/adapters/compaction/policy.cjs.map +1 -1
- package/dist/src/adapters/compaction/policy.d.cts +1 -0
- package/dist/src/adapters/compaction/policy.d.cts.map +1 -1
- package/dist/src/adapters/compaction/policy.d.mts +1 -0
- package/dist/src/adapters/compaction/policy.d.mts.map +1 -1
- package/dist/src/adapters/compaction/policy.mjs +3 -3
- package/dist/src/adapters/compaction/policy.mjs.map +1 -1
- package/dist/src/adapters/pi/extension.cjs +6 -6
- package/dist/src/adapters/pi/extension.cjs.map +1 -1
- package/dist/src/adapters/pi/extension.d.cts +1 -2
- package/dist/src/adapters/pi/extension.d.cts.map +1 -1
- package/dist/src/adapters/pi/extension.d.mts +1 -2
- package/dist/src/adapters/pi/extension.d.mts.map +1 -1
- package/dist/src/adapters/pi/extension.mjs +11 -11
- package/dist/src/adapters/pi/extension.mjs.map +1 -1
- package/dist/src/adapters/telemetry/logSinkTelemetry.cjs +1 -1
- package/dist/src/adapters/telemetry/logSinkTelemetry.cjs.map +1 -1
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts +12 -11
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts.map +1 -1
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts +12 -11
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts.map +1 -1
- package/dist/src/adapters/telemetry/logSinkTelemetry.mjs.map +1 -1
- package/dist/src/services/summarizationModel.cjs.map +1 -1
- package/dist/src/services/summarizationModel.d.cts +0 -1
- package/dist/src/services/summarizationModel.d.cts.map +1 -1
- package/dist/src/services/summarizationModel.d.mts +0 -1
- package/dist/src/services/summarizationModel.d.mts.map +1 -1
- package/dist/src/services/summarizationModel.mjs.map +1 -1
- package/dist/src/types/constants.cjs.map +1 -1
- package/dist/src/types/constants.mjs.map +1 -1
- package/dist/src/types/index.d.cts +1 -0
- package/dist/src/types/index.d.cts.map +1 -1
- package/dist/src/types/index.d.mts +1 -0
- package/dist/src/types/index.d.mts.map +1 -1
- package/package.json +10 -10
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require(
|
|
1
|
+
let e=require("node:worker_threads"),t=require("@earendil-works/pi-coding-agent");async function n(n){try{let r=await(0,t.generateSummary)(n.messages,n.model,n.reserveTokens,n.apiKey,n.headers,void 0,n.instructions,n.previousCheckpoint,n.thinkingLevel,void 0,n.env);e.parentPort?.postMessage({checkpoint:r})}catch(t){e.parentPort?.postMessage({error:t instanceof Error?t.message:String(t)})}}n(e.workerData);
|
|
2
2
|
//# sourceMappingURL=checkpointWorker.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpointWorker.cjs","names":["workerData"],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\nimport { generateSummary } from '@earendil-works/pi-coding-agent';\n\ntype GenerateSummaryArguments = Parameters<typeof generateSummary>;\n\ninterface CheckpointWorkerInput {\n messages: GenerateSummaryArguments[0];\n model: GenerateSummaryArguments[1];\n reserveTokens: GenerateSummaryArguments[2];\n apiKey?: GenerateSummaryArguments[3];\n headers?: GenerateSummaryArguments[4];\n instructions: GenerateSummaryArguments[6];\n previousCheckpoint?: GenerateSummaryArguments[7];\n thinkingLevel?: GenerateSummaryArguments[8];\n env?: GenerateSummaryArguments[10];\n}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateSummary(\n input.messages,\n input.model,\n input.reserveTokens,\n input.apiKey,\n input.headers,\n undefined,\n input.instructions,\n input.previousCheckpoint,\n input.thinkingLevel,\n undefined,\n input.env,\n );\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nvoid summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"kFAkBA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAA,
|
|
1
|
+
{"version":3,"file":"checkpointWorker.cjs","names":["generateSummary","workerData"],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\nimport { generateSummary } from '@earendil-works/pi-coding-agent';\n\ntype GenerateSummaryArguments = Parameters<typeof generateSummary>;\n\ninterface CheckpointWorkerInput {\n messages: GenerateSummaryArguments[0];\n model: GenerateSummaryArguments[1];\n reserveTokens: GenerateSummaryArguments[2];\n apiKey?: GenerateSummaryArguments[3];\n headers?: GenerateSummaryArguments[4];\n instructions: GenerateSummaryArguments[6];\n previousCheckpoint?: GenerateSummaryArguments[7];\n thinkingLevel?: GenerateSummaryArguments[8];\n env?: GenerateSummaryArguments[10];\n}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateSummary(\n input.messages,\n input.model,\n input.reserveTokens,\n input.apiKey,\n input.headers,\n undefined,\n input.instructions,\n input.previousCheckpoint,\n input.thinkingLevel,\n undefined,\n input.env,\n );\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nvoid summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"kFAkBA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAA,EAAMA,EAAAA,gBAAAA,CACvB,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,GACR,EACA,EAAA,YAAY,YAAY,CAAE,YAAW,CAAC,CACxC,OAAS,EAAO,CACd,EAAA,YAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAAE,CAAC,CAC3F,CACF,CAEK,EAAUC,EAAAA,UAAmC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpointWorker.mjs","names":[],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\nimport { generateSummary } from '@earendil-works/pi-coding-agent';\n\ntype GenerateSummaryArguments = Parameters<typeof generateSummary>;\n\ninterface CheckpointWorkerInput {\n messages: GenerateSummaryArguments[0];\n model: GenerateSummaryArguments[1];\n reserveTokens: GenerateSummaryArguments[2];\n apiKey?: GenerateSummaryArguments[3];\n headers?: GenerateSummaryArguments[4];\n instructions: GenerateSummaryArguments[6];\n previousCheckpoint?: GenerateSummaryArguments[7];\n thinkingLevel?: GenerateSummaryArguments[8];\n env?: GenerateSummaryArguments[10];\n}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateSummary(\n input.messages,\n input.model,\n input.reserveTokens,\n input.apiKey,\n input.headers,\n undefined,\n input.instructions,\n input.previousCheckpoint,\n input.thinkingLevel,\n undefined,\n input.env,\n );\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nvoid summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"mIAkBA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAM,EACvB,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,
|
|
1
|
+
{"version":3,"file":"checkpointWorker.mjs","names":[],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\nimport { generateSummary } from '@earendil-works/pi-coding-agent';\n\ntype GenerateSummaryArguments = Parameters<typeof generateSummary>;\n\ninterface CheckpointWorkerInput {\n messages: GenerateSummaryArguments[0];\n model: GenerateSummaryArguments[1];\n reserveTokens: GenerateSummaryArguments[2];\n apiKey?: GenerateSummaryArguments[3];\n headers?: GenerateSummaryArguments[4];\n instructions: GenerateSummaryArguments[6];\n previousCheckpoint?: GenerateSummaryArguments[7];\n thinkingLevel?: GenerateSummaryArguments[8];\n env?: GenerateSummaryArguments[10];\n}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateSummary(\n input.messages,\n input.model,\n input.reserveTokens,\n input.apiKey,\n input.headers,\n undefined,\n input.instructions,\n input.previousCheckpoint,\n input.thinkingLevel,\n undefined,\n input.env,\n );\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nvoid summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"mIAkBA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAM,EACvB,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,GACR,EACA,GAAY,YAAY,CAAE,YAAW,CAAC,CACxC,OAAS,EAAO,CACd,GAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAAE,CAAC,CAC3F,CACF,CAEK,EAAU,CAAmC"}
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(
|
|
1
|
+
const e=require("../src/adapters/pi/extension.cjs");module.exports=e.autocompactExtension;
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{autocompactExtension as e}from"../src/adapters/pi/extension.mjs";export{e as default};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src/adapters/compaction/policy.cjs"),t=require("./src/adapters/pi/extension.cjs");exports.installAutocompactRuntime=t.installAutocompactRuntime,exports.thresholdTokens=e.thresholdTokens;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const e=require(
|
|
2
|
-
`).trim()||void 0}function c(e){return i(e)&&typeof e.role==`string`}function l(e){if(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(c)||!i(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function u(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function d(n,r,i=0){let a=e.COMPACTION_THRESHOLDS[n],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-t.DEFAULT_COMPACTION_SETTINGS.reserveTokens;return l>o?Math.min(c,l):c}function f(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function p(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function m(e,n){let r=e.findIndex(e=>e.id===n);return r===-1?[]:e.slice(r+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,t.sessionEntryToContextMessages)(e))}function h(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=l(r.details),a=v(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&l(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function g(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function _(e){if(!i(e)||e.version!==2||typeof e.cycle!=`number`||!o(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(o)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let s=e.exhaustedPasses??[];if(!Array.isArray(s)||!s.every(o))return;let c=e.invalidAttempts??0;if(!(typeof c!=`number`||c<0)&&!(!a(e.readFiles)||!a(e.modifiedFiles))
|
|
1
|
+
const e=require("../../types/constants.cjs");let t=require("@earendil-works/pi-coding-agent");const n=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,r=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function i(e){return typeof e==`object`&&!!e}function a(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function o(e){return e===1||e===2||e===3}function s(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
+
`).trim()||void 0}function c(e){return i(e)&&typeof e.role==`string`}function l(e){if(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(c)||!i(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function u(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function d(n,r,i=0){let a=e.COMPACTION_THRESHOLDS[n],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-t.DEFAULT_COMPACTION_SETTINGS.reserveTokens;return l>o?Math.min(c,l):c}function f(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function p(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function m(e,n){let r=e.findIndex(e=>e.id===n);return r===-1?[]:e.slice(r+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,t.sessionEntryToContextMessages)(e))}function h(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=l(r.details),a=v(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&l(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function g(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function _(e){if(!i(e)||e.version!==2||typeof e.cycle!=`number`||!o(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(o)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let s=e.exhaustedPasses??[];if(!Array.isArray(s)||!s.every(o))return;let c=e.invalidAttempts??0;if(!(typeof c!=`number`||c<0)&&!(!a(e.readFiles)||!a(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...s],invalidAttempts:c,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function v(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?i(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
3
3
|
`)).trim()||void 0:s(e)}function y(e){let t=e.match(n),r=e.replace(n,``).trim();return t?{summary:r,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:r}}function b(t){return e.CHECKPOINT_HEADINGS.every(e=>t.includes(e))}function x(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function S(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function C(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function w(e){if(!(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function T(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
|
|
4
4
|
`)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
|
|
5
5
|
`)}\n</modified-files>`);let i=e.replace(r,``).trim();return n.length>0?`${i}\n\n${n.join(`
|
|
6
6
|
|
|
7
|
-
`)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
|
|
7
|
+
`)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.contextDetailsFromUnknown=l,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
|
|
8
8
|
//# sourceMappingURL=policy.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.cjs","names":["COMPACTION_THRESHOLDS","DEFAULT_COMPACTION_SETTINGS","CHECKPOINT_HEADINGS"],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\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: SessionEntry): 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.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\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 doomAutocompact: {\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\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[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 * threshold.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\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | 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 (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && 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: SessionEntry[],\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) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.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)?.doomAutocompact.requestId === details.doomAutocompact.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.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\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: SessionEntry | 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 if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.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":"8FAwBA,MAAM,EAAyB,sDACzB,EAAuB,+EAE7B,SAAS,EAAS,EAAkD,CAClE,OAAO,OAAO,GAAU,YAAY,EAGtC,SAAS,EAAc,EAAmC,CACxD,OAAO,MAAM,QAAQ,EAAM,EAAI,EAAM,MAAO,GAAS,OAAO,GAAS,SAAS,CAGhF,SAAS,EAAO,EAA0C,CACxD,OAAO,IAAU,GAAK,IAAU,GAAK,IAAU,EAGjD,SAAS,EAAc,EAAyC,CAC1D,OAAM,OAAS,WAAa,EAAM,QAAQ,OAAS,aAMvD,OALa,EAAM,QAAQ,QACxB,OAAQ,GAAU,EAAM,OAAS,OAAO,CACxC,IAAK,GAAU,EAAM,KAAK,CAC1B,KAAK;EAAK,CACV,MACQ,EAAI,IAAA,GAGjB,SAAS,EAAqB,EAA6C,CACzE,OAAO,EAAS,EAAM,EAAI,OAAO,EAAM,MAAS,SAGlD,SAAgB,EAA0B,EAAuD,CAG/F,GAFI,CAAC,EAAS,EAAM,EAAI,CAAC,EAAc,EAAM,UAAU,EAAI,CAAC,EAAc,EAAM,cAAc,EAC1F,CAAC,MAAM,QAAQ,EAAM,iBAAiB,EAAI,CAAC,EAAM,iBAAiB,MAAM,EAAqB,EAC7F,CAAC,EAAS,EAAM,gBAAgB,CAAE,OACtC,IAAM,EAAS,EAAM,gBAEnB,OAAO,UAAA,GACN,EAAO,OAAS,GAAK,EAAO,OAAS,GACtC,OAAO,EAAO,OAAU,UACxB,OAAO,EAAO,WAAc,UAC5B,OAAO,EAAO,gBAAmB,UACjC,OAAO,EAAO,cAAiB,UAGjC,MAAO,CACL,UAAW,CAAC,GAAG,EAAM,UAAU,CAC/B,cAAe,CAAC,GAAG,EAAM,cAAc,CACvC,iBAAkB,CAAC,GAAG,EAAM,iBAAiB,CAC7C,gBAAiB,CACf,QAAA,EACA,MAAO,EAAO,MACd,KAAM,EAAO,KACb,UAAW,EAAO,UAClB,eAAgB,EAAO,eACvB,aAAc,EAAO,aACtB,CACF,CAGH,SAAgB,GAAuC,CACrD,MAAO,CACL,QAAA,EACA,MAAO,EACP,KAAM,EACN,MAAO,UACP,gBAAiB,EAAE,CACnB,gBAAiB,EAAE,CACnB,gBAAiB,EACjB,eAAgB,EAChB,gBAAiB,GACjB,UAAW,EAAE,CACb,cAAe,EAAE,CAClB,CAGH,SAAgB,EAAgB,EAAuB,EAAuB,EAAiB,EAAW,CACxG,IAAM,EAAYA,EAAAA,sBAAsB,GAClC,EAAW,KAAK,IAAI,EAAG,KAAK,IAAI,EAAgB,EAAc,CAAC,CAC/D,EAAY,EAAgB,EAC5B,EAAS,EAAW,KAAK,IAAI,KAAK,MAAM,EAAY,EAAU,MAAM,CAAE,EAAU,UAAU,CAI1F,EAAgB,EAAgBC,EAAAA,4BAA4B,cAClE,OAAO,EAAgB,EAAW,KAAK,IAAI,EAAQ,EAAc,CAAG,EAGtE,SAAgB,EAA8B,EAAyD,CACrG,OAAO,EAAc,SAClB,GACC,EAAM,OAAS,cAEd,EAAM,OAAS,UAAY,EAAM,aAAA,+BAEjC,EAAM,OAAS,mBACb,EAAM,aAAA,+BAA0C,EAAM,aAAA,4BAC5D,CAGH,SAAgB,EAAuB,EAAwC,CAC7E,IAAM,EAAgB,EAAc,cACjC,GACC,EAAM,OAAS,cAAiB,EAAM,OAAS,kBAAoB,EAAM,aAAA,2BAC5E,CACD,OAAO,EAAc,MAAM,EAAgB,EAAE,CAAC,KAAM,GAAU,CAC5D,GAAI,EAAM,OAAS,WAAa,EAAM,QAAQ,OAAS,YAAa,MAAO,GAC3E,GAAM,CAAE,aAAY,SAAU,EAAM,QAEpC,OADI,IAAe,WAAa,IAAe,SAAW,CAAC,EAAc,IACjE,EAAM,aAAe,EAAM,MAAQ,EAAM,OAAS,EAAM,UAAY,EAAM,YAAc,GAChG,CAGJ,SAAgB,EACd,EACA,EACsB,CACtB,IAAM,EAAgB,EAAc,UAAW,GAAU,EAAM,KAAO,EAAe,CAErF,OADI,IAAkB,GAAW,EAAE,CAC5B,EACJ,MAAM,EAAgB,EAAE,CACxB,OAAQ,GAAU,EAAM,OAAS,kBAAoB,EAAM,aAAA,8BAAuC,CAClG,QAAS,IAAA,EAAA,EAAA,+BAAwC,EAAM,CAAC,CAG7D,SAAgB,EACd,EACA,EACmB,CACnB,IAAM,EAAwB,EAAc,cAAe,GAAU,EAAM,OAAS,aAAa,CAC3F,EAAc,EACjB,MAAM,EAAwB,EAAE,CAChC,SAAU,GAAU,EAAM,OAAS,kBAAoB,EAAM,aAAA,2BAAoC,CACpG,GAAI,CAAC,GAAe,EAAY,OAAS,iBACvC,MAAO,CAAE,WAAU,qBAAsB,EAAG,CAG9C,IAAM,EAAU,EAA0B,EAAY,QAAQ,CACxD,EAAU,EAA2B,EAAY,CACvD,GAAI,CAAC,GAAW,CAAC,EAAS,MAAO,CAAE,WAAU,cAAe,GAAM,qBAAsB,EAAG,CAE3F,IAAM,EAAqB,EAAS,cACjC,GACC,EAAQ,OAAS,UACjB,EAAQ,aAAA,4BACR,EAA0B,EAAQ,QAAQ,EAAE,gBAAgB,YAAc,EAAQ,gBAAgB,UACrG,CASD,OARI,IAAuB,GAAW,CAAE,WAAU,cAAe,GAAM,qBAAsB,EAAG,CAQzF,CACL,SAAU,CAAC,CANX,KAAM,oBACN,UACA,aAAc,EAAQ,gBAAgB,aACtC,UAAW,EAAS,IAAqB,WAAa,KAAK,KAAK,CAGvC,CAAE,GAAG,EAAQ,iBAAkB,GAAG,EAAS,MAAM,EAAqB,EAAE,CAAC,CAClG,OAAQ,EAAQ,gBAChB,qBAAsB,EAAQ,iBAAiB,OAChD,CAGH,SAAgB,EAA2B,EAAgD,CACzF,IAAM,EAA0B,CAAE,KAAM,IAAI,IAAO,QAAS,IAAI,IAAO,OAAQ,IAAI,IAAO,CAC1F,IAAK,IAAM,KAAW,EAChB,KAAQ,OAAS,YACrB,IAAK,IAAM,KAAS,EAAQ,QAAS,CACnC,GAAI,EAAM,OAAS,WAAY,SAC/B,IAAM,EAAO,OAAO,EAAM,UAAU,MAAS,SAAW,EAAM,UAAU,KAAO,IAAA,GAC1E,IACD,EAAM,OAAS,OAAQ,EAAQ,KAAK,IAAI,EAAK,CACxC,EAAM,OAAS,QAAS,EAAQ,QAAQ,IAAI,EAAK,CACjD,EAAM,OAAS,QAAQ,EAAQ,OAAO,IAAI,EAAK,EAG5D,OAAO,EAGT,SAAgB,EAAW,EAA8C,CAGvE,GAFI,CAAC,EAAS,EAAM,EAChB,EAAM,UAAA,GAA6B,OAAO,EAAM,OAAU,UAAY,CAAC,EAAO,EAAM,KAAK,EAE3F,EAAM,QAAU,WAChB,EAAM,QAAU,sBAChB,EAAM,QAAU,oBAChB,EAAM,QAAU,aAEhB,OACF,IAAM,EAAiB,EAAM,gBAAkB,EAC/C,GAAI,OAAO,GAAmB,UAAY,EAAiB,EAAG,OAC9D,IAAM,EAAkB,EAAM,iBAAmB,GACjD,GAAI,OAAO,GAAoB,UAAW,OAC1C,IAAM,EAAkB,EAAM,iBAAmB,EAAE,CACnD,GACE,CAAC,MAAM,QAAQ,EAAgB,EAC/B,CAAC,EAAgB,MAAM,EAAO,EAC9B,EAAgB,MAAM,EAAM,IAAU,EAAQ,GAAK,GAAQ,EAAgB,EAAQ,GAAI,CAEvF,OAEF,IAAM,EAAkB,EAAM,iBAAmB,EAAE,CACnD,GAAI,CAAC,MAAM,QAAQ,EAAgB,EAAI,CAAC,EAAgB,MAAM,EAAO,CAAE,OACvE,IAAM,EAAkB,EAAM,iBAAmB,EAC7C,YAAO,GAAoB,UAAY,EAAkB,IACzD,GAAC,EAAc,EAAM,UAAU,EAAI,CAAC,EAAc,EAAM,cAAc,GACtE,IAAM,YAAc,IAAA,IAAa,OAAO,EAAM,WAAc,WAC5D,IAAM,iBAAmB,IAAA,IAAa,EAAM,iBAAmB,GAAK,EAAM,iBAAmB,IAC7F,8BAA6B,IAC7B,IAAM,iCAAmC,IAAA,IAAa,OAAO,EAAM,gCAAmC,WAEtG,IAAM,oBAAsB,IAAA,IAAa,OAAO,EAAM,mBAAsB,WAC5E,IAAM,iBAAmB,IAAA,IAAa,OAAO,EAAM,gBAAmB,WACtE,IAAM,iBAAmB,IAAA,KAAc,OAAO,EAAM,gBAAmB,UAAY,EAAM,eAAiB,KAE1G,IAAM,oBAAsB,IAAA,IAAa,OAAO,EAAM,mBAAsB,UAEhF,MAAO,CACL,QAAA,EACA,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,MAAO,EAAM,MACb,gBAAiB,CAAC,GAAG,EAAgB,CACrC,gBAAiB,CAAC,GAAG,EAAgB,CACrC,kBACA,iBACA,kBACA,UAAW,CAAC,GAAG,EAAM,UAAU,CAC/B,cAAe,CAAC,GAAG,EAAM,cAAc,CACvC,GAAI,EAAM,UAAY,CAAE,UAAW,EAAM,UAAW,CAAG,EAAE,CACzD,GAAI,EAAM,eAAiB,CAAE,eAAgB,EAAM,eAAgB,CAAG,EAAE,CACxE,GAAI,EAAM,+BACN,CAAE,+BAAgC,EAAM,+BAAgC,CACxE,EAAE,CACN,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CACjF,GAAI,EAAM,eAAiB,CAAE,eAAgB,EAAM,eAAgB,CAAG,EAAE,CACxE,GAAI,EAAM,iBAAmB,IAAA,GAAuD,EAAE,CAA7C,CAAE,eAAgB,EAAM,eAAgB,CACjF,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CAClF,CAGH,SAAgB,EAA2B,EAAqD,CACzF,KAiBL,OAhBI,EAAM,OAAS,aAAqB,EAAM,QAAQ,MAAM,EAAI,IAAA,GAC5D,EAAM,OAAS,SACV,EAAS,EAAM,KAAK,EAAI,OAAO,EAAM,KAAK,SAAY,UACzD,EAAM,KAAK,QAAQ,MAAM,EACzB,IAAA,GAEF,EAAM,OAAS,kBAEf,OAAO,EAAM,SAAY,SACrB,EAAM,QACN,EAAM,QACH,OAAQ,GAAU,EAAM,OAAS,OAAO,CACxC,IAAK,GAAU,EAAM,KAAK,CAC1B,KAAK;EAAK,EACJ,MAAM,EAAI,IAAA,GAEpB,EAAc,EAAM,CAG7B,SAAgB,EAAwB,EAAsC,CAC5E,IAAM,EAAQ,EAAS,MAAM,EAAuB,CAC9C,EAAU,EAAS,QAAQ,EAAwB,GAAG,CAAC,MAAM,CAEnE,OADK,EACE,CAAE,UAAS,cAAe,EAAM,IAAI,aAAa,GAAK,OAAQ,CADlD,CAAE,UAAS,CAIhC,SAAgB,EAAuB,EAA0B,CAC/D,OAAOC,EAAAA,oBAAoB,MAAO,GAAY,EAAQ,SAAS,EAAQ,CAAC,CAG1E,SAAgB,EACd,EACA,EACA,EACA,EACQ,CACR,MAAO,GAAG,EAAU,GAAG,EAAM,GAAG,EAAK,GAAG,GAAU,SAGpD,SAAgB,EACd,EACA,EACA,EAC0B,CAC1B,MAAO,CAAE,QAAA,EAAwB,QAAO,OAAM,YAAW,CAG3D,SAAgB,EACd,EACA,EACA,EACwB,CACxB,IAAM,EAAW,IAAI,IAAI,CACvB,GAAG,EAAQ,cACX,GAAI,GAAY,eAAiB,EAAE,CACnC,GAAI,EAAU,CAAC,GAAG,EAAQ,OAAQ,GAAG,EAAQ,QAAQ,CAAG,EAAE,CAC3D,CAAC,CACI,EAAO,IAAI,IAAI,CAAC,GAAG,EAAQ,UAAW,GAAI,GAAY,WAAa,EAAE,CAAG,GAAI,EAAU,CAAC,GAAG,EAAQ,KAAK,CAAG,EAAE,CAAE,CAAC,CACrH,IAAK,IAAM,KAAQ,EAAU,EAAK,OAAO,EAAK,CAC9C,MAAO,CAAE,UAAW,CAAC,GAAG,EAAK,CAAC,MAAM,CAAE,cAAe,CAAC,GAAG,EAAS,CAAC,MAAM,CAAE,CAG7E,SAAgB,EAAuB,EAAoD,CACrF,MAAC,EAAS,EAAM,EAAI,CAAC,EAAc,EAAM,UAAU,EAAI,CAAC,EAAc,EAAM,cAAc,EAC9F,MAAO,CAAE,UAAW,EAAM,UAAW,cAAe,EAAM,cAAe,CAG3E,SAAgB,EAA0B,EAAiB,EAAyC,CAClG,IAAM,EAAqB,EAAE,CACzB,EAAQ,UAAU,OAAS,GAAG,EAAS,KAAK,iBAAiB,EAAQ,UAAU,KAAK;EAAK,CAAC,iBAAiB,CAC3G,EAAQ,cAAc,OAAS,GACjC,EAAS,KAAK,qBAAqB,EAAQ,cAAc,KAAK;EAAK,CAAC,qBAAqB,CAE3F,IAAM,EAAa,EAAQ,QAAQ,EAAsB,GAAG,CAAC,MAAM,CACnE,OAAO,EAAS,OAAS,EAAI,GAAG,EAAW,MAAM,EAAS,KAAK;;EAAO,GAAK"}
|
|
1
|
+
{"version":3,"file":"policy.cjs","names":["COMPACTION_THRESHOLDS","DEFAULT_COMPACTION_SETTINGS","sessionEntryToContextMessages","CHECKPOINT_HEADINGS"],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\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: SessionEntry): 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.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\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 doomAutocompact: {\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\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[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 * threshold.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\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | 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 (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && 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: SessionEntry[],\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) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.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)?.doomAutocompact.requestId === details.doomAutocompact.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.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\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: SessionEntry | 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 if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.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,4 +1,5 @@
|
|
|
1
1
|
import { AutocompactPass } from "../../types/index.cjs";
|
|
2
|
+
import "@earendil-works/pi-coding-agent";
|
|
2
3
|
//#region src/adapters/compaction/policy.d.ts
|
|
3
4
|
declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
|
|
4
5
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.cts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.d.cts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":";;;iBAkGgB,gBAAgB,MAAM,iBAAiB,uBAAuB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AutocompactPass } from "../../types/index.mjs";
|
|
2
|
+
import "@earendil-works/pi-coding-agent";
|
|
2
3
|
//#region src/adapters/compaction/policy.d.ts
|
|
3
4
|
declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
|
|
4
5
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.mts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.d.mts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":";;;iBAkGgB,gBAAgB,MAAM,iBAAiB,uBAAuB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"../../types/constants.mjs";import{DEFAULT_COMPACTION_SETTINGS as n,sessionEntryToContextMessages as r}from"@earendil-works/pi-coding-agent";const i=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,a=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function o(e){return typeof e==`object`&&!!e}function s(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function c(e){return e===1||e===2||e===3}function l(e){if(
|
|
2
|
-
`).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))
|
|
1
|
+
import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"../../types/constants.mjs";import{DEFAULT_COMPACTION_SETTINGS as n,sessionEntryToContextMessages as r}from"@earendil-works/pi-coding-agent";const i=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,a=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function o(e){return typeof e==`object`&&!!e}function s(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function c(e){return e===1||e===2||e===3}function l(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
+
`).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...i],invalidAttempts:a,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function b(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?o(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
3
3
|
`)).trim()||void 0:l(e)}function x(e){let t=e.match(i),n=e.replace(i,``).trim();return t?{summary:n,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:n}}function S(t){return e.every(e=>t.includes(e))}function C(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function w(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function T(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function E(e){if(!(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function D(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
|
|
4
4
|
`)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
|
|
5
5
|
`)}\n</modified-files>`);let r=e.replace(a,``).trim();return n.length>0?`${r}\n\n${n.join(`
|
|
6
6
|
|
|
7
|
-
`)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
|
|
7
|
+
`)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,d as contextDetailsFromUnknown,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
|
|
8
8
|
//# sourceMappingURL=policy.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.mjs","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\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: SessionEntry): 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.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\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 doomAutocompact: {\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\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[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 * threshold.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\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | 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 (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && 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: SessionEntry[],\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) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.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)?.doomAutocompact.requestId === details.doomAutocompact.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.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\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: SessionEntry | 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 if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.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
|
+
{"version":3,"file":"policy.mjs","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\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: SessionEntry): 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.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\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 doomAutocompact: {\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\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[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 * threshold.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\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | 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 (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && 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: SessionEntry[],\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) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.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)?.doomAutocompact.requestId === details.doomAutocompact.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.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\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: SessionEntry | 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 if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.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,6 +1,6 @@
|
|
|
1
|
-
const e=require(
|
|
1
|
+
const e=require("../../types/constants.cjs"),t=require("../compaction/policy.cjs"),n=require("../../services/summarizationModel.cjs"),r=require("../telemetry/logSinkTelemetry.cjs");let i=require("node:fs"),a=require("node:path"),o=require("node:url"),s=require("node:worker_threads"),c=require("@agimon-ai/doompi-config"),l=require("@agimon-ai/doompi-extension-contracts/cordis-host"),u=require("@agimon-ai/doompi-task/store/paths"),d=require("@agimon-ai/doompi-task/store/taskStore"),f=require("@agimon-ai/doompi-team/api/team-snapshot"),p=require("@agimon-ai/doompi-extension-contracts/ui-hub"),m=require("@earendil-works/pi-coding-agent");const h=`@root`,g=`doom-autocompact`,_={waiting:`waiting`,checkpointPending:`checkpoint_pending`,checkpointReady:`checkpoint_ready`,compacting:`compacting`};function v(e,t={}){return{"pi.session.id":e.sessionManager.getSessionId(),...t}}function y(e){for(let n=e.length-1;n>=0;--n){let r=e[n];if(r?.type!==`custom`||r.customType!==`doom-autocompact-state`)continue;let i=t.parseState(r.data);if(i)return i}}function b(e){for(let t of e.sessionManager.getBranch().toReversed())if((t.type!==`custom`||t.customType!==`doom-autocompact-state`)&&t.type!==`label`)return t.id;return h}function x(e){return e instanceof Error?e.message:String(e)}function S(e){for(let t of e.toReversed()){if(t.type!==`custom`||t.customType!==`agent-harness-plan-document`)continue;if(!t.data||typeof t.data!=`object`)return;let e=t.data;return typeof e.content!=`string`||typeof e.path!=`string`?void 0:{content:e.content,path:e.path}}}function C(e){let t=[];try{let n=new d.TaskStore({cwd:e.cwd,report:{error:(e,n)=>t.push(`${e}: ${x(n)}`),warn:(e,n)=>t.push(`${e}: ${x(n)}`),event:()=>void 0}});return n.configureSession((0,u.resolveSessionKey)(e.sessionManager.getSessionId())),{tasks:n.read().tasks,...t.length>0?{error:t.join(`; `)}:{}}}catch(e){return{tasks:[],error:x(e)}}}function w(){try{let e=(0,f.readActiveTeamSnapshot)();return e?{members:e.members}:{}}catch(e){return{error:x(e)}}}function T(e){return e.tasks.filter(e=>e.status===`pending`||e.status===`in_progress`||e.status===`failed`).map(e=>({id:e.id,status:e.status,subject:e.subject,...e.activeForm?{activeForm:e.activeForm}:{},...e.owner?{owner:e.owner}:{},...e.blockedBy?.length?{blockedBy:e.blockedBy}:{},...e.delegation?{delegation:{agent:e.delegation.agent,state:e.delegation.state,...e.delegation.result?.error?{error:e.delegation.result.error}:{}}}:{}}))}function E(e,t){let n=e.map(e=>{let t=[e.activeForm?`active: ${e.activeForm}`:void 0,e.owner?`owner: ${e.owner}`:void 0,e.blockedBy?.length?`blocked by: ${e.blockedBy.join(`, `)}`:void 0,e.delegation?`delegation: ${e.delegation.agent} (${e.delegation.state})`:void 0,e.delegation?.error?`error: ${e.delegation.error}`:void 0].filter(e=>!!e);return`- #${e.id} [${e.status}] ${e.subject}${t.length>0?` | ${t.join(` | `)}`:``}`});return t&&n.push(`- Task snapshot error: ${t}`),n.length>0?n.join(`
|
|
2
2
|
`):`(no active tasks)`}function D(e){let t=(e.members??[]).map(e=>{let t=[`role: ${e.role}`,e.agent?`agent: ${e.agent}`:void 0,e.runId?`run: ${e.runId}`:void 0,e.task?`task ${e.task.id}: ${e.task.subject}`:void 0].filter(e=>!!e);return`- ${e.name} | ${t.join(` | `)}`});return e.error&&t.push(`- Team snapshot error: ${e.error}`),t.length>0?t.join(`
|
|
3
|
-
`):e.members?`(no active team members)`:`(team runtime unavailable)`}function
|
|
3
|
+
`):e.members?`(no active team members)`:`(team runtime unavailable)`}function O(e,t,n){let r=S(e);return{...r?{planPath:r.path}:{},tasks:T(t),...t.error?{taskError:t.error}:{},teamAvailable:!!n.members,teamMembers:n.members??[],...n.error?{teamError:n.error}:{}}}function k(e){let t=e.planPath?`Source: ${e.planPath}\nExact plan content is restored separately by Doom Plan.`:`(no active plan document)`,n={...e.teamAvailable?{members:e.teamMembers}:{},...e.teamError?{error:e.teamError}:{}};return`<compaction-runtime-state>
|
|
4
4
|
Authoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.
|
|
5
5
|
<active-plan>
|
|
6
6
|
${t}
|
|
@@ -11,7 +11,7 @@ ${E(e.tasks,e.taskError)}
|
|
|
11
11
|
<active-team>
|
|
12
12
|
${D(n)}
|
|
13
13
|
</active-team>
|
|
14
|
-
</compaction-runtime-state>`}function
|
|
14
|
+
</compaction-runtime-state>`}function A(e){return{"autocompact.runtime.plan_present":!!e.planPath,"autocompact.runtime.task_count":e.tasks.length,"autocompact.runtime.team_available":e.teamAvailable,"autocompact.runtime.team_member_count":e.teamMembers.length}}function j(e){let t=e.plan?`Source: ${e.plan.path}\n\n${e.plan.content}`:`(no active plan document)`,n=[e.readFiles.length>0?`Read files: ${e.readFiles.join(`, `)}`:void 0,e.modifiedFiles.length>0?`Modified files: ${e.modifiedFiles.join(`, `)}`:void 0].filter(e=>!!e);return`<compaction-steering priority="user,plan,tasks,team,important-context,recent-messages">
|
|
15
15
|
<user-prompt source="conversation">
|
|
16
16
|
Treat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.
|
|
17
17
|
</user-prompt>
|
|
@@ -28,11 +28,11 @@ ${D(e.teamSnapshot)}
|
|
|
28
28
|
${n.length>0?n.join(`
|
|
29
29
|
`):`(none recorded outside the conversation)`}
|
|
30
30
|
</important-context>
|
|
31
|
-
</compaction-steering>`}function
|
|
31
|
+
</compaction-steering>`}function M(e,t){let n=e===2?`Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.
|
|
32
32
|
|
|
33
33
|
`:``;return`Create Doom autocompact checkpoint pass ${e}.
|
|
34
34
|
|
|
35
|
-
${
|
|
35
|
+
${j(t)}
|
|
36
36
|
|
|
37
37
|
Apply the steering evidence in priority order. Do not invent plan, task, or team state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.
|
|
38
38
|
|
|
@@ -46,5 +46,5 @@ ${n}Return only the decision tag when required, followed by a concise structured
|
|
|
46
46
|
### Blocked
|
|
47
47
|
## Key Decisions
|
|
48
48
|
## Next Steps
|
|
49
|
-
## Critical Context`}function M(e,n,r){let i=t.projectContextMessages((0,m.buildSessionContext)(n).messages,n).messages;if(e===1||!r)return i;let a=n.findIndex(e=>e.id===r);return a===-1?i:n.slice(a+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,m.sessionEntryToContextMessages)(e))}function N(e){let t=(0,o.fileURLToPath)(e),n=(0,a.dirname)(t);for(;;){let e=(0,a.join)(n,`checkpointWorker.mjs`);if((0,i.existsSync)(e))return(0,o.pathToFileURL)(e);let t=(0,a.dirname)(n);if(t===n)break;n=t}throw Error(`Cannot find checkpointWorker.mjs by walking from ${t}.`)}function P(e,t){return new Promise((n,r)=>{let i=new s.Worker(N(require(`url`).pathToFileURL(__filename).href),{workerData:e}),a=!1,o=e=>{a||(a=!0,t.removeEventListener(`abort`,c),e())},c=()=>{o(()=>{i.terminate(),r(t.reason instanceof Error?t.reason:Error(`Autocompact summarization aborted.`))})};i.once(`message`,e=>{o(()=>{typeof e.checkpoint==`string`?n(e.checkpoint):r(Error(e.error??`Autocompact summarization worker returned no checkpoint.`))})}),i.once(`error`,e=>o(()=>r(e))),i.once(`exit`,e=>{e!==0&&o(()=>r(Error(`Autocompact summarization worker exited with code ${e}.`)))}),t.addEventListener(`abort`,c,{once:!0}),i.unref(),t.aborted&&c()})}function F(e){try{return(0,c.loadDoomConfig)((0,c.getHarnessState)().root??e).modes?.planning?.subagents}catch{process.emitWarning(`Doom autocompact planning configuration could not be loaded; using the active session model instead.`);return}}function I(e){let t=F(e.cwd),r=t?.model?n.parseModelReference(t.model):void 0,i=r?e.modelRegistry.find(r.provider,r.modelId):void 0,a=i??e.model;if(!a)return;let o=t?.thinking??(i?r?.thinking:void 0)??e.thinkingLevel;return{model:a,...o?{thinkingLevel:o}:{}}}async function L(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);return P({messages:e.messages,model:n.model,reserveTokens:m.DEFAULT_COMPACTION_SETTINGS.reserveTokens,apiKey:r.apiKey,headers:r.headers,instructions:e.instructions,previousCheckpoint:e.previousCheckpoint,thinkingLevel:n.thinkingLevel,env:r.env},e.signal)}function R(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function z(n,i,a={}){let o=a.resolveModel??I,s=a.generateCheckpoint??(e=>L(e,o)),c=a.readTaskSnapshot??C,l=a.readTeamSnapshot??w,u=a.telemetry??r.createAutocompactTelemetry(),d=a.doomIntegrations??!0,f=new Set,x=new Set,T=new Set,E=!0,D=0,A=t.createInitialState(),N,P,F;n.effect(()=>async()=>{E=!1,D+=1,P?.abort(Error(`Autocompact runtime is shutting down.`)),P=void 0,await Promise.allSettled(T),F=void 0,N=void 0,f.clear(),x.clear(),A=t.createInitialState(),await u.shutdown()},`${g}/runtime`),d&&n.inject([p.DOOM_UI_HUB_SERVICE],e=>{let t=(0,p.requireDoomUiHub)(e).registerFooter({source:g,id:`autocompact`,order:20});return F=t,()=>{t.dispose(),F===t&&(F=void 0)}});let z=e=>{if(!E)return;let t=A.phase===_.checkpointPending?`summarizing`:A.phase===_.checkpointReady?`applying`:void 0;F?.update(t?{fullText:`Compacting p${A.pass}`,compactText:`C${A.pass}`}:void 0);let n=e??N;n?.hasUI&&n.ui.setStatus(`doom-autocompact`,t?`Compacting pass ${A.pass} (${t})…`:void 0)},B=()=>{E&&(i.appendEntry(e.STATE_CUSTOM_TYPE,{...A}),z())},V=()=>{delete A.requestId,delete A.snapshotLeafId,delete A.snapshotTokens,delete A.pendingCheckpoint,delete A.compactionPass},H=e=>{A.checkpointQueue=A.checkpointQueue.filter(t=>t!==e)},te=e=>{E&&(A=y(e.sessionManager.getBranch())??t.createInitialState(),!(A.phase===_.checkpointReady&&A.requestId&&A.snapshotLeafId&&A.pendingCheckpoint||A.phase===_.waiting)&&(P?.abort(),P=void 0,A.phase=_.waiting,V(),B()))},U=t=>{E&&i.sendMessage({customType:e.RESUME_MESSAGE_TYPE,content:`${t} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:A.cycle,pass:A.pass}},{triggerTurn:!0,deliverAs:`steer`})},W=(e,t)=>{if(!E||e!==A.requestId||A.phase!==_.checkpointPending)return;let n=A.snapshotLeafId;A.phase=_.waiting,n&&(A.lastAttemptLeafId=n),V(),B(),R(N,`Doom autocompact summarization pass ${A.pass} failed: ${t instanceof Error?t.message:String(t)}`,`error`)},G=(e,t,n,i)=>{E&&(t.error&&(R(e,`Doom autocompact task steering degraded: ${t.error}`,`warning`),u.recordWarning(r.AUTOCOMPACT_EVENT.taskSnapshotDegraded,Error(t.error),i)),n.error&&(R(e,`Doom autocompact team steering degraded: ${n.error}`,`warning`),u.recordWarning(r.AUTOCOMPACT_EVENT.teamSnapshotDegraded,Error(n.error),i)))},K=(t,n,r)=>{if(!E)return{tasks:[],teamAvailable:!1,teamMembers:[]};let a=c(t),o=l();G(t,a,o,r);let s=ee(n,a,o);return i.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:O(s),display:!1,details:{version:1,...s}}),s},q=(n,a)=>{if(!E||!A.requestId||!A.snapshotLeafId||!A.pendingCheckpoint)return!1;let o=a.sessionManager.getBranch(),s=t.projectContextMessages((0,m.buildSessionContext)(o).messages,o).messages,c=t.mergeFileDetails(A,t.fileOperationsFromMessages(s)),l=A.requestId,d=A.cycle,f=t.withCanonicalFileSections(A.pendingCheckpoint,c),p={...c,doomAutocompact:{version:2,cycle:d,pass:n,requestId:l,snapshotLeafId:A.snapshotLeafId,tokensBefore:A.snapshotTokens??a.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(o,A.snapshotLeafId)};R(a,`Doom autocompact pass ${n} context commit started.`);let h=a.isIdle();i.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:f,display:!1,details:p});let g=b(a),y=K(a,o,v(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":n}));return h&&i.setLabel(g,`autocompact:c${d}:p${n}`),A.readFiles=c.readFiles,A.modifiedFiles=c.modifiedFiles,delete A.latestCheckpointSnapshotLeafId,A.phase=_.waiting,A.checkpointQueue=[],A.exhaustedPasses=[],A.invalidAttempts=0,A.baselinePending=!0,delete A.lastAttemptLeafId,V(),A.cycle+=1,A.pass=1,B(),u.recordEvent(r.AUTOCOMPACT_EVENT.contextCommitted,v(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":n,"autocompact.snapshot_leaf_id":p.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":p.doomAutocompact.tokensBefore,"autocompact.message_count.before":s.length,"autocompact.message_count.retained":p.retainedMessages.length,"autocompact.apply_mode":h?`idle`:`turn_end`,...k(y)})),R(a,`Doom autocompact context committed. Baseline will be captured from the next settled context.`),h&&U(`Asynchronous compaction completed.`),!0},J=(e,n,i)=>{if(!E)return;let a=D,o=n.sessionManager.getBranch(),d=b(n),f=t.createRequestId(n.sessionManager.getSessionId(),A.cycle,e,d),p=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(o)):void 0,m=M(e,o,A.latestCheckpointSnapshotLeafId),h=c(n),g=l(),y=v(n,{"autocompact.request.id":f,"autocompact.cycle":A.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":d,"autocompact.tokens_before":i,"autocompact.message_count.before":m.length});G(n,h,g,y),A.phase=_.checkpointPending,A.pass=e,A.requestId=f,A.snapshotLeafId=d,A.snapshotTokens=i,delete A.pendingCheckpoint,delete A.compactionPass,delete A.lastAttemptLeafId,B(),P?.abort(),P=new AbortController;let x=P.signal;R(n,`Doom autocompact summarization pass ${e} started.`);let C=u.runInSpan(`doom_autocompact.checkpoint`,y,async()=>{await u.recordEvent(r.AUTOCOMPACT_EVENT.checkpointStarted,y);try{let t=await s({messages:m,instructions:j(e,{plan:S(o),taskSnapshot:h,teamSnapshot:g,readFiles:A.readFiles,modifiedFiles:A.modifiedFiles}),...p?{previousCheckpoint:p}:{},context:n,signal:x});if(!E||a!==D)throw x.reason??Error(`Autocompact checkpoint became stale.`);if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await u.recordEvent(r.AUTOCOMPACT_EVENT.checkpointCompleted,{...y,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw E&&a===D&&await u.recordError(r.AUTOCOMPACT_EVENT.checkpointFailed,e,y),e}}).then(t=>{!E||a!==D||f!==A.requestId||A.phase!==_.checkpointPending||(A.phase=_.checkpointReady,A.pendingCheckpoint=t.trim(),B(),R(N,`Doom autocompact summarization pass ${e} completed.`),N&&Q(N))}).catch(e=>{E&&a===D&&W(f,e)});T.add(C),C.finally(()=>T.delete(C))},Y=e=>{if(!E||A.phase!==_.waiting||e.hasPendingMessages())return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(A.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(A.baselineTokens=n.tokens,A.baselinePending=!1,B(),R(e,`Doom autocompact baseline captured at ${A.baselineTokens} tokens.`),!1):!1;let r=b(e);if(A.lastAttemptLeafId===r)return!1;for(let e of[1,2,3])e<A.pass||A.checkpointQueue.includes(e)||A.exhaustedPasses.includes(e)||n.tokens>=t.thresholdTokens(e,n.contextWindow,A.baselineTokens)&&A.checkpointQueue.push(e);let i=A.checkpointQueue[0];return i?(J(i,e,n.tokens),!0):!1},X=(n,r)=>{if(!E)return;let a=A.snapshotLeafId;i.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(A.cycle,n,A.requestId??`completed`),summary:r}),a&&(A.latestCheckpointSnapshotLeafId=a)},Z=e=>{if(!E||A.phase!==_.checkpointReady||!A.requestId||!A.pendingCheckpoint)return`none`;let n=A.pass,i=t.parseCheckpointDecision(A.pendingCheckpoint);if(!t.isStructuredCheckpoint(i.summary)){let t=A.snapshotLeafId,i=A.requestId,a=A.invalidAttempts+1,o=a>=3;A.phase=_.waiting,t&&(A.lastAttemptLeafId=t),o?(H(n),A.exhaustedPasses=[...A.exhaustedPasses,n],A.invalidAttempts=0):A.invalidAttempts=a,V(),B();let s=Error(`Summarization pass ${n} returned an incomplete checkpoint.`);return R(e,o?`Doom autocompact summarization pass ${n} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${n} returned an incomplete checkpoint.`,`error`),u.recordError(r.AUTOCOMPACT_EVENT.checkpointInvalid,s,v(e,{"autocompact.cycle":A.cycle,"autocompact.pass":n,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...i?{"autocompact.request.id":i}:{}})),`invalid`}return A.invalidAttempts=0,n===1?(X(1,i.summary),H(1),A.phase=_.waiting,A.pass=2,V(),B(),`pass1`):n===2&&i.shouldCompact!==!0?(X(2,i.summary),H(2),A.phase=_.waiting,A.pass=3,V(),B(),`deferred`):(A.pendingCheckpoint=i.summary,q(n,e)?`committed`:`invalid`)};function Q(e){E&&(N=e,e.isIdle()&&Z(e)!==`committed`&&Y(e))}i.on(`context`,(e,n)=>{if(!E)return;let i=t.projectContextMessages(e.messages,n.sessionManager.getBranch());if(i.invalidMarker){let e=n.sessionManager.getLeafId()??h;x.has(e)||(x.add(e),u.recordError(r.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),v(n,{"autocompact.leaf_id":e})));return}if(i.marker)return f.has(i.marker.requestId)||(f.add(i.marker.requestId),u.recordEvent(r.AUTOCOMPACT_EVENT.contextApplied,v(n,{"autocompact.request.id":i.marker.requestId,"autocompact.cycle":i.marker.cycle,"autocompact.pass":i.marker.pass,"autocompact.snapshot_leaf_id":i.marker.snapshotLeafId,"autocompact.tokens_before":i.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":i.messages.length,"autocompact.message_count.retained":i.retainedMessageCount}))),{messages:i.messages}});let $=e=>{E&&(D+=1,P?.abort(Error(`Autocompact session generation was replaced.`)),P=void 0,f.clear(),x.clear(),N=e,te(e),Q(e))};i.on(`session_start`,(e,t)=>$(t)),i.on(`session_tree`,(e,t)=>$(t)),i.on(`turn_end`,(e,t)=>{if(E){if(N=t,t.isIdle()){Q(t);return}A.phase===_.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&Z(t)!==`none`||Y(t)}}),i.on(`agent_settled`,(e,t)=>{E&&Q(t)}),i.on(`session_before_compact`,e=>{if(!(!E||e.reason!==`threshold`))return A.phase===_.checkpointPending||A.phase===_.checkpointReady||A.baselinePending?{cancel:!0}:void 0}),i.on(`session_compact`,(e,n)=>{if(!E)return;D+=1,P?.abort(),P=void 0;let a=t.fileDetailsFromUnknown(e.compactionEntry.details),o=t.mergeFileDetails(A,void 0,a);A.readFiles=o.readFiles,A.modifiedFiles=o.modifiedFiles,delete A.latestCheckpointSnapshotLeafId,A.baselinePending=!0,A.phase=_.waiting,V(),A.checkpointQueue=[],A.exhaustedPasses=[],A.invalidAttempts=0,delete A.lastAttemptLeafId,i.setLabel(e.compactionEntry.id,`autocompact:c${A.cycle}:external`);let s=A.cycle,c=v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason}),l=K(n,n.sessionManager.getBranch(),c);A.cycle+=1,A.pass=1,B(),u.recordEvent(r.AUTOCOMPACT_EVENT.nativeCompactionCompleted,v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...k(l)})),R(n,`Doom autocompact completed. Baseline will be captured from the next settled context. Next pass: ${A.pass}.`)})}async function B(e){let t=await(0,l.connectDoomCordisHost)(e,`@agimon-ai/doompi-autocompact`),n=t.root.plugin(V,{pi:e});try{await n}catch(e){try{await n.dispose()}finally{await t.dispose()}throw e}let r;e.on(`session_shutdown`,()=>r??=(async()=>{try{await n.dispose()}finally{await t.dispose()}})())}function V(e,t){z(e,t.pi)}exports.default=B,exports.installAutocompactRuntime=z;
|
|
49
|
+
## Critical Context`}function N(e,n,r){let i=t.projectContextMessages((0,m.buildSessionContext)(n).messages,n).messages;if(e===1||!r)return i;let a=n.findIndex(e=>e.id===r);return a===-1?i:n.slice(a+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,m.sessionEntryToContextMessages)(e))}function P(e){let t=(0,o.fileURLToPath)(e),n=(0,a.dirname)(t);for(;;){let e=(0,a.join)(n,`checkpointWorker.mjs`);if((0,i.existsSync)(e))return(0,o.pathToFileURL)(e);let t=(0,a.dirname)(n);if(t===n)break;n=t}throw Error(`Cannot find checkpointWorker.mjs by walking from ${t}.`)}function F(e,t){return new Promise((n,r)=>{let i=new s.Worker(P(require("url").pathToFileURL(__filename).href),{workerData:e}),a=!1,o=e=>{a||(a=!0,t.removeEventListener(`abort`,c),e())},c=()=>{o(()=>{i.terminate(),r(t.reason instanceof Error?t.reason:Error(`Autocompact summarization aborted.`))})};i.once(`message`,e=>{o(()=>{typeof e.checkpoint==`string`?n(e.checkpoint):r(Error(e.error??`Autocompact summarization worker returned no checkpoint.`))})}),i.once(`error`,e=>o(()=>r(e))),i.once(`exit`,e=>{e!==0&&o(()=>r(Error(`Autocompact summarization worker exited with code ${e}.`)))}),t.addEventListener(`abort`,c,{once:!0}),i.unref(),t.aborted&&c()})}function I(e){try{return(0,c.loadDoomConfig)((0,c.getHarnessState)().root??e).modes?.planning?.subagents}catch{process.emitWarning(`Doom autocompact planning configuration could not be loaded; using the active session model instead.`);return}}function L(e){let t=I(e.cwd),r=t?.model?n.parseModelReference(t.model):void 0,i=r?e.modelRegistry.find(r.provider,r.modelId):void 0,a=i??e.model;if(!a)return;let o=t?.thinking??(i?r?.thinking:void 0)??e.thinkingLevel;return{model:a,...o?{thinkingLevel:o}:{}}}async function R(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);return F({messages:e.messages,model:n.model,reserveTokens:m.DEFAULT_COMPACTION_SETTINGS.reserveTokens,apiKey:r.apiKey,headers:r.headers,instructions:e.instructions,previousCheckpoint:e.previousCheckpoint,thinkingLevel:n.thinkingLevel,env:r.env},e.signal)}function z(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function B(n,i,a={}){let o=a.resolveModel??L,s=a.generateCheckpoint??(e=>R(e,o)),c=a.readTaskSnapshot??C,l=a.readTeamSnapshot??w,u=a.telemetry??r.createAutocompactTelemetry(),d=a.doomIntegrations??!0,f=new Set,x=new Set,T=new Set,E=!0,D=0,j=t.createInitialState(),P,F,I;n.effect(()=>async()=>{E=!1,D+=1,F?.abort(Error(`Autocompact runtime is shutting down.`)),F=void 0,await Promise.allSettled(T),I=void 0,P=void 0,f.clear(),x.clear(),j=t.createInitialState(),await u.shutdown()},`${g}/runtime`),d&&n.inject([p.DOOM_UI_HUB_SERVICE],e=>{let t=(0,p.requireDoomUiHub)(e).registerFooter({source:g,id:`autocompact`,order:20});return I=t,()=>{t.dispose(),I===t&&(I=void 0)}});let B=e=>{if(!E)return;let t=j.phase===_.checkpointPending?`summarizing`:j.phase===_.checkpointReady?`applying`:void 0;I?.update(t?{fullText:`Compacting p${j.pass}`,compactText:`C${j.pass}`}:void 0);let n=e??P;n?.hasUI&&n.ui.setStatus(`doom-autocompact`,t?`Compacting pass ${j.pass} (${t})…`:void 0)},V=()=>{E&&(i.appendEntry(e.STATE_CUSTOM_TYPE,{...j}),B())},H=()=>{delete j.requestId,delete j.snapshotLeafId,delete j.snapshotTokens,delete j.pendingCheckpoint,delete j.compactionPass},U=e=>{j.checkpointQueue=j.checkpointQueue.filter(t=>t!==e)},ee=e=>{E&&(j=y(e.sessionManager.getBranch())??t.createInitialState(),!(j.phase===_.checkpointReady&&j.requestId&&j.snapshotLeafId&&j.pendingCheckpoint||j.phase===_.waiting)&&(F?.abort(),F=void 0,j.phase=_.waiting,H(),V()))},te=t=>{E&&i.sendMessage({customType:e.RESUME_MESSAGE_TYPE,content:`${t} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:j.cycle,pass:j.pass}},{triggerTurn:!0,deliverAs:`steer`})},W=(e,t)=>{if(!E||e!==j.requestId||j.phase!==_.checkpointPending)return;let n=j.snapshotLeafId;j.phase=_.waiting,n&&(j.lastAttemptLeafId=n),H(),V(),z(P,`Doom autocompact summarization pass ${j.pass} failed: ${t instanceof Error?t.message:String(t)}`,`error`)},G=(e,t,n,i)=>{E&&(t.error&&(z(e,`Doom autocompact task steering degraded: ${t.error}`,`warning`),u.recordWarning(r.AUTOCOMPACT_EVENT.taskSnapshotDegraded,Error(t.error),i)),n.error&&(z(e,`Doom autocompact team steering degraded: ${n.error}`,`warning`),u.recordWarning(r.AUTOCOMPACT_EVENT.teamSnapshotDegraded,Error(n.error),i)))},K=(t,n,r)=>{if(!E)return{tasks:[],teamAvailable:!1,teamMembers:[]};let a=c(t),o=l();G(t,a,o,r);let s=O(n,a,o);return i.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:k(s),display:!1,details:{version:1,...s}}),s},q=(n,a)=>{if(!E||!j.requestId||!j.snapshotLeafId||!j.pendingCheckpoint)return!1;let o=a.sessionManager.getBranch(),s=t.projectContextMessages((0,m.buildSessionContext)(o).messages,o).messages,c=t.mergeFileDetails(j,t.fileOperationsFromMessages(s)),l=j.requestId,d=j.cycle,f=t.withCanonicalFileSections(j.pendingCheckpoint,c),p={...c,doomAutocompact:{version:2,cycle:d,pass:n,requestId:l,snapshotLeafId:j.snapshotLeafId,tokensBefore:j.snapshotTokens??a.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(o,j.snapshotLeafId)};z(a,`Doom autocompact pass ${n} context commit started.`);let h=a.isIdle();i.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:f,display:!1,details:p});let g=b(a),y=v(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":n}),x=K(a,o,y);return h&&i.setLabel(g,`autocompact:c${d}:p${n}`),j.readFiles=c.readFiles,j.modifiedFiles=c.modifiedFiles,delete j.latestCheckpointSnapshotLeafId,j.phase=_.waiting,j.checkpointQueue=[],j.exhaustedPasses=[],j.invalidAttempts=0,j.baselinePending=!0,delete j.lastAttemptLeafId,H(),j.cycle+=1,j.pass=1,V(),u.recordEvent(r.AUTOCOMPACT_EVENT.contextCommitted,v(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":n,"autocompact.snapshot_leaf_id":p.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":p.doomAutocompact.tokensBefore,"autocompact.message_count.before":s.length,"autocompact.message_count.retained":p.retainedMessages.length,"autocompact.apply_mode":h?`idle`:`turn_end`,...A(x)})),z(a,`Doom autocompact context committed. Baseline will be captured from the next settled context.`),h&&te(`Asynchronous compaction completed.`),!0},J=(e,n,i)=>{if(!E)return;let a=D,o=n.sessionManager.getBranch(),d=b(n),f=t.createRequestId(n.sessionManager.getSessionId(),j.cycle,e,d),p=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(o)):void 0,m=N(e,o,j.latestCheckpointSnapshotLeafId),h=c(n),g=l(),y=v(n,{"autocompact.request.id":f,"autocompact.cycle":j.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":d,"autocompact.tokens_before":i,"autocompact.message_count.before":m.length});G(n,h,g,y),j.phase=_.checkpointPending,j.pass=e,j.requestId=f,j.snapshotLeafId=d,j.snapshotTokens=i,delete j.pendingCheckpoint,delete j.compactionPass,delete j.lastAttemptLeafId,V(),F?.abort(),F=new AbortController;let x=F.signal;z(n,`Doom autocompact summarization pass ${e} started.`);let C=u.runInSpan(`doom_autocompact.checkpoint`,y,async()=>{await u.recordEvent(r.AUTOCOMPACT_EVENT.checkpointStarted,y);try{let t=await s({messages:m,instructions:M(e,{plan:S(o),taskSnapshot:h,teamSnapshot:g,readFiles:j.readFiles,modifiedFiles:j.modifiedFiles}),...p?{previousCheckpoint:p}:{},context:n,signal:x});if(!E||a!==D)throw x.reason??Error(`Autocompact checkpoint became stale.`);if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await u.recordEvent(r.AUTOCOMPACT_EVENT.checkpointCompleted,{...y,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw E&&a===D&&await u.recordError(r.AUTOCOMPACT_EVENT.checkpointFailed,e,y),e}}).then(t=>{!E||a!==D||f!==j.requestId||j.phase!==_.checkpointPending||(j.phase=_.checkpointReady,j.pendingCheckpoint=t.trim(),V(),z(P,`Doom autocompact summarization pass ${e} completed.`),P&&Q(P))}).catch(e=>{E&&a===D&&W(f,e)});T.add(C),C.finally(()=>T.delete(C))},Y=e=>{if(!E||j.phase!==_.waiting||e.hasPendingMessages())return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(j.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(j.baselineTokens=n.tokens,j.baselinePending=!1,V(),z(e,`Doom autocompact baseline captured at ${j.baselineTokens} tokens.`),!1):!1;let r=b(e);if(j.lastAttemptLeafId===r)return!1;for(let e of[1,2,3])e<j.pass||j.checkpointQueue.includes(e)||j.exhaustedPasses.includes(e)||n.tokens>=t.thresholdTokens(e,n.contextWindow,j.baselineTokens)&&j.checkpointQueue.push(e);let i=j.checkpointQueue[0];return i?(J(i,e,n.tokens),!0):!1},X=(n,r)=>{if(!E)return;let a=j.snapshotLeafId;i.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(j.cycle,n,j.requestId??`completed`),summary:r}),a&&(j.latestCheckpointSnapshotLeafId=a)},Z=e=>{if(!E||j.phase!==_.checkpointReady||!j.requestId||!j.pendingCheckpoint)return`none`;let n=j.pass,i=t.parseCheckpointDecision(j.pendingCheckpoint);if(!t.isStructuredCheckpoint(i.summary)){let t=j.snapshotLeafId,i=j.requestId,a=j.invalidAttempts+1,o=a>=3;j.phase=_.waiting,t&&(j.lastAttemptLeafId=t),o?(U(n),j.exhaustedPasses=[...j.exhaustedPasses,n],j.invalidAttempts=0):j.invalidAttempts=a,H(),V();let s=Error(`Summarization pass ${n} returned an incomplete checkpoint.`);return z(e,o?`Doom autocompact summarization pass ${n} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${n} returned an incomplete checkpoint.`,`error`),u.recordError(r.AUTOCOMPACT_EVENT.checkpointInvalid,s,v(e,{"autocompact.cycle":j.cycle,"autocompact.pass":n,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...i?{"autocompact.request.id":i}:{}})),`invalid`}return j.invalidAttempts=0,n===1?(X(1,i.summary),U(1),j.phase=_.waiting,j.pass=2,H(),V(),`pass1`):n===2&&i.shouldCompact!==!0?(X(2,i.summary),U(2),j.phase=_.waiting,j.pass=3,H(),V(),`deferred`):(j.pendingCheckpoint=i.summary,q(n,e)?`committed`:`invalid`)};function Q(e){E&&(P=e,e.isIdle()&&Z(e)!==`committed`&&Y(e))}i.on(`context`,(e,n)=>{if(!E)return;let i=t.projectContextMessages(e.messages,n.sessionManager.getBranch());if(i.invalidMarker){let e=n.sessionManager.getLeafId()??h;x.has(e)||(x.add(e),u.recordError(r.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),v(n,{"autocompact.leaf_id":e})));return}if(i.marker)return f.has(i.marker.requestId)||(f.add(i.marker.requestId),u.recordEvent(r.AUTOCOMPACT_EVENT.contextApplied,v(n,{"autocompact.request.id":i.marker.requestId,"autocompact.cycle":i.marker.cycle,"autocompact.pass":i.marker.pass,"autocompact.snapshot_leaf_id":i.marker.snapshotLeafId,"autocompact.tokens_before":i.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":i.messages.length,"autocompact.message_count.retained":i.retainedMessageCount}))),{messages:i.messages}});let $=e=>{E&&(D+=1,F?.abort(Error(`Autocompact session generation was replaced.`)),F=void 0,f.clear(),x.clear(),P=e,ee(e),Q(e))};i.on(`session_start`,(e,t)=>$(t)),i.on(`session_tree`,(e,t)=>$(t)),i.on(`turn_end`,(e,t)=>{if(E){if(P=t,t.isIdle()){Q(t);return}j.phase===_.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&Z(t)!==`none`||Y(t)}}),i.on(`agent_settled`,(e,t)=>{E&&Q(t)}),i.on(`session_before_compact`,e=>{if(!(!E||e.reason!==`threshold`))return j.phase===_.checkpointPending||j.phase===_.checkpointReady||j.baselinePending?{cancel:!0}:void 0}),i.on(`session_compact`,(e,n)=>{if(!E)return;D+=1,F?.abort(),F=void 0;let a=t.fileDetailsFromUnknown(e.compactionEntry.details),o=t.mergeFileDetails(j,void 0,a);j.readFiles=o.readFiles,j.modifiedFiles=o.modifiedFiles,delete j.latestCheckpointSnapshotLeafId,j.baselinePending=!0,j.phase=_.waiting,H(),j.checkpointQueue=[],j.exhaustedPasses=[],j.invalidAttempts=0,delete j.lastAttemptLeafId,i.setLabel(e.compactionEntry.id,`autocompact:c${j.cycle}:external`);let s=j.cycle,c=v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason}),l=K(n,n.sessionManager.getBranch(),c);j.cycle+=1,j.pass=1,V(),u.recordEvent(r.AUTOCOMPACT_EVENT.nativeCompactionCompleted,v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...A(l)})),z(n,`Doom autocompact completed. Baseline will be captured from the next settled context. Next pass: ${j.pass}.`)})}async function V(e){let t=await(0,l.connectDoomCordisHost)(e,`@agimon-ai/doompi-autocompact`),n=t.root.plugin(H,{pi:e});try{await n}catch(e){try{await n.dispose()}finally{await t.dispose()}throw e}let r;e.on(`session_shutdown`,()=>r??=(async()=>{try{await n.dispose()}finally{await t.dispose()}})())}function H(e,t){B(e,t.pi)}exports.autocompactExtension=V,exports.default=V,exports.findCheckpointWorkerUrl=P,exports.installAutocompactRuntime=B,exports.resolveDoomSummarizationModel=L;
|
|
50
50
|
//# sourceMappingURL=extension.cjs.map
|