@agimon-ai/doompi-autocompact 0.0.1-alpha.3 → 0.0.1-alpha.31

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 (102) hide show
  1. package/README.md +62 -18
  2. package/dist/checkpointWorker.cjs +1 -1
  3. package/dist/checkpointWorker.cjs.map +1 -1
  4. package/dist/checkpointWorker.d.cts +19 -1
  5. package/dist/checkpointWorker.d.cts.map +1 -0
  6. package/dist/checkpointWorker.d.mts +19 -1
  7. package/dist/checkpointWorker.d.mts.map +1 -0
  8. package/dist/checkpointWorker.mjs +1 -1
  9. package/dist/checkpointWorker.mjs.map +1 -1
  10. package/dist/extensions/pi.cjs +1 -2
  11. package/dist/extensions/pi.d.cts +2 -2
  12. package/dist/extensions/pi.d.mts +2 -2
  13. package/dist/extensions/pi.mjs +1 -2
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.d.cts +4 -4
  16. package/dist/index.d.mts +4 -4
  17. package/dist/index.mjs +1 -1
  18. package/dist/{policy.cjs → src/adapters/compaction/policy.cjs} +3 -3
  19. package/dist/src/adapters/compaction/policy.cjs.map +1 -0
  20. package/dist/src/adapters/compaction/policy.d.cts +7 -0
  21. package/dist/src/adapters/compaction/policy.d.cts.map +1 -0
  22. package/dist/src/adapters/compaction/policy.d.mts +7 -0
  23. package/dist/src/adapters/compaction/policy.d.mts.map +1 -0
  24. package/dist/{policy.mjs → src/adapters/compaction/policy.mjs} +3 -3
  25. package/dist/src/adapters/compaction/policy.mjs.map +1 -0
  26. package/dist/src/adapters/pi/extension.cjs +44 -0
  27. package/dist/src/adapters/pi/extension.cjs.map +1 -0
  28. package/dist/src/adapters/pi/extension.d.cts +25 -0
  29. package/dist/src/adapters/pi/extension.d.cts.map +1 -0
  30. package/dist/src/adapters/pi/extension.d.mts +25 -0
  31. package/dist/src/adapters/pi/extension.d.mts.map +1 -0
  32. package/dist/src/adapters/pi/extension.mjs +44 -0
  33. package/dist/src/adapters/pi/extension.mjs.map +1 -0
  34. package/dist/src/adapters/telemetry/logSinkTelemetry.cjs +2 -0
  35. package/dist/src/adapters/telemetry/logSinkTelemetry.cjs.map +1 -0
  36. package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts +26 -0
  37. package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts.map +1 -0
  38. package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts +26 -0
  39. package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts.map +1 -0
  40. package/dist/src/adapters/telemetry/logSinkTelemetry.mjs +2 -0
  41. package/dist/src/adapters/telemetry/logSinkTelemetry.mjs.map +1 -0
  42. package/dist/src/services/summarizationModel.cjs +2 -0
  43. package/dist/src/services/summarizationModel.cjs.map +1 -0
  44. package/dist/{summarizationModel.d.cts → src/services/summarizationModel.d.cts} +1 -2
  45. package/dist/src/services/summarizationModel.d.cts.map +1 -0
  46. package/dist/{summarizationModel.d.mts → src/services/summarizationModel.d.mts} +1 -2
  47. package/dist/src/services/summarizationModel.d.mts.map +1 -0
  48. package/dist/src/services/summarizationModel.mjs +2 -0
  49. package/dist/src/services/summarizationModel.mjs.map +1 -0
  50. package/dist/src/types/constants.cjs.map +1 -0
  51. package/dist/src/types/constants.mjs.map +1 -0
  52. package/dist/src/types/index.d.cts +6 -0
  53. package/dist/src/types/index.d.cts.map +1 -0
  54. package/dist/src/types/index.d.mts +6 -0
  55. package/dist/src/types/index.d.mts.map +1 -0
  56. package/package.json +35 -15
  57. package/dist/constants.cjs.map +0 -1
  58. package/dist/constants.mjs.map +0 -1
  59. package/dist/extension.cjs +0 -50
  60. package/dist/extension.cjs.map +0 -1
  61. package/dist/extension.d.cts +0 -36
  62. package/dist/extension.d.cts.map +0 -1
  63. package/dist/extension.d.mts +0 -36
  64. package/dist/extension.d.mts.map +0 -1
  65. package/dist/extension.mjs +0 -50
  66. package/dist/extension.mjs.map +0 -1
  67. package/dist/extensions/pi.cjs.map +0 -1
  68. package/dist/extensions/pi.mjs.map +0 -1
  69. package/dist/logSinkTelemetry.cjs +0 -2
  70. package/dist/logSinkTelemetry.cjs.map +0 -1
  71. package/dist/logSinkTelemetry.d.cts +0 -26
  72. package/dist/logSinkTelemetry.d.cts.map +0 -1
  73. package/dist/logSinkTelemetry.d.mts +0 -26
  74. package/dist/logSinkTelemetry.d.mts.map +0 -1
  75. package/dist/logSinkTelemetry.mjs +0 -2
  76. package/dist/logSinkTelemetry.mjs.map +0 -1
  77. package/dist/policy.cjs.map +0 -1
  78. package/dist/policy.d.cts +0 -6
  79. package/dist/policy.d.cts.map +0 -1
  80. package/dist/policy.d.mts +0 -6
  81. package/dist/policy.d.mts.map +0 -1
  82. package/dist/policy.mjs.map +0 -1
  83. package/dist/standard.cjs +0 -2
  84. package/dist/standard.cjs.map +0 -1
  85. package/dist/standard.d.cts +0 -8
  86. package/dist/standard.d.cts.map +0 -1
  87. package/dist/standard.d.mts +0 -8
  88. package/dist/standard.d.mts.map +0 -1
  89. package/dist/standard.mjs +0 -2
  90. package/dist/standard.mjs.map +0 -1
  91. package/dist/summarizationModel.cjs +0 -2
  92. package/dist/summarizationModel.cjs.map +0 -1
  93. package/dist/summarizationModel.d.cts.map +0 -1
  94. package/dist/summarizationModel.d.mts.map +0 -1
  95. package/dist/summarizationModel.mjs +0 -2
  96. package/dist/summarizationModel.mjs.map +0 -1
  97. package/dist/types.d.cts +0 -5
  98. package/dist/types.d.cts.map +0 -1
  99. package/dist/types.d.mts +0 -5
  100. package/dist/types.d.mts.map +0 -1
  101. /package/dist/{constants.cjs → src/types/constants.cjs} +0 -0
  102. /package/dist/{constants.mjs → src/types/constants.mjs} +0 -0
package/README.md CHANGED
@@ -1,35 +1,79 @@
1
1
  # @agimon-ai/doompi-autocompact
2
2
 
3
- Staged checkpoint steering and iterative context compaction for Doompi.
3
+ Staged checkpoint summarization and iterative context compaction for DoomPi.
4
4
 
5
- Compaction runs on a three-pass ladder in a worker thread, so the session never blocks on
6
- it. It reads the live plan, task graph, and team snapshot and commits them next to the
7
- summary as authoritative, rather than leaving coordination state to be reconstructed from
8
- prose.
5
+ Part of the [DoomPi distribution](https://www.npmjs.com/package/@agimon-ai/doompi).
9
6
 
10
- Part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi), a coding agent that loads
11
- only the skills and tools you name. This package is composed by Doompi and is not usually
12
- installed on its own.
7
+ Instead of waiting for one final summary near the context limit, Autocompact creates up to three
8
+ asynchronous checkpoints and combines each checkpoint with subsequent messages.
9
+
10
+ > **Alpha:** thresholds and compaction steering may change between releases.
11
+
12
+ ## Requirements
13
+
14
+ - Node.js 22.19.0 or newer
15
+ - Pi 0.84.2
16
+ - Authentication for the model selected for summarization
13
17
 
14
18
  ## Install
15
19
 
20
+ DoomPi includes Autocompact in every composition. Pi discovers its sole extension entry through
21
+ `package.json.pi.extensions`. For direct Pi installation:
22
+
16
23
  ```bash
17
- npm install @agimon-ai/doompi-autocompact
24
+ pi install npm:@agimon-ai/doompi-autocompact
18
25
  ```
19
26
 
20
- ## How it loads
27
+ The extension entry is `@agimon-ai/doompi-autocompact/extensions/pi`.
28
+
29
+ ## Checkpoint ladder
30
+
31
+ The standard adapter uses thresholds around 50%, 75%, and 95% of the usable context window,
32
+ subject to token caps and Pi's native-compaction clamp:
33
+
34
+ 1. create an initial compact summary;
35
+ 2. combine it with later messages and allow the model to decide whether compaction is ready;
36
+ 3. combine again and force compaction on the final pass.
37
+
38
+ Summarization runs in a worker thread so the foreground session can continue. Checkpoints are
39
+ persisted as hidden session entries and used for later steering.
21
40
 
