@agimon-ai/doompi-autocompact 0.0.1-alpha.2 → 0.0.1-alpha.21

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.
Files changed (96) hide show
  1. package/README.md +21 -16
  2. package/dist/adapters/pi/extension.cjs +50 -0
  3. package/dist/adapters/pi/extension.cjs.map +1 -0
  4. package/dist/{extension.d.cts → adapters/pi/extension.d.cts} +3 -4
  5. package/dist/adapters/pi/extension.d.cts.map +1 -0
  6. package/dist/{extension.d.mts → adapters/pi/extension.d.mts} +3 -4
  7. package/dist/adapters/pi/extension.d.mts.map +1 -0
  8. package/dist/adapters/pi/extension.mjs +50 -0
  9. package/dist/adapters/pi/extension.mjs.map +1 -0
  10. package/dist/adapters/process/checkpointWorker.cjs +2 -0
  11. package/dist/adapters/process/checkpointWorker.cjs.map +1 -0
  12. package/dist/adapters/process/checkpointWorker.mjs +2 -0
  13. package/dist/adapters/process/checkpointWorker.mjs.map +1 -0
  14. package/dist/adapters/telemetry/logSinkTelemetry.cjs.map +1 -0
  15. package/dist/{logSinkTelemetry.d.cts → adapters/telemetry/logSinkTelemetry.d.cts} +1 -1
  16. package/dist/adapters/telemetry/logSinkTelemetry.d.cts.map +1 -0
  17. package/dist/{logSinkTelemetry.d.mts → adapters/telemetry/logSinkTelemetry.d.mts} +1 -1
  18. package/dist/adapters/telemetry/logSinkTelemetry.d.mts.map +1 -0
  19. package/dist/adapters/telemetry/logSinkTelemetry.mjs.map +1 -0
  20. package/dist/checkpointWorker.cjs +1 -2
  21. package/dist/checkpointWorker.mjs +1 -2
  22. package/dist/extensions/pi.cjs +1 -1
  23. package/dist/extensions/pi.cjs.map +1 -1
  24. package/dist/extensions/pi.d.cts +1 -1
  25. package/dist/extensions/pi.d.mts +1 -1
  26. package/dist/extensions/pi.mjs +1 -1
  27. package/dist/extensions/pi.mjs.map +1 -1
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.d.cts +3 -3
  30. package/dist/index.d.mts +3 -3
  31. package/dist/index.mjs +1 -1
  32. package/dist/{policy.cjs → services/compaction/policy.cjs} +1 -1
  33. package/dist/services/compaction/policy.cjs.map +1 -0
  34. package/dist/{policy.d.cts → services/compaction/policy.d.cts} +2 -2
  35. package/dist/services/compaction/policy.d.cts.map +1 -0
  36. package/dist/{policy.d.mts → services/compaction/policy.d.mts} +2 -2
  37. package/dist/services/compaction/policy.d.mts.map +1 -0
  38. package/dist/{policy.mjs → services/compaction/policy.mjs} +1 -1
  39. package/dist/services/compaction/policy.mjs.map +1 -0
  40. package/dist/services/compaction/standard.cjs +2 -0
  41. package/dist/services/compaction/standard.cjs.map +1 -0
  42. package/dist/{standard.d.cts → services/compaction/standard.d.cts} +1 -1
  43. package/dist/services/compaction/standard.d.cts.map +1 -0
  44. package/dist/{standard.d.mts → services/compaction/standard.d.mts} +1 -1
  45. package/dist/services/compaction/standard.d.mts.map +1 -0
  46. package/dist/services/compaction/standard.mjs +2 -0
  47. package/dist/services/compaction/standard.mjs.map +1 -0
  48. package/dist/services/compaction/summarizationModel.cjs.map +1 -0
  49. package/dist/{summarizationModel.d.cts → services/compaction/summarizationModel.d.cts} +1 -1
  50. package/dist/services/compaction/summarizationModel.d.cts.map +1 -0
  51. package/dist/{summarizationModel.d.mts → services/compaction/summarizationModel.d.mts} +1 -1
  52. package/dist/services/compaction/summarizationModel.d.mts.map +1 -0
  53. package/dist/services/compaction/summarizationModel.mjs.map +1 -0
  54. package/dist/types/constants.cjs.map +1 -0
  55. package/dist/types/constants.mjs.map +1 -0
  56. package/dist/{types.d.cts → types/index.d.cts} +2 -2
  57. package/dist/types/index.d.cts.map +1 -0
  58. package/dist/{types.d.mts → types/index.d.mts} +2 -2
  59. package/dist/types/index.d.mts.map +1 -0
  60. package/package.json +15 -8
  61. package/dist/checkpointWorker.cjs.map +0 -1
  62. package/dist/checkpointWorker.mjs.map +0 -1
  63. package/dist/constants.cjs.map +0 -1
  64. package/dist/constants.mjs.map +0 -1
  65. package/dist/extension.cjs +0 -50
  66. package/dist/extension.cjs.map +0 -1
  67. package/dist/extension.d.cts.map +0 -1
  68. package/dist/extension.d.mts.map +0 -1
  69. package/dist/extension.mjs +0 -50
  70. package/dist/extension.mjs.map +0 -1
  71. package/dist/logSinkTelemetry.cjs.map +0 -1
  72. package/dist/logSinkTelemetry.d.cts.map +0 -1
  73. package/dist/logSinkTelemetry.d.mts.map +0 -1
  74. package/dist/logSinkTelemetry.mjs.map +0 -1
  75. package/dist/policy.cjs.map +0 -1
  76. package/dist/policy.d.cts.map +0 -1
  77. package/dist/policy.d.mts.map +0 -1
  78. package/dist/policy.mjs.map +0 -1
  79. package/dist/standard.cjs +0 -2
  80. package/dist/standard.cjs.map +0 -1
  81. package/dist/standard.d.cts.map +0 -1
  82. package/dist/standard.d.mts.map +0 -1
  83. package/dist/standard.mjs +0 -2
  84. package/dist/standard.mjs.map +0 -1
  85. package/dist/summarizationModel.cjs.map +0 -1
  86. package/dist/summarizationModel.d.cts.map +0 -1
  87. package/dist/summarizationModel.d.mts.map +0 -1
  88. package/dist/summarizationModel.mjs.map +0 -1
  89. package/dist/types.d.cts.map +0 -1
  90. package/dist/types.d.mts.map +0 -1
  91. /package/dist/{logSinkTelemetry.cjs → adapters/telemetry/logSinkTelemetry.cjs} +0 -0
  92. /package/dist/{logSinkTelemetry.mjs → adapters/telemetry/logSinkTelemetry.mjs} +0 -0
  93. /package/dist/{summarizationModel.cjs → services/compaction/summarizationModel.cjs} +0 -0
  94. /package/dist/{summarizationModel.mjs → services/compaction/summarizationModel.mjs} +0 -0
  95. /package/dist/{constants.cjs → types/constants.cjs} +0 -0
  96. /package/dist/{constants.mjs → types/constants.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSinkTelemetry.d.cts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";cAKa,iBAAA;EAAA;;;;;;;;;;;KAaD,oBAAA,WAA+B,iBAAA,eAAgC,iBAAA;AAAA,KAC/D,0BAAA,GAA6B,MAAA;AAAA,UAUxB,oBAAA;EACf,WAAA,CAAY,KAAA,EAAO,oBAAA,EAAsB,KAAA,WAAgB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACnG,aAAA,CAAc,KAAA,EAAO,oBAAA,EAAsB,KAAA,WAAgB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACrG,WAAA,CAAY,KAAA,EAAO,oBAAA,EAAsB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACnF,SAAA,IAAa,IAAA,UAAc,UAAA,EAAY,0BAAA,EAA4B,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EACxG,KAAA,IAAS,OAAA;EACT,QAAA,IAAY,OAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region src/logSinkTelemetry.d.ts
1
+ //#region src/adapters/telemetry/logSinkTelemetry.d.ts
2
2
  declare const AUTOCOMPACT_EVENT: {
3
3
  readonly checkpointStarted: "doom_autocompact.checkpoint_started";
4
4
  readonly checkpointCompleted: "doom_autocompact.checkpoint_completed";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSinkTelemetry.d.mts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";cAKa,iBAAA;EAAA;;;;;;;;;;;KAaD,oBAAA,WAA+B,iBAAA,eAAgC,iBAAA;AAAA,KAC/D,0BAAA,GAA6B,MAAA;AAAA,UAUxB,oBAAA;EACf,WAAA,CAAY,KAAA,EAAO,oBAAA,EAAsB,KAAA,WAAgB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACnG,aAAA,CAAc,KAAA,EAAO,oBAAA,EAAsB,KAAA,WAAgB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACrG,WAAA,CAAY,KAAA,EAAO,oBAAA,EAAsB,UAAA,GAAa,0BAAA,GAA6B,OAAA;EACnF,SAAA,IAAa,IAAA,UAAc,UAAA,EAAY,0BAAA,EAA4B,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EACxG,KAAA,IAAS,OAAA;EACT,QAAA,IAAY,OAAA;AAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSinkTelemetry.mjs","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/doompi-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n taskSnapshotDegraded: 'doom_autocompact.task_snapshot_degraded',\n teamSnapshotDegraded: 'doom_autocompact.team_snapshot_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"kEAEA,MAGa,EAAoB,CAC/B,kBAAmB,sCACnB,oBAAqB,wCACrB,iBAAkB,qCAClB,kBAAmB,sCACnB,qBAAsB,0CACtB,qBAAsB,0CACtB,iBAAkB,qCAClB,eAAgB,mCAChB,qBAAsB,0CACtB,0BAA2B,+CAC5B,CAsBD,SAAgB,EAA2B,EAAuC,EAAE,CAAwB,CAC1G,IAAM,EAA2B,EAAoB,CACnD,YAAa,mBACb,YAAa,gCACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,GACf,CAAC,CACF,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,EAAW,CAC1F,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,EAAW,CAC9F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,EAAW,CAC5E,WAAY,EAAM,EAAY,IAAa,EAAU,UAAU,EAAM,EAAY,EAAS,CAC1F,UAAa,EAAU,OAAO,CAC9B,aAAgB,EAAU,UAAU,CACrC"}
@@ -1,2 +1 @@
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
- //# sourceMappingURL=checkpointWorker.cjs.map
1
+ require(`./adapters/process/checkpointWorker.cjs`);
@@ -1,2 +1 @@
1
- import{parentPort as e,workerData as t}from"node:worker_threads";import{generateSummary as n}from"@earendil-works/pi-coding-agent";async function r(t){try{let r=await n(t.messages,t.model,t.reserveTokens,t.apiKey,t.headers,void 0,t.instructions,t.previousCheckpoint,t.thinkingLevel,void 0,t.env);e?.postMessage({checkpoint:r})}catch(t){e?.postMessage({error:t instanceof Error?t.message:String(t)})}}r(t);export{};
2
- //# sourceMappingURL=checkpointWorker.mjs.map
1
+ import"./adapters/process/checkpointWorker.mjs";export{};
@@ -1,2 +1,2 @@
1
- var e=require(`../standard.cjs`).registerStandardAutocompactExtension;module.exports=e;
1
+ var e=require(`../services/compaction/standard.cjs`).registerStandardAutocompactExtension;module.exports=e;
2
2
  //# sourceMappingURL=pi.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi.cjs","names":["registerStandardAutocompactExtension"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { registerStandardAutocompactExtension } from '../standard.ts';\n\nexport default registerStandardAutocompactExtension;\n"],"mappings":"AAEA,IAAA,4BAAeA,CAAAA"}
1
+ {"version":3,"file":"pi.cjs","names":["registerStandardAutocompactExtension"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { registerStandardAutocompactExtension } from '../services/compaction/standard.ts';\n\nexport default registerStandardAutocompactExtension;\n"],"mappings":"AAEA,IAAA,gDAAeA,CAAAA"}
@@ -1,2 +1,2 @@
1
- import { registerStandardAutocompactExtension } from "../standard.cjs";
1
+ import { registerStandardAutocompactExtension } from "../services/compaction/standard.cjs";
2
2
  export = registerStandardAutocompactExtension;
@@ -1,2 +1,2 @@
1
- import { registerStandardAutocompactExtension } from "../standard.mjs";
1
+ import { registerStandardAutocompactExtension } from "../services/compaction/standard.mjs";
2
2
  export { registerStandardAutocompactExtension as default };
@@ -1,2 +1,2 @@
1
- import{registerStandardAutocompactExtension as e}from"../standard.mjs";var t=e;export{t as default};
1
+ import{registerStandardAutocompactExtension as e}from"../services/compaction/standard.mjs";var t=e;export{t as default};
2
2
  //# sourceMappingURL=pi.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { registerStandardAutocompactExtension } from '../standard.ts';\n\nexport default registerStandardAutocompactExtension;\n"],"mappings":"uEAEA,IAAA,EAAe"}
1
+ {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { registerStandardAutocompactExtension } from '../services/compaction/standard.ts';\n\nexport default registerStandardAutocompactExtension;\n"],"mappings":"2FAEA,IAAA,EAAe"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./policy.cjs`),t=require(`./extension.cjs`);exports.registerAutocompactExtension=t.registerAutocompactExtension,exports.thresholdTokens=e.thresholdTokens;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/compaction/policy.cjs`),t=require(`./adapters/pi/extension.cjs`);exports.registerAutocompactExtension=t.registerAutocompactExtension,exports.thresholdTokens=e.thresholdTokens;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { registerAutocompactExtension } from "./extension.cjs";
2
- import { AutocompactPass } from "./types.cjs";
3
- import { thresholdTokens } from "./policy.cjs";
1
+ import { registerAutocompactExtension } from "./adapters/pi/extension.cjs";
2
+ import { AutocompactPass } from "./types/index.cjs";
3
+ import { thresholdTokens } from "./services/compaction/policy.cjs";
4
4
  export { type AutocompactPass, registerAutocompactExtension, thresholdTokens };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { registerAutocompactExtension } from "./extension.mjs";
2
- import { AutocompactPass } from "./types.mjs";
3
- import { thresholdTokens } from "./policy.mjs";
1
+ import { registerAutocompactExtension } from "./adapters/pi/extension.mjs";
2
+ import { AutocompactPass } from "./types/index.mjs";
3
+ import { thresholdTokens } from "./services/compaction/policy.mjs";
4
4
  export { type AutocompactPass, registerAutocompactExtension, thresholdTokens };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{thresholdTokens as e}from"./policy.mjs";import{registerAutocompactExtension as t}from"./extension.mjs";export{t as registerAutocompactExtension,e as thresholdTokens};
1
+ import{thresholdTokens as e}from"./services/compaction/policy.mjs";import{registerAutocompactExtension as t}from"./adapters/pi/extension.mjs";export{t as registerAutocompactExtension,e as thresholdTokens};
@@ -1,4 +1,4 @@
1
- const e=require(`./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(`
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
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(`
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.cjs","names":["COMPACTION_THRESHOLDS","DEFAULT_COMPACTION_SETTINGS","CHECKPOINT_HEADINGS"],"sources":["../../../src/services/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,5 +1,5 @@
1
- import { AutocompactPass } from "./types.cjs";
2
- //#region src/policy.d.ts
1
+ import { AutocompactPass } from "../../types/index.cjs";
2
+ //#region src/services/compaction/policy.d.ts
3
3
  declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
4
4
  //#endregion
5
5
  export { thresholdTokens };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.cts","names":[],"sources":["../../../src/services/compaction/policy.ts"],"mappings":";;iBAkGgB,eAAA,CAAgB,IAAA,EAAM,eAAA,EAAiB,aAAA,UAAuB,cAAA"}
@@ -1,5 +1,5 @@
1
- import { AutocompactPass } from "./types.mjs";
2
- //#region src/policy.d.ts
1
+ import { AutocompactPass } from "../../types/index.mjs";
2
+ //#region src/services/compaction/policy.d.ts
3
3
  declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
4
4
  //#endregion
5
5
  export { thresholdTokens };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.mts","names":[],"sources":["../../../src/services/compaction/policy.ts"],"mappings":";;iBAkGgB,eAAA,CAAgB,IAAA,EAAM,eAAA,EAAiB,aAAA,UAAuB,cAAA"}
@@ -1,4 +1,4 @@
1
- import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"./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(`
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
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(`
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.mjs","names":[],"sources":["../../../src/services/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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"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./summarizationModel.cjs`),t=require(`../../adapters/pi/extension.cjs`),n={recordError:async()=>void 0,recordWarning:async()=>void 0,recordEvent:async()=>void 0,runInSpan:async(e,t,n)=>n(),flush:async()=>void 0,shutdown:async()=>void 0};function r(r){t.registerAutocompactExtension(r,{resolveModel:e.resolveSummarizationModel,readTaskSnapshot:()=>({tasks:[]}),readTeamSnapshot:()=>({members:[]}),telemetry:n,doomIntegrations:!1})}exports.registerStandardAutocompactExtension=r;
2
+ //# sourceMappingURL=standard.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.cjs","names":["resolveSummarizationModel"],"sources":["../../../src/services/compaction/standard.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { registerAutocompactExtension } from '../../adapters/pi/extension.ts';\nimport type { AutocompactTelemetry } from '../../adapters/telemetry/logSinkTelemetry.ts';\nimport { resolveSummarizationModel } from './summarizationModel.ts';\n\nconst standardTelemetry: AutocompactTelemetry = {\n recordError: async () => undefined,\n recordWarning: async () => undefined,\n recordEvent: async () => undefined,\n runInSpan: async (_name, _attributes, callback) => callback(),\n flush: async () => undefined,\n shutdown: async () => undefined,\n};\n\n/** Standard Pi composition with active-model selection and empty optional Doom snapshots. */\nexport function registerStandardAutocompactExtension(pi: ExtensionAPI): void {\n registerAutocompactExtension(pi, {\n resolveModel: resolveSummarizationModel,\n readTaskSnapshot: () => ({ tasks: [] }),\n readTeamSnapshot: () => ({ members: [] }),\n telemetry: standardTelemetry,\n doomIntegrations: false,\n });\n}\n"],"mappings":"yFAMM,EAA0C,CAC9C,YAAa,SAAY,IAAA,GACzB,cAAe,SAAY,IAAA,GAC3B,YAAa,SAAY,IAAA,GACzB,UAAW,MAAO,EAAO,EAAa,IAAa,GAAU,CAC7D,MAAO,SAAY,IAAA,GACnB,SAAU,SAAY,IAAA,GACvB,CAGD,SAAgB,EAAqC,EAAwB,CAC3E,EAAA,6BAA6B,EAAI,CAC/B,aAAcA,EAAAA,0BACd,sBAAyB,CAAE,MAAO,EAAE,CAAE,EACtC,sBAAyB,CAAE,QAAS,EAAE,CAAE,EACxC,UAAW,EACX,iBAAkB,GACnB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
2
 
3
- //#region src/standard.d.ts
3
+ //#region src/services/compaction/standard.d.ts
4
4
  /** Standard Pi composition with active-model selection and empty optional Doom snapshots. */
5
5
  declare function registerStandardAutocompactExtension(pi: ExtensionAPI): void;
6
6
  //#endregion
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.d.cts","names":[],"sources":["../../../src/services/compaction/standard.ts"],"mappings":";;;;iBAgBgB,oCAAA,CAAqC,EAAA,EAAI,YAAA"}
@@ -1,6 +1,6 @@
1
1
  import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
2
 
3
- //#region src/standard.d.ts
3
+ //#region src/services/compaction/standard.d.ts
4
4
  /** Standard Pi composition with active-model selection and empty optional Doom snapshots. */
5
5
  declare function registerStandardAutocompactExtension(pi: ExtensionAPI): void;
6
6
  //#endregion
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.d.mts","names":[],"sources":["../../../src/services/compaction/standard.ts"],"mappings":";;;;iBAgBgB,oCAAA,CAAqC,EAAA,EAAI,YAAA"}
@@ -0,0 +1,2 @@
1
+ import{resolveSummarizationModel as e}from"./summarizationModel.mjs";import{registerAutocompactExtension as t}from"../../adapters/pi/extension.mjs";const n={recordError:async()=>void 0,recordWarning:async()=>void 0,recordEvent:async()=>void 0,runInSpan:async(e,t,n)=>n(),flush:async()=>void 0,shutdown:async()=>void 0};function r(r){t(r,{resolveModel:e,readTaskSnapshot:()=>({tasks:[]}),readTeamSnapshot:()=>({members:[]}),telemetry:n,doomIntegrations:!1})}export{r as registerStandardAutocompactExtension};
2
+ //# sourceMappingURL=standard.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.mjs","names":[],"sources":["../../../src/services/compaction/standard.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { registerAutocompactExtension } from '../../adapters/pi/extension.ts';\nimport type { AutocompactTelemetry } from '../../adapters/telemetry/logSinkTelemetry.ts';\nimport { resolveSummarizationModel } from './summarizationModel.ts';\n\nconst standardTelemetry: AutocompactTelemetry = {\n recordError: async () => undefined,\n recordWarning: async () => undefined,\n recordEvent: async () => undefined,\n runInSpan: async (_name, _attributes, callback) => callback(),\n flush: async () => undefined,\n shutdown: async () => undefined,\n};\n\n/** Standard Pi composition with active-model selection and empty optional Doom snapshots. */\nexport function registerStandardAutocompactExtension(pi: ExtensionAPI): void {\n registerAutocompactExtension(pi, {\n resolveModel: resolveSummarizationModel,\n readTaskSnapshot: () => ({ tasks: [] }),\n readTeamSnapshot: () => ({ members: [] }),\n telemetry: standardTelemetry,\n doomIntegrations: false,\n });\n}\n"],"mappings":"oJAMA,MAAM,EAA0C,CAC9C,YAAa,SAAY,IAAA,GACzB,cAAe,SAAY,IAAA,GAC3B,YAAa,SAAY,IAAA,GACzB,UAAW,MAAO,EAAO,EAAa,IAAa,GAAU,CAC7D,MAAO,SAAY,IAAA,GACnB,SAAU,SAAY,IAAA,GACvB,CAGD,SAAgB,EAAqC,EAAwB,CAC3E,EAA6B,EAAI,CAC/B,aAAc,EACd,sBAAyB,CAAE,MAAO,EAAE,CAAE,EACtC,sBAAyB,CAAE,QAAS,EAAE,CAAE,EACxC,UAAW,EACX,iBAAkB,GACnB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizationModel.cjs","names":[],"sources":["../../../src/services/compaction/summarizationModel.ts"],"sourcesContent":["import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nconst THINKING_SUFFIX_PATTERN = /:(off|minimal|low|medium|high|xhigh|max)$/;\n\nexport interface SummarizationModel {\n model: NonNullable<ExtensionContext['model']>;\n thinkingLevel?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\nexport interface ModelReference {\n provider: string;\n modelId: string;\n thinking?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\n/** Splits a `provider/model` reference, tolerating the optional thinking suffix. */\nexport function parseModelReference(reference: string): ModelReference | undefined {\n const trimmed = reference.trim();\n const thinking = THINKING_SUFFIX_PATTERN.exec(trimmed)?.[1] as SummarizationModel['thinkingLevel'];\n const identity = trimmed.replace(THINKING_SUFFIX_PATTERN, '');\n const separator = identity.indexOf('/');\n if (separator <= 0 || separator >= identity.length - 1) return undefined;\n return {\n provider: identity.slice(0, separator),\n modelId: identity.slice(separator + 1),\n ...(thinking ? { thinking } : {}),\n };\n}\n\n/** Standard Pi model selection never consults Doom configuration. */\nexport function resolveSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n if (!ctx.model) return undefined;\n return {\n model: ctx.model,\n ...(ctx.thinkingLevel ? { thinkingLevel: ctx.thinkingLevel } : {}),\n };\n}\n"],"mappings":"AAEA,MAAM,EAA0B,4CAchC,SAAgB,EAAoB,EAA+C,CACjF,IAAM,EAAU,EAAU,MAAM,CAC1B,EAAW,EAAwB,KAAK,EAAQ,GAAG,GACnD,EAAW,EAAQ,QAAQ,EAAyB,GAAG,CACvD,EAAY,EAAS,QAAQ,IAAI,CACnC,QAAa,GAAK,GAAa,EAAS,OAAS,GACrD,MAAO,CACL,SAAU,EAAS,MAAM,EAAG,EAAU,CACtC,QAAS,EAAS,MAAM,EAAY,EAAE,CACtC,GAAI,EAAW,CAAE,WAAU,CAAG,EAAE,CACjC,CAIH,SAAgB,EAA0B,EAAuD,CAC1F,KAAI,MACT,MAAO,CACL,MAAO,EAAI,MACX,GAAI,EAAI,cAAgB,CAAE,cAAe,EAAI,cAAe,CAAG,EAAE,CAClE"}
@@ -1,6 +1,6 @@
1
1
  import { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
- //#region src/summarizationModel.d.ts
3
+ //#region src/services/compaction/summarizationModel.d.ts
4
4
  interface SummarizationModel {
5
5
  model: NonNullable<ExtensionContext['model']>;
6
6
  thinkingLevel?: NonNullable<ExtensionContext['thinkingLevel']>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizationModel.d.cts","names":[],"sources":["../../../src/services/compaction/summarizationModel.ts"],"mappings":";;;UAIiB,kBAAA;EACf,KAAA,EAAO,WAAA,CAAY,gBAAA;EACnB,aAAA,GAAgB,WAAA,CAAY,gBAAA;AAAA"}
@@ -1,6 +1,6 @@
1
1
  import { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
- //#region src/summarizationModel.d.ts
3
+ //#region src/services/compaction/summarizationModel.d.ts
4
4
  interface SummarizationModel {
5
5
  model: NonNullable<ExtensionContext['model']>;
6
6
  thinkingLevel?: NonNullable<ExtensionContext['thinkingLevel']>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizationModel.d.mts","names":[],"sources":["../../../src/services/compaction/summarizationModel.ts"],"mappings":";;;UAIiB,kBAAA;EACf,KAAA,EAAO,WAAA,CAAY,gBAAA;EACnB,aAAA,GAAgB,WAAA,CAAY,gBAAA;AAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizationModel.mjs","names":[],"sources":["../../../src/services/compaction/summarizationModel.ts"],"sourcesContent":["import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nconst THINKING_SUFFIX_PATTERN = /:(off|minimal|low|medium|high|xhigh|max)$/;\n\nexport interface SummarizationModel {\n model: NonNullable<ExtensionContext['model']>;\n thinkingLevel?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\nexport interface ModelReference {\n provider: string;\n modelId: string;\n thinking?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\n/** Splits a `provider/model` reference, tolerating the optional thinking suffix. */\nexport function parseModelReference(reference: string): ModelReference | undefined {\n const trimmed = reference.trim();\n const thinking = THINKING_SUFFIX_PATTERN.exec(trimmed)?.[1] as SummarizationModel['thinkingLevel'];\n const identity = trimmed.replace(THINKING_SUFFIX_PATTERN, '');\n const separator = identity.indexOf('/');\n if (separator <= 0 || separator >= identity.length - 1) return undefined;\n return {\n provider: identity.slice(0, separator),\n modelId: identity.slice(separator + 1),\n ...(thinking ? { thinking } : {}),\n };\n}\n\n/** Standard Pi model selection never consults Doom configuration. */\nexport function resolveSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n if (!ctx.model) return undefined;\n return {\n model: ctx.model,\n ...(ctx.thinkingLevel ? { thinkingLevel: ctx.thinkingLevel } : {}),\n };\n}\n"],"mappings":"AAEA,MAAM,EAA0B,4CAchC,SAAgB,EAAoB,EAA+C,CACjF,IAAM,EAAU,EAAU,MAAM,CAC1B,EAAW,EAAwB,KAAK,EAAQ,GAAG,GACnD,EAAW,EAAQ,QAAQ,EAAyB,GAAG,CACvD,EAAY,EAAS,QAAQ,IAAI,CACnC,QAAa,GAAK,GAAa,EAAS,OAAS,GACrD,MAAO,CACL,SAAU,EAAS,MAAM,EAAG,EAAU,CACtC,QAAS,EAAS,MAAM,EAAY,EAAE,CACtC,GAAI,EAAW,CAAE,WAAU,CAAG,EAAE,CACjC,CAIH,SAAgB,EAA0B,EAAuD,CAC1F,KAAI,MACT,MAAO,CACL,MAAO,EAAI,MACX,GAAI,EAAI,cAAgB,CAAE,cAAe,EAAI,cAAe,CAAG,EAAE,CAClE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs","names":[],"sources":["../../src/types/constants.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'doom-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'doom-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'doom-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'doom-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'doom-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n"],"mappings":"AAAA,MAUa,EAAwB,CACnC,EAAG,CAAE,MAAO,GAAK,UAAW,IAAS,CACrC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACtC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACvC,CAEY,EAAsB,CACjC,UACA,+BACA,cACA,WACA,kBACA,cACA,mBACA,gBACA,sBACD"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/types/constants.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'doom-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'doom-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'doom-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'doom-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'doom-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n"],"mappings":"AAAA,MAAa,EAAoB,yBACpB,EAA0B,8BAC1B,EAAuB,2BACvB,EAAsB,0BACtB,EAA6B,iCAM7B,EAAwB,CACnC,EAAG,CAAE,MAAO,GAAK,UAAW,IAAS,CACrC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACtC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACvC,CAEY,EAAsB,CACjC,UACA,+BACA,cACA,WACA,kBACA,cACA,mBACA,gBACA,sBACD"}
@@ -1,5 +1,5 @@
1
- //#region src/types.d.ts
1
+ //#region src/types/index.d.ts
2
2
  type AutocompactPass = 1 | 2 | 3;
3
3
  //#endregion
4
4
  export { AutocompactPass };
5
- //# sourceMappingURL=types.d.cts.map
5
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/types/index.ts"],"mappings":";KAEY,eAAA"}
@@ -1,5 +1,5 @@
1
- //#region src/types.d.ts
1
+ //#region src/types/index.d.ts
2
2
  type AutocompactPass = 1 | 2 | 3;
3
3
  //#endregion
4
4
  export { AutocompactPass };
5
- //# sourceMappingURL=types.d.mts.map
5
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types/index.ts"],"mappings":";KAEY,eAAA"}
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-autocompact",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1-alpha.21",
4
4
  "description": "Staged checkpoint steering and iterative context compaction for Doompi",
5
+ "keywords": [
6
+ "ai",
7
+ "coding-agent",
8
+ "developer-tools",
9
+ "doompi",
10
+ "pi-package"
11
+ ],
5
12
  "homepage": "https://agimon.ai",
6
13
  "license": "MIT",
7
14
  "author": "Vuong Ngo",
@@ -20,21 +27,21 @@
20
27
  "access": "public"
21
28
  },
22
29
  "dependencies": {
23
- "@agimon-ai/doompi-config": "0.0.1-alpha.2",
24
- "@agimon-ai/doompi-telemetry": "0.0.1-alpha.2",
25
- "@agimon-ai/doompi-team": "0.0.1-alpha.2",
26
- "@agimon-ai/doompi-task": "0.0.1-alpha.2",
27
- "@agimon-ai/doompi-ui": "0.0.1-alpha.2"
30
+ "@agimon-ai/doompi-config": "0.0.1-alpha.21",
31
+ "@agimon-ai/doompi-team": "0.0.1-alpha.21",
32
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.21",
33
+ "@agimon-ai/doompi-task": "0.0.1-alpha.21",
34
+ "@agimon-ai/doompi-ui": "0.0.1-alpha.21"
28
35
  },
29
36
  "devDependencies": {
30
- "@earendil-works/pi-coding-agent": "0.84.1",
37
+ "@earendil-works/pi-coding-agent": "0.84.2",
31
38
  "@types/node": "26.1.1",
32
39
  "@vitest/coverage-v8": "4.1.10",
33
40
  "typescript": "6.0.3",
34
41
  "vitest": "4.1.10"
35
42
  },
36
43
  "peerDependencies": {
37
- "@earendil-works/pi-coding-agent": "0.84.1"
44
+ "@earendil-works/pi-coding-agent": "0.84.2"
38
45
  },
39
46
  "peerDependenciesMeta": {
40
47
  "@earendil-works/pi-coding-agent": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkpointWorker.cjs","names":["workerData"],"sources":["../src/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,EAAA,EAAA,iBACjB,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,IACP,CACD,EAAA,YAAY,YAAY,CAAE,aAAY,CAAC,OAChC,EAAO,CACd,EAAA,YAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAE,CAAC,EAIzF,EAAUA,EAAAA,WAAoC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkpointWorker.mjs","names":[],"sources":["../src/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,IACP,CACD,GAAY,YAAY,CAAE,aAAY,CAAC,OAChC,EAAO,CACd,GAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAE,CAAC,EAIzF,EAAU,EAAoC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.cjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'doom-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'doom-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'doom-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'doom-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'doom-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n"],"mappings":"AAAA,MAUa,EAAwB,CACnC,EAAG,CAAE,MAAO,GAAK,UAAW,IAAS,CACrC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACtC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACvC,CAEY,EAAsB,CACjC,UACA,+BACA,cACA,WACA,kBACA,cACA,mBACA,gBACA,sBACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'doom-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'doom-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'doom-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'doom-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'doom-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n"],"mappings":"AAAA,MAAa,EAAoB,yBACpB,EAA0B,8BAC1B,EAAuB,2BACvB,EAAsB,0BACtB,EAA6B,iCAM7B,EAAwB,CACnC,EAAG,CAAE,MAAO,GAAK,UAAW,IAAS,CACrC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACtC,EAAG,CAAE,MAAO,IAAM,UAAW,IAAS,CACvC,CAEY,EAAsB,CACjC,UACA,+BACA,cACA,WACA,kBACA,cACA,mBACA,gBACA,sBACD"}
@@ -1,50 +0,0 @@
1
- const e=require(`./constants.cjs`),t=require(`./policy.cjs`),n=require(`./logSinkTelemetry.cjs`),r=require(`./summarizationModel.cjs`);let i=require(`node:worker_threads`),a=require(`@agimon-ai/doompi-config`),o=require(`@agimon-ai/doompi-ui/footer`),s=require(`@agimon-ai/doompi-task/store/paths`),c=require(`@agimon-ai/doompi-task/store/taskStore`),l=require(`@agimon-ai/doompi-team/api/team-snapshot`),u=require(`@earendil-works/pi-coding-agent`);const d=`@root`,f={waiting:`waiting`,checkpointPending:`checkpoint_pending`,checkpointReady:`checkpoint_ready`,compacting:`compacting`};function p(e,t={}){return{"pi.session.id":e.sessionManager.getSessionId(),...t}}function m(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 h(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 d}function g(e){return e instanceof Error?e.message:String(e)}function _(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 v(e){let t=[];try{let n=new c.TaskStore({cwd:e.cwd,report:{error:(e,n)=>t.push(`${e}: ${g(n)}`),warn:(e,n)=>t.push(`${e}: ${g(n)}`),event:()=>void 0}});return n.configureSession((0,s.resolveSessionKey)(e.sessionManager.getSessionId())),{tasks:n.read().tasks,...t.length>0?{error:t.join(`; `)}:{}}}catch(e){return{tasks:[],error:g(e)}}}function y(){try{let e=(0,l.readActiveNativeTeamSnapshot)();return e?{members:e.members}:{}}catch(e){return{error:g(e)}}}function b(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 x(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
- `):`(no active tasks)`}function S(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 C(e,t,n){let r=_(e);return{...r?{planPath:r.path}:{},tasks:b(t),...t.error?{taskError:t.error}:{},teamAvailable:!!n.members,teamMembers:n.members??[],...n.error?{teamError:n.error}:{}}}function w(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
- Authoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.
5
- <active-plan>
6
- ${t}
7
- </active-plan>
8
- <active-tasks>
9
- ${x(e.tasks,e.taskError)}
10
- </active-tasks>
11
- <active-team>
12
- ${S(n)}
13
- </active-team>
14
- </compaction-runtime-state>`}function T(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 E(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
- <user-prompt source="conversation">
16
- Treat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.
17
- </user-prompt>
18
- <active-plan>
19
- ${t}
20
- </active-plan>
21
- <active-tasks>
22
- ${x(b(e.taskSnapshot),e.taskSnapshot.error)}
23
- </active-tasks>
24
- <active-team>
25
- ${S(e.teamSnapshot)}
26
- </active-team>
27
- <important-context>
28
- ${n.length>0?n.join(`
29
- `):`(none recorded outside the conversation)`}
30
- </important-context>
31
- </compaction-steering>`}function D(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
-
33
- `:``;return`Create Doom autocompact checkpoint pass ${e}.
34
-
35
- ${E(t)}
36
-
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
-
39
- ${n}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.
40
-
41
- ## Goal
42
- ## Constraints & Preferences
43
- ## Progress
44
- ### Done
45
- ### In Progress
46
- ### Blocked
47
- ## Key Decisions
48
- ## Next Steps
49
- ## Critical Context`}function O(e,n,r){let i=t.projectContextMessages((0,u.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,u.sessionEntryToContextMessages)(e))}function k(e,t){return new Promise((n,r)=>{let a=new i.Worker(new URL(`./checkpointWorker.mjs`,require(`url`).pathToFileURL(__filename).href),{workerData:e}),o=!1,s=e=>{o||(o=!0,t.removeEventListener(`abort`,c),e())},c=()=>{s(()=>{a.terminate(),r(t.reason instanceof Error?t.reason:Error(`Autocompact summarization aborted.`))})};a.once(`message`,e=>{s(()=>{typeof e.checkpoint==`string`?n(e.checkpoint):r(Error(e.error??`Autocompact summarization worker returned no checkpoint.`))})}),a.once(`error`,e=>s(()=>r(e))),a.once(`exit`,e=>{e!==0&&s(()=>r(Error(`Autocompact summarization worker exited with code ${e}.`)))}),t.addEventListener(`abort`,c,{once:!0}),a.unref(),t.aborted&&c()})}function A(e){try{return(0,a.loadDoomConfig)((0,a.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 j(e){let t=A(e.cwd),n=t?.model?r.parseModelReference(t.model):void 0,i=n?e.modelRegistry.find(n.provider,n.modelId):void 0,a=i??e.model;if(!a)return;let o=t?.thinking??(i?n?.thinking:void 0)??e.thinkingLevel;return{model:a,...o?{thinkingLevel:o}:{}}}async function M(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 k({messages:e.messages,model:n.model,reserveTokens:u.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 N(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function P(r,i={}){let a=i.resolveModel??j,s=i.generateCheckpoint??(e=>M(e,a)),c=i.readTaskSnapshot??v,l=i.readTeamSnapshot??y,g=i.telemetry??n.createAutocompactTelemetry(),b=i.doomIntegrations??!0,x=new Set,S=new Set,E=t.createInitialState(),k,A,P=b?(0,o.registerDoomFooterContribution)(r,{source:`doom-autocompact`,id:`autocompact`,order:20}):{update:()=>void 0,dispose:()=>void 0},F=e=>{let t=E.phase===f.checkpointPending?`summarizing`:E.phase===f.checkpointReady?`applying`:void 0;P.update(t?{fullText:`Compacting p${E.pass}`,compactText:`C${E.pass}`}:void 0);let n=e??k;n?.hasUI&&n.ui.setStatus(`doom-autocompact`,t?`Compacting pass ${E.pass} (${t})…`:void 0)},I=()=>{r.appendEntry(e.STATE_CUSTOM_TYPE,{...E}),F()},L=()=>{delete E.requestId,delete E.snapshotLeafId,delete E.snapshotTokens,delete E.pendingCheckpoint,delete E.compactionPass},R=e=>{E.checkpointQueue=E.checkpointQueue.filter(t=>t!==e)},z=e=>{E=m(e.sessionManager.getBranch())??t.createInitialState(),!(E.phase===f.checkpointReady&&E.requestId&&E.snapshotLeafId&&E.pendingCheckpoint||E.phase===f.waiting)&&(A?.abort(),A=void 0,E.phase=f.waiting,L(),I())},B=t=>{r.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:E.cycle,pass:E.pass}},{triggerTurn:!0,deliverAs:`steer`})},V=(e,t)=>{if(e!==E.requestId||E.phase!==f.checkpointPending)return;let n=E.snapshotLeafId;E.phase=f.waiting,n&&(E.lastAttemptLeafId=n),L(),I(),N(k,`Doom autocompact summarization pass ${E.pass} failed: ${t instanceof Error?t.message:String(t)}`,`error`)},H=(e,t,r,i)=>{t.error&&(N(e,`Doom autocompact task steering degraded: ${t.error}`,`warning`),g.recordWarning(n.AUTOCOMPACT_EVENT.taskSnapshotDegraded,Error(t.error),i)),r.error&&(N(e,`Doom autocompact team steering degraded: ${r.error}`,`warning`),g.recordWarning(n.AUTOCOMPACT_EVENT.teamSnapshotDegraded,Error(r.error),i))},U=(t,n,i)=>{let a=c(t),o=l();H(t,a,o,i);let s=C(n,a,o);return r.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:w(s),display:!1,details:{version:1,...s}}),s},W=(i,a)=>{if(!E.requestId||!E.snapshotLeafId||!E.pendingCheckpoint)return!1;let o=a.sessionManager.getBranch(),s=t.projectContextMessages((0,u.buildSessionContext)(o).messages,o).messages,c=t.mergeFileDetails(E,t.fileOperationsFromMessages(s)),l=E.requestId,d=E.cycle,m=t.withCanonicalFileSections(E.pendingCheckpoint,c),_={...c,doomAutocompact:{version:2,cycle:d,pass:i,requestId:l,snapshotLeafId:E.snapshotLeafId,tokensBefore:E.snapshotTokens??a.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(o,E.snapshotLeafId)};N(a,`Doom autocompact pass ${i} context commit started.`);let v=a.isIdle();r.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:m,display:!1,details:_});let y=h(a),b=U(a,o,p(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":i}));return v&&r.setLabel(y,`autocompact:c${d}:p${i}`),E.readFiles=c.readFiles,E.modifiedFiles=c.modifiedFiles,delete E.latestCheckpointSnapshotLeafId,E.phase=f.waiting,E.checkpointQueue=[],E.exhaustedPasses=[],E.invalidAttempts=0,E.baselinePending=!0,delete E.lastAttemptLeafId,L(),E.cycle+=1,E.pass=1,I(),g.recordEvent(n.AUTOCOMPACT_EVENT.contextCommitted,p(a,{"autocompact.request.id":l,"autocompact.cycle":d,"autocompact.pass":i,"autocompact.snapshot_leaf_id":_.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":_.doomAutocompact.tokensBefore,"autocompact.message_count.before":s.length,"autocompact.message_count.retained":_.retainedMessages.length,"autocompact.apply_mode":v?`idle`:`turn_end`,...T(b)})),N(a,`Doom autocompact context committed. Baseline will be captured from the next settled context.`),v&&B(`Asynchronous compaction completed.`),!0},G=(e,r,i)=>{let a=r.sessionManager.getBranch(),o=h(r),u=t.createRequestId(r.sessionManager.getSessionId(),E.cycle,e,o),d=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(a)):void 0,m=O(e,a,E.latestCheckpointSnapshotLeafId),v=c(r),y=l(),b=p(r,{"autocompact.request.id":u,"autocompact.cycle":E.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":o,"autocompact.tokens_before":i,"autocompact.message_count.before":m.length});H(r,v,y,b),E.phase=f.checkpointPending,E.pass=e,E.requestId=u,E.snapshotLeafId=o,E.snapshotTokens=i,delete E.pendingCheckpoint,delete E.compactionPass,delete E.lastAttemptLeafId,I(),A?.abort(),A=new AbortController;let x=A.signal;N(r,`Doom autocompact summarization pass ${e} started.`),g.runInSpan(`doom_autocompact.checkpoint`,b,async()=>{await g.recordEvent(n.AUTOCOMPACT_EVENT.checkpointStarted,b);try{let t=await s({messages:m,instructions:D(e,{plan:_(a),taskSnapshot:v,teamSnapshot:y,readFiles:E.readFiles,modifiedFiles:E.modifiedFiles}),...d?{previousCheckpoint:d}:{},context:r,signal:x});if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await g.recordEvent(n.AUTOCOMPACT_EVENT.checkpointCompleted,{...b,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw await g.recordError(n.AUTOCOMPACT_EVENT.checkpointFailed,e,b),e}}).then(t=>{u!==E.requestId||E.phase!==f.checkpointPending||(E.phase=f.checkpointReady,E.pendingCheckpoint=t.trim(),I(),N(k,`Doom autocompact summarization pass ${e} completed.`),k&&Y(k))}).catch(e=>V(u,e))},K=e=>{if(E.phase!==f.waiting||e.hasPendingMessages())return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(E.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(E.baselineTokens=n.tokens,E.baselinePending=!1,I(),N(e,`Doom autocompact baseline captured at ${E.baselineTokens} tokens.`),!1):!1;let r=h(e);if(E.lastAttemptLeafId===r)return!1;for(let e of[1,2,3])e<E.pass||E.checkpointQueue.includes(e)||E.exhaustedPasses.includes(e)||n.tokens>=t.thresholdTokens(e,n.contextWindow,E.baselineTokens)&&E.checkpointQueue.push(e);let i=E.checkpointQueue[0];return i?(G(i,e,n.tokens),!0):!1},q=(n,i)=>{let a=E.snapshotLeafId;r.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(E.cycle,n,E.requestId??`completed`),summary:i}),a&&(E.latestCheckpointSnapshotLeafId=a)},J=e=>{if(E.phase!==f.checkpointReady||!E.requestId||!E.pendingCheckpoint)return`none`;let r=E.pass,i=t.parseCheckpointDecision(E.pendingCheckpoint);if(!t.isStructuredCheckpoint(i.summary)){let t=E.snapshotLeafId,i=E.requestId,a=E.invalidAttempts+1,o=a>=3;E.phase=f.waiting,t&&(E.lastAttemptLeafId=t),o?(R(r),E.exhaustedPasses=[...E.exhaustedPasses,r],E.invalidAttempts=0):E.invalidAttempts=a,L(),I();let s=Error(`Summarization pass ${r} returned an incomplete checkpoint.`);return N(e,o?`Doom autocompact summarization pass ${r} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${r} returned an incomplete checkpoint.`,`error`),g.recordError(n.AUTOCOMPACT_EVENT.checkpointInvalid,s,p(e,{"autocompact.cycle":E.cycle,"autocompact.pass":r,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...i?{"autocompact.request.id":i}:{}})),`invalid`}return E.invalidAttempts=0,r===1?(q(1,i.summary),R(1),E.phase=f.waiting,E.pass=2,L(),I(),`pass1`):r===2&&i.shouldCompact!==!0?(q(2,i.summary),R(2),E.phase=f.waiting,E.pass=3,L(),I(),`deferred`):(E.pendingCheckpoint=i.summary,W(r,e)?`committed`:`invalid`)};function Y(e){k=e,e.isIdle()&&J(e)!==`committed`&&K(e)}r.on(`context`,(e,r)=>{let i=t.projectContextMessages(e.messages,r.sessionManager.getBranch());if(i.invalidMarker){let e=r.sessionManager.getLeafId()??d;S.has(e)||(S.add(e),g.recordError(n.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),p(r,{"autocompact.leaf_id":e})));return}if(i.marker)return x.has(i.marker.requestId)||(x.add(i.marker.requestId),g.recordEvent(n.AUTOCOMPACT_EVENT.contextApplied,p(r,{"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}}),r.on(`session_start`,(e,t)=>{k=t,z(t),Y(t)}),r.on(`session_tree`,(e,t)=>{k=t,z(t),Y(t)}),r.on(`turn_end`,(e,t)=>{if(k=t,t.isIdle()){Y(t);return}E.phase===f.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&J(t)!==`none`||K(t)}),r.on(`agent_settled`,(e,t)=>{Y(t)}),r.on(`session_before_compact`,e=>{if(e.reason===`threshold`)return E.phase===f.checkpointPending||E.phase===f.checkpointReady||E.baselinePending?{cancel:!0}:void 0}),r.on(`session_compact`,(e,i)=>{A?.abort(),A=void 0;let a=t.fileDetailsFromUnknown(e.compactionEntry.details),o=t.mergeFileDetails(E,void 0,a);E.readFiles=o.readFiles,E.modifiedFiles=o.modifiedFiles,delete E.latestCheckpointSnapshotLeafId,E.baselinePending=!0,E.phase=f.waiting,L(),E.checkpointQueue=[],E.exhaustedPasses=[],E.invalidAttempts=0,delete E.lastAttemptLeafId,r.setLabel(e.compactionEntry.id,`autocompact:c${E.cycle}:external`);let s=E.cycle,c=p(i,{"autocompact.cycle":s,"autocompact.native.reason":e.reason}),l=U(i,i.sessionManager.getBranch(),c);E.cycle+=1,E.pass=1,I(),g.recordEvent(n.AUTOCOMPACT_EVENT.nativeCompactionCompleted,p(i,{"autocompact.cycle":s,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...T(l)})),N(i,`Doom autocompact completed. Baseline will be captured from the next settled context. Next pass: ${E.pass}.`)}),r.on(`session_shutdown`,async()=>{A?.abort(),A=void 0,P.dispose(),k=void 0,x.clear(),S.clear(),E=t.createInitialState(),await g.shutdown()})}exports.registerAutocompactExtension=P;
50
- //# sourceMappingURL=extension.cjs.map