pi-smart-compact 7.19.0 → 7.20.0
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/CHANGELOG.md +20 -0
- package/README.md +10 -2
- package/dist/app/run-smart-compact.d.ts +2 -0
- package/dist/app/run-smart-compact.d.ts.map +1 -1
- package/dist/app/steps/extract.d.ts.map +1 -1
- package/dist/app/steps/state.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +342 -258
- package/dist/infra/fs.d.ts +4 -0
- package/dist/infra/fs.d.ts.map +1 -1
- package/dist/infra/services.d.ts +1 -1
- package/dist/infra/services.d.ts.map +1 -1
- package/dist/phases/explore.d.ts +4 -7
- package/dist/phases/explore.d.ts.map +1 -1
- package/dist/ui/dashboard-format.d.ts.map +1 -1
- package/dist/ui/metrics-report.d.ts +4 -0
- package/dist/ui/metrics-report.d.ts.map +1 -0
- package/dist/utils/cache.d.ts +0 -2
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/damage.d.ts.map +1 -1
- package/dist/utils/pruning.d.ts.map +1 -1
- package/dist/utils/state.d.ts +1 -0
- package/dist/utils/state.d.ts.map +1 -1
- package/docs/RELEASE.md +1 -0
- package/package.json +4 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [7.20.0] - 2026-07-14
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Mixed parallel tool calls could lose unrelated edits** — redundant-read and failed-chain pruning deleted an entire assistant message when only one nested tool call was redundant. Pruning now removes individual direct or `multi_tool_use.parallel` blocks while preserving sibling calls, text, and tool-result pairing.
|
|
7
|
+
- **`smart_compact` ignored host cancellation** — the tool now links Pi's `AbortSignal` to the pipeline controller, handles already-aborted calls before authentication, removes listeners in `finally`, and prevents stale pending summaries.
|
|
8
|
+
- **Cross-compaction delta omissions** — removed decisions and resolved errors now count as meaningful changes and render correctly through one shared delta predicate.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Pi version compatibility runner** — `bun run compat:pi [version]` validates an exact or latest Pi release in an isolated temporary workspace without changing the checkout. Daily CI exercises the latest host packages; a package-boundary regression test prevents accidental bundling or version pinning.
|
|
12
|
+
- **Repeatable hot-path benchmark** — `bun run bench` reports median/p95 performance for incremental extraction and pruning.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Pi core dependency boundary** — `@earendil-works/pi-*` and `typebox` are host-provided wildcard peers only; duplicated versioned development dependencies were removed. The lockfile remains the reproducible local baseline.
|
|
16
|
+
- **Bounded runtime logs** — metrics and damage JSONL logs retain complete trailing records under a 5 MiB cap using the same lock as concurrent appenders.
|
|
17
|
+
- **Metrics UI separation** — text/HTML reporting moved from `utils/cache.ts` to `ui/metrics-report.ts`, reusing shared dashboard formatters; legacy service lifecycle comments now match production's run-scoped DI.
|
|
18
|
+
- **Deferred filesystem maintenance** — extraction-cache cleanup now runs on a later event-loop turn rather than in the microtask queue.
|
|
19
|
+
|
|
20
|
+
### Performance
|
|
21
|
+
- **Incremental extraction** — cache hits no longer build an unused full-history tool-call index. The 5,000-message benchmark reduced the measured median from about 0.133 ms to 0.035 ms on the development machine (~74%).
|
|
22
|
+
|
|
3
23
|
## [7.19.0] - 2026-07-10
|
|
4
24
|
|
|
5
25
|
### Fixed
|
package/README.md
CHANGED
|
@@ -223,6 +223,11 @@ The legacy config key `semanticCompact` is still accepted.
|
|
|
223
223
|
|
|
224
224
|
## Companions & compatibility
|
|
225
225
|
|
|
226
|
+
Pi core libraries are host-provided wildcard peers and are excluded from the
|
|
227
|
+
published bundle. This keeps the extension independent from Pi's release cadence:
|
|
228
|
+
the lockfile provides a reproducible development baseline, while daily CI runs
|
|
229
|
+
the full suite against the latest Pi packages without changing the manifest.
|
|
230
|
+
|
|
226
231
|
`pi-smart-compact` is designed to coexist with — and recommended alongside —
|
|
227
232
|
[`pi-toolkit`](https://github.com/ersintarhan/pi-toolkit). pi-toolkit handles
|
|
228
233
|
everyday context hygiene (anchors, pivots, status lines, old tool-output
|
|
@@ -245,11 +250,11 @@ The extension writes under `~/.pi/agent/`:
|
|
|
245
250
|
| `settings.json` | configuration (read) |
|
|
246
251
|
| `compact-backups/` | conversation backups (retention-pruned) |
|
|
247
252
|
| `.cache/compact-extraction-<session>.json` | incremental extraction cache |
|
|
248
|
-
| `.cache/compact-metrics.jsonl` | metrics log |
|
|
253
|
+
| `.cache/compact-metrics.jsonl` | metrics log (tail-retained, 5 MiB cap) |
|
|
249
254
|
| `.cache/smart-compact-report.html` | HTML dashboard |
|
|
250
255
|
| `.cache/smart-compact/projects/<projectId>.json` | project fingerprint |
|
|
251
256
|
| `.cache/smart-compact/states/<projectId>.json` | reusable compaction state |
|
|
252
|
-
| `.cache/smart-compact/damage-reports.jsonl` | regression signals |
|
|
257
|
+
| `.cache/smart-compact/damage-reports.jsonl` | regression signals (tail-retained, 5 MiB cap) |
|
|
253
258
|
| `.cache/smart-compact/remediation-<projectId>.json` | files to re-preserve after damage |
|
|
254
259
|
|
|
255
260
|
## Development
|
|
@@ -258,6 +263,9 @@ The extension writes under `~/.pi/agent/`:
|
|
|
258
263
|
bun install
|
|
259
264
|
bun run typecheck # tsc --noEmit
|
|
260
265
|
bun test # full test suite
|
|
266
|
+
bun run bench # repeatable hot-path benchmark
|
|
267
|
+
bun run compat:pi # latest Pi, without changing package.json or bun.lock
|
|
268
|
+
bun run compat:pi 0.80.6 # optional exact Pi version
|
|
261
269
|
bun run build # dist/ output for publishing
|
|
262
270
|
```
|
|
263
271
|
|
|
@@ -62,6 +62,8 @@ export interface SmartCompactOptions {
|
|
|
62
62
|
force?: boolean;
|
|
63
63
|
/** Optional hard budget for native auto-trigger only. Manual/tool runs do not time out by default. */
|
|
64
64
|
timeoutMs?: number;
|
|
65
|
+
/** Host cancellation for tool/manual callers. Linked to the pipeline controller. */
|
|
66
|
+
abortSignal?: AbortSignal;
|
|
65
67
|
/**
|
|
66
68
|
* If provided, populated with the run's cancellation handle before any
|
|
67
69
|
* async work begins. The session_before_compact hook uses this to enforce
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-smart-compact.d.ts","sourceRoot":"","sources":["../../src/app/run-smart-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,OAAO,KAAK,EACQ,UAAU,EAC7B,MAAM,kBAAkB,CAAC;AAc1B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,GAAG,EAAE,gBAAgB,CAAC;IACtB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sGAAsG;IACtG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACrD;AAwCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"run-smart-compact.d.ts","sourceRoot":"","sources":["../../src/app/run-smart-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,OAAO,KAAK,EACQ,UAAU,EAC7B,MAAM,kBAAkB,CAAC;AAc1B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,GAAG,EAAE,gBAAgB,CAAC;IACtB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sGAAsG;IACtG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACrD;AAwCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmM9E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../../src/app/steps/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkB/D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../../src/app/steps/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkB/D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,WAAW,CAuJ1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/app/steps/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAY9D,wBAAgB,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/app/steps/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAY9D,wBAAgB,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,QAAQ,CAoFnD"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { CompressionProfile, ProfileConfig } from "./types.ts";
|
|
|
8
8
|
* `package.json#version`. Do not hand-edit this line for releases; bump
|
|
9
9
|
* package.json and run `bun run sync-version`.
|
|
10
10
|
*/
|
|
11
|
-
export declare const VERSION = "7.
|
|
11
|
+
export declare const VERSION = "7.20.0";
|
|
12
12
|
export declare const CHARS_PER_TOKEN = 3.8;
|
|
13
13
|
export declare const COMPACT_SYSTEM_PREFIX: string;
|
|
14
14
|
export declare const PROFILES: Record<CompressionProfile, ProfileConfig>;
|
|
@@ -111,6 +111,7 @@ export declare const ERROR_RETRY_WINDOW = 6;
|
|
|
111
111
|
/** How far forward to look for that retry's resolving (non-error) result. */
|
|
112
112
|
export declare const ERROR_RESOLVE_WINDOW = 10;
|
|
113
113
|
export declare const METRICS_BUFFER_MAX = 200;
|
|
114
|
+
export declare const RUNTIME_LOG_MAX_BYTES: number;
|
|
114
115
|
export declare const DAMAGE_LOOKBACK_MSGS = 15;
|
|
115
116
|
export declare const VERIFICATION_GAP_SNIPPET_LEN = 80;
|
|
116
117
|
export declare const CONFIG_KEY = "smartCompact";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,eAAO,MAAM,qBAAqB,QAKqB,CAAC;AAExD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAyB9D,CAAC;AAEF,eAAO,MAAM,cAAc;IACzB,OAAO,EAAgB,kBAAkB;IACzC,QAAQ;IACR,YAAY,EAAU,MAAM,GAAG,IAAI;IACnC,iBAAiB,EAAU,MAAM,GAAG,IAAI;IACxC,WAAW;IACX,oBAAoB;IACpB,aAAa;IACb,SAAS;IACT,iBAAiB;IACjB,QAAQ,EAAQ,MAAM,EAAE;CACzB,CAAC;AAEF,eAAO,MAAM,QAAQ,QAA+E,CAAC;AAIrG,eAAO,MAAM,QAAQ,QAAwK,CAAC;AAC9L,eAAO,MAAM,SAAS,QAAmG,CAAC;AAI1H,eAAO,MAAM,kBAAkB,QAgB+C,CAAC;AAE/E,eAAO,MAAM,kBAAkB,yHACyF,CAAC;AAEzH,eAAO,MAAM,mBAAmB,QAWoB,CAAC;AAErD,eAAO,MAAM,mBAAmB,8DAA8D,CAAC;AAE/F,eAAO,MAAM,sBAAsB,QAoB2B,CAAC;AAE/D,eAAO,MAAM,sBAAsB,8OAC0M,CAAC;AAI9O,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK5D,CAAC;AAGF,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAClE,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAC9C,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AACpD,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAC1D,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,eAAO,MAAM,cAAc,sBAAsB,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,eAAe,qCAAqC,CAAC;AAGlE,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAG5C,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAQxC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,iBAAiB,QAA2B,CAAC;AAG1D,eAAO,MAAM,eAAe,QAAgB,CAAC;AAC7C,eAAO,MAAM,WAAW,QAAiB,CAAC;AAC1C,eAAO,MAAM,aAAa,QAA0B,CAAC;AACrD,eAAO,MAAM,cAAc,QAA2B,CAAC;AAGvD,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAG7D,eAAO,MAAM,SAAS;aACpB,OAAO,EAAE,OAAO;aAChB,eAAe,EAAE,KAAK;aACtB,wBAAwB,EAAE,MAAM;aAChC,SAAS,EAAE,OAAO;aAClB,QAAQ,EAAE,WAAW;aACrB,KAAK,EAAE,QAAQ;CACP,CAAC;AAGX,eAAO,MAAM,MAAM;aACjB,QAAQ,EAAE,GAAG;aACb,UAAU,EAAE,GAAG;aACf,qBAAqB,EAAE,GAAG;aAC1B,qBAAqB,EAAE,CAAG;aAC1B,eAAe,EAAE,IAAI;aACrB,iBAAiB,EAAE,GAAG;aACtB,cAAc,EAAE,GAAG;CACX,CAAC;AAGX,eAAO,MAAM,KAAK;aAEhB,OAAO,EAAE,GAAG;aACZ,YAAY,EAAE,GAAG;aACjB,gBAAgB,EAAE,GAAG;aACrB,aAAa,EAAE,GAAG;aAClB,eAAe,EAAE,GAAG;aACpB,iBAAiB,EAAE,GAAG;aACtB,cAAc,EAAE,GAAG;aACnB,cAAc,EAAE,GAAG;aAEnB,OAAO,EAAE,EAAE;aACX,OAAO,EAAE,GAAG;aACZ,WAAW,EAAE,GAAG;aAChB,MAAM,EAAE,GAAG;aACX,YAAY,EAAE,GAAG;aACjB,UAAU,EAAE,GAAG;aACf,cAAc,EAAE,GAAG;aACnB,eAAe,EAAE,EAAE;aACnB,WAAW,EAAE,GAAG;aAEhB,YAAY,EAAE,EAAE;aAChB,SAAS,EAAE,CAAC;aACZ,WAAW,EAAE,CAAC;aACd,kBAAkB,EAAE,EAAE;aACtB,aAAa,EAAE,EAAE;aACjB,gBAAgB,EAAE,EAAE;aACpB,eAAe,EAAE,EAAE;aACnB,oBAAoB,EAAE,CAAC;aACvB,eAAe,EAAE,CAAC;CACV,CAAC;AAGX,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAG3C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAGzC,sFAAsF;AACtF,eAAO,MAAM,eAAe,QAA8J,CAAC;AAC3L,+FAA+F;AAC/F,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAOvC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAGtC,eAAO,MAAM,qBAAqB,QAAkB,CAAC;AAGrD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAG/C,eAAO,MAAM,UAAU,iBAAiB,CAAC;AACzC,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD,eAAO,MAAM,sBAAsB,QAU6T,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAwE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAwE,MAAM,oBAAoB,CAAC;AAgDtH,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAG5F;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/B,MAAM,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACrC,QAAQ,UAAQ,GACf;IAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAA;CAAE,CAoBxE;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,QA4R7D"}
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
17
17
|
var __require = import.meta.require;
|
|
18
18
|
|
|
19
19
|
// src/constants.ts
|
|
20
|
-
var VERSION = "7.
|
|
20
|
+
var VERSION = "7.20.0", CHARS_PER_TOKEN = 3.8, COMPACT_SYSTEM_PREFIX, PROFILES, DEFAULT_CONFIG, NO_OP_RE, SHIFT_RE, CHOICE_RE, SINGLE_PASS_PREFIX, SINGLE_PASS_SUFFIX = `
|
|
21
21
|
{PREV_CONTEXT}
|
|
22
22
|
|
|
23
23
|
{EXTRACTION_CONTEXT}
|
|
@@ -40,7 +40,7 @@ IMMUTABLE CONTEXT (verified deterministic data):
|
|
|
40
40
|
{EXPLORATION_CONTEXT}
|
|
41
41
|
{PREV_CONTEXT}
|
|
42
42
|
|
|
43
|
-
<summaries>{SUMMARIES}</summaries>`, SESSION_TYPE_INSTRUCTIONS, SECTION_GOAL = "## Goal", SECTION_CONSTRAINTS = "## Constraints & Preferences", SECTION_PROGRESS = "## Progress", SECTION_DECISIONS = "## Key Decisions", SECTION_FILES_MODIFIED = "## Files Modified", SECTION_FILES_READ = "## Files Read", SECTION_NEXT_STEPS = "## Next Steps", SECTION_CRITICAL_CONTEXT = "## Critical Context", SECTION_TOPICS = "## Topics Covered", SECTION_OPEN_LOOPS = "## Open Loops", SECTION_CHANGES = "## Changes Since Last Compaction", LOG_PREFIX = "[smart-compact]", MIN_TOKEN_THRESHOLD = 5000, MAX_EXPLORATION_ROUNDS = 8, BACKUP_MAX_FILES = 20, BACKUP_MAX_AGE_MS, FIVE_MINUTES_MS, ONE_HOUR_MS, SEVEN_DAYS_MS, THIRTY_DAYS_MS, EXTRACTION_CACHE_PREFIX = "compact-extraction-", ID_PREFIX, TUNING, TRUNC, MAX_TOOL_OUTPUT_CHARS = 800, LIKELY_ERROR_RE, ERROR_SCAN_MAX_LEN = 2000, ERROR_RETRY_WINDOW = 6, ERROR_RESOLVE_WINDOW = 10, METRICS_BUFFER_MAX = 200, CONFIG_KEY = "smartCompact", CONFIG_KEY_ALT = "semanticCompact", EXPLORER_SYSTEM_PROMPT;
|
|
43
|
+
<summaries>{SUMMARIES}</summaries>`, SESSION_TYPE_INSTRUCTIONS, SECTION_GOAL = "## Goal", SECTION_CONSTRAINTS = "## Constraints & Preferences", SECTION_PROGRESS = "## Progress", SECTION_DECISIONS = "## Key Decisions", SECTION_FILES_MODIFIED = "## Files Modified", SECTION_FILES_READ = "## Files Read", SECTION_NEXT_STEPS = "## Next Steps", SECTION_CRITICAL_CONTEXT = "## Critical Context", SECTION_TOPICS = "## Topics Covered", SECTION_OPEN_LOOPS = "## Open Loops", SECTION_CHANGES = "## Changes Since Last Compaction", LOG_PREFIX = "[smart-compact]", MIN_TOKEN_THRESHOLD = 5000, MAX_EXPLORATION_ROUNDS = 8, BACKUP_MAX_FILES = 20, BACKUP_MAX_AGE_MS, FIVE_MINUTES_MS, ONE_HOUR_MS, SEVEN_DAYS_MS, THIRTY_DAYS_MS, EXTRACTION_CACHE_PREFIX = "compact-extraction-", ID_PREFIX, TUNING, TRUNC, MAX_TOOL_OUTPUT_CHARS = 800, LIKELY_ERROR_RE, ERROR_SCAN_MAX_LEN = 2000, ERROR_RETRY_WINDOW = 6, ERROR_RESOLVE_WINDOW = 10, METRICS_BUFFER_MAX = 200, RUNTIME_LOG_MAX_BYTES, CONFIG_KEY = "smartCompact", CONFIG_KEY_ALT = "semanticCompact", EXPLORER_SYSTEM_PROMPT;
|
|
44
44
|
var init_constants = __esm(() => {
|
|
45
45
|
COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
|
|
46
46
|
PROFILES = {
|
|
@@ -229,6 +229,7 @@ Rules for Accuracy:
|
|
|
229
229
|
FINGERPRINT_SEG: 2
|
|
230
230
|
};
|
|
231
231
|
LIKELY_ERROR_RE = /(?:command not found|no such file|permission denied|syntax error|cannot find|module not found|compilation error|build failed|test failed|^FAIL\b|ERROR:)/i;
|
|
232
|
+
RUNTIME_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
232
233
|
EXPLORER_SYSTEM_PROMPT = `You are a conversation analyst. You have deterministic extraction data and can query the raw conversation using tools.
|
|
233
234
|
|
|
234
235
|
` + `Your job:
|
|
@@ -402,6 +403,42 @@ function appendLineLocked(target, line) {
|
|
|
402
403
|
release();
|
|
403
404
|
}
|
|
404
405
|
}
|
|
406
|
+
function trimFileTailLocked(target, maxBytes) {
|
|
407
|
+
const release = acquireLockSync(target);
|
|
408
|
+
try {
|
|
409
|
+
const stat = fs.statSync(target);
|
|
410
|
+
if (stat.size <= maxBytes)
|
|
411
|
+
return;
|
|
412
|
+
const length = Math.min(stat.size, maxBytes);
|
|
413
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
414
|
+
const fd = fs.openSync(target, "r");
|
|
415
|
+
try {
|
|
416
|
+
fs.readSync(fd, buffer, 0, length, stat.size - length);
|
|
417
|
+
} finally {
|
|
418
|
+
fs.closeSync(fd);
|
|
419
|
+
}
|
|
420
|
+
const tail = buffer.toString("utf8");
|
|
421
|
+
const firstNewline = tail.indexOf(`
|
|
422
|
+
`);
|
|
423
|
+
atomicWriteFileSync(target, firstNewline >= 0 ? tail.slice(firstNewline + 1) : "");
|
|
424
|
+
} finally {
|
|
425
|
+
release();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function scheduleFileTailTrim(target, maxBytes) {
|
|
429
|
+
if (scheduledTailTrims.has(target))
|
|
430
|
+
return;
|
|
431
|
+
scheduledTailTrims.add(target);
|
|
432
|
+
setTimeout(() => {
|
|
433
|
+
try {
|
|
434
|
+
trimFileTailLocked(target, maxBytes);
|
|
435
|
+
} catch (e) {
|
|
436
|
+
debug("tail trim failed for " + target, e);
|
|
437
|
+
} finally {
|
|
438
|
+
scheduledTailTrims.delete(target);
|
|
439
|
+
}
|
|
440
|
+
}, 0);
|
|
441
|
+
}
|
|
405
442
|
function readJsonSync(target) {
|
|
406
443
|
try {
|
|
407
444
|
if (!fs.existsSync(target))
|
|
@@ -416,9 +453,10 @@ function readJsonSync(target) {
|
|
|
416
453
|
function writeJsonSync(target, value, pretty = false) {
|
|
417
454
|
atomicWriteFileSync(target, pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value));
|
|
418
455
|
}
|
|
419
|
-
var LOCK_STALE_MS = 5000, LOCK_RETRY_MS = 25, LOCK_MAX_RETRIES = 80;
|
|
456
|
+
var LOCK_STALE_MS = 5000, LOCK_RETRY_MS = 25, LOCK_MAX_RETRIES = 80, scheduledTailTrims;
|
|
420
457
|
var init_fs = __esm(() => {
|
|
421
458
|
init_logger();
|
|
459
|
+
scheduledTailTrims = new Set;
|
|
422
460
|
});
|
|
423
461
|
|
|
424
462
|
// src/utils/tokens.ts
|
|
@@ -1051,7 +1089,7 @@ function scheduleExtractionCacheCleanup() {
|
|
|
1051
1089
|
if (_extractionPruneInFlight)
|
|
1052
1090
|
return;
|
|
1053
1091
|
_extractionPruneInFlight = true;
|
|
1054
|
-
|
|
1092
|
+
setTimeout(() => {
|
|
1055
1093
|
try {
|
|
1056
1094
|
const dir = path5.dirname(getCachePath("_"));
|
|
1057
1095
|
if (!fs3.existsSync(dir))
|
|
@@ -1121,7 +1159,9 @@ function appendMetricsLog(sessionId, extra, services) {
|
|
|
1121
1159
|
...summary,
|
|
1122
1160
|
...extra
|
|
1123
1161
|
};
|
|
1124
|
-
|
|
1162
|
+
const logPath = metricsLogFile();
|
|
1163
|
+
appendLineLocked(logPath, JSON.stringify(entry));
|
|
1164
|
+
scheduleFileTailTrim(logPath, RUNTIME_LOG_MAX_BYTES);
|
|
1125
1165
|
} catch (e) {
|
|
1126
1166
|
warn("appendMetricsLog failed", e);
|
|
1127
1167
|
}
|
|
@@ -1165,238 +1205,6 @@ function readMetricsLog(limit = 100) {
|
|
|
1165
1205
|
return [];
|
|
1166
1206
|
}
|
|
1167
1207
|
}
|
|
1168
|
-
function escapeHtml(value) {
|
|
1169
|
-
return String(value ?? "").replace(/[&<>\"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c] ?? c);
|
|
1170
|
-
}
|
|
1171
|
-
function durationOf(entry) {
|
|
1172
|
-
return entry.durationMs ?? entry.phaseTimings?.reduce((sum, phase) => sum + phase.durationMs, 0) ?? 0;
|
|
1173
|
-
}
|
|
1174
|
-
function percentile(values, p) {
|
|
1175
|
-
if (!values.length)
|
|
1176
|
-
return 0;
|
|
1177
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
1178
|
-
return sorted[Math.min(sorted.length - 1, Math.max(0, Math.floor(p / 100 * sorted.length)))];
|
|
1179
|
-
}
|
|
1180
|
-
function average(values) {
|
|
1181
|
-
return values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0;
|
|
1182
|
-
}
|
|
1183
|
-
function compactNumber(value) {
|
|
1184
|
-
return new Intl.NumberFormat("en", { notation: Math.abs(value) >= 1e4 ? "compact" : "standard", maximumFractionDigits: 1 }).format(value);
|
|
1185
|
-
}
|
|
1186
|
-
function formatNumber(value) {
|
|
1187
|
-
if (typeof value !== "number" || !Number.isFinite(value))
|
|
1188
|
-
return escapeHtml(value);
|
|
1189
|
-
return value.toLocaleString();
|
|
1190
|
-
}
|
|
1191
|
-
function formatMs(value) {
|
|
1192
|
-
if (!value)
|
|
1193
|
-
return "0ms";
|
|
1194
|
-
if (value >= 60000)
|
|
1195
|
-
return (value / 60000).toFixed(value >= 600000 ? 0 : 1) + "m";
|
|
1196
|
-
if (value >= 1000)
|
|
1197
|
-
return (value / 1000).toFixed(value >= 1e4 ? 0 : 1) + "s";
|
|
1198
|
-
return Math.round(value) + "ms";
|
|
1199
|
-
}
|
|
1200
|
-
function formatPercent(value) {
|
|
1201
|
-
return Math.round(value * 100) + "%";
|
|
1202
|
-
}
|
|
1203
|
-
function statusClass(status) {
|
|
1204
|
-
if (status === "timeout" || status === "error")
|
|
1205
|
-
return "bad";
|
|
1206
|
-
if (status === "dry-run")
|
|
1207
|
-
return "warn";
|
|
1208
|
-
return "good";
|
|
1209
|
-
}
|
|
1210
|
-
function statusLabel(status) {
|
|
1211
|
-
return status ?? "success";
|
|
1212
|
-
}
|
|
1213
|
-
function badge(status) {
|
|
1214
|
-
const label = statusLabel(status);
|
|
1215
|
-
return `<span class="badge ${statusClass(label)}">${escapeHtml(label)}</span>`;
|
|
1216
|
-
}
|
|
1217
|
-
function summarizeDashboard(entries) {
|
|
1218
|
-
const durations = entries.map(durationOf).filter(Boolean);
|
|
1219
|
-
const success = entries.filter((e) => statusLabel(e.status) === "success").length;
|
|
1220
|
-
const timeout = entries.filter((e) => e.status === "timeout").length;
|
|
1221
|
-
const error = entries.filter((e) => e.status === "error").length;
|
|
1222
|
-
const dryRun = entries.filter((e) => e.status === "dry-run").length;
|
|
1223
|
-
const scored = entries.map((e) => e.verificationScore).filter((v) => typeof v === "number");
|
|
1224
|
-
return {
|
|
1225
|
-
runs: entries.length,
|
|
1226
|
-
success,
|
|
1227
|
-
timeout,
|
|
1228
|
-
error,
|
|
1229
|
-
dryRun,
|
|
1230
|
-
successRate: entries.length ? success / entries.length : 0,
|
|
1231
|
-
avgDuration: Math.round(average(durations)),
|
|
1232
|
-
p95Duration: percentile(durations, 95),
|
|
1233
|
-
totalCalls: entries.reduce((sum, e) => sum + (e.totalCalls ?? 0), 0),
|
|
1234
|
-
totalInput: entries.reduce((sum, e) => sum + (e.totalInput ?? 0), 0),
|
|
1235
|
-
totalOutput: entries.reduce((sum, e) => sum + (e.totalOutput ?? 0), 0),
|
|
1236
|
-
totalSaved: entries.reduce((sum, e) => sum + (e.tokensSaved ?? 0), 0),
|
|
1237
|
-
avgScore: Math.round(average(scored))
|
|
1238
|
-
};
|
|
1239
|
-
}
|
|
1240
|
-
function groupMetrics(entries, keyFn) {
|
|
1241
|
-
const groups = new Map;
|
|
1242
|
-
for (const entry of entries) {
|
|
1243
|
-
const key = keyFn(entry);
|
|
1244
|
-
if (!key)
|
|
1245
|
-
continue;
|
|
1246
|
-
groups.set(key, [...groups.get(key) ?? [], entry]);
|
|
1247
|
-
}
|
|
1248
|
-
return [...groups.entries()].map(([name, group]) => {
|
|
1249
|
-
const durations = group.map(durationOf).filter(Boolean);
|
|
1250
|
-
const scores = group.map((e) => e.verificationScore).filter((v) => typeof v === "number");
|
|
1251
|
-
const failures = group.filter((e) => e.status === "timeout" || e.status === "error").length;
|
|
1252
|
-
return {
|
|
1253
|
-
name,
|
|
1254
|
-
runs: group.length,
|
|
1255
|
-
avgDuration: Math.round(average(durations)),
|
|
1256
|
-
p95Duration: percentile(durations, 95),
|
|
1257
|
-
avgScore: Math.round(average(scores)),
|
|
1258
|
-
totalSaved: group.reduce((sum, e) => sum + (e.tokensSaved ?? 0), 0),
|
|
1259
|
-
totalCalls: group.reduce((sum, e) => sum + (e.totalCalls ?? 0), 0),
|
|
1260
|
-
errorRate: group.length ? failures / group.length : 0
|
|
1261
|
-
};
|
|
1262
|
-
}).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
1263
|
-
}
|
|
1264
|
-
function progressBar(value, label = formatPercent(value)) {
|
|
1265
|
-
const pct = Math.max(0, Math.min(100, Math.round(value * 100)));
|
|
1266
|
-
return `<div class="meter" title="${escapeHtml(label)}"><span style="width:${pct}%"></span></div>`;
|
|
1267
|
-
}
|
|
1268
|
-
function sparkline(values) {
|
|
1269
|
-
const nums = values.filter((v) => Number.isFinite(v));
|
|
1270
|
-
if (nums.length < 2)
|
|
1271
|
-
return `<div class="empty">Need at least two runs for trend</div>`;
|
|
1272
|
-
const width = 520;
|
|
1273
|
-
const height = 120;
|
|
1274
|
-
const min = Math.min(...nums);
|
|
1275
|
-
const max = Math.max(...nums);
|
|
1276
|
-
const span = Math.max(1, max - min);
|
|
1277
|
-
const points = nums.map((value, i) => {
|
|
1278
|
-
const x = i / Math.max(1, nums.length - 1) * width;
|
|
1279
|
-
const y = height - (value - min) / span * (height - 18) - 9;
|
|
1280
|
-
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
1281
|
-
}).join(" ");
|
|
1282
|
-
const last = nums[nums.length - 1];
|
|
1283
|
-
return `<svg class="spark" viewBox="0 0 ${width} ${height}" role="img" aria-label="Duration trend"><polyline points="${points}" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle cx="${width}" cy="${(height - (last - min) / span * (height - 18) - 9).toFixed(1)}" r="4" fill="currentColor"/><text x="0" y="14">${escapeHtml(formatMs(max))}</text><text x="0" y="${height - 4}">${escapeHtml(formatMs(min))}</text></svg>`;
|
|
1284
|
-
}
|
|
1285
|
-
function metricCard(label, value, detail, tone = "neutral") {
|
|
1286
|
-
return `<article class="card ${tone}"><div class="label">${escapeHtml(label)}</div><div class="value">${escapeHtml(value)}</div><div class="detail">${escapeHtml(detail)}</div></article>`;
|
|
1287
|
-
}
|
|
1288
|
-
function comparisonRows(groups) {
|
|
1289
|
-
if (!groups.length)
|
|
1290
|
-
return `<tr><td colspan="8" class="empty">No data yet</td></tr>`;
|
|
1291
|
-
return groups.map((group) => `<tr>
|
|
1292
|
-
<td><strong>${escapeHtml(group.name)}</strong></td>
|
|
1293
|
-
<td class="num">${formatNumber(group.runs)}</td>
|
|
1294
|
-
<td class="num">${escapeHtml(formatMs(group.avgDuration))}</td>
|
|
1295
|
-
<td class="num">${escapeHtml(formatMs(group.p95Duration))}</td>
|
|
1296
|
-
<td class="num">${group.avgScore ? formatNumber(group.avgScore) : "\u2014"}</td>
|
|
1297
|
-
<td class="num">${formatNumber(group.totalCalls)}</td>
|
|
1298
|
-
<td class="num">${formatNumber(group.totalSaved)}</td>
|
|
1299
|
-
<td>${progressBar(1 - group.errorRate, formatPercent(1 - group.errorRate) + " reliable")}</td>
|
|
1300
|
-
</tr>`).join(`
|
|
1301
|
-
`);
|
|
1302
|
-
}
|
|
1303
|
-
function phaseRows(entry) {
|
|
1304
|
-
const timings = entry?.phaseTimings ?? [];
|
|
1305
|
-
if (!timings.length)
|
|
1306
|
-
return `<tr><td colspan="3" class="empty">No phase timings yet</td></tr>`;
|
|
1307
|
-
const total = timings.reduce((sum, phase) => sum + phase.durationMs, 0) || 1;
|
|
1308
|
-
return timings.map((phase) => `<tr>
|
|
1309
|
-
<td>${escapeHtml(phase.phase)}</td>
|
|
1310
|
-
<td class="num">${escapeHtml(formatMs(phase.durationMs))}</td>
|
|
1311
|
-
<td>${progressBar(phase.durationMs / total, formatPercent(phase.durationMs / total))}</td>
|
|
1312
|
-
</tr>`).join(`
|
|
1313
|
-
`);
|
|
1314
|
-
}
|
|
1315
|
-
function recentRunRows(entries) {
|
|
1316
|
-
if (!entries.length)
|
|
1317
|
-
return `<tr><td colspan="12" class="empty">No runs recorded yet</td></tr>`;
|
|
1318
|
-
return entries.slice(-80).reverse().map((entry) => `<tr>
|
|
1319
|
-
<td class="mono small">${escapeHtml(entry.ts)}</td>
|
|
1320
|
-
<td>${escapeHtml(entry.profile)}</td>
|
|
1321
|
-
<td>${escapeHtml(entry.provider ?? entry.model?.split("/")[0])}</td>
|
|
1322
|
-
<td>${escapeHtml(entry.method)}</td>
|
|
1323
|
-
<td>${escapeHtml(entry.runType)}</td>
|
|
1324
|
-
<td>${badge(entry.status)}</td>
|
|
1325
|
-
<td class="num">${escapeHtml(formatMs(durationOf(entry)))}</td>
|
|
1326
|
-
<td class="num">${typeof entry.verificationScore === "number" ? formatNumber(entry.verificationScore) : "\u2014"}</td>
|
|
1327
|
-
<td class="num">${typeof entry.tokensSaved === "number" ? formatNumber(entry.tokensSaved) : "\u2014"}</td>
|
|
1328
|
-
<td class="num">${formatNumber(entry.totalCalls ?? 0)}</td>
|
|
1329
|
-
<td class="num">${typeof entry.extractionCacheHitRate === "number" ? formatPercent(entry.extractionCacheHitRate) : "\u2014"}</td>
|
|
1330
|
-
<td class="mono small reason">${escapeHtml(entry.fallbackReason ?? entry.extractionCacheMissReason ?? "")}</td>
|
|
1331
|
-
</tr>`).join(`
|
|
1332
|
-
`);
|
|
1333
|
-
}
|
|
1334
|
-
function dashboardCss() {
|
|
1335
|
-
return `:root{color-scheme:dark;--bg:#08111f;--surface:#0f172a;--surface2:#111c33;--card:#111827;--text:#e5edf8;--muted:#8fa3bf;--line:#24324a;--accent:#60a5fa;--good:#22c55e;--bad:#fb7185;--warn:#fbbf24;--shadow:0 18px 50px rgba(0,0,0,.28)}@media(prefers-color-scheme:light){:root{color-scheme:light;--bg:#f4f7fb;--surface:#ffffff;--surface2:#f8fafc;--card:#ffffff;--text:#0f172a;--muted:#64748b;--line:#e2e8f0;--shadow:0 18px 50px rgba(15,23,42,.08)}}*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at top left,rgba(96,165,250,.20),transparent 34rem),var(--bg);color:var(--text);font:14px/1.5 Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}main{max-width:1280px;margin:0 auto;padding:32px}header{display:flex;justify-content:space-between;gap:20px;align-items:flex-start;margin-bottom:24px}.eyebrow{color:var(--accent);font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-size:12px}h1{font-size:32px;line-height:1.1;margin:6px 0 6px}.muted,.detail{color:var(--muted)}.cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin:20px 0 22px}.card{background:linear-gradient(180deg,rgba(255,255,255,.035),transparent),var(--card);border:1px solid var(--line);border-radius:18px;padding:16px;box-shadow:var(--shadow)}.card.good{border-color:rgba(34,197,94,.45)}.card.warn{border-color:rgba(251,191,36,.45)}.card.bad{border-color:rgba(251,113,133,.5)}.label{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;font-weight:700}.value{font-size:28px;font-weight:800;margin-top:6px}.layout{display:grid;grid-template-columns:1.15fr .85fr;gap:18px}.panel{background:var(--surface);border:1px solid var(--line);border-radius:18px;box-shadow:var(--shadow);overflow:hidden}.panel h2{display:flex;align-items:center;justify-content:space-between;margin:0;padding:15px 18px;background:linear-gradient(180deg,rgba(255,255,255,.035),transparent),var(--surface2);font-size:15px}.table-wrap{overflow:auto;max-height:560px}table{border-collapse:separate;border-spacing:0;width:100%}th,td{border-bottom:1px solid var(--line);padding:9px 11px;text-align:left;vertical-align:middle;white-space:nowrap}th{position:sticky;top:0;z-index:1;background:var(--surface2);color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em}tr:hover td{background:rgba(96,165,250,.06)}.num{text-align:right}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.small{font-size:12px}.reason{max-width:280px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.badge{display:inline-flex;align-items:center;border-radius:999px;padding:3px 9px;font-size:12px;font-weight:800}.badge.good{background:rgba(34,197,94,.14);color:var(--good)}.badge.bad{background:rgba(251,113,133,.16);color:var(--bad)}.badge.warn{background:rgba(251,191,36,.16);color:var(--warn)}.meter{height:8px;background:rgba(148,163,184,.22);border-radius:99px;min-width:96px;overflow:hidden}.meter span{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--accent),var(--good))}.spark{width:100%;height:160px;color:var(--accent);padding:18px}.spark text{fill:var(--muted);font-size:12px}.empty{padding:18px;color:var(--muted);text-align:center}pre{white-space:pre-wrap;background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:16px;overflow:auto}.section{margin-top:18px}.two{display:grid;grid-template-columns:1fr 1fr;gap:18px}@media(max-width:960px){main{padding:20px}.cards,.layout,.two{grid-template-columns:1fr}header{display:block}th,td{padding:8px}.value{font-size:24px}}`;
|
|
1336
|
-
}
|
|
1337
|
-
function buildMetricsReport(entries = readMetricsLog(100)) {
|
|
1338
|
-
if (!entries.length)
|
|
1339
|
-
return "No smart-compact metrics recorded yet.";
|
|
1340
|
-
const summary = summarizeDashboard(entries);
|
|
1341
|
-
const byProfile = groupMetrics(entries, (e) => e.profile);
|
|
1342
|
-
const byProvider = groupMetrics(entries, (e) => e.provider ?? e.model?.split("/")[0]);
|
|
1343
|
-
const summarizeGroup = (group) => "- " + group.name + ": n=" + group.runs + ", avg=" + group.avgDuration + "ms, p95=" + group.p95Duration + "ms, score=" + group.avgScore + ", saved=" + group.totalSaved + "t, reliability=" + formatPercent(1 - group.errorRate);
|
|
1344
|
-
const extractionCacheRuns = entries.filter((e) => typeof e.extractionCacheHitRate === "number");
|
|
1345
|
-
const extractionCacheAvg = average(extractionCacheRuns.map((e) => e.extractionCacheHitRate ?? 0));
|
|
1346
|
-
return [
|
|
1347
|
-
"# Smart Compact Metrics",
|
|
1348
|
-
"",
|
|
1349
|
-
"Runs: " + summary.runs + " (success " + summary.success + ", dry-run " + summary.dryRun + ", timeout " + summary.timeout + ", error " + summary.error + ")",
|
|
1350
|
-
"Reliability: " + formatPercent(summary.successRate),
|
|
1351
|
-
"Latency: avg " + summary.avgDuration + "ms, p95 " + summary.p95Duration + "ms",
|
|
1352
|
-
"LLM calls: " + summary.totalCalls + ", input " + summary.totalInput + "t, output " + summary.totalOutput + "t",
|
|
1353
|
-
"Extraction cache: avg " + (extractionCacheRuns.length ? formatPercent(extractionCacheAvg) : "\u2014") + " across " + extractionCacheRuns.length + " measured run(s)",
|
|
1354
|
-
"Tokens saved: " + summary.totalSaved + "t, average verification score: " + summary.avgScore,
|
|
1355
|
-
"",
|
|
1356
|
-
"## Profile comparison",
|
|
1357
|
-
...byProfile.map(summarizeGroup),
|
|
1358
|
-
"",
|
|
1359
|
-
"## Provider comparison",
|
|
1360
|
-
...byProvider.map(summarizeGroup)
|
|
1361
|
-
].join(`
|
|
1362
|
-
`);
|
|
1363
|
-
}
|
|
1364
|
-
function writeMetricsDashboard(entries = readMetricsLog(200)) {
|
|
1365
|
-
try {
|
|
1366
|
-
ensureDir(cacheDir());
|
|
1367
|
-
const summary = summarizeDashboard(entries);
|
|
1368
|
-
const latest = entries[entries.length - 1];
|
|
1369
|
-
const report = buildMetricsReport(entries);
|
|
1370
|
-
const profileGroups = groupMetrics(entries, (e) => e.profile);
|
|
1371
|
-
const providerGroups = groupMetrics(entries, (e) => e.provider ?? e.model?.split("/")[0]);
|
|
1372
|
-
const healthTone = summary.error + summary.timeout > 0 ? "warn" : "good";
|
|
1373
|
-
const html = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Smart Compact Metrics</title><style>${dashboardCss()}</style></head><body><main>
|
|
1374
|
-
<header><div><div class="eyebrow">pi-smart-compact</div><h1>Operational Metrics</h1><div class="muted">Generated ${escapeHtml(new Date().toISOString())} \xB7 ${formatNumber(entries.length)} recent runs \xB7 local file dashboard</div></div><div>${badge(latest?.status)} ${latest ? `<span class="muted">latest ${escapeHtml(latest.profile ?? "unknown")}</span>` : ""}</div></header>
|
|
1375
|
-
<section class="cards">
|
|
1376
|
-
${metricCard("Reliability", formatPercent(summary.successRate), `${summary.success} success \xB7 ${summary.timeout} timeout \xB7 ${summary.error} error`, healthTone)}
|
|
1377
|
-
${metricCard("Avg duration", formatMs(summary.avgDuration), `p95 ${formatMs(summary.p95Duration)}`)}
|
|
1378
|
-
${metricCard("LLM calls", compactNumber(summary.totalCalls), `${compactNumber(summary.totalInput)} input \xB7 ${compactNumber(summary.totalOutput)} output`)}
|
|
1379
|
-
${metricCard("Tokens saved", compactNumber(summary.totalSaved), `avg score ${summary.avgScore || "\u2014"}`)}
|
|
1380
|
-
</section>
|
|
1381
|
-
<section class="layout">
|
|
1382
|
-
<div class="panel"><h2>Duration trend <span class="muted">last ${Math.min(entries.length, 80)} runs</span></h2>${sparkline(entries.slice(-80).map(durationOf))}</div>
|
|
1383
|
-
<div class="panel"><h2>Latest phase timings</h2><div class="table-wrap"><table><thead><tr><th>Phase</th><th class="num">Duration</th><th>Share</th></tr></thead><tbody>${phaseRows(latest)}</tbody></table></div></div>
|
|
1384
|
-
</section>
|
|
1385
|
-
<section class="two section">
|
|
1386
|
-
<div class="panel"><h2>Profile comparison</h2><div class="table-wrap"><table><thead><tr><th>Profile</th><th class="num">Runs</th><th class="num">Avg</th><th class="num">p95</th><th class="num">Score</th><th class="num">Calls</th><th class="num">Saved</th><th>Reliability</th></tr></thead><tbody>${comparisonRows(profileGroups)}</tbody></table></div></div>
|
|
1387
|
-
<div class="panel"><h2>Provider comparison</h2><div class="table-wrap"><table><thead><tr><th>Provider</th><th class="num">Runs</th><th class="num">Avg</th><th class="num">p95</th><th class="num">Score</th><th class="num">Calls</th><th class="num">Saved</th><th>Reliability</th></tr></thead><tbody>${comparisonRows(providerGroups)}</tbody></table></div></div>
|
|
1388
|
-
</section>
|
|
1389
|
-
<section class="panel section"><h2>Recent runs</h2><div class="table-wrap"><table><thead><tr><th>Time</th><th>Profile</th><th>Provider</th><th>Method</th><th>Run</th><th>Status</th><th class="num">Duration</th><th class="num">Score</th><th class="num">Saved</th><th class="num">Calls</th><th class="num">Ext cache</th><th>Reason</th></tr></thead><tbody>${recentRunRows(entries)}</tbody></table></div></section>
|
|
1390
|
-
<section class="section"><h2>Raw text report</h2><pre>${escapeHtml(report)}</pre></section>
|
|
1391
|
-
</main></body></html>`;
|
|
1392
|
-
const fp = metricsDashboardFile();
|
|
1393
|
-
atomicWriteFileSync(fp, html);
|
|
1394
|
-
return fp;
|
|
1395
|
-
} catch (e) {
|
|
1396
|
-
warn("writeMetricsDashboard failed", e);
|
|
1397
|
-
return null;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
1208
|
var INTERNAL_PHASES, EXTRACTION_CACHE_TTL_MS, EXTRACTION_CACHE_PRUNE_MAX_AGE_MS, _extractionPruneInFlight = false;
|
|
1401
1209
|
var init_cache = __esm(() => {
|
|
1402
1210
|
init_tokens();
|
|
@@ -1427,6 +1235,8 @@ function metricDuration(entry) {
|
|
|
1427
1235
|
function metricMs(ms) {
|
|
1428
1236
|
if (!Number.isFinite(ms) || ms <= 0)
|
|
1429
1237
|
return "0ms";
|
|
1238
|
+
if (ms >= 60000)
|
|
1239
|
+
return (ms / 60000).toFixed(ms >= 600000 ? 0 : 1) + "m";
|
|
1430
1240
|
return ms >= 1000 ? (ms / 1000).toFixed(ms >= 1e4 ? 0 : 1) + "s" : Math.round(ms) + "ms";
|
|
1431
1241
|
}
|
|
1432
1242
|
function clampRatio(value) {
|
|
@@ -3122,6 +2932,223 @@ function buildExplorationContext(report) {
|
|
|
3122
2932
|
init_tokens();
|
|
3123
2933
|
init_cache();
|
|
3124
2934
|
|
|
2935
|
+
// src/ui/metrics-report.ts
|
|
2936
|
+
init_paths();
|
|
2937
|
+
init_fs();
|
|
2938
|
+
init_logger();
|
|
2939
|
+
init_cache();
|
|
2940
|
+
function escapeHtml(value) {
|
|
2941
|
+
return String(value ?? "").replace(/[&<>\"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c] ?? c);
|
|
2942
|
+
}
|
|
2943
|
+
function percentile(values, p) {
|
|
2944
|
+
if (!values.length)
|
|
2945
|
+
return 0;
|
|
2946
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
2947
|
+
return sorted[Math.min(sorted.length - 1, Math.max(0, Math.floor(p / 100 * sorted.length)))];
|
|
2948
|
+
}
|
|
2949
|
+
function average(values) {
|
|
2950
|
+
return values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0;
|
|
2951
|
+
}
|
|
2952
|
+
function compactNumber(value) {
|
|
2953
|
+
return new Intl.NumberFormat("en", { notation: Math.abs(value) >= 1e4 ? "compact" : "standard", maximumFractionDigits: 1 }).format(value);
|
|
2954
|
+
}
|
|
2955
|
+
function statusClass(status) {
|
|
2956
|
+
if (status === "timeout" || status === "error")
|
|
2957
|
+
return "bad";
|
|
2958
|
+
if (status === "dry-run")
|
|
2959
|
+
return "warn";
|
|
2960
|
+
return "good";
|
|
2961
|
+
}
|
|
2962
|
+
function statusLabel(status) {
|
|
2963
|
+
return status ?? "success";
|
|
2964
|
+
}
|
|
2965
|
+
function badge(status) {
|
|
2966
|
+
const label = statusLabel(status);
|
|
2967
|
+
return `<span class="badge ${statusClass(label)}">${escapeHtml(label)}</span>`;
|
|
2968
|
+
}
|
|
2969
|
+
function summarizeDashboard(entries) {
|
|
2970
|
+
const durations = entries.map(metricDuration).filter(Boolean);
|
|
2971
|
+
const success = entries.filter((e) => statusLabel(e.status) === "success").length;
|
|
2972
|
+
const timeout = entries.filter((e) => e.status === "timeout").length;
|
|
2973
|
+
const error = entries.filter((e) => e.status === "error").length;
|
|
2974
|
+
const dryRun = entries.filter((e) => e.status === "dry-run").length;
|
|
2975
|
+
const scored = entries.map((e) => e.verificationScore).filter((v) => typeof v === "number");
|
|
2976
|
+
return {
|
|
2977
|
+
runs: entries.length,
|
|
2978
|
+
success,
|
|
2979
|
+
timeout,
|
|
2980
|
+
error,
|
|
2981
|
+
dryRun,
|
|
2982
|
+
successRate: entries.length ? success / entries.length : 0,
|
|
2983
|
+
avgDuration: Math.round(average(durations)),
|
|
2984
|
+
p95Duration: percentile(durations, 95),
|
|
2985
|
+
totalCalls: entries.reduce((sum, e) => sum + (e.totalCalls ?? 0), 0),
|
|
2986
|
+
totalInput: entries.reduce((sum, e) => sum + (e.totalInput ?? 0), 0),
|
|
2987
|
+
totalOutput: entries.reduce((sum, e) => sum + (e.totalOutput ?? 0), 0),
|
|
2988
|
+
totalSaved: entries.reduce((sum, e) => sum + (e.tokensSaved ?? 0), 0),
|
|
2989
|
+
avgScore: Math.round(average(scored))
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2992
|
+
function groupMetrics(entries, keyFn) {
|
|
2993
|
+
const groups = new Map;
|
|
2994
|
+
for (const entry of entries) {
|
|
2995
|
+
const key = keyFn(entry);
|
|
2996
|
+
if (!key)
|
|
2997
|
+
continue;
|
|
2998
|
+
groups.set(key, [...groups.get(key) ?? [], entry]);
|
|
2999
|
+
}
|
|
3000
|
+
return [...groups.entries()].map(([name, group]) => {
|
|
3001
|
+
const durations = group.map(metricDuration).filter(Boolean);
|
|
3002
|
+
const scores = group.map((e) => e.verificationScore).filter((v) => typeof v === "number");
|
|
3003
|
+
const failures = group.filter((e) => e.status === "timeout" || e.status === "error").length;
|
|
3004
|
+
return {
|
|
3005
|
+
name,
|
|
3006
|
+
runs: group.length,
|
|
3007
|
+
avgDuration: Math.round(average(durations)),
|
|
3008
|
+
p95Duration: percentile(durations, 95),
|
|
3009
|
+
avgScore: Math.round(average(scores)),
|
|
3010
|
+
totalSaved: group.reduce((sum, e) => sum + (e.tokensSaved ?? 0), 0),
|
|
3011
|
+
totalCalls: group.reduce((sum, e) => sum + (e.totalCalls ?? 0), 0),
|
|
3012
|
+
errorRate: group.length ? failures / group.length : 0
|
|
3013
|
+
};
|
|
3014
|
+
}).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
3015
|
+
}
|
|
3016
|
+
function progressBar(value, label = metricPct(value)) {
|
|
3017
|
+
const pct = Math.max(0, Math.min(100, Math.round(value * 100)));
|
|
3018
|
+
return `<div class="meter" title="${escapeHtml(label)}"><span style="width:${pct}%"></span></div>`;
|
|
3019
|
+
}
|
|
3020
|
+
function sparkline(values) {
|
|
3021
|
+
const nums = values.filter((v) => Number.isFinite(v));
|
|
3022
|
+
if (nums.length < 2)
|
|
3023
|
+
return `<div class="empty">Need at least two runs for trend</div>`;
|
|
3024
|
+
const width = 520;
|
|
3025
|
+
const height = 120;
|
|
3026
|
+
const min = Math.min(...nums);
|
|
3027
|
+
const max = Math.max(...nums);
|
|
3028
|
+
const span = Math.max(1, max - min);
|
|
3029
|
+
const points = nums.map((value, i) => {
|
|
3030
|
+
const x = i / Math.max(1, nums.length - 1) * width;
|
|
3031
|
+
const y = height - (value - min) / span * (height - 18) - 9;
|
|
3032
|
+
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
3033
|
+
}).join(" ");
|
|
3034
|
+
const last = nums[nums.length - 1];
|
|
3035
|
+
return `<svg class="spark" viewBox="0 0 ${width} ${height}" role="img" aria-label="Duration trend"><polyline points="${points}" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle cx="${width}" cy="${(height - (last - min) / span * (height - 18) - 9).toFixed(1)}" r="4" fill="currentColor"/><text x="0" y="14">${escapeHtml(metricMs(max))}</text><text x="0" y="${height - 4}">${escapeHtml(metricMs(min))}</text></svg>`;
|
|
3036
|
+
}
|
|
3037
|
+
function metricCard(label, value, detail, tone = "neutral") {
|
|
3038
|
+
return `<article class="card ${tone}"><div class="label">${escapeHtml(label)}</div><div class="value">${escapeHtml(value)}</div><div class="detail">${escapeHtml(detail)}</div></article>`;
|
|
3039
|
+
}
|
|
3040
|
+
function comparisonRows(groups) {
|
|
3041
|
+
if (!groups.length)
|
|
3042
|
+
return `<tr><td colspan="8" class="empty">No data yet</td></tr>`;
|
|
3043
|
+
return groups.map((group) => `<tr>
|
|
3044
|
+
<td><strong>${escapeHtml(group.name)}</strong></td>
|
|
3045
|
+
<td class="num">${metricNum(group.runs)}</td>
|
|
3046
|
+
<td class="num">${escapeHtml(metricMs(group.avgDuration))}</td>
|
|
3047
|
+
<td class="num">${escapeHtml(metricMs(group.p95Duration))}</td>
|
|
3048
|
+
<td class="num">${group.avgScore ? metricNum(group.avgScore) : "\u2014"}</td>
|
|
3049
|
+
<td class="num">${metricNum(group.totalCalls)}</td>
|
|
3050
|
+
<td class="num">${metricNum(group.totalSaved)}</td>
|
|
3051
|
+
<td>${progressBar(1 - group.errorRate, metricPct(1 - group.errorRate) + " reliable")}</td>
|
|
3052
|
+
</tr>`).join(`
|
|
3053
|
+
`);
|
|
3054
|
+
}
|
|
3055
|
+
function phaseRows(entry) {
|
|
3056
|
+
const timings = entry?.phaseTimings ?? [];
|
|
3057
|
+
if (!timings.length)
|
|
3058
|
+
return `<tr><td colspan="3" class="empty">No phase timings yet</td></tr>`;
|
|
3059
|
+
const total = timings.reduce((sum, phase) => sum + phase.durationMs, 0) || 1;
|
|
3060
|
+
return timings.map((phase) => `<tr>
|
|
3061
|
+
<td>${escapeHtml(phase.phase)}</td>
|
|
3062
|
+
<td class="num">${escapeHtml(metricMs(phase.durationMs))}</td>
|
|
3063
|
+
<td>${progressBar(phase.durationMs / total, metricPct(phase.durationMs / total))}</td>
|
|
3064
|
+
</tr>`).join(`
|
|
3065
|
+
`);
|
|
3066
|
+
}
|
|
3067
|
+
function recentRunRows(entries) {
|
|
3068
|
+
if (!entries.length)
|
|
3069
|
+
return `<tr><td colspan="12" class="empty">No runs recorded yet</td></tr>`;
|
|
3070
|
+
return entries.slice(-80).reverse().map((entry) => `<tr>
|
|
3071
|
+
<td class="mono small">${escapeHtml(entry.ts)}</td>
|
|
3072
|
+
<td>${escapeHtml(entry.profile)}</td>
|
|
3073
|
+
<td>${escapeHtml(entry.provider ?? entry.model?.split("/")[0])}</td>
|
|
3074
|
+
<td>${escapeHtml(entry.method)}</td>
|
|
3075
|
+
<td>${escapeHtml(entry.runType)}</td>
|
|
3076
|
+
<td>${badge(entry.status)}</td>
|
|
3077
|
+
<td class="num">${escapeHtml(metricMs(metricDuration(entry)))}</td>
|
|
3078
|
+
<td class="num">${typeof entry.verificationScore === "number" ? metricNum(entry.verificationScore) : "\u2014"}</td>
|
|
3079
|
+
<td class="num">${typeof entry.tokensSaved === "number" ? metricNum(entry.tokensSaved) : "\u2014"}</td>
|
|
3080
|
+
<td class="num">${metricNum(entry.totalCalls ?? 0)}</td>
|
|
3081
|
+
<td class="num">${typeof entry.extractionCacheHitRate === "number" ? metricPct(entry.extractionCacheHitRate) : "\u2014"}</td>
|
|
3082
|
+
<td class="mono small reason">${escapeHtml(entry.fallbackReason ?? entry.extractionCacheMissReason ?? "")}</td>
|
|
3083
|
+
</tr>`).join(`
|
|
3084
|
+
`);
|
|
3085
|
+
}
|
|
3086
|
+
function dashboardCss() {
|
|
3087
|
+
return `:root{color-scheme:dark;--bg:#08111f;--surface:#0f172a;--surface2:#111c33;--card:#111827;--text:#e5edf8;--muted:#8fa3bf;--line:#24324a;--accent:#60a5fa;--good:#22c55e;--bad:#fb7185;--warn:#fbbf24;--shadow:0 18px 50px rgba(0,0,0,.28)}@media(prefers-color-scheme:light){:root{color-scheme:light;--bg:#f4f7fb;--surface:#ffffff;--surface2:#f8fafc;--card:#ffffff;--text:#0f172a;--muted:#64748b;--line:#e2e8f0;--shadow:0 18px 50px rgba(15,23,42,.08)}}*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at top left,rgba(96,165,250,.20),transparent 34rem),var(--bg);color:var(--text);font:14px/1.5 Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}main{max-width:1280px;margin:0 auto;padding:32px}header{display:flex;justify-content:space-between;gap:20px;align-items:flex-start;margin-bottom:24px}.eyebrow{color:var(--accent);font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-size:12px}h1{font-size:32px;line-height:1.1;margin:6px 0 6px}.muted,.detail{color:var(--muted)}.cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin:20px 0 22px}.card{background:linear-gradient(180deg,rgba(255,255,255,.035),transparent),var(--card);border:1px solid var(--line);border-radius:18px;padding:16px;box-shadow:var(--shadow)}.card.good{border-color:rgba(34,197,94,.45)}.card.warn{border-color:rgba(251,191,36,.45)}.card.bad{border-color:rgba(251,113,133,.5)}.label{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;font-weight:700}.value{font-size:28px;font-weight:800;margin-top:6px}.layout{display:grid;grid-template-columns:1.15fr .85fr;gap:18px}.panel{background:var(--surface);border:1px solid var(--line);border-radius:18px;box-shadow:var(--shadow);overflow:hidden}.panel h2{display:flex;align-items:center;justify-content:space-between;margin:0;padding:15px 18px;background:linear-gradient(180deg,rgba(255,255,255,.035),transparent),var(--surface2);font-size:15px}.table-wrap{overflow:auto;max-height:560px}table{border-collapse:separate;border-spacing:0;width:100%}th,td{border-bottom:1px solid var(--line);padding:9px 11px;text-align:left;vertical-align:middle;white-space:nowrap}th{position:sticky;top:0;z-index:1;background:var(--surface2);color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em}tr:hover td{background:rgba(96,165,250,.06)}.num{text-align:right}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.small{font-size:12px}.reason{max-width:280px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.badge{display:inline-flex;align-items:center;border-radius:999px;padding:3px 9px;font-size:12px;font-weight:800}.badge.good{background:rgba(34,197,94,.14);color:var(--good)}.badge.bad{background:rgba(251,113,133,.16);color:var(--bad)}.badge.warn{background:rgba(251,191,36,.16);color:var(--warn)}.meter{height:8px;background:rgba(148,163,184,.22);border-radius:99px;min-width:96px;overflow:hidden}.meter span{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--accent),var(--good))}.spark{width:100%;height:160px;color:var(--accent);padding:18px}.spark text{fill:var(--muted);font-size:12px}.empty{padding:18px;color:var(--muted);text-align:center}pre{white-space:pre-wrap;background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:16px;overflow:auto}.section{margin-top:18px}.two{display:grid;grid-template-columns:1fr 1fr;gap:18px}@media(max-width:960px){main{padding:20px}.cards,.layout,.two{grid-template-columns:1fr}header{display:block}th,td{padding:8px}.value{font-size:24px}}`;
|
|
3088
|
+
}
|
|
3089
|
+
function buildMetricsReport(entries = readMetricsLog(100)) {
|
|
3090
|
+
if (!entries.length)
|
|
3091
|
+
return "No smart-compact metrics recorded yet.";
|
|
3092
|
+
const summary = summarizeDashboard(entries);
|
|
3093
|
+
const byProfile = groupMetrics(entries, (e) => e.profile);
|
|
3094
|
+
const byProvider = groupMetrics(entries, (e) => e.provider ?? e.model?.split("/")[0]);
|
|
3095
|
+
const summarizeGroup = (group) => "- " + group.name + ": n=" + group.runs + ", avg=" + group.avgDuration + "ms, p95=" + group.p95Duration + "ms, score=" + group.avgScore + ", saved=" + group.totalSaved + "t, reliability=" + metricPct(1 - group.errorRate);
|
|
3096
|
+
const extractionCacheRuns = entries.filter((e) => typeof e.extractionCacheHitRate === "number");
|
|
3097
|
+
const extractionCacheAvg = average(extractionCacheRuns.map((e) => e.extractionCacheHitRate ?? 0));
|
|
3098
|
+
return [
|
|
3099
|
+
"# Smart Compact Metrics",
|
|
3100
|
+
"",
|
|
3101
|
+
"Runs: " + summary.runs + " (success " + summary.success + ", dry-run " + summary.dryRun + ", timeout " + summary.timeout + ", error " + summary.error + ")",
|
|
3102
|
+
"Reliability: " + metricPct(summary.successRate),
|
|
3103
|
+
"Latency: avg " + summary.avgDuration + "ms, p95 " + summary.p95Duration + "ms",
|
|
3104
|
+
"LLM calls: " + summary.totalCalls + ", input " + summary.totalInput + "t, output " + summary.totalOutput + "t",
|
|
3105
|
+
"Extraction cache: avg " + (extractionCacheRuns.length ? metricPct(extractionCacheAvg) : "\u2014") + " across " + extractionCacheRuns.length + " measured run(s)",
|
|
3106
|
+
"Tokens saved: " + summary.totalSaved + "t, average verification score: " + summary.avgScore,
|
|
3107
|
+
"",
|
|
3108
|
+
"## Profile comparison",
|
|
3109
|
+
...byProfile.map(summarizeGroup),
|
|
3110
|
+
"",
|
|
3111
|
+
"## Provider comparison",
|
|
3112
|
+
...byProvider.map(summarizeGroup)
|
|
3113
|
+
].join(`
|
|
3114
|
+
`);
|
|
3115
|
+
}
|
|
3116
|
+
function writeMetricsDashboard(entries = readMetricsLog(200)) {
|
|
3117
|
+
try {
|
|
3118
|
+
const summary = summarizeDashboard(entries);
|
|
3119
|
+
const latest = entries[entries.length - 1];
|
|
3120
|
+
const report = buildMetricsReport(entries);
|
|
3121
|
+
const profileGroups = groupMetrics(entries, (e) => e.profile);
|
|
3122
|
+
const providerGroups = groupMetrics(entries, (e) => e.provider ?? e.model?.split("/")[0]);
|
|
3123
|
+
const healthTone = summary.error + summary.timeout > 0 ? "warn" : "good";
|
|
3124
|
+
const html = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Smart Compact Metrics</title><style>${dashboardCss()}</style></head><body><main>
|
|
3125
|
+
<header><div><div class="eyebrow">pi-smart-compact</div><h1>Operational Metrics</h1><div class="muted">Generated ${escapeHtml(new Date().toISOString())} \xB7 ${metricNum(entries.length)} recent runs \xB7 local file dashboard</div></div><div>${badge(latest?.status)} ${latest ? `<span class="muted">latest ${escapeHtml(latest.profile ?? "unknown")}</span>` : ""}</div></header>
|
|
3126
|
+
<section class="cards">
|
|
3127
|
+
${metricCard("Reliability", metricPct(summary.successRate), `${summary.success} success \xB7 ${summary.timeout} timeout \xB7 ${summary.error} error`, healthTone)}
|
|
3128
|
+
${metricCard("Avg duration", metricMs(summary.avgDuration), `p95 ${metricMs(summary.p95Duration)}`)}
|
|
3129
|
+
${metricCard("LLM calls", compactNumber(summary.totalCalls), `${compactNumber(summary.totalInput)} input \xB7 ${compactNumber(summary.totalOutput)} output`)}
|
|
3130
|
+
${metricCard("Tokens saved", compactNumber(summary.totalSaved), `avg score ${summary.avgScore || "\u2014"}`)}
|
|
3131
|
+
</section>
|
|
3132
|
+
<section class="layout">
|
|
3133
|
+
<div class="panel"><h2>Duration trend <span class="muted">last ${Math.min(entries.length, 80)} runs</span></h2>${sparkline(entries.slice(-80).map(metricDuration))}</div>
|
|
3134
|
+
<div class="panel"><h2>Latest phase timings</h2><div class="table-wrap"><table><thead><tr><th>Phase</th><th class="num">Duration</th><th>Share</th></tr></thead><tbody>${phaseRows(latest)}</tbody></table></div></div>
|
|
3135
|
+
</section>
|
|
3136
|
+
<section class="two section">
|
|
3137
|
+
<div class="panel"><h2>Profile comparison</h2><div class="table-wrap"><table><thead><tr><th>Profile</th><th class="num">Runs</th><th class="num">Avg</th><th class="num">p95</th><th class="num">Score</th><th class="num">Calls</th><th class="num">Saved</th><th>Reliability</th></tr></thead><tbody>${comparisonRows(profileGroups)}</tbody></table></div></div>
|
|
3138
|
+
<div class="panel"><h2>Provider comparison</h2><div class="table-wrap"><table><thead><tr><th>Provider</th><th class="num">Runs</th><th class="num">Avg</th><th class="num">p95</th><th class="num">Score</th><th class="num">Calls</th><th class="num">Saved</th><th>Reliability</th></tr></thead><tbody>${comparisonRows(providerGroups)}</tbody></table></div></div>
|
|
3139
|
+
</section>
|
|
3140
|
+
<section class="panel section"><h2>Recent runs</h2><div class="table-wrap"><table><thead><tr><th>Time</th><th>Profile</th><th>Provider</th><th>Method</th><th>Run</th><th>Status</th><th class="num">Duration</th><th class="num">Score</th><th class="num">Saved</th><th class="num">Calls</th><th class="num">Ext cache</th><th>Reason</th></tr></thead><tbody>${recentRunRows(entries)}</tbody></table></div></section>
|
|
3141
|
+
<section class="section"><h2>Raw text report</h2><pre>${escapeHtml(report)}</pre></section>
|
|
3142
|
+
</main></body></html>`;
|
|
3143
|
+
const fp = metricsDashboardFile();
|
|
3144
|
+
atomicWriteFileSync(fp, html);
|
|
3145
|
+
return fp;
|
|
3146
|
+
} catch (e) {
|
|
3147
|
+
warn("writeMetricsDashboard failed", e);
|
|
3148
|
+
return null;
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3125
3152
|
// src/app/run-smart-compact.ts
|
|
3126
3153
|
init_overlays();
|
|
3127
3154
|
init_logger();
|
|
@@ -3501,6 +3528,7 @@ function pruneRedundant(msgs, precomputedTcIdx) {
|
|
|
3501
3528
|
}
|
|
3502
3529
|
const tcIdx = ensuredIndex;
|
|
3503
3530
|
const keep = new Set(msgs.map((_, i2) => i2));
|
|
3531
|
+
const removedToolCallIds = new Set;
|
|
3504
3532
|
const reasonMap = new Map;
|
|
3505
3533
|
const readIndices = new Map;
|
|
3506
3534
|
for (let i2 = 0;i2 < msgs.length; i2++) {
|
|
@@ -3518,10 +3546,10 @@ function pruneRedundant(msgs, precomputedTcIdx) {
|
|
|
3518
3546
|
}
|
|
3519
3547
|
for (const [fp, indices] of readIndices) {
|
|
3520
3548
|
for (let j = 0;j < indices.length - 1; j++) {
|
|
3549
|
+
const toolCallId = msgs[indices[j]].toolCallId ?? "";
|
|
3521
3550
|
keep.delete(indices[j]);
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
keep.delete(tc.msgIndex);
|
|
3551
|
+
if (tcIdx.has(toolCallId))
|
|
3552
|
+
removedToolCallIds.add(toolCallId);
|
|
3525
3553
|
}
|
|
3526
3554
|
if (indices.length > 1) {
|
|
3527
3555
|
reasonMap.set("Duplicate file reads", (reasonMap.get("Duplicate file reads") ?? 0) + indices.length - 1);
|
|
@@ -3531,8 +3559,9 @@ function pruneRedundant(msgs, precomputedTcIdx) {
|
|
|
3531
3559
|
for (let i2 = 0;i2 < msgs.length; i2++) {
|
|
3532
3560
|
if (msgs[i2].role !== "toolResult" || !msgs[i2].isError)
|
|
3533
3561
|
continue;
|
|
3534
|
-
const
|
|
3535
|
-
|
|
3562
|
+
const toolCallId = msgs[i2].toolCallId ?? "";
|
|
3563
|
+
const tc = tcIdx.get(toolCallId);
|
|
3564
|
+
failedToolResults.push({ index: i2, tool: tc?.name ?? "unknown", toolCallId });
|
|
3536
3565
|
}
|
|
3537
3566
|
let i = 0;
|
|
3538
3567
|
while (i < failedToolResults.length) {
|
|
@@ -3544,8 +3573,8 @@ function pruneRedundant(msgs, precomputedTcIdx) {
|
|
|
3544
3573
|
if (j - i >= 3) {
|
|
3545
3574
|
for (let k = i + 1;k < j - 1; k++) {
|
|
3546
3575
|
keep.delete(failedToolResults[k].index);
|
|
3547
|
-
if (failedToolResults[k].
|
|
3548
|
-
|
|
3576
|
+
if (tcIdx.has(failedToolResults[k].toolCallId))
|
|
3577
|
+
removedToolCallIds.add(failedToolResults[k].toolCallId);
|
|
3549
3578
|
}
|
|
3550
3579
|
reasonMap.set("Collapsed error chains", (reasonMap.get("Collapsed error chains") ?? 0) + (j - i - 2));
|
|
3551
3580
|
}
|
|
@@ -3583,22 +3612,57 @@ function pruneRedundant(msgs, precomputedTcIdx) {
|
|
|
3583
3612
|
const half = Math.floor(MAX_TOOL_OUTPUT_CHARS / 2);
|
|
3584
3613
|
for (let idx = 0;idx < msgs.length; idx++) {
|
|
3585
3614
|
const m = msgs[idx];
|
|
3586
|
-
const
|
|
3587
|
-
if (
|
|
3588
|
-
originalTokens += estimateTokens(
|
|
3615
|
+
const originalText = extractText(m.content);
|
|
3616
|
+
if (originalText.length > 0)
|
|
3617
|
+
originalTokens += estimateTokens(originalText);
|
|
3589
3618
|
if (!keep.has(idx))
|
|
3590
3619
|
continue;
|
|
3591
|
-
|
|
3592
|
-
if (m.role === "
|
|
3620
|
+
let keptMessage = m;
|
|
3621
|
+
if (m.role === "assistant" && removedToolCallIds.size > 0 && Array.isArray(m.content)) {
|
|
3622
|
+
let changed = false;
|
|
3623
|
+
const content = [];
|
|
3624
|
+
for (const block of m.content) {
|
|
3625
|
+
if (!isToolCallBlock(block)) {
|
|
3626
|
+
content.push(block);
|
|
3627
|
+
continue;
|
|
3628
|
+
}
|
|
3629
|
+
if (block.name === "multi_tool_use.parallel" && Array.isArray(block.arguments?.tool_uses)) {
|
|
3630
|
+
const tools = block.arguments.tool_uses;
|
|
3631
|
+
const retained = tools.filter((tool, toolIndex) => {
|
|
3632
|
+
const id = typeof tool.id === "string" ? tool.id : block.id ? block.id + "_" + toolIndex : "mtu_" + idx + "_" + toolIndex;
|
|
3633
|
+
return !removedToolCallIds.has(id);
|
|
3634
|
+
});
|
|
3635
|
+
if (retained.length !== tools.length)
|
|
3636
|
+
changed = true;
|
|
3637
|
+
if (retained.length > 0) {
|
|
3638
|
+
content.push(retained.length === tools.length ? block : { ...block, arguments: { ...block.arguments, tool_uses: retained } });
|
|
3639
|
+
}
|
|
3640
|
+
continue;
|
|
3641
|
+
}
|
|
3642
|
+
if (block.id && removedToolCallIds.has(block.id)) {
|
|
3643
|
+
changed = true;
|
|
3644
|
+
continue;
|
|
3645
|
+
}
|
|
3646
|
+
content.push(block);
|
|
3647
|
+
}
|
|
3648
|
+
if (changed) {
|
|
3649
|
+
if (content.length === 0)
|
|
3650
|
+
continue;
|
|
3651
|
+
keptMessage = { ...m, content };
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
const text = extractText(keptMessage.content);
|
|
3655
|
+
const protectFromTruncation = keptMessage.role === "toolResult" && text.length > MAX_TOOL_OUTPUT_CHARS && text.length < ERROR_SCAN_MAX_LEN && LIKELY_ERROR_RE.test(text);
|
|
3656
|
+
if (keptMessage.role === "toolResult" && text.length > MAX_TOOL_OUTPUT_CHARS && !protectFromTruncation) {
|
|
3593
3657
|
const head = text.slice(0, half);
|
|
3594
3658
|
const tail = text.slice(-half);
|
|
3595
3659
|
const truncated = head + `
|
|
3596
3660
|
... [truncated ` + (text.length - MAX_TOOL_OUTPUT_CHARS) + ` chars] ...
|
|
3597
3661
|
` + tail;
|
|
3598
|
-
finalMsgs.push({ ...
|
|
3662
|
+
finalMsgs.push({ ...keptMessage, content: [{ type: "text", text: truncated }] });
|
|
3599
3663
|
prunedTokens += estimateTokens(truncated);
|
|
3600
3664
|
} else {
|
|
3601
|
-
finalMsgs.push(
|
|
3665
|
+
finalMsgs.push(keptMessage);
|
|
3602
3666
|
if (text.length > 0)
|
|
3603
3667
|
prunedTokens += estimateTokens(text);
|
|
3604
3668
|
}
|
|
@@ -3884,7 +3948,6 @@ function extractWithCache(rc) {
|
|
|
3884
3948
|
rc.vlog("Extraction cache ignored: legacy entry lacks keptEntryIds/keptEntryIdsFp");
|
|
3885
3949
|
}
|
|
3886
3950
|
}
|
|
3887
|
-
const prunedTcIdx = buildToolCallIndex(rc.llmMessages);
|
|
3888
3951
|
if (cacheUsable && cachedExt) {
|
|
3889
3952
|
const newMsgs = rc.llmMessages.slice(cachedExt.messageCount);
|
|
3890
3953
|
const deltaTcIdx = buildToolCallIndex(newMsgs);
|
|
@@ -3895,6 +3958,7 @@ function extractWithCache(rc) {
|
|
|
3895
3958
|
missReason = undefined;
|
|
3896
3959
|
recordExtractionCacheHit(rc.services);
|
|
3897
3960
|
} else {
|
|
3961
|
+
const prunedTcIdx = buildToolCallIndex(rc.llmMessages);
|
|
3898
3962
|
extraction = extractStructured(rc.llmMessages, rc.profileCfg, prunedTcIdx);
|
|
3899
3963
|
rc.notify("Phase 1 Full: " + extraction.modifiedFiles.length + " files, " + extraction.errors.length + " errors", "info");
|
|
3900
3964
|
rc.vlog("Full extraction \u2014 " + rc.llmMessages.length + " messages, tier=" + rc.tier);
|
|
@@ -5342,6 +5406,9 @@ function computeDelta(prev, current) {
|
|
|
5342
5406
|
previousGoal: goalChanged ? prev.goal : null
|
|
5343
5407
|
};
|
|
5344
5408
|
}
|
|
5409
|
+
function hasDeltaChanges(delta) {
|
|
5410
|
+
return delta.goalChanged || delta.removedDecisions.length > 0 || delta.resolvedLoops.length > 0 || delta.newLoops.length > 0 || delta.newDecisions.length > 0 || delta.resolvedErrors.length > 0 || delta.newErrors.length > 0 || delta.newModifiedFiles.length > 0;
|
|
5411
|
+
}
|
|
5345
5412
|
function formatDeltaSection(delta) {
|
|
5346
5413
|
const lines = ["## Changes Since Last Compaction", ""];
|
|
5347
5414
|
if (delta.goalChanged) {
|
|
@@ -5359,6 +5426,9 @@ function formatDeltaSection(delta) {
|
|
|
5359
5426
|
if (delta.newDecisions.length) {
|
|
5360
5427
|
lines.push("- **New decisions**: " + delta.newDecisions.map((s) => s.slice(0, TRUNC.SNIPPET)).join("; "));
|
|
5361
5428
|
}
|
|
5429
|
+
if (delta.removedDecisions.length) {
|
|
5430
|
+
lines.push("- **Removed decisions**: " + delta.removedDecisions.map((s) => "~~" + s.slice(0, TRUNC.SNIPPET) + "~~").join("; "));
|
|
5431
|
+
}
|
|
5362
5432
|
if (delta.resolvedErrors.length) {
|
|
5363
5433
|
lines.push("- **Resolved errors**: " + delta.resolvedErrors.map((s) => s.slice(0, TRUNC.DECISION_DETAIL)).join("; "));
|
|
5364
5434
|
}
|
|
@@ -5373,8 +5443,7 @@ function formatDeltaSection(delta) {
|
|
|
5373
5443
|
`);
|
|
5374
5444
|
}
|
|
5375
5445
|
function injectDeltaSection(summary, delta) {
|
|
5376
|
-
|
|
5377
|
-
if (!hasChanges)
|
|
5446
|
+
if (!hasDeltaChanges(delta))
|
|
5378
5447
|
return summary;
|
|
5379
5448
|
const body = formatDeltaSection(delta).replace(/^## Changes Since Last Compaction\s*\n?/i, "").trim();
|
|
5380
5449
|
if (!body)
|
|
@@ -5512,7 +5581,9 @@ function logDamageReport(sessionId, report, details) {
|
|
|
5512
5581
|
signals: report.signals.length,
|
|
5513
5582
|
summary: report.summary
|
|
5514
5583
|
};
|
|
5515
|
-
|
|
5584
|
+
const logPath = damageReportsFile();
|
|
5585
|
+
appendLineLocked(logPath, JSON.stringify(entry));
|
|
5586
|
+
scheduleFileTailTrim(logPath, RUNTIME_LOG_MAX_BYTES);
|
|
5516
5587
|
} catch (e) {
|
|
5517
5588
|
warn("logDamageReport failed", e);
|
|
5518
5589
|
}
|
|
@@ -5564,7 +5635,7 @@ function buildState(rc) {
|
|
|
5564
5635
|
const prevState = loadCompactionState(rc.projectId);
|
|
5565
5636
|
if (prevState) {
|
|
5566
5637
|
const delta = computeDelta(prevState, compactionState);
|
|
5567
|
-
if (delta
|
|
5638
|
+
if (hasDeltaChanges(delta)) {
|
|
5568
5639
|
summary = injectDeltaSection(summary, delta);
|
|
5569
5640
|
rc.notify("Delta: " + delta.newLoops.length + " new loops, " + delta.resolvedLoops.length + " resolved, " + delta.newModifiedFiles.length + " new files", "info");
|
|
5570
5641
|
}
|
|
@@ -5788,6 +5859,16 @@ async function runSmartCompact(opts) {
|
|
|
5788
5859
|
}
|
|
5789
5860
|
opts.isRunning.value = true;
|
|
5790
5861
|
const base = makeBase(opts);
|
|
5862
|
+
const abortFromHost = () => {
|
|
5863
|
+
base.cancellation.timedOut = true;
|
|
5864
|
+
base.cancellation.controller.abort();
|
|
5865
|
+
};
|
|
5866
|
+
if (opts.abortSignal) {
|
|
5867
|
+
if (opts.abortSignal.aborted)
|
|
5868
|
+
abortFromHost();
|
|
5869
|
+
else
|
|
5870
|
+
opts.abortSignal.addEventListener("abort", abortFromHost, { once: true });
|
|
5871
|
+
}
|
|
5791
5872
|
let finalRc = null;
|
|
5792
5873
|
let failureSummaryFields = { profile: opts.profile };
|
|
5793
5874
|
if (opts.cancellationOut) {
|
|
@@ -5805,6 +5886,8 @@ async function runSmartCompact(opts) {
|
|
|
5805
5886
|
};
|
|
5806
5887
|
}
|
|
5807
5888
|
try {
|
|
5889
|
+
if (base.cancellation.signal.aborted)
|
|
5890
|
+
return;
|
|
5808
5891
|
const prepared = await prepareRun(base);
|
|
5809
5892
|
if (!prepared)
|
|
5810
5893
|
return;
|
|
@@ -5882,6 +5965,7 @@ async function runSmartCompact(opts) {
|
|
|
5882
5965
|
recordFailureMetrics(finalRc ?? base, err, failureSummaryFields);
|
|
5883
5966
|
throw err;
|
|
5884
5967
|
} finally {
|
|
5968
|
+
opts.abortSignal?.removeEventListener("abort", abortFromHost);
|
|
5885
5969
|
if (base.cancellation.timeoutId)
|
|
5886
5970
|
clearTimeout(base.cancellation.timeoutId);
|
|
5887
5971
|
opts.isRunning.value = false;
|
|
@@ -6202,7 +6286,7 @@ function smartCompactExtension(pi) {
|
|
|
6202
6286
|
dashboard: { type: "boolean", description: "Write a local HTML metrics dashboard and return its path." }
|
|
6203
6287
|
}
|
|
6204
6288
|
},
|
|
6205
|
-
async execute(_id, params,
|
|
6289
|
+
async execute(_id, params, signal, _onUp, ctx) {
|
|
6206
6290
|
const profile = params.profile === "light" || params.profile === "balanced" || params.profile === "aggressive" ? params.profile : undefined;
|
|
6207
6291
|
const verbose = !!params.verbose;
|
|
6208
6292
|
const dryRun = !!params.dry_run;
|
|
@@ -6232,7 +6316,7 @@ Dashboard: ` + fp : "") }], details: undefined };
|
|
|
6232
6316
|
}
|
|
6233
6317
|
try {
|
|
6234
6318
|
const toolStart = Date.now();
|
|
6235
|
-
await runSmartCompact({ ctx, summaryModel: sumModel, segModel: segModel ?? sumModel, profile: resolvedProfile, verbose, dryRun, pendingRef, isRunning, autoTriggered: true, skipCompact: true });
|
|
6319
|
+
await runSmartCompact({ ctx, summaryModel: sumModel, segModel: segModel ?? sumModel, profile: resolvedProfile, verbose, dryRun, pendingRef, isRunning, autoTriggered: true, skipCompact: true, abortSignal: signal });
|
|
6236
6320
|
const toolSecs = ((Date.now() - toolStart) / 1000).toFixed(1);
|
|
6237
6321
|
const staged = pendingRef.peek();
|
|
6238
6322
|
if (staged) {
|
package/dist/infra/fs.d.ts
CHANGED
|
@@ -52,6 +52,10 @@ export declare function acquireLockSync(target: string): () => void;
|
|
|
52
52
|
* `line` does not already end with one.
|
|
53
53
|
*/
|
|
54
54
|
export declare function appendLineLocked(target: string, line: string): void;
|
|
55
|
+
/** Keep only complete trailing lines that fit within `maxBytes`. */
|
|
56
|
+
export declare function trimFileTailLocked(target: string, maxBytes: number): void;
|
|
57
|
+
/** Defer disk retention work to a later event-loop turn and coalesce writers. */
|
|
58
|
+
export declare function scheduleFileTailTrim(target: string, maxBytes: number): void;
|
|
55
59
|
export declare function readJsonSync<T>(target: string): T | null;
|
|
56
60
|
export declare function writeJsonSync(target: string, value: unknown, pretty?: boolean): void;
|
|
57
61
|
//# sourceMappingURL=fs.d.ts.map
|
package/dist/infra/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/infra/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAYH,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQ3C;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/D;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAWnF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CA2D1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAQnE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CASxD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,IAAI,CAElF"}
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/infra/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAYH,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQ3C;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/D;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAWnF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CA2D1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAQnE;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAgBzE;AAID,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ3E;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CASxD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,IAAI,CAElF"}
|
package/dist/infra/services.d.ts
CHANGED
|
@@ -107,6 +107,6 @@ export declare function createServices(overrides?: Partial<SmartCompactServices>
|
|
|
107
107
|
export declare function getDefaultServices(): SmartCompactServices;
|
|
108
108
|
/** Swap the default container; tests use this to inject a clock/llm. */
|
|
109
109
|
export declare function setDefaultServices(services: SmartCompactServices): void;
|
|
110
|
-
/** Reset
|
|
110
|
+
/** Reset the legacy/test default container. Production runs do not call this. */
|
|
111
111
|
export declare function resetDefaultServices(): void;
|
|
112
112
|
//# sourceMappingURL=services.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/infra/services.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6D;IACrF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAc,EAAyB;IAExD,wEAAwE;IACxE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAKjD;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAElD;IAED,8DAA8D;IAC9D,IAAI,IAAI,MAAM,CAA8B;CAC7C;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,YAAY,UAAU,SAAqB,EAAmC;IAE9E,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAOlC;IAED,QAAQ,IAAI,aAAa,EAAE,CAA0B;IACrD,KAAK,IAAI,IAAI,CAAyB;IAEtC,OAAO,IAAI;QACT,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAC5D,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;KACjE,CAeA;CACF;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IAEnB,SAAS,IAAI,IAAI,CAAiB;IAClC,UAAU,IAAI,IAAI,CAAmB;IAErC,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAG5D;IAED,KAAK,IAAI,IAAI,CAAoC;CAClD;AAED,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,EAAE,gBAAgB,CAAC;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,oBAAoB,CAalG;
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/infra/services.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6D;IACrF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAc,EAAyB;IAExD,wEAAwE;IACxE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAKjD;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAElD;IAED,8DAA8D;IAC9D,IAAI,IAAI,MAAM,CAA8B;CAC7C;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,YAAY,UAAU,SAAqB,EAAmC;IAE9E,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAOlC;IAED,QAAQ,IAAI,aAAa,EAAE,CAA0B;IACrD,KAAK,IAAI,IAAI,CAAyB;IAEtC,OAAO,IAAI;QACT,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAC5D,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;KACjE,CAeA;CACF;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IAEnB,SAAS,IAAI,IAAI,CAAiB;IAClC,UAAU,IAAI,IAAI,CAAmB;IAErC,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAG5D;IAED,KAAK,IAAI,IAAI,CAAoC;CAClD;AAED,oCAAoC;AACpC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,EAAE,gBAAgB,CAAC;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,oBAAoB,CAalG;AAWD,wBAAgB,kBAAkB,IAAI,oBAAoB,CAAqB;AAE/E,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAyB;AAEjG,iFAAiF;AACjF,wBAAgB,oBAAoB,IAAI,IAAI,CAAiC"}
|
package/dist/phases/explore.d.ts
CHANGED
|
@@ -20,13 +20,10 @@ export declare function fallbackExplorationReport(llmMessages: LlmMessage[]): Ex
|
|
|
20
20
|
/**
|
|
21
21
|
* Top-level exploration entry point.
|
|
22
22
|
*
|
|
23
|
-
* `services` is threaded in explicitly
|
|
24
|
-
* `getDefaultServices()`
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `toolSupport` cache. The optional fallback to `getDefaultServices()` is
|
|
28
|
-
* preserved for direct callers that haven't been migrated yet (legacy
|
|
29
|
-
* tests, REPL use).
|
|
23
|
+
* `services` is threaded in explicitly so concurrent production runs never
|
|
24
|
+
* share mutable tool-support state. The optional `getDefaultServices()`
|
|
25
|
+
* fallback exists only for legacy direct callers and test/REPL use; the
|
|
26
|
+
* production orchestrator always supplies a run-scoped container.
|
|
30
27
|
*/
|
|
31
28
|
export declare function exploreConversation(llmMessages: LlmMessage[], extraction: StructuredExtraction, model: Model<Api>, auth: {
|
|
32
29
|
apiKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/phases/explore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAwC,MAAM,uBAAuB,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAQtG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQjE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAcvE;AAoCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAsFpI;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAmCjG;AA0CD,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CA2B9G;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAOtF;AAED
|
|
1
|
+
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/phases/explore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAwC,MAAM,uBAAuB,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAQtG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQjE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAcvE;AAoCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAsFpI;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAmCjG;AA0CD,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CA2B9G;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAOtF;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,oBAAoB,EAC3D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAC7E,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC7D,MAAM,CAAC,EAAE,WAAW,EAAE,SAAS,SAAyB,EACxD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,KAAK,IAAI,EAC/E,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAAC,CA+IhF;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAC7E,WAAW,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,oBAAoB,EAC3D,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC7D,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAiB5B;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,oBAAoB,EAC3D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAC7E,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC7D,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAsB5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-format.d.ts","sourceRoot":"","sources":["../../src/ui/dashboard-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,aAAa,CAAC;AAE5E,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAEjE;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"dashboard-format.d.ts","sourceRoot":"","sources":["../../src/ui/dashboard-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,aAAa,CAAC;AAE5E,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAEjE;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAI3C;AAMD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE3D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,GAAG,MAAM,CAE1E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAIlF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAEzE;AAOD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBhG;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAmBnH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAOzE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompactMetricsEntry } from "../types.ts";
|
|
2
|
+
export declare function buildMetricsReport(entries?: CompactMetricsEntry[]): string;
|
|
3
|
+
export declare function writeMetricsDashboard(entries?: CompactMetricsEntry[]): string | null;
|
|
4
|
+
//# sourceMappingURL=metrics-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-report.d.ts","sourceRoot":"","sources":["../../src/ui/metrics-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA4LvD,wBAAgB,kBAAkB,CAAC,OAAO,wBAAsB,GAAG,MAAM,CAwBxE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,wBAAsB,GAAG,MAAM,GAAG,IAAI,CA+BlF"}
|
package/dist/utils/cache.d.ts
CHANGED
|
@@ -80,6 +80,4 @@ export declare function appendMetricsLog(sessionId: string, extra: Partial<Omit<
|
|
|
80
80
|
* - Returned in chronological order (oldest -> newest within the window).
|
|
81
81
|
*/
|
|
82
82
|
export declare function readMetricsLog(limit?: number): CompactMetricsEntry[];
|
|
83
|
-
export declare function buildMetricsReport(entries?: CompactMetricsEntry[]): string;
|
|
84
|
-
export declare function writeMetricsDashboard(entries?: CompactMetricsEntry[]): string | null;
|
|
85
83
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGjI,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAKnF,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAYrF,wBAAgB,SAAS,CACvB,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,SAAS,EACzC,QAAQ,EAAE,oBAAoB,GAC7B,iBAAiB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAY5C;AAWD,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAgC;AAEpH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAO9F;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAUlM;AAKD,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,iBAAiB,EACvB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAuC3B;AAUD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAEzH;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAA+C;AAC7H,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAgD;AAE/H;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,IAAI,CAUN;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAS/E;AAwCD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,oBAAoB,CAoCpI;AAGD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,eAAe,GAAG,YAAY,GAAG,cAAc,CAAC,CAAC,GAAG,SAAS,EACzK,QAAQ,EAAE,oBAAoB,GAC7B,IAAI,CAeN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,SAAM,GAAG,mBAAmB,EAAE,CAkCjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"damage.d.ts","sourceRoot":"","sources":["../../src/utils/damage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUnE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,eAAe,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB;mEAC+D;IAC/D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AASD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,UAAU,EAAE,EAC1B,OAAO,EAAE,mBAAmB,GAC3B,YAAY,CA2Fd;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,GAC3B,IAAI,
|
|
1
|
+
{"version":3,"file":"damage.d.ts","sourceRoot":"","sources":["../../src/utils/damage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUnE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,eAAe,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB;mEAC+D;IAC/D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AASD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,UAAU,EAAE,EAC1B,OAAO,EAAE,mBAAmB,GAC3B,YAAY,CA2Fd;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CAiBN;AAID;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAO9E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKhE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pruning.d.ts","sourceRoot":"","sources":["../../src/utils/pruning.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAmC,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGtF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD;;;;;;;OAOG;IACH,aAAa,EAAE,aAAa,CAAC;CAC9B;AAYD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,gBAAgB,CAAC,EAAE,aAAa,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"pruning.d.ts","sourceRoot":"","sources":["../../src/utils/pruning.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAmC,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGtF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD;;;;;;;OAOG;IACH,aAAa,EAAE,aAAa,CAAC;CAC9B;AAYD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,gBAAgB,CAAC,EAAE,aAAa,GAAG,aAAa,CAoNlG"}
|
package/dist/utils/state.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ export interface CompactionDelta {
|
|
|
52
52
|
previousGoal: string | null;
|
|
53
53
|
}
|
|
54
54
|
export declare function computeDelta(prev: CompactionState, current: CompactionState): CompactionDelta;
|
|
55
|
+
export declare function hasDeltaChanges(delta: CompactionDelta): boolean;
|
|
55
56
|
/**
|
|
56
57
|
* Format delta as Markdown section for injection into summary.
|
|
57
58
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAanH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAInF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAa7E;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,oBAAoB,EAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,eAAe,CAsDjB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAYrF;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,sDAAsD;IACtD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,eAAe,CAsD7F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/utils/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAanH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAInF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAa7E;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,oBAAoB,EAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EAAE,GACxB,eAAe,CAsDjB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAYrF;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,sDAAsD;IACtD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,eAAe,CAsD7F;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAS/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAkCjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CAsBlF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAapF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAU5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAIhE"}
|
package/docs/RELEASE.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-compact",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.20.0",
|
|
4
4
|
"description": "Verification-oriented smart compaction extension for Pi Coding Agent — deterministic extraction, exploration, synthesis, verification, metrics, and safety checks.",
|
|
5
5
|
"packageManager": "bun@1.3.14",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,6 +47,8 @@
|
|
|
47
47
|
"prebuild": "bun run sync-version",
|
|
48
48
|
"build": "rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target bun --external '@earendil-works/*' --external 'typebox' && bun x tsc --emitDeclarationOnly --outDir dist",
|
|
49
49
|
"test": "bun test",
|
|
50
|
+
"bench": "bun bench/hot-paths.bench.ts",
|
|
51
|
+
"compat:pi": "bun run scripts/check-pi-compat.ts",
|
|
50
52
|
"typecheck": "bun x tsc --noEmit",
|
|
51
53
|
"prepublishOnly": "bun run typecheck && bun test && bun run build"
|
|
52
54
|
},
|
|
@@ -62,11 +64,7 @@
|
|
|
62
64
|
},
|
|
63
65
|
"devDependencies": {
|
|
64
66
|
"@types/node": "^26.1.1",
|
|
65
|
-
"
|
|
66
|
-
"@earendil-works/pi-coding-agent": "^0.80.3",
|
|
67
|
-
"@earendil-works/pi-tui": "^0.80.3",
|
|
68
|
-
"typebox": "^1.3.6",
|
|
69
|
-
"typescript": "^7.0.0"
|
|
67
|
+
"typescript": "^7.0.2"
|
|
70
68
|
},
|
|
71
69
|
"publishConfig": {
|
|
72
70
|
"access": "public"
|