22
- Doompi loads this unconditionally. It is core, not a layer, so it does not appear in
23
- `.doom/modes.yaml`: making it optional would only create broken configurations.
41
+ DoomPi uses the configured planning subagent model and thinking level when available, then falls
42
+ back to the active Pi model. Standalone Pi without DoomPi planning configuration uses the active
43
+ model. Each checkpoint can therefore make another provider request, consume quota, and require the
44
+ credentials for the selected model. Provider errors or missing authentication affect checkpoint
45
+ generation rather than granting a free local summary.
24
46
 
25
- Extension entry: `@agimon-ai/doompi-autocompact/extensions/pi`
47
+ ## Coordination state
26
48
 
27
- ## Entry points
49
+ Autocompact does not own `@agimon-ai/doompi-task` or `@agimon-ai/doompi-team` persistence. The
50
+ standard adapter reads best-effort snapshots from those packages when available, while Task's
51
+ `tasks.json` and Team's run and intercom state remain owned by their respective packages. Missing
52
+ snapshot data is reported as unavailable and must not be inferred from an Autocompact summary.
53
+
54
+ ## Public API
55
+
56
+ ```ts
57
+ import { installAutocompactRuntime, thresholdTokens } from '@agimon-ai/doompi-autocompact';
58
+ import type { AutocompactPass } from '@agimon-ai/doompi-autocompact';
59
+ ```
60
+
61
+ Normal Pi activation should use the discovered `extensions/pi` entry. Host integrations can call
62
+ `installAutocompactRuntime` to install package resources into the shared runner-scoped Cordis host.
63
+ The extension entry manages its plugin lifecycle and releases the host lease when the Pi session
64
+ shuts down. `thresholdTokens` exposes the threshold policy for hosts that need to preview or test
65
+ checkpoint boundaries.
66
+
67
+ ## Development
68
+
69
+ ```bash
70
+ pnpm build
71
+ pnpm typecheck
72
+ pnpm test
73
+ pnpm lint
74
+ ```
28
75
 
29
- | Import |
30
- | --------------------------------------------- |
31
- | `@agimon-ai/doompi-autocompact` |
32
- | `@agimon-ai/doompi-autocompact/extensions/pi` |
76
+ Maintained by [Agimon](https://agimon.ai/about).
33
77
 
34
78
  ## License
35
79
 
@@ -1,2 +1,2 @@
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);
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("node:worker_threads");async function t(e){let{generateSummary:t}=await import(e.piModuleUrl);return t(e.messages,e.model,e.reserveTokens,e.apiKey,e.headers,void 0,e.instructions,e.previousCheckpoint,e.thinkingLevel,void 0,e.env)}async function n(n){try{let r=await t(n);e.parentPort?.postMessage({checkpoint:r})}catch(t){e.parentPort?.postMessage({error:t instanceof Error?t.message:String(t)})}}e.parentPort&&n(e.workerData),exports.generateCheckpointInWorker=t;
2
2
  //# sourceMappingURL=checkpointWorker.cjs.map
