@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.
- package/README.md +62 -18
- package/dist/checkpointWorker.cjs +1 -1
- package/dist/checkpointWorker.cjs.map +1 -1
- package/dist/checkpointWorker.d.cts +19 -1
- package/dist/checkpointWorker.d.cts.map +1 -0
- package/dist/checkpointWorker.d.mts +19 -1
- package/dist/checkpointWorker.d.mts.map +1 -0
- package/dist/checkpointWorker.mjs +1 -1
- package/dist/checkpointWorker.mjs.map +1 -1
- package/dist/extensions/pi.cjs +1 -2
- package/dist/extensions/pi.d.cts +2 -2
- package/dist/extensions/pi.d.mts +2 -2
- package/dist/extensions/pi.mjs +1 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/dist/{policy.cjs → src/adapters/compaction/policy.cjs} +3 -3
- package/dist/src/adapters/compaction/policy.cjs.map +1 -0
- package/dist/src/adapters/compaction/policy.d.cts +7 -0
- package/dist/src/adapters/compaction/policy.d.cts.map +1 -0
- package/dist/src/adapters/compaction/policy.d.mts +7 -0
- package/dist/src/adapters/compaction/policy.d.mts.map +1 -0
- package/dist/{policy.mjs → src/adapters/compaction/policy.mjs} +3 -3
- package/dist/src/adapters/compaction/policy.mjs.map +1 -0
- package/dist/src/adapters/pi/extension.cjs +44 -0
- package/dist/src/adapters/pi/extension.cjs.map +1 -0
- package/dist/src/adapters/pi/extension.d.cts +25 -0
- package/dist/src/adapters/pi/extension.d.cts.map +1 -0
- package/dist/src/adapters/pi/extension.d.mts +25 -0
- package/dist/src/adapters/pi/extension.d.mts.map +1 -0
- package/dist/src/adapters/pi/extension.mjs +44 -0
- package/dist/src/adapters/pi/extension.mjs.map +1 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.cjs +2 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.cjs.map +1 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts +26 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.cts.map +1 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts +26 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.d.mts.map +1 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.mjs +2 -0
- package/dist/src/adapters/telemetry/logSinkTelemetry.mjs.map +1 -0
- package/dist/src/services/summarizationModel.cjs +2 -0
- package/dist/src/services/summarizationModel.cjs.map +1 -0
- package/dist/{summarizationModel.d.cts → src/services/summarizationModel.d.cts} +1 -2
- package/dist/src/services/summarizationModel.d.cts.map +1 -0
- package/dist/{summarizationModel.d.mts → src/services/summarizationModel.d.mts} +1 -2
- package/dist/src/services/summarizationModel.d.mts.map +1 -0
- package/dist/src/services/summarizationModel.mjs +2 -0
- package/dist/src/services/summarizationModel.mjs.map +1 -0
- package/dist/src/types/constants.cjs.map +1 -0
- package/dist/src/types/constants.mjs.map +1 -0
- package/dist/src/types/index.d.cts +6 -0
- package/dist/src/types/index.d.cts.map +1 -0
- package/dist/src/types/index.d.mts +6 -0
- package/dist/src/types/index.d.mts.map +1 -0
- package/package.json +35 -15
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.mjs.map +0 -1
- package/dist/extension.cjs +0 -50
- package/dist/extension.cjs.map +0 -1
- package/dist/extension.d.cts +0 -36
- package/dist/extension.d.cts.map +0 -1
- package/dist/extension.d.mts +0 -36
- package/dist/extension.d.mts.map +0 -1
- package/dist/extension.mjs +0 -50
- package/dist/extension.mjs.map +0 -1
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/logSinkTelemetry.cjs +0 -2
- package/dist/logSinkTelemetry.cjs.map +0 -1
- package/dist/logSinkTelemetry.d.cts +0 -26
- package/dist/logSinkTelemetry.d.cts.map +0 -1
- package/dist/logSinkTelemetry.d.mts +0 -26
- package/dist/logSinkTelemetry.d.mts.map +0 -1
- package/dist/logSinkTelemetry.mjs +0 -2
- package/dist/logSinkTelemetry.mjs.map +0 -1
- package/dist/policy.cjs.map +0 -1
- package/dist/policy.d.cts +0 -6
- package/dist/policy.d.cts.map +0 -1
- package/dist/policy.d.mts +0 -6
- package/dist/policy.d.mts.map +0 -1
- package/dist/policy.mjs.map +0 -1
- package/dist/standard.cjs +0 -2
- package/dist/standard.cjs.map +0 -1
- package/dist/standard.d.cts +0 -8
- package/dist/standard.d.cts.map +0 -1
- package/dist/standard.d.mts +0 -8
- package/dist/standard.d.mts.map +0 -1
- package/dist/standard.mjs +0 -2
- package/dist/standard.mjs.map +0 -1
- package/dist/summarizationModel.cjs +0 -2
- package/dist/summarizationModel.cjs.map +0 -1
- package/dist/summarizationModel.d.cts.map +0 -1
- package/dist/summarizationModel.d.mts.map +0 -1
- package/dist/summarizationModel.mjs +0 -2
- package/dist/summarizationModel.mjs.map +0 -1
- package/dist/types.d.cts +0 -5
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts +0 -5
- package/dist/types.d.mts.map +0 -1
- /package/dist/{constants.cjs → src/types/constants.cjs} +0 -0
- /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
|
|
3
|
+
Staged checkpoint summarization and iterative context compaction for DoomPi.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
24
|
+
pi install npm:@agimon-ai/doompi-autocompact
|
|
18
25
|
```
|
|
19
26
|
|
|
20
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
47
|
+
## Coordination state
|
|
26
48
|
|
|
27
|
-
|
|
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
|
-
|
|
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(
|
|
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\
|
|
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
|
-
|
|
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
|
-
|
|
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";
|
|
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\
|
|
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"}
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=pi.cjs.map
|
|
1
|
+
const e=require("../src/adapters/pi/extension.cjs");module.exports=e.autocompactExtension;
|
package/dist/extensions/pi.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export =
|
|
1
|
+
import { autocompactExtension } from "../src/adapters/pi/extension.cjs";
|
|
2
|
+
export = autocompactExtension;
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { autocompactExtension } from "../src/adapters/pi/extension.mjs";
|
|
2
|
+
export { autocompactExtension as default };
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{
|
|
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(
|
|
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 {
|
|
2
|
-
import { AutocompactPass } from "./types.cjs";
|
|
3
|
-
import { thresholdTokens } from "./policy.cjs";
|
|
4
|
-
export { type AutocompactPass,
|
|
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 {
|
|
2
|
-
import { AutocompactPass } from "./types.mjs";
|
|
3
|
-
import { thresholdTokens } from "./policy.mjs";
|
|
4
|
-
export { type AutocompactPass,
|
|
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{
|
|
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(
|
|
2
|
-
`).trim()||void 0}function c(e){return i(e)&&typeof e.role==`string`}function l(e){if(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(c)||!i(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function u(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function d(n,r,i=0){let a=e.COMPACTION_THRESHOLDS[n],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-t.DEFAULT_COMPACTION_SETTINGS.reserveTokens;return l>o?Math.min(c,l):c}function f(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function p(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function m(e,n){let r=e.findIndex(e=>e.id===n);return r===-1?[]:e.slice(r+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,t.sessionEntryToContextMessages)(e))}function h(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=l(r.details),a=v(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&l(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function g(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function _(e){if(!i(e)||e.version!==2||typeof e.cycle!=`number`||!o(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(o)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let s=e.exhaustedPasses??[];if(!Array.isArray(s)||!s.every(o))return;let c=e.invalidAttempts??0;if(!(typeof c!=`number`||c<0)&&!(!a(e.readFiles)||!a(e.modifiedFiles))
|
|
1
|
+
const e=require("../../types/constants.cjs");let t=require("@earendil-works/pi-coding-agent");const n=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,r=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function i(e){return typeof e==`object`&&!!e}function a(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function o(e){return e===1||e===2||e===3}function s(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
+
`).trim()||void 0}function c(e){return i(e)&&typeof e.role==`string`}function l(e){if(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(c)||!i(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function u(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function d(n,r,i=0){let a=e.COMPACTION_THRESHOLDS[n],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-t.DEFAULT_COMPACTION_SETTINGS.reserveTokens;return l>o?Math.min(c,l):c}function f(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function p(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function m(e,n){let r=e.findIndex(e=>e.id===n);return r===-1?[]:e.slice(r+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,t.sessionEntryToContextMessages)(e))}function h(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=l(r.details),a=v(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&l(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function g(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function _(e){if(!i(e)||e.version!==2||typeof e.cycle!=`number`||!o(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(o)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let s=e.exhaustedPasses??[];if(!Array.isArray(s)||!s.every(o))return;let c=e.invalidAttempts??0;if(!(typeof c!=`number`||c<0)&&!(!a(e.readFiles)||!a(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...s],invalidAttempts:c,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function v(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?i(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
3
3
|
`)).trim()||void 0:s(e)}function y(e){let t=e.match(n),r=e.replace(n,``).trim();return t?{summary:r,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:r}}function b(t){return e.CHECKPOINT_HEADINGS.every(e=>t.includes(e))}function x(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function S(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function C(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function w(e){if(!(!i(e)||!a(e.readFiles)||!a(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function T(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
|
|
4
4
|
`)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
|
|
5
5
|
`)}\n</modified-files>`);let i=e.replace(r,``).trim();return n.length>0?`${i}\n\n${n.join(`
|
|
6
6
|
|
|
7
|
-
`)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
|
|
7
|
+
`)}`:i}exports.baselineUsageIsSettled=p,exports.checkpointRequestDetails=S,exports.checkpointSummaryFromEntry=v,exports.contextDetailsFromUnknown=l,exports.createInitialState=u,exports.createRequestId=x,exports.fileDetailsFromUnknown=w,exports.fileOperationsFromMessages=g,exports.isStructuredCheckpoint=b,exports.latestCheckpointArtifactEntry=f,exports.mergeFileDetails=C,exports.parseCheckpointDecision=y,exports.parseState=_,exports.projectContextMessages=h,exports.retainedMessagesAfterSnapshot=m,exports.thresholdTokens=d,exports.withCanonicalFileSections=T;
|
|
8
8
|
//# sourceMappingURL=policy.cjs.map
|
|
@@ -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"
|
|
2
|
-
`).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))
|
|
1
|
+
import{CHECKPOINT_HEADINGS as e,COMPACTION_THRESHOLDS as t}from"../../types/constants.mjs";import{DEFAULT_COMPACTION_SETTINGS as n,sessionEntryToContextMessages as r}from"@earendil-works/pi-coding-agent";const i=/<shouldCompact>\s*(true|false)\s*<\/shouldCompact>/i,a=/\n*<(?:read-files|modified-files)>[\s\S]*?<\/(?:read-files|modified-files)>/g;function o(e){return typeof e==`object`&&!!e}function s(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function c(e){return e===1||e===2||e===3}function l(e){if(e.type===`message`&&e.message.role===`assistant`)return e.message.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
|
+
`).trim()||void 0}function u(e){return o(e)&&typeof e.role==`string`}function d(e){if(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)||!Array.isArray(e.retainedMessages)||!e.retainedMessages.every(u)||!o(e.doomAutocompact))return;let t=e.doomAutocompact;if(!(t.version!==2||t.pass!==2&&t.pass!==3||typeof t.cycle!=`number`||typeof t.requestId!=`string`||typeof t.snapshotLeafId!=`string`||typeof t.tokensBefore!=`number`))return{readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],retainedMessages:[...e.retainedMessages],doomAutocompact:{version:2,cycle:t.cycle,pass:t.pass,requestId:t.requestId,snapshotLeafId:t.snapshotLeafId,tokensBefore:t.tokensBefore}}}function f(){return{version:2,cycle:1,pass:1,phase:`waiting`,checkpointQueue:[],exhaustedPasses:[],invalidAttempts:0,baselineTokens:0,baselinePending:!1,readFiles:[],modifiedFiles:[]}}function p(e,r,i=0){let a=t[e],o=Math.max(0,Math.min(i,r)),s=r-o,c=o+Math.min(Math.floor(s*a.ratio),a.capTokens),l=r-n.reserveTokens;return l>o?Math.min(c,l):c}function m(e){return e.findLast(e=>e.type===`compaction`||e.type===`custom`&&e.customType===`doom-autocompact-checkpoint`||e.type===`custom_message`&&(e.customType===`doom-autocompact-checkpoint`||e.customType===`doom-autocompact-context`))}function h(e){let t=e.findLastIndex(e=>e.type===`compaction`||e.type===`custom_message`&&e.customType===`doom-autocompact-context`);return e.slice(t+1).some(e=>{if(e.type!==`message`||e.message.role!==`assistant`)return!1;let{stopReason:t,usage:n}=e.message;return t===`aborted`||t===`error`||!n?!1:(n.totalTokens||n.input+n.output+n.cacheRead+n.cacheWrite)>0})}function g(e,t){let n=e.findIndex(e=>e.id===t);return n===-1?[]:e.slice(n+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>r(e))}function _(e,t){let n=t.findLastIndex(e=>e.type===`compaction`),r=t.slice(n+1).findLast(e=>e.type===`custom_message`&&e.customType===`doom-autocompact-context`);if(!r||r.type!==`custom_message`)return{messages:e,retainedMessageCount:0};let i=d(r.details),a=b(r);if(!i||!a)return{messages:e,invalidMarker:!0,retainedMessageCount:0};let o=e.findLastIndex(e=>e.role===`custom`&&e.customType===`doom-autocompact-context`&&d(e.details)?.doomAutocompact.requestId===i.doomAutocompact.requestId);return o===-1?{messages:e,invalidMarker:!0,retainedMessageCount:0}:{messages:[{role:`compactionSummary`,summary:a,tokensBefore:i.doomAutocompact.tokensBefore,timestamp:e[o]?.timestamp??Date.now()},...i.retainedMessages,...e.slice(o+1)],marker:i.doomAutocompact,retainedMessageCount:i.retainedMessages.length}}function v(e){let t={read:new Set,written:new Set,edited:new Set};for(let n of e)if(n.role===`assistant`)for(let e of n.content){if(e.type!==`toolCall`)continue;let n=typeof e.arguments.path==`string`?e.arguments.path:void 0;n&&(e.name===`read`?t.read.add(n):e.name===`write`?t.written.add(n):e.name===`edit`&&t.edited.add(n))}return t}function y(e){if(!o(e)||e.version!==2||typeof e.cycle!=`number`||!c(e.pass)||e.phase!==`waiting`&&e.phase!==`checkpoint_pending`&&e.phase!==`checkpoint_ready`&&e.phase!==`compacting`)return;let t=e.baselineTokens??0;if(typeof t!=`number`||t<0)return;let n=e.baselinePending??!1;if(typeof n!=`boolean`)return;let r=e.checkpointQueue??[];if(!Array.isArray(r)||!r.every(c)||r.some((e,t)=>t>0&&e<=r[t-1]))return;let i=e.exhaustedPasses??[];if(!Array.isArray(i)||!i.every(c))return;let a=e.invalidAttempts??0;if(!(typeof a!=`number`||a<0)&&!(!s(e.readFiles)||!s(e.modifiedFiles))&&(e.requestId===void 0||typeof e.requestId==`string`)&&(e.compactionPass===void 0||e.compactionPass===2||e.compactionPass===3)&&!(`latestCheckpointEntryId`in e)&&(e.latestCheckpointSnapshotLeafId===void 0||typeof e.latestCheckpointSnapshotLeafId==`string`)&&(e.lastAttemptLeafId===void 0||typeof e.lastAttemptLeafId==`string`)&&(e.snapshotLeafId===void 0||typeof e.snapshotLeafId==`string`)&&!(e.snapshotTokens!==void 0&&(typeof e.snapshotTokens!=`number`||e.snapshotTokens<0))&&(e.pendingCheckpoint===void 0||typeof e.pendingCheckpoint==`string`))return{version:2,cycle:e.cycle,pass:e.pass,phase:e.phase,checkpointQueue:[...r],exhaustedPasses:[...i],invalidAttempts:a,baselineTokens:t,baselinePending:n,readFiles:[...e.readFiles],modifiedFiles:[...e.modifiedFiles],...e.requestId?{requestId:e.requestId}:{},...e.compactionPass?{compactionPass:e.compactionPass}:{},...e.latestCheckpointSnapshotLeafId?{latestCheckpointSnapshotLeafId:e.latestCheckpointSnapshotLeafId}:{},...e.lastAttemptLeafId?{lastAttemptLeafId:e.lastAttemptLeafId}:{},...e.snapshotLeafId?{snapshotLeafId:e.snapshotLeafId}:{},...e.snapshotTokens===void 0?{}:{snapshotTokens:e.snapshotTokens},...e.pendingCheckpoint?{pendingCheckpoint:e.pendingCheckpoint}:{}}}function b(e){if(e)return e.type===`compaction`?e.summary.trim()||void 0:e.type===`custom`?o(e.data)&&typeof e.data.summary==`string`&&e.data.summary.trim()||void 0:e.type===`custom_message`?(typeof e.content==`string`?e.content:e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
3
3
|
`)).trim()||void 0:l(e)}function x(e){let t=e.match(i),n=e.replace(i,``).trim();return t?{summary:n,shouldCompact:t[1]?.toLowerCase()===`true`}:{summary:n}}function S(t){return e.every(e=>t.includes(e))}function C(e,t,n,r){return`${e}:${t}:${n}:${r??`root`}`}function w(e,t,n){return{version:2,cycle:e,pass:t,requestId:n}}function T(e,t,n){let r=new Set([...e.modifiedFiles,...n?.modifiedFiles??[],...t?[...t.edited,...t.written]:[]]),i=new Set([...e.readFiles,...n?.readFiles??[],...t?[...t.read]:[]]);for(let e of r)i.delete(e);return{readFiles:[...i].sort(),modifiedFiles:[...r].sort()}}function E(e){if(!(!o(e)||!s(e.readFiles)||!s(e.modifiedFiles)))return{readFiles:e.readFiles,modifiedFiles:e.modifiedFiles}}function D(e,t){let n=[];t.readFiles.length>0&&n.push(`<read-files>\n${t.readFiles.join(`
|
|
4
4
|
`)}\n</read-files>`),t.modifiedFiles.length>0&&n.push(`<modified-files>\n${t.modifiedFiles.join(`
|
|
5
5
|
`)}\n</modified-files>`);let r=e.replace(a,``).trim();return n.length>0?`${r}\n\n${n.join(`
|
|
6
6
|
|
|
7
|
-
`)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
|
|
7
|
+
`)}`:r}export{h as baselineUsageIsSettled,w as checkpointRequestDetails,b as checkpointSummaryFromEntry,d as contextDetailsFromUnknown,f as createInitialState,C as createRequestId,E as fileDetailsFromUnknown,v as fileOperationsFromMessages,S as isStructuredCheckpoint,m as latestCheckpointArtifactEntry,T as mergeFileDetails,x as parseCheckpointDecision,y as parseState,_ as projectContextMessages,g as retainedMessagesAfterSnapshot,p as thresholdTokens,D as withCanonicalFileSections};
|
|
8
8
|
//# sourceMappingURL=policy.mjs.map
|
|
@@ -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
|