@@ -1 +1 @@
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
+ {"version":3,"file":"checkpointWorker.cjs","names":["parentPort","workerData"],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\ntype PiCodingAgentModule = typeof import('@earendil-works/pi-coding-agent');\ntype GenerateSummaryArguments = Parameters<PiCodingAgentModule['generateSummary']>;\n\ninterface CheckpointWorkerInput {\n piModuleUrl: string;\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\nexport async function generateCheckpointInWorker(input: CheckpointWorkerInput): Promise<string> {\n const { generateSummary } = (await import(input.piModuleUrl)) as PiCodingAgentModule;\n return 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}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateCheckpointInWorker(input);\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nif (parentPort) void summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"wGAkBA,eAAsB,EAA2B,EAA+C,CAC9F,GAAM,CAAE,mBAAqB,MAAM,OAAO,EAAM,aAChD,OAAO,EACL,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,GACR,CACF,CAEA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAM,EAA2B,CAAK,EACzD,EAAA,YAAY,YAAY,CAAE,YAAW,CAAC,CACxC,OAAS,EAAO,CACd,EAAA,YAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAAE,CAAC,CAC3F,CACF,CAEIA,EAAAA,YAAY,EAAeC,EAAAA,UAAmC"}
@@ -1 +1,19 @@
1
- export { };
1
+ //#region src/adapters/process/checkpointWorker.d.ts
2
+ type PiCodingAgentModule = typeof import('@earendil-works/pi-coding-agent');
3
+ type GenerateSummaryArguments = Parameters<PiCodingAgentModule['generateSummary']>;
4
+ interface CheckpointWorkerInput {
5
+ piModuleUrl: string;
6
+ messages: GenerateSummaryArguments[0];
7
+ model: GenerateSummaryArguments[1];
8
+ reserveTokens: GenerateSummaryArguments[2];
9
+ apiKey?: GenerateSummaryArguments[3];
10
+ headers?: GenerateSummaryArguments[4];
11
+ instructions: GenerateSummaryArguments[6];
12
+ previousCheckpoint?: GenerateSummaryArguments[7];
13
+ thinkingLevel?: GenerateSummaryArguments[8];
14
+ env?: GenerateSummaryArguments[10];
15
+ }
16
+ declare function generateCheckpointInWorker(input: CheckpointWorkerInput): Promise<string>;
17
+ //#endregion
18
+ export { generateCheckpointInWorker };
19
+ //# sourceMappingURL=checkpointWorker.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpointWorker.d.cts","names":[],"sources":["../src/adapters/process/checkpointWorker.ts"],"mappings":";KAEK;KACA,2BAA2B,WAAW;UAEjC;EACR;EACA,UAAU;EACV,OAAO;EACP,eAAe;EACf,SAAS;EACT,UAAU;EACV,cAAc;EACd,qBAAqB;EACrB,gBAAgB;EAChB,MAAM;;iBAGc,2BAA2B,OAAO,wBAAwB"}
@@ -1 +1,19 @@
1
- export { };
1
+ //#region src/adapters/process/checkpointWorker.d.ts
2
+ type PiCodingAgentModule = typeof import('@earendil-works/pi-coding-agent');
3
+ type GenerateSummaryArguments = Parameters<PiCodingAgentModule['generateSummary']>;
4
+ interface CheckpointWorkerInput {
5
+ piModuleUrl: string;
6
+ messages: GenerateSummaryArguments[0];
7
+ model: GenerateSummaryArguments[1];
8
+ reserveTokens: GenerateSummaryArguments[2];
9
+ apiKey?: GenerateSummaryArguments[3];
10
+ headers?: GenerateSummaryArguments[4];
11
+ instructions: GenerateSummaryArguments[6];
12
+ previousCheckpoint?: GenerateSummaryArguments[7];
13
+ thinkingLevel?: GenerateSummaryArguments[8];
14
+ env?: GenerateSummaryArguments[10];
15
+ }
16
+ declare function generateCheckpointInWorker(input: CheckpointWorkerInput): Promise<string>;
17
+ //#endregion
18
+ export { generateCheckpointInWorker };
19
+ //# sourceMappingURL=checkpointWorker.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpointWorker.d.mts","names":[],"sources":["../src/adapters/process/checkpointWorker.ts"],"mappings":";KAEK;KACA,2BAA2B,WAAW;UAEjC;EACR;EACA,UAAU;EACV,OAAO;EACP,eAAe;EACf,SAAS;EACT,UAAU;EACV,cAAc;EACd,qBAAqB;EACrB,gBAAgB;EAChB,MAAM;;iBAGc,2BAA2B,OAAO,wBAAwB"}
@@ -1,2 +1,2 @@
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{};
1
+ import{parentPort as e,workerData as t}from"node:worker_threads";async function n(e){let{generateSummary:t}=await import(e.piModuleUrl);return t(e.messages,e.model,e.reserveTokens,e.apiKey,e.headers,void 0,e.instructions,e.previousCheckpoint,e.thinkingLevel,void 0,e.env)}async function r(t){try{let r=await n(t);e?.postMessage({checkpoint:r})}catch(t){e?.postMessage({error:t instanceof Error?t.message:String(t)})}}e&&r(t);export{n as generateCheckpointInWorker};
2
2
  //# sourceMappingURL=checkpointWorker.mjs.map
@@ -1 +1 @@
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
+ {"version":3,"file":"checkpointWorker.mjs","names":[],"sources":["../src/adapters/process/checkpointWorker.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\n\ntype PiCodingAgentModule = typeof import('@earendil-works/pi-coding-agent');\ntype GenerateSummaryArguments = Parameters<PiCodingAgentModule['generateSummary']>;\n\ninterface CheckpointWorkerInput {\n piModuleUrl: string;\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\nexport async function generateCheckpointInWorker(input: CheckpointWorkerInput): Promise<string> {\n const { generateSummary } = (await import(input.piModuleUrl)) as PiCodingAgentModule;\n return 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}\n\nasync function summarize(input: CheckpointWorkerInput): Promise<void> {\n try {\n const checkpoint = await generateCheckpointInWorker(input);\n parentPort?.postMessage({ checkpoint });\n } catch (error) {\n parentPort?.postMessage({ error: error instanceof Error ? error.message : String(error) });\n }\n}\n\nif (parentPort) void summarize(workerData as CheckpointWorkerInput);\n"],"mappings":"iEAkBA,eAAsB,EAA2B,EAA+C,CAC9F,GAAM,CAAE,mBAAqB,MAAM,OAAO,EAAM,aAChD,OAAO,EACL,EAAM,SACN,EAAM,MACN,EAAM,cACN,EAAM,OACN,EAAM,QACN,IAAA,GACA,EAAM,aACN,EAAM,mBACN,EAAM,cACN,IAAA,GACA,EAAM,GACR,CACF,CAEA,eAAe,EAAU,EAA6C,CACpE,GAAI,CACF,IAAM,EAAa,MAAM,EAA2B,CAAK,EACzD,GAAY,YAAY,CAAE,YAAW,CAAC,CACxC,OAAS,EAAO,CACd,GAAY,YAAY,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAAE,CAAC,CAC3F,CACF,CAEI,GAAY,EAAe,CAAmC"}
@@ -1,2 +1 @@
1
- var e=require(`../standard.cjs`).registerStandardAutocompactExtension;module.exports=e;
2
- //# sourceMappingURL=pi.cjs.map
1
+ const e=require("../src/adapters/pi/extension.cjs");module.exports=e.autocompactExtension;
@@ -1,2 +1,2 @@
1
- import { registerStandardAutocompactExtension } from "../standard.cjs";
2
- export = registerStandardAutocompactExtension;
1
+ import { autocompactExtension } from "../src/adapters/pi/extension.cjs";
2
+ export = autocompactExtension;
@@ -1,2 +1,2 @@
1
- import { registerStandardAutocompactExtension } from "../standard.mjs";
2
- export { registerStandardAutocompactExtension as default };
1
+ import { autocompactExtension } from "../src/adapters/pi/extension.mjs";
2
+ export { autocompactExtension as default };
@@ -1,2 +1 @@
1
- import{registerStandardAutocompactExtension as e}from"../standard.mjs";var t=e;export{t as default};
2
- //# sourceMappingURL=pi.mjs.map
1
+ import{autocompactExtension as e}from"../src/adapters/pi/extension.mjs";export{e as default};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./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("./src/adapters/compaction/policy.cjs"),t=require("./src/adapters/pi/extension.cjs");exports.installAutocompactRuntime=t.installAutocompactRuntime,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";
4
- export { type AutocompactPass, registerAutocompactExtension, thresholdTokens };
1
+ import { installAutocompactRuntime } from "./src/adapters/pi/extension.cjs";
2
+ import { AutocompactPass } from "./src/types/index.cjs";
3
+ import { thresholdTokens } from "./src/adapters/compaction/policy.cjs";
4
+ export { type AutocompactPass, installAutocompactRuntime, 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";
4
- export { type AutocompactPass, registerAutocompactExtension, thresholdTokens };
1
+ import { installAutocompactRuntime } from "./src/adapters/pi/extension.mjs";
2
+ import { AutocompactPass } from "./src/types/index.mjs";
3
+ import { thresholdTokens } from "./src/adapters/compaction/policy.mjs";
4
+ export { type AutocompactPass, installAutocompactRuntime, 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"./src/adapters/compaction/policy.mjs";import{installAutocompactRuntime as t}from"./src/adapters/pi/extension.mjs";export{t as installAutocompactRuntime,e as thresholdTokens};
@@ -1,8 +1,8 @@
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(`
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(`
1
+ const e=require("../../types/constants.cjs");let t=require("@earendil-works/pi-coding-agent");const n=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,r=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function i(e){return typeof e==`object`&&!!e}function a(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function o(e){return e===1||e===2||e===3}function s(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
+ `).trim()||void 0}function c(e){return i(e)&&typeof e.role==`string`}function l(e){if(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(c)||!i(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function u(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function d(n,r,i=0){let a=e.COMPACTION_THRESHOLDS[n],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-t.DEFAULT_COMPACTION_SETTINGS.reserveTokens;return l>o?Math.min(c,l):c}function f(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function p(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function m(e,n){let r=e.findIndex(e=>e.id===n);return r===-1?[]:e.slice(r+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,t.sessionEntryToContextMessages)(e))}function h(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=l(r.details),a=v(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&l(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function g(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function _(e){if(!i(e)||e.version!==2||typeof e.cycle!=`number`||!o(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(o)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let s=e.exhaustedPasses??[];if(!Array.isArray(s)||!s.every(o))return;let c=e.invalidAttempts??0;if(!(typeof c!=`number`||c<0)&&!(!a(e.readFiles)||!a(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...s],invalidAttempts:c,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function v(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?i(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
3
3
  `)).trim()||void 0:s(e)}function y(e){let t=e.match(n),r=e.replace(n,``).trim();return t?{summary:r,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:r}}function b(t){return e.CHECKPOINT_HEADINGS.every(e=>t.includes(e))}function x(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function S(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function C(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function w(e){if(!(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function T(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
4
4
  `)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
5
5
  `)}\n</modified-files>`);let i=e.replace(r,``).trim();return n.length>0?`${i}\n\n${n.join(`
6
6
 
7
- `)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
7
+ `)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.contextDetailsFromUnknown=l,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
8
8
  //# sourceMappingURL=policy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.cjs","names":["COMPACTION_THRESHOLDS","DEFAULT_COMPACTION_SETTINGS","sessionEntryToContextMessages","CHECKPOINT_HEADINGS"],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\n\nconst SHOULD_COMPACT_PATTERN = /<shouldCompact>\\s*(true|false)\\s*<\\/shouldCompact>/i;\nconst FILE_SECTION_PATTERN = /\\n*<(?:read-files|modified-files)>[\\s\\S]*?<\\/(?:read-files|modified-files)>/g;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction isPass(value: unknown): value is AutocompactPass {\n return value === 1 || value === 2 || value === 3;\n}\n\nfunction assistantText(entry: SessionEntry): string | undefined {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return undefined;\n const text = entry.message.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .trim();\n return text || undefined;\n}\n\nfunction isAutocompactMessage(value: unknown): value is AutocompactMessage {\n return isRecord(value) && typeof value.role === 'string';\n}\n\nexport function contextDetailsFromUnknown(value: unknown): AutocompactContextDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return undefined;\n if (!isRecord(value.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\n if (\n marker.version !== STATE_VERSION ||\n (marker.pass !== 2 && marker.pass !== 3) ||\n typeof marker.cycle !== 'number' ||\n typeof marker.requestId !== 'string' ||\n typeof marker.snapshotLeafId !== 'string' ||\n typeof marker.tokensBefore !== 'number'\n )\n return undefined;\n return {\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n retainedMessages: [...value.retainedMessages],\n doomAutocompact: {\n version: STATE_VERSION,\n cycle: marker.cycle,\n pass: marker.pass,\n requestId: marker.requestId,\n snapshotLeafId: marker.snapshotLeafId,\n tokensBefore: marker.tokensBefore,\n },\n };\n}\n\nexport function createInitialState(): AutocompactState {\n return {\n version: STATE_VERSION,\n cycle: 1,\n pass: 1,\n phase: 'waiting',\n checkpointQueue: [],\n exhaustedPasses: [],\n invalidAttempts: 0,\n baselineTokens: 0,\n baselinePending: false,\n readFiles: [],\n modifiedFiles: [],\n };\n}\n\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[pass];\n const baseline = Math.max(0, Math.min(baselineTokens, contextWindow));\n const remaining = contextWindow - baseline;\n const staged = baseline + Math.min(Math.floor(remaining * threshold.ratio), threshold.capTokens);\n // Pi compacts natively above `contextWindow - reserveTokens`. A staged threshold above that\n // point can never fire, so the ladder would silently degrade into native compaction: on a\n // 200k window the raw pass 3 ratio lands at 190_000, while Pi already compacted at 183_616.\n const nativeTrigger = contextWindow - DEFAULT_COMPACTION_SETTINGS.reserveTokens;\n return nativeTrigger > baseline ? Math.min(staged, nativeTrigger) : staged;\n}\n\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | undefined {\n return branchEntries.findLast(\n (entry) =>\n entry.type === 'compaction' ||\n // Staged checkpoints are plain entries so they stay out of the agent's LLM context.\n (entry.type === 'custom' && entry.customType === CHECKPOINT_MESSAGE_TYPE) ||\n // Legacy sessions staged checkpoints as custom messages; committed markers still are.\n (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE),\n );\n return branchEntries.slice(boundaryIndex + 1).some((entry) => {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return false;\n const { stopReason, usage } = entry.message;\n if (stopReason === 'aborted' || stopReason === 'error' || !usage) return false;\n return (usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n });\n}\n\nexport function retainedMessagesAfterSnapshot(\n branchEntries: SessionEntry[],\n snapshotLeafId: string,\n): AutocompactMessage[] {\n const snapshotIndex = branchEntries.findIndex((entry) => entry.id === snapshotLeafId);\n if (snapshotIndex === -1) return [];\n return branchEntries\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.details);\n const summary = checkpointSummaryFromEntry(markerEntry);\n if (!details || !summary) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const markerMessageIndex = messages.findLastIndex(\n (message) =>\n message.role === 'custom' &&\n message.customType === CONTEXT_MESSAGE_TYPE &&\n contextDetailsFromUnknown(message.details)?.doomAutocompact.requestId === details.doomAutocompact.requestId,\n );\n if (markerMessageIndex === -1) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const summaryMessage: AutocompactMessage = {\n role: 'compactionSummary',\n summary,\n tokensBefore: details.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\n retainedMessageCount: details.retainedMessages.length,\n };\n}\n\nexport function fileOperationsFromMessages(messages: AutocompactMessage[]): FileOperations {\n const fileOps: FileOperations = { read: new Set(), written: new Set(), edited: new Set() };\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const block of message.content) {\n if (block.type !== 'toolCall') continue;\n const path = typeof block.arguments.path === 'string' ? block.arguments.path : undefined;\n if (!path) continue;\n if (block.name === 'read') fileOps.read.add(path);\n else if (block.name === 'write') fileOps.written.add(path);\n else if (block.name === 'edit') fileOps.edited.add(path);\n }\n }\n return fileOps;\n}\n\nexport function parseState(value: unknown): AutocompactState | undefined {\n if (!isRecord(value)) return undefined;\n if (value.version !== STATE_VERSION || typeof value.cycle !== 'number' || !isPass(value.pass)) return undefined;\n if (\n value.phase !== 'waiting' &&\n value.phase !== 'checkpoint_pending' &&\n value.phase !== 'checkpoint_ready' &&\n value.phase !== 'compacting'\n )\n return undefined;\n const baselineTokens = value.baselineTokens ?? 0;\n if (typeof baselineTokens !== 'number' || baselineTokens < 0) return undefined;\n const baselinePending = value.baselinePending ?? false;\n if (typeof baselinePending !== 'boolean') return undefined;\n const checkpointQueue = value.checkpointQueue ?? [];\n if (\n !Array.isArray(checkpointQueue) ||\n !checkpointQueue.every(isPass) ||\n checkpointQueue.some((pass, index) => index > 0 && pass <= checkpointQueue[index - 1]!)\n )\n return undefined;\n // Sessions persisted before bounded retry landed simply have no attempt history to restore.\n const exhaustedPasses = value.exhaustedPasses ?? [];\n if (!Array.isArray(exhaustedPasses) || !exhaustedPasses.every(isPass)) return undefined;\n const invalidAttempts = value.invalidAttempts ?? 0;\n if (typeof invalidAttempts !== 'number' || invalidAttempts < 0) return undefined;\n if (!isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (value.requestId !== undefined && typeof value.requestId !== 'string') return undefined;\n if (value.compactionPass !== undefined && value.compactionPass !== 2 && value.compactionPass !== 3) return undefined;\n if ('latestCheckpointEntryId' in value) return undefined;\n if (value.latestCheckpointSnapshotLeafId !== undefined && typeof value.latestCheckpointSnapshotLeafId !== 'string')\n return undefined;\n if (value.lastAttemptLeafId !== undefined && typeof value.lastAttemptLeafId !== 'string') return undefined;\n if (value.snapshotLeafId !== undefined && typeof value.snapshotLeafId !== 'string') return undefined;\n if (value.snapshotTokens !== undefined && (typeof value.snapshotTokens !== 'number' || value.snapshotTokens < 0))\n return undefined;\n if (value.pendingCheckpoint !== undefined && typeof value.pendingCheckpoint !== 'string') return undefined;\n\n return {\n version: STATE_VERSION,\n cycle: value.cycle,\n pass: value.pass,\n phase: value.phase,\n checkpointQueue: [...checkpointQueue],\n exhaustedPasses: [...exhaustedPasses],\n invalidAttempts,\n baselineTokens,\n baselinePending,\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n ...(value.requestId ? { requestId: value.requestId } : {}),\n ...(value.compactionPass ? { compactionPass: value.compactionPass } : {}),\n ...(value.latestCheckpointSnapshotLeafId\n ? { latestCheckpointSnapshotLeafId: value.latestCheckpointSnapshotLeafId }\n : {}),\n ...(value.lastAttemptLeafId ? { lastAttemptLeafId: value.lastAttemptLeafId } : {}),\n ...(value.snapshotLeafId ? { snapshotLeafId: value.snapshotLeafId } : {}),\n ...(value.snapshotTokens !== undefined ? { snapshotTokens: value.snapshotTokens } : {}),\n ...(value.pendingCheckpoint ? { pendingCheckpoint: value.pendingCheckpoint } : {}),\n };\n}\n\nexport function checkpointSummaryFromEntry(entry: SessionEntry | undefined): string | undefined {\n if (!entry) return undefined;\n if (entry.type === 'compaction') return entry.summary.trim() || undefined;\n if (entry.type === 'custom') {\n return isRecord(entry.data) && typeof entry.data.summary === 'string'\n ? entry.data.summary.trim() || undefined\n : undefined;\n }\n if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n');\n return content.trim() || undefined;\n }\n return assistantText(entry);\n}\n\nexport function parseCheckpointDecision(response: string): CheckpointDecision {\n const match = response.match(SHOULD_COMPACT_PATTERN);\n const summary = response.replace(SHOULD_COMPACT_PATTERN, '').trim();\n if (!match) return { summary };\n return { summary, shouldCompact: match[1]?.toLowerCase() === 'true' };\n}\n\nexport function isStructuredCheckpoint(summary: string): boolean {\n return CHECKPOINT_HEADINGS.every((heading) => summary.includes(heading));\n}\n\nexport function createRequestId(\n sessionId: string,\n cycle: number,\n pass: AutocompactPass,\n leafId: string | null,\n): string {\n return `${sessionId}:${cycle}:${pass}:${leafId ?? 'root'}`;\n}\n\nexport function checkpointRequestDetails(\n cycle: number,\n pass: AutocompactPass,\n requestId: string,\n): CheckpointRequestDetails {\n return { version: STATE_VERSION, cycle, pass, requestId };\n}\n\nexport function mergeFileDetails(\n current: AutocompactFileDetails,\n fileOps?: FileOperations,\n additional?: AutocompactFileDetails,\n): AutocompactFileDetails {\n const modified = new Set([\n ...current.modifiedFiles,\n ...(additional?.modifiedFiles ?? []),\n ...(fileOps ? [...fileOps.edited, ...fileOps.written] : []),\n ]);\n const read = new Set([...current.readFiles, ...(additional?.readFiles ?? []), ...(fileOps ? [...fileOps.read] : [])]);\n for (const path of modified) read.delete(path);\n return { readFiles: [...read].sort(), modifiedFiles: [...modified].sort() };\n}\n\nexport function fileDetailsFromUnknown(value: unknown): AutocompactFileDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n return { readFiles: value.readFiles, modifiedFiles: value.modifiedFiles };\n}\n\nexport function withCanonicalFileSections(summary: string, details: AutocompactFileDetails): string {\n const sections: string[] = [];\n if (details.readFiles.length > 0) sections.push(`<read-files>\\n${details.readFiles.join('\\n')}\\n</read-files>`);\n if (details.modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${details.modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n const normalized = summary.replace(FILE_SECTION_PATTERN, '').trim();\n return sections.length > 0 ? `${normalized}\\n\\n${sections.join('\\n\\n')}` : normalized;\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { AutocompactPass } from "../../types/index.cjs";
2
+ import "@earendil-works/pi-coding-agent";
3
+ //#region src/adapters/compaction/policy.d.ts
4
+ declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
5
+ //#endregion
6
+ export { thresholdTokens };
7
+ //# sourceMappingURL=policy.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.cts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":";;;iBAkGgB,gBAAgB,MAAM,iBAAiB,uBAAuB"}
@@ -0,0 +1,7 @@
1
+ import { AutocompactPass } from "../../types/index.mjs";
2
+ import "@earendil-works/pi-coding-agent";
3
+ //#region src/adapters/compaction/policy.d.ts
4
+ declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number): number;
5
+ //#endregion
6
+ export { thresholdTokens };
7
+ //# sourceMappingURL=policy.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.mts","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"mappings":";;;iBAkGgB,gBAAgB,MAAM,iBAAiB,uBAAuB"}
@@ -1,8 +1,8 @@
1
- import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"./constants.mjs";import{DEFAULT_COMPACTION_SETTINGS as n,sessionEntryToContextMessages as r}from"@earendil-works/pi-coding-agent";const i=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,a=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function o(e){return typeof e==`object`&&!!e}function s(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function c(e){return e===1||e===2||e===3}function l(e){if(!(e.type!==`message`||e.message.role!==`assistant`))return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
- `).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))&&!(e.requestId!==void 0&&typeof e.requestId!=`string`)&&!(e.compactionPass!==void 0&&e.compactionPass!==2&&e.compactionPass!==3)&&!(`latestCheckpointEntryId`in e)&&!(e.latestCheckpointSnapshotLeafId!==void 0&&typeof e.latestCheckpointSnapshotLeafId!=`string`)&&!(e.lastAttemptLeafId!==void 0&&typeof e.lastAttemptLeafId!=`string`)&&!(e.snapshotLeafId!==void 0&&typeof e.snapshotLeafId!=`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&!(e.pendingCheckpoint!==void 0&&typeof e.pendingCheckpoint!=`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...i],invalidAttempts:a,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function b(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?o(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
1
+ import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"../../types/constants.mjs";import{DEFAULT_COMPACTION_SETTINGS as n,sessionEntryToContextMessages as r}from"@earendil-works/pi-coding-agent";const i=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,a=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function o(e){return typeof e==`object`&&!!e}function s(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function c(e){return e===1||e===2||e===3}function l(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
+ `).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...i],invalidAttempts:a,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function b(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?o(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
3
3
  `)).trim()||void 0:l(e)}function x(e){let t=e.match(i),n=e.replace(i,``).trim();return t?{summary:n,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:n}}function S(t){return e.every(e=>t.includes(e))}function C(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function w(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function T(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function E(e){if(!(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function D(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
4
4
  `)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
5
5
  `)}\n</modified-files>`);let r=e.replace(a,``).trim();return n.length>0?`${r}\n\n${n.join(`
6
6
 
7
- `)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
7
+ `)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,d as contextDetailsFromUnknown,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
8
8
  //# sourceMappingURL=policy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.mjs","names":[],"sources":["../../../../src/adapters/compaction/policy.ts"],"sourcesContent":["import {\n DEFAULT_COMPACTION_SETTINGS,\n type FileOperations,\n type SessionEntry,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\nimport {\n CHECKPOINT_HEADINGS,\n CHECKPOINT_MESSAGE_TYPE,\n COMPACTION_THRESHOLDS,\n CONTEXT_MESSAGE_TYPE,\n STATE_VERSION,\n} from '../../types/constants.ts';\nimport type {\n AutocompactContextDetails,\n AutocompactFileDetails,\n AutocompactMessage,\n AutocompactPass,\n AutocompactState,\n CheckpointDecision,\n CheckpointRequestDetails,\n ContextProjection,\n} from '../../types/index.ts';\n\nconst SHOULD_COMPACT_PATTERN = /<shouldCompact>\\s*(true|false)\\s*<\\/shouldCompact>/i;\nconst FILE_SECTION_PATTERN = /\\n*<(?:read-files|modified-files)>[\\s\\S]*?<\\/(?:read-files|modified-files)>/g;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction isPass(value: unknown): value is AutocompactPass {\n return value === 1 || value === 2 || value === 3;\n}\n\nfunction assistantText(entry: SessionEntry): string | undefined {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return undefined;\n const text = entry.message.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n')\n .trim();\n return text || undefined;\n}\n\nfunction isAutocompactMessage(value: unknown): value is AutocompactMessage {\n return isRecord(value) && typeof value.role === 'string';\n}\n\nexport function contextDetailsFromUnknown(value: unknown): AutocompactContextDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (!Array.isArray(value.retainedMessages) || !value.retainedMessages.every(isAutocompactMessage)) return undefined;\n if (!isRecord(value.doomAutocompact)) return undefined;\n const marker = value.doomAutocompact;\n if (\n marker.version !== STATE_VERSION ||\n (marker.pass !== 2 && marker.pass !== 3) ||\n typeof marker.cycle !== 'number' ||\n typeof marker.requestId !== 'string' ||\n typeof marker.snapshotLeafId !== 'string' ||\n typeof marker.tokensBefore !== 'number'\n )\n return undefined;\n return {\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n retainedMessages: [...value.retainedMessages],\n doomAutocompact: {\n version: STATE_VERSION,\n cycle: marker.cycle,\n pass: marker.pass,\n requestId: marker.requestId,\n snapshotLeafId: marker.snapshotLeafId,\n tokensBefore: marker.tokensBefore,\n },\n };\n}\n\nexport function createInitialState(): AutocompactState {\n return {\n version: STATE_VERSION,\n cycle: 1,\n pass: 1,\n phase: 'waiting',\n checkpointQueue: [],\n exhaustedPasses: [],\n invalidAttempts: 0,\n baselineTokens: 0,\n baselinePending: false,\n readFiles: [],\n modifiedFiles: [],\n };\n}\n\nexport function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens = 0): number {\n const threshold = COMPACTION_THRESHOLDS[pass];\n const baseline = Math.max(0, Math.min(baselineTokens, contextWindow));\n const remaining = contextWindow - baseline;\n const staged = baseline + Math.min(Math.floor(remaining * threshold.ratio), threshold.capTokens);\n // Pi compacts natively above `contextWindow - reserveTokens`. A staged threshold above that\n // point can never fire, so the ladder would silently degrade into native compaction: on a\n // 200k window the raw pass 3 ratio lands at 190_000, while Pi already compacted at 183_616.\n const nativeTrigger = contextWindow - DEFAULT_COMPACTION_SETTINGS.reserveTokens;\n return nativeTrigger > baseline ? Math.min(staged, nativeTrigger) : staged;\n}\n\nexport function latestCheckpointArtifactEntry(branchEntries: SessionEntry[]): SessionEntry | undefined {\n return branchEntries.findLast(\n (entry) =>\n entry.type === 'compaction' ||\n // Staged checkpoints are plain entries so they stay out of the agent's LLM context.\n (entry.type === 'custom' && entry.customType === CHECKPOINT_MESSAGE_TYPE) ||\n // Legacy sessions staged checkpoints as custom messages; committed markers still are.\n (entry.type === 'custom_message' &&\n (entry.customType === CHECKPOINT_MESSAGE_TYPE || entry.customType === CONTEXT_MESSAGE_TYPE)),\n );\n}\n\nexport function baselineUsageIsSettled(branchEntries: SessionEntry[]): boolean {\n const boundaryIndex = branchEntries.findLastIndex(\n (entry) =>\n entry.type === 'compaction' || (entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE),\n );\n return branchEntries.slice(boundaryIndex + 1).some((entry) => {\n if (entry.type !== 'message' || entry.message.role !== 'assistant') return false;\n const { stopReason, usage } = entry.message;\n if (stopReason === 'aborted' || stopReason === 'error' || !usage) return false;\n return (usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;\n });\n}\n\nexport function retainedMessagesAfterSnapshot(\n branchEntries: SessionEntry[],\n snapshotLeafId: string,\n): AutocompactMessage[] {\n const snapshotIndex = branchEntries.findIndex((entry) => entry.id === snapshotLeafId);\n if (snapshotIndex === -1) return [];\n return branchEntries\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\nexport function projectContextMessages(\n messages: AutocompactMessage[],\n branchEntries: SessionEntry[],\n): ContextProjection {\n const nativeCompactionIndex = branchEntries.findLastIndex((entry) => entry.type === 'compaction');\n const markerEntry = branchEntries\n .slice(nativeCompactionIndex + 1)\n .findLast((entry) => entry.type === 'custom_message' && entry.customType === CONTEXT_MESSAGE_TYPE);\n if (!markerEntry || markerEntry.type !== 'custom_message') {\n return { messages, retainedMessageCount: 0 };\n }\n\n const details = contextDetailsFromUnknown(markerEntry.details);\n const summary = checkpointSummaryFromEntry(markerEntry);\n if (!details || !summary) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const markerMessageIndex = messages.findLastIndex(\n (message) =>\n message.role === 'custom' &&\n message.customType === CONTEXT_MESSAGE_TYPE &&\n contextDetailsFromUnknown(message.details)?.doomAutocompact.requestId === details.doomAutocompact.requestId,\n );\n if (markerMessageIndex === -1) return { messages, invalidMarker: true, retainedMessageCount: 0 };\n\n const summaryMessage: AutocompactMessage = {\n role: 'compactionSummary',\n summary,\n tokensBefore: details.doomAutocompact.tokensBefore,\n timestamp: messages[markerMessageIndex]?.timestamp ?? Date.now(),\n };\n return {\n messages: [summaryMessage, ...details.retainedMessages, ...messages.slice(markerMessageIndex + 1)],\n marker: details.doomAutocompact,\n retainedMessageCount: details.retainedMessages.length,\n };\n}\n\nexport function fileOperationsFromMessages(messages: AutocompactMessage[]): FileOperations {\n const fileOps: FileOperations = { read: new Set(), written: new Set(), edited: new Set() };\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const block of message.content) {\n if (block.type !== 'toolCall') continue;\n const path = typeof block.arguments.path === 'string' ? block.arguments.path : undefined;\n if (!path) continue;\n if (block.name === 'read') fileOps.read.add(path);\n else if (block.name === 'write') fileOps.written.add(path);\n else if (block.name === 'edit') fileOps.edited.add(path);\n }\n }\n return fileOps;\n}\n\nexport function parseState(value: unknown): AutocompactState | undefined {\n if (!isRecord(value)) return undefined;\n if (value.version !== STATE_VERSION || typeof value.cycle !== 'number' || !isPass(value.pass)) return undefined;\n if (\n value.phase !== 'waiting' &&\n value.phase !== 'checkpoint_pending' &&\n value.phase !== 'checkpoint_ready' &&\n value.phase !== 'compacting'\n )\n return undefined;\n const baselineTokens = value.baselineTokens ?? 0;\n if (typeof baselineTokens !== 'number' || baselineTokens < 0) return undefined;\n const baselinePending = value.baselinePending ?? false;\n if (typeof baselinePending !== 'boolean') return undefined;\n const checkpointQueue = value.checkpointQueue ?? [];\n if (\n !Array.isArray(checkpointQueue) ||\n !checkpointQueue.every(isPass) ||\n checkpointQueue.some((pass, index) => index > 0 && pass <= checkpointQueue[index - 1]!)\n )\n return undefined;\n // Sessions persisted before bounded retry landed simply have no attempt history to restore.\n const exhaustedPasses = value.exhaustedPasses ?? [];\n if (!Array.isArray(exhaustedPasses) || !exhaustedPasses.every(isPass)) return undefined;\n const invalidAttempts = value.invalidAttempts ?? 0;\n if (typeof invalidAttempts !== 'number' || invalidAttempts < 0) return undefined;\n if (!isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n if (value.requestId !== undefined && typeof value.requestId !== 'string') return undefined;\n if (value.compactionPass !== undefined && value.compactionPass !== 2 && value.compactionPass !== 3) return undefined;\n if ('latestCheckpointEntryId' in value) return undefined;\n if (value.latestCheckpointSnapshotLeafId !== undefined && typeof value.latestCheckpointSnapshotLeafId !== 'string')\n return undefined;\n if (value.lastAttemptLeafId !== undefined && typeof value.lastAttemptLeafId !== 'string') return undefined;\n if (value.snapshotLeafId !== undefined && typeof value.snapshotLeafId !== 'string') return undefined;\n if (value.snapshotTokens !== undefined && (typeof value.snapshotTokens !== 'number' || value.snapshotTokens < 0))\n return undefined;\n if (value.pendingCheckpoint !== undefined && typeof value.pendingCheckpoint !== 'string') return undefined;\n\n return {\n version: STATE_VERSION,\n cycle: value.cycle,\n pass: value.pass,\n phase: value.phase,\n checkpointQueue: [...checkpointQueue],\n exhaustedPasses: [...exhaustedPasses],\n invalidAttempts,\n baselineTokens,\n baselinePending,\n readFiles: [...value.readFiles],\n modifiedFiles: [...value.modifiedFiles],\n ...(value.requestId ? { requestId: value.requestId } : {}),\n ...(value.compactionPass ? { compactionPass: value.compactionPass } : {}),\n ...(value.latestCheckpointSnapshotLeafId\n ? { latestCheckpointSnapshotLeafId: value.latestCheckpointSnapshotLeafId }\n : {}),\n ...(value.lastAttemptLeafId ? { lastAttemptLeafId: value.lastAttemptLeafId } : {}),\n ...(value.snapshotLeafId ? { snapshotLeafId: value.snapshotLeafId } : {}),\n ...(value.snapshotTokens !== undefined ? { snapshotTokens: value.snapshotTokens } : {}),\n ...(value.pendingCheckpoint ? { pendingCheckpoint: value.pendingCheckpoint } : {}),\n };\n}\n\nexport function checkpointSummaryFromEntry(entry: SessionEntry | undefined): string | undefined {\n if (!entry) return undefined;\n if (entry.type === 'compaction') return entry.summary.trim() || undefined;\n if (entry.type === 'custom') {\n return isRecord(entry.data) && typeof entry.data.summary === 'string'\n ? entry.data.summary.trim() || undefined\n : undefined;\n }\n if (entry.type === 'custom_message') {\n const content =\n typeof entry.content === 'string'\n ? entry.content\n : entry.content\n .filter((block) => block.type === 'text')\n .map((block) => block.text)\n .join('\\n');\n return content.trim() || undefined;\n }\n return assistantText(entry);\n}\n\nexport function parseCheckpointDecision(response: string): CheckpointDecision {\n const match = response.match(SHOULD_COMPACT_PATTERN);\n const summary = response.replace(SHOULD_COMPACT_PATTERN, '').trim();\n if (!match) return { summary };\n return { summary, shouldCompact: match[1]?.toLowerCase() === 'true' };\n}\n\nexport function isStructuredCheckpoint(summary: string): boolean {\n return CHECKPOINT_HEADINGS.every((heading) => summary.includes(heading));\n}\n\nexport function createRequestId(\n sessionId: string,\n cycle: number,\n pass: AutocompactPass,\n leafId: string | null,\n): string {\n return `${sessionId}:${cycle}:${pass}:${leafId ?? 'root'}`;\n}\n\nexport function checkpointRequestDetails(\n cycle: number,\n pass: AutocompactPass,\n requestId: string,\n): CheckpointRequestDetails {\n return { version: STATE_VERSION, cycle, pass, requestId };\n}\n\nexport function mergeFileDetails(\n current: AutocompactFileDetails,\n fileOps?: FileOperations,\n additional?: AutocompactFileDetails,\n): AutocompactFileDetails {\n const modified = new Set([\n ...current.modifiedFiles,\n ...(additional?.modifiedFiles ?? []),\n ...(fileOps ? [...fileOps.edited, ...fileOps.written] : []),\n ]);\n const read = new Set([...current.readFiles, ...(additional?.readFiles ?? []), ...(fileOps ? [...fileOps.read] : [])]);\n for (const path of modified) read.delete(path);\n return { readFiles: [...read].sort(), modifiedFiles: [...modified].sort() };\n}\n\nexport function fileDetailsFromUnknown(value: unknown): AutocompactFileDetails | undefined {\n if (!isRecord(value) || !isStringArray(value.readFiles) || !isStringArray(value.modifiedFiles)) return undefined;\n return { readFiles: value.readFiles, modifiedFiles: value.modifiedFiles };\n}\n\nexport function withCanonicalFileSections(summary: string, details: AutocompactFileDetails): string {\n const sections: string[] = [];\n if (details.readFiles.length > 0) sections.push(`<read-files>\\n${details.readFiles.join('\\n')}\\n</read-files>`);\n if (details.modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${details.modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n const normalized = summary.replace(FILE_SECTION_PATTERN, '').trim();\n return sections.length > 0 ? `${normalized}\\n\\n${sections.join('\\n\\n')}` : normalized;\n}\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ const e=require("../../types/constants.cjs"),t=require("../compaction/policy.cjs"),n=require("../../services/summarizationModel.cjs"),r=require("../telemetry/logSinkTelemetry.cjs");let i=require("node:fs"),a=require("node:path"),o=require("node:url"),s=require("node:worker_threads"),c=require("@agimon-ai/doompi-config"),l=require("@agimon-ai/doompi-extension-contracts/cordis-host"),u=require("@agimon-ai/doompi-extension-contracts/context-contributions"),d=require("@agimon-ai/doompi-extension-contracts/ui-hub"),f=require("@earendil-works/pi-coding-agent");const p=`@root`,m=`@earendil-works/pi-coding-agent`,h=`package.json`,g=`doom-autocompact`,_={waiting:`waiting`,checkpointPending:`checkpoint_pending`,checkpointReady:`checkpoint_ready`,compacting:`compacting`};function v(e,t={}){return{"pi.session.id":e.sessionManager.getSessionId(),...t}}function y(e){for(let n=e.length-1;n>=0;--n){let r=e[n];if(r?.type!==`custom`||r.customType!==`doom-autocompact-state`)continue;let i=t.parseState(r.data);if(i)return i}}function b(e){for(let t of e.sessionManager.getBranch().toReversed())if((t.type!==`custom`||t.customType!==`doom-autocompact-state`)&&t.type!==`label`)return t.id;return p}function x(e){return e instanceof Error?e.message:String(e)}function S(e){for(let t of e.toReversed()){if(t.type!==`custom`||t.customType!==`agent-harness-plan-document`)continue;if(!t.data||typeof t.data!=`object`)return;let e=t.data;return typeof e.content!=`string`||typeof e.path!=`string`?void 0:{content:e.content,path:e.path}}}const C=Object.freeze({entries:Object.freeze([]),errors:Object.freeze([])});function w(e){if(!e)return C;try{return e.snapshot()}catch(e){return{entries:[],errors:[{source:u.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,id:`service-snapshot`,label:`Context contributions`,order:0,message:x(e)}]}}}function T(e){let t=e.entries.map(e=>`### ${e.label}\n${e.text}`);return t.push(...e.errors.map(e=>`### ${e.label}\n(unavailable: ${e.message})`)),t.length>0?t.join(`
2
+
3
+ `):`(no registered context contributions)`}function E(e,t){let n=S(e);return{...n?{planPath:n.path}:{},contributions:t.entries,contributionErrors:t.errors}}function D(e){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
+ ${e.planPath?`Source: ${e.planPath}\nExact plan content is restored separately by Doom Plan.`:`(no active plan document)`}
7
+ </active-plan>
8
+ <context-contributions>
9
+ ${T({entries:e.contributions,errors:e.contributionErrors})}
10
+ </context-contributions>
11
+ </compaction-runtime-state>`}function O(e){return{"autocompact.runtime.plan_present":!!e.planPath,"autocompact.runtime.contribution_count":e.contributions.length,"autocompact.runtime.contribution_error_count":e.contributionErrors.length}}function k(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,context-contributions,important-context,recent-messages">
12
+ <user-prompt source="conversation">
13
+ Treat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.
14
+ </user-prompt>
15
+ <active-plan>
16
+ ${t}
17
+ </active-plan>
18
+ <context-contributions>
19
+ ${T(e.contextContributions)}
20
+ </context-contributions>
21
+ <important-context>
22
+ ${n.length>0?n.join(`
23
+ `):`(none recorded outside the conversation)`}
24
+ </important-context>
25
+ </compaction-steering>`}function A(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.
26
+
27
+ `:``;return`Create Doom autocompact checkpoint pass ${e}.
28
+
29
+ ${k(t)}
30
+
31
+ Apply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.
32
+
33
+ ${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.
34
+
35
+ ## Goal
36
+ ## Constraints & Preferences
37
+ ## Progress
38
+ ### Done
39
+ ### In Progress
40
+ ### Blocked
41
+ ## Key Decisions
42
+ ## Next Steps
43
+ ## Critical Context`}function ee(e,n,r){let i=t.projectContextMessages((0,f.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,f.sessionEntryToContextMessages)(e))}function j(e){let t=(0,o.fileURLToPath)(e),n=(0,a.dirname)(t);for(;;){let e=(0,a.join)(n,`checkpointWorker.mjs`);if((0,i.existsSync)(e))return(0,o.pathToFileURL)(e);let t=(0,a.dirname)(n);if(t===n)break;n=t}throw Error(`Cannot find checkpointWorker.mjs by walking from ${t}.`)}function M(e=[...process.argv[1]?[process.argv[1]]:[],(0,o.fileURLToPath)(require("url").pathToFileURL(__filename).href),(0,a.join)(process.cwd(),h)]){for(let t of e){let e=(0,i.existsSync)(t)?(0,i.realpathSync)(t):(0,a.resolve)(t),n=(0,a.dirname)(e);for(;;){let e=(0,a.join)(n,`node_modules`,m),t=(0,a.join)(e,h);if((0,i.existsSync)(t)){let n=JSON.parse((0,i.readFileSync)(t,`utf8`));if(typeof n.main==`string`){let t=(0,a.resolve)(e,n.main);if((0,i.existsSync)(t))return(0,o.pathToFileURL)(t).href}}let r=(0,a.dirname)(n);if(r===n)break;n=r}}throw Error(`Cannot resolve ${m} from the DoomPi or host module trees.`)}function N(e,t){return new Promise((n,r)=>{let i=new s.Worker(j(require("url").pathToFileURL(__filename).href),{workerData:{...e,piModuleUrl:M()}}),a=!1,o=e=>{a||(a=!0,t.removeEventListener(`abort`,c),e())},c=()=>{o(()=>{i.terminate(),r(t.reason instanceof Error?t.reason:Error(`Autocompact summarization aborted.`))})};i.once(`message`,e=>{o(()=>{typeof e.checkpoint==`string`?n(e.checkpoint):r(Error(e.error??`Autocompact summarization worker returned no checkpoint.`))})}),i.once(`error`,e=>o(()=>r(e))),i.once(`exit`,e=>{e!==0&&o(()=>r(Error(`Autocompact summarization worker exited with code ${e}.`)))}),t.addEventListener(`abort`,c,{once:!0}),i.unref(),t.aborted&&c()})}function P(e){try{return(0,c.loadDoomConfig)((0,c.getHarnessState)().root??e).modes?.planning?.subagents}catch{process.emitWarning(`Doom autocompact planning configuration could not be loaded; using the active session model instead.`);return}}function F(e){let t=P(e.cwd),r=t?.model?n.parseModelReference(t.model):void 0,i=r?e.modelRegistry.find(r.provider,r.modelId):void 0,a=i??e.model;if(!a)return;let o=t?.thinking??(i?r?.thinking:void 0)??e.thinkingLevel;return{model:a,...o?{thinkingLevel:o}:{}}}async function I(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 N({messages:e.messages,model:n.model,reserveTokens:f.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 L(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function R(n,i,a={}){let o=a.resolveModel??F,s=a.generateCheckpoint??(e=>I(e,o)),c=a.telemetry??r.createAutocompactTelemetry(),l=a.doomIntegrations??!0,m=new Set,h=new Set,x=new Set,C=!0,T=0,k=t.createInitialState(),j,M,N,P;n.effect(()=>async()=>{C=!1,T+=1,M?.abort(Error(`Autocompact runtime is shutting down.`)),M=void 0,await Promise.allSettled(x),N=void 0,P=void 0,j=void 0,m.clear(),h.clear(),k=t.createInitialState(),await c.shutdown()},`${g}/runtime`),n.inject([u.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE],e=>{let t=(0,u.requireDoomContextContributions)(e);return P=t,()=>{P===t&&(P=void 0)}}),l&&n.inject([d.DOOM_UI_HUB_SERVICE],e=>{let t=(0,d.requireDoomUiHub)(e).registerFooter({source:g,id:`autocompact`,order:20});return N=t,()=>{t.dispose(),N===t&&(N=void 0)}});let R=e=>{if(!C)return;let t=k.phase===_.checkpointPending?`summarizing`:k.phase===_.checkpointReady?`applying`:void 0;N?.update(t?{fullText:`Compacting p${k.pass}`,compactText:`C${k.pass}`}:void 0);let n=e??j;n?.hasUI&&n.ui.setStatus(`doom-autocompact`,t?`Compacting pass ${k.pass} (${t})…`:void 0)},z=()=>{C&&(i.appendEntry(e.STATE_CUSTOM_TYPE,{...k}),R())},B=()=>{delete k.requestId,delete k.snapshotLeafId,delete k.snapshotTokens,delete k.pendingCheckpoint,delete k.compactionPass},V=e=>{k.checkpointQueue=k.checkpointQueue.filter(t=>t!==e)},H=e=>{C&&(k=y(e.sessionManager.getBranch())??t.createInitialState(),!(k.phase===_.checkpointReady&&k.requestId&&k.snapshotLeafId&&k.pendingCheckpoint||k.phase===_.waiting)&&(M?.abort(),M=void 0,k.phase=_.waiting,B(),z()))},U=t=>{C&&i.sendMessage({customType:e.RESUME_MESSAGE_TYPE,content:`${t} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:k.cycle,pass:k.pass}},{triggerTurn:!0,deliverAs:`steer`})},W=(e,t)=>{if(!C||e!==k.requestId||k.phase!==_.checkpointPending)return;let n=k.snapshotLeafId;k.phase=_.waiting,n&&(k.lastAttemptLeafId=n),B(),z(),L(j,`Doom autocompact summarization pass ${k.pass} failed: ${t instanceof Error?t.message:String(t)}`,`error`)},G=(e,t,n)=>{if(C)for(let i of t.errors)L(e,`Doom autocompact context contribution degraded (${i.source}/${i.id}): ${i.message}`,`warning`),c.recordWarning(r.AUTOCOMPACT_EVENT.contextContributionDegraded,Error(i.message),{...n,"autocompact.context_contribution.source":i.source,"autocompact.context_contribution.id":i.id,"autocompact.context_contribution.order":i.order})},K=(t,n,r)=>{if(!C)return{contributions:[],contributionErrors:[]};let a=w(P);G(t,a,r);let o=E(n,a);return i.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:D(o),display:!1,details:{version:2,...o}}),o},q=(n,a)=>{if(!C||!k.requestId||!k.snapshotLeafId||!k.pendingCheckpoint)return!1;let o=a.sessionManager.getBranch(),s=t.projectContextMessages((0,f.buildSessionContext)(o).messages,o).messages,l=t.mergeFileDetails(k,t.fileOperationsFromMessages(s)),u=k.requestId,d=k.cycle,p=t.withCanonicalFileSections(k.pendingCheckpoint,l),m={...l,doomAutocompact:{version:2,cycle:d,pass:n,requestId:u,snapshotLeafId:k.snapshotLeafId,tokensBefore:k.snapshotTokens??a.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(o,k.snapshotLeafId)};L(a,`Doom autocompact pass ${n} context commit started.`);let h=a.isIdle();i.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:p,display:!1,details:m});let g=b(a),y=v(a,{"autocompact.request.id":u,"autocompact.cycle":d,"autocompact.pass":n}),x=K(a,o,y);return h&&i.setLabel(g,`autocompact:c${d}:p${n}`),k.readFiles=l.readFiles,k.modifiedFiles=l.modifiedFiles,delete k.latestCheckpointSnapshotLeafId,k.phase=_.waiting,k.checkpointQueue=[],k.exhaustedPasses=[],k.invalidAttempts=0,k.baselinePending=!0,delete k.lastAttemptLeafId,B(),k.cycle+=1,k.pass=1,z(),c.recordEvent(r.AUTOCOMPACT_EVENT.contextCommitted,v(a,{"autocompact.request.id":u,"autocompact.cycle":d,"autocompact.pass":n,"autocompact.snapshot_leaf_id":m.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":m.doomAutocompact.tokensBefore,"autocompact.message_count.before":s.length,"autocompact.message_count.retained":m.retainedMessages.length,"autocompact.apply_mode":h?`idle`:`turn_end`,...O(x)})),L(a,`Doom autocompact context committed. Baseline will be captured from the next settled context.`),h&&U(`Asynchronous compaction completed.`),!0},J=(e,n,i)=>{if(!C)return;let a=T,o=n.sessionManager.getBranch(),l=b(n),u=t.createRequestId(n.sessionManager.getSessionId(),k.cycle,e,l),d=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(o)):void 0,f=ee(e,o,k.latestCheckpointSnapshotLeafId),p=w(P),m=v(n,{"autocompact.request.id":u,"autocompact.cycle":k.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":l,"autocompact.tokens_before":i,"autocompact.message_count.before":f.length});G(n,p,m),k.phase=_.checkpointPending,k.pass=e,k.requestId=u,k.snapshotLeafId=l,k.snapshotTokens=i,delete k.pendingCheckpoint,delete k.compactionPass,delete k.lastAttemptLeafId,z(),M?.abort(),M=new AbortController;let h=M.signal;L(n,`Doom autocompact summarization pass ${e} started.`);let g=c.runInSpan(`doom_autocompact.checkpoint`,m,async()=>{await c.recordEvent(r.AUTOCOMPACT_EVENT.checkpointStarted,m);try{let t=await s({messages:f,instructions:A(e,{plan:S(o),contextContributions:p,readFiles:k.readFiles,modifiedFiles:k.modifiedFiles}),...d?{previousCheckpoint:d}:{},context:n,signal:h});if(!C||a!==T)throw h.reason??Error(`Autocompact checkpoint became stale.`);if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await c.recordEvent(r.AUTOCOMPACT_EVENT.checkpointCompleted,{...m,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw C&&a===T&&await c.recordError(r.AUTOCOMPACT_EVENT.checkpointFailed,e,m),e}}).then(t=>{!C||a!==T||u!==k.requestId||k.phase!==_.checkpointPending||(k.phase=_.checkpointReady,k.pendingCheckpoint=t.trim(),z(),L(j,`Doom autocompact summarization pass ${e} completed.`),j&&Q(j))}).catch(e=>{C&&a===T&&W(u,e)});x.add(g),g.finally(()=>x.delete(g))},Y=e=>{if(!C||k.phase!==_.waiting||e.hasPendingMessages())return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(k.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(k.baselineTokens=n.tokens,k.baselinePending=!1,z(),L(e,`Doom autocompact baseline captured at ${k.baselineTokens} tokens.`),!1):!1;let r=b(e);if(k.lastAttemptLeafId===r)return!1;for(let e of[1,2,3])e<k.pass||k.checkpointQueue.includes(e)||k.exhaustedPasses.includes(e)||n.tokens>=t.thresholdTokens(e,n.contextWindow,k.baselineTokens)&&k.checkpointQueue.push(e);let i=k.checkpointQueue[0];return i?(J(i,e,n.tokens),!0):!1},X=(n,r)=>{if(!C)return;let a=k.snapshotLeafId;i.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(k.cycle,n,k.requestId??`completed`),summary:r}),a&&(k.latestCheckpointSnapshotLeafId=a)},Z=e=>{if(!C||k.phase!==_.checkpointReady||!k.requestId||!k.pendingCheckpoint)return`none`;let n=k.pass,i=t.parseCheckpointDecision(k.pendingCheckpoint);if(!t.isStructuredCheckpoint(i.summary)){let t=k.snapshotLeafId,i=k.requestId,a=k.invalidAttempts+1,o=a>=3;k.phase=_.waiting,t&&(k.lastAttemptLeafId=t),o?(V(n),k.exhaustedPasses=[...k.exhaustedPasses,n],k.invalidAttempts=0):k.invalidAttempts=a,B(),z();let s=Error(`Summarization pass ${n} returned an incomplete checkpoint.`);return L(e,o?`Doom autocompact summarization pass ${n} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${n} returned an incomplete checkpoint.`,`error`),c.recordError(r.AUTOCOMPACT_EVENT.checkpointInvalid,s,v(e,{"autocompact.cycle":k.cycle,"autocompact.pass":n,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...i?{"autocompact.request.id":i}:{}})),`invalid`}return k.invalidAttempts=0,n===1?(X(1,i.summary),V(1),k.phase=_.waiting,k.pass=2,B(),z(),`pass1`):n===2&&i.shouldCompact!==!0?(X(2,i.summary),V(2),k.phase=_.waiting,k.pass=3,B(),z(),`deferred`):(k.pendingCheckpoint=i.summary,q(n,e)?`committed`:`invalid`)};function Q(e){C&&(j=e,e.isIdle()&&Z(e)!==`committed`&&Y(e))}i.on(`context`,(e,n)=>{if(!C)return;let i=t.projectContextMessages(e.messages,n.sessionManager.getBranch());if(i.invalidMarker){let e=n.sessionManager.getLeafId()??p;h.has(e)||(h.add(e),c.recordError(r.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),v(n,{"autocompact.leaf_id":e})));return}if(i.marker)return m.has(i.marker.requestId)||(m.add(i.marker.requestId),c.recordEvent(r.AUTOCOMPACT_EVENT.contextApplied,v(n,{"autocompact.request.id":i.marker.requestId,"autocompact.cycle":i.marker.cycle,"autocompact.pass":i.marker.pass,"autocompact.snapshot_leaf_id":i.marker.snapshotLeafId,"autocompact.tokens_before":i.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":i.messages.length,"autocompact.message_count.retained":i.retainedMessageCount}))),{messages:i.messages}});let $=e=>{C&&(T+=1,M?.abort(Error(`Autocompact session generation was replaced.`)),M=void 0,m.clear(),h.clear(),j=e,H(e),Q(e))};i.on(`session_start`,(e,t)=>$(t)),i.on(`session_tree`,(e,t)=>$(t)),i.on(`turn_end`,(e,t)=>{if(C){if(j=t,t.isIdle()){Q(t);return}k.phase===_.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&Z(t)!==`none`||Y(t)}}),i.on(`agent_settled`,(e,t)=>{C&&Q(t)}),i.on(`session_before_compact`,e=>{if(!(!C||e.reason!==`threshold`))return k.phase===_.checkpointPending||k.phase===_.checkpointReady||k.baselinePending?{cancel:!0}:void 0}),i.on(`session_compact`,(e,n)=>{if(!C)return;T+=1,M?.abort(),M=void 0;let a=t.fileDetailsFromUnknown(e.compactionEntry.details),o=t.mergeFileDetails(k,void 0,a);k.readFiles=o.readFiles,k.modifiedFiles=o.modifiedFiles,delete k.latestCheckpointSnapshotLeafId,k.baselinePending=!0,k.phase=_.waiting,B(),k.checkpointQueue=[],k.exhaustedPasses=[],k.invalidAttempts=0,delete k.lastAttemptLeafId,i.setLabel(e.compactionEntry.id,`autocompact:c${k.cycle}:external`);let s=k.cycle,l=v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason}),u=K(n,n.sessionManager.getBranch(),l);k.cycle+=1,k.pass=1,z(),c.recordEvent(r.AUTOCOMPACT_EVENT.nativeCompactionCompleted,v(n,{"autocompact.cycle":s,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...O(u)})),L(n,`Doom autocompact completed. Baseline will be captured from the next settled context. Next pass: ${k.pass}.`)})}async function z(e){let t=await(0,l.connectDoomCordisHost)(e,`@agimon-ai/doompi-autocompact`),n=t.root.plugin(B,{pi:e});try{await n}catch(e){try{await n.dispose()}finally{await t.dispose()}throw e}let r;e.on(`session_shutdown`,()=>r??=(async()=>{try{await n.dispose()}finally{await t.dispose()}})())}function B(e,t){R(e,t.pi)}exports.autocompactExtension=z,exports.default=z,exports.findCheckpointWorkerUrl=j,exports.findInstalledPiModuleUrl=M,exports.installAutocompactRuntime=R,exports.resolveDoomSummarizationModel=F;
44
+ //# sourceMappingURL=extension.cjs.map