pi-smart-compact 9.6.1 → 9.7.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/ARCHITECTURE.md +21 -9
- package/CHANGELOG.md +26 -0
- package/README.md +33 -10
- package/dist/app/mode-policy.d.ts +3 -1
- package/dist/app/mode-policy.d.ts.map +1 -1
- package/dist/app/preflight.d.ts.map +1 -1
- package/dist/app/register-context-tools.d.ts.map +1 -1
- package/dist/app/register-smart-compact-command.d.ts.map +1 -1
- package/dist/app/register-smart-compact-tool.d.ts.map +1 -1
- package/dist/app/run-smart-compact.d.ts.map +1 -1
- package/dist/app/smart-compact-input.d.ts +1 -1
- package/dist/app/smart-compact-input.d.ts.map +1 -1
- package/dist/app/steps/extract.d.ts.map +1 -1
- package/dist/app/steps/prepare.d.ts.map +1 -1
- package/dist/app/steps/state.d.ts.map +1 -1
- package/dist/app/steps/synthesize.d.ts.map +1 -1
- package/dist/app/steps/window.d.ts.map +1 -1
- package/dist/constants.d.ts +9 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/domain/provider-evaluation.d.ts.map +1 -1
- package/dist/domain/telemetry.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1978 -1831
- package/dist/infra/ai-messages.d.ts +6 -2
- package/dist/infra/ai-messages.d.ts.map +1 -1
- package/dist/infra/context-graph.d.ts +7 -0
- package/dist/infra/context-graph.d.ts.map +1 -1
- package/dist/phases/synthesize.d.ts.map +1 -1
- package/dist/phases/verify.d.ts.map +1 -1
- package/dist/provider-eval.js +252 -27
- package/dist/provider-scenario-eval.js +262 -35
- package/dist/telemetry-report.js +31 -29
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/error-format.d.ts +3 -1
- package/dist/ui/error-format.d.ts.map +1 -1
- package/dist/ui/metrics-report.d.ts.map +1 -1
- package/dist/ui/settings-complex.d.ts.map +1 -1
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/session-log.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -15,9 +15,13 @@
|
|
|
15
15
|
* conversation buffer in native `Message[]` directly (see `phases/explore.ts`),
|
|
16
16
|
* which is the preferred pattern for any new code that talks to a provider.
|
|
17
17
|
*/
|
|
18
|
-
import type
|
|
19
|
-
import type { LlmMessage } from "../types.ts";
|
|
18
|
+
import { type Message } from "@earendil-works/pi-ai";
|
|
19
|
+
import type { LlmMessage, SessionMessageEntry } from "../types.ts";
|
|
20
20
|
import type { SecretScrubber } from "../domain/scrub.ts";
|
|
21
|
+
/** Preserve the host's context projection and original entry IDs, including custom and branch summaries. */
|
|
22
|
+
export declare function contextMessageEntries(entries: readonly unknown[]): SessionMessageEntry[];
|
|
23
|
+
/** Text transcript without the host summarizer's implicit 2,000-character tool-result cap. */
|
|
24
|
+
export declare function serializeConversationText(messages: LlmMessage[]): string;
|
|
21
25
|
/**
|
|
22
26
|
* Upcast a raw branch entry's `message` to a `Message` for `convertToLlm`.
|
|
23
27
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-messages.d.ts","sourceRoot":"","sources":["../../src/infra/ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ai-messages.d.ts","sourceRoot":"","sources":["../../src/infra/ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,4GAA4G;AAC5G,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAKxF;AAED,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAKxE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAIpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,cAAc,GAAG,UAAU,EAAE,CAE3F"}
|
|
@@ -54,4 +54,11 @@ export declare function saveContextMemory(scope: ContextGraphScope, memory: Omit
|
|
|
54
54
|
export declare function recallContext(scope: ContextGraphScope, query: string, options?: ContextRecallOptions): ContextRecallResult[];
|
|
55
55
|
export declare function formatRecallResults(results: ContextRecallResult[], maxChars?: number): string;
|
|
56
56
|
export declare function getContextGraphStats(projectId: string): ContextGraphStats;
|
|
57
|
+
/**
|
|
58
|
+
* Permanently forget all graph memory for a project (#63): FTS copies,
|
|
59
|
+
* edges, and nodes in one transaction. Drains any queued index writes
|
|
60
|
+
* first so a scheduled compaction cannot resurrect the memory afterwards.
|
|
61
|
+
* Compaction state files (restore data) and backups are left intact.
|
|
62
|
+
*/
|
|
63
|
+
export declare function forgetProjectGraph(projectId: string): boolean;
|
|
57
64
|
//# sourceMappingURL=context-graph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-graph.d.ts","sourceRoot":"","sources":["../../src/infra/context-graph.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,aAAa,CAAC;AAcvE,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,OAAO,GACP,MAAM,GACN,aAAa,GACb,UAAU,GACV,OAAO,GACP,MAAM,GACN,YAAY,GACZ,SAAS,GACT,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,GAAG,QAAQ,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CACX,iBAAiB,EACf,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,WAAW,GACX,SAAS,CACZ,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;
|
|
1
|
+
{"version":3,"file":"context-graph.d.ts","sourceRoot":"","sources":["../../src/infra/context-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/phases/synthesize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,MAAM,aAAa,CAAC;AAYrB,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/phases/synthesize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,MAAM,aAAa,CAAC;AAYrB,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AA0BjE,oFAAoF;AACpF,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,6BAA6B;IAE1C,YAAY,MAAM,EAAE,MAAM,EAEzB;CACD;AAoRD,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,UAAU,EAAE,EAClB,UAAU,EAAE,OAAO,aAAa,EAAE,aAAa,EAAE,EACjD,EAAE,EAAE,aAAa,EACjB,SAAS,GAAE,cAAqC,EAChD,KAAK,CAAC,EAAE,MAAM,GACZ,QAAQ,EAAE,CAwGZ;AAED,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAA;CAAE,CAAC,CA2D3C;AAED,wBAAsB,cAAc,CACnC,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,EAAE,oBAAoB,EAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,eAAe,CAAC,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CA0MzB;AA6BD,wBAAsB,WAAW,CAChC,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,KAAK,CAAC,EAAE,MAAM,EACd,UAAU,GAAE,eAAe,GAAG,IAAW,GACvC,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAED,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,EAChD,YAAY,GAAE,MAAc,EAC5B,UAAU,GAAE,eAAe,GAAG,IAAW,GACvC,MAAM,CAwIR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAiB7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACX,KAAK,EACL,GAAG,EACH,eAAe,EAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,UAAU,EACV,MAAM,aAAa,CAAC;AAoCrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,MAAM,WAAW,oBAAoB;IACpC,cAAc,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACX,KAAK,EACL,GAAG,EACH,eAAe,EAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,UAAU,EACV,MAAM,aAAa,CAAC;AAoCrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,MAAM,WAAW,oBAAoB;IACpC,cAAc,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAiTD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAkClE;AAED,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,kBAAkB,GACxB,MAAM,GAAG,IAAI,CAcf;AAED,wFAAwF;AACxF,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YACC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,qBAAqB,EAW5B;CACD;AA4UD,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAK1E;AAED,qGAAqG;AACrG,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,EACnC,SAAS,SAAI,GACX;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAyB7E;AAkYD,wBAAgB,aAAa,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,GACjC,kBAAkB,CA4CpB;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,GACjC,MAAM,CA4MR;AA2CD,wBAAsB,YAAY,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA2DjB"}
|
package/dist/provider-eval.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var __require = import.meta.require;
|
|
3
|
-
|
|
4
2
|
// src/domain/provider-evaluation.ts
|
|
5
3
|
function providerScenario(entry) {
|
|
6
4
|
const context = (entry.contextPercent ?? 0) >= 90 ? "critical" : (entry.contextPercent ?? 0) >= 70 ? "pressure" : "compact";
|
|
@@ -156,7 +154,7 @@ function formatProviderEvaluation(report) {
|
|
|
156
154
|
import fs2 from "fs";
|
|
157
155
|
|
|
158
156
|
// src/constants.ts
|
|
159
|
-
var VERSION = "9.
|
|
157
|
+
var VERSION = "9.7.0";
|
|
160
158
|
var SETTLED_TRIGGER_COOLDOWN_MS = 10 * 60000;
|
|
161
159
|
var 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.";
|
|
162
160
|
var PROFILES = {
|
|
@@ -209,6 +207,7 @@ var DEFAULT_CONFIG = {
|
|
|
209
207
|
maxLlmInputTokens: 0,
|
|
210
208
|
codexMaxCallMs: 0,
|
|
211
209
|
maxLatencyMs: 0,
|
|
210
|
+
pendingTtlMs: 300000,
|
|
212
211
|
focusWeighting: true,
|
|
213
212
|
zeroCallEnabled: true,
|
|
214
213
|
contextGraphEnabled: true,
|
|
@@ -849,9 +848,12 @@ function classifyToolOperation(args, toolName) {
|
|
|
849
848
|
|
|
850
849
|
// src/utils/logger.ts
|
|
851
850
|
var DEBUG = process.env.DEBUG?.includes("smart-compact") ?? false;
|
|
851
|
+
function ts() {
|
|
852
|
+
return new Date().toISOString();
|
|
853
|
+
}
|
|
852
854
|
function warn(msg, err) {
|
|
853
855
|
const detail = err instanceof Error ? err.message : err ?? "";
|
|
854
|
-
console.error(LOG_PREFIX + " " + msg + (detail ? ": " + detail : ""));
|
|
856
|
+
console.error(ts() + " " + LOG_PREFIX + " " + msg + (detail ? ": " + detail : ""));
|
|
855
857
|
}
|
|
856
858
|
|
|
857
859
|
// src/infra/fs.ts
|
|
@@ -1026,7 +1028,7 @@ function buildSummaryPathEvidence(paths, budgetTokens = PROFILES.balanced.summar
|
|
|
1026
1028
|
const unique = Array.from(new Set(paths.filter(Boolean)));
|
|
1027
1029
|
if (!unique.length)
|
|
1028
1030
|
return new Map;
|
|
1029
|
-
const full = unique.map((
|
|
1031
|
+
const full = unique.map((path) => [path, summaryPathLine(path)]);
|
|
1030
1032
|
const minimumPerLine = JSON.stringify("#" + "x".repeat(12)).length + 3;
|
|
1031
1033
|
const budgetChars = Math.max(unique.length * minimumPerLine, Math.min(20000, Math.max(4000, Math.floor(budgetTokens * 2))));
|
|
1032
1034
|
if (full.reduce((total, [, line]) => total + line.length + 3, 0) <= budgetChars) {
|
|
@@ -1034,21 +1036,21 @@ function buildSummaryPathEvidence(paths, budgetTokens = PROFILES.balanced.summar
|
|
|
1034
1036
|
}
|
|
1035
1037
|
const digests = new Map;
|
|
1036
1038
|
const owners = new Map;
|
|
1037
|
-
for (const
|
|
1038
|
-
const fullDigest = createHash("sha256").update(
|
|
1039
|
+
for (const path of unique) {
|
|
1040
|
+
const fullDigest = createHash("sha256").update(path).digest("base64url");
|
|
1039
1041
|
let digest = fullDigest.slice(0, 12);
|
|
1040
1042
|
const owner = owners.get(digest);
|
|
1041
|
-
if (owner && owner !==
|
|
1043
|
+
if (owner && owner !== path) {
|
|
1042
1044
|
digest = fullDigest;
|
|
1043
1045
|
digests.set(owner, createHash("sha256").update(owner).digest("base64url"));
|
|
1044
1046
|
}
|
|
1045
|
-
owners.set(digest,
|
|
1046
|
-
digests.set(
|
|
1047
|
+
owners.set(digest, path);
|
|
1048
|
+
digests.set(path, digest);
|
|
1047
1049
|
}
|
|
1048
1050
|
const perPath = Math.max(JSON.stringify("#" + "x".repeat(12)).length, Math.floor((budgetChars - unique.length * 3) / unique.length));
|
|
1049
|
-
return new Map(unique.map((
|
|
1050
|
-
|
|
1051
|
-
compactPathLine(
|
|
1051
|
+
return new Map(unique.map((path) => [
|
|
1052
|
+
path,
|
|
1053
|
+
compactPathLine(path, perPath, digests.get(path) ?? "")
|
|
1052
1054
|
]));
|
|
1053
1055
|
}
|
|
1054
1056
|
function mergeBodies(first, second) {
|
|
@@ -1553,27 +1555,27 @@ class SecretScrubber {
|
|
|
1553
1555
|
findings.set("credential", (findings.get("credential") ?? 0) + 1);
|
|
1554
1556
|
this.total++;
|
|
1555
1557
|
};
|
|
1556
|
-
const visit = (
|
|
1557
|
-
if (typeof
|
|
1558
|
-
const result = this.scrubText(
|
|
1558
|
+
const visit = (value) => {
|
|
1559
|
+
if (typeof value === "string") {
|
|
1560
|
+
const result = this.scrubText(value);
|
|
1559
1561
|
mergeFindings(findings, result.findings);
|
|
1560
1562
|
return result.value;
|
|
1561
1563
|
}
|
|
1562
|
-
if (
|
|
1563
|
-
return
|
|
1564
|
-
const cached = seen.get(
|
|
1564
|
+
if (value == null || typeof value !== "object")
|
|
1565
|
+
return value;
|
|
1566
|
+
const cached = seen.get(value);
|
|
1565
1567
|
if (cached !== undefined)
|
|
1566
1568
|
return cached;
|
|
1567
|
-
if (Array.isArray(
|
|
1568
|
-
const
|
|
1569
|
-
seen.set(
|
|
1570
|
-
for (const item of
|
|
1571
|
-
|
|
1572
|
-
return
|
|
1569
|
+
if (Array.isArray(value)) {
|
|
1570
|
+
const output = [];
|
|
1571
|
+
seen.set(value, output);
|
|
1572
|
+
for (const item of value)
|
|
1573
|
+
output.push(visit(item));
|
|
1574
|
+
return output;
|
|
1573
1575
|
}
|
|
1574
1576
|
const output = {};
|
|
1575
|
-
seen.set(
|
|
1576
|
-
for (const [key, item] of Object.entries(
|
|
1577
|
+
seen.set(value, output);
|
|
1578
|
+
for (const [key, item] of Object.entries(value)) {
|
|
1577
1579
|
const carriesSecret = typeof item === "string" && item.length >= 8;
|
|
1578
1580
|
if (this.secretsEnabled && isSecretBearingKey(key) && carriesSecret) {
|
|
1579
1581
|
output[key] = "[REDACTED:credential]";
|
|
@@ -1815,6 +1817,229 @@ var processToolSupport = new ToolSupportCache;
|
|
|
1815
1817
|
var processTokenCalibration = new TokenCalibrationStore;
|
|
1816
1818
|
var _default = createServices();
|
|
1817
1819
|
|
|
1820
|
+
// src/domain/telemetry.ts
|
|
1821
|
+
function p95(values) {
|
|
1822
|
+
if (!values.length)
|
|
1823
|
+
return 0;
|
|
1824
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
1825
|
+
return sorted[Math.max(0, Math.ceil(sorted.length * 0.95) - 1)] ?? 0;
|
|
1826
|
+
}
|
|
1827
|
+
function stats(entries, damage) {
|
|
1828
|
+
const evidence = entries.filter((entry) => entry.status !== "dry-run");
|
|
1829
|
+
const successfulRuns = evidence.filter((entry) => entry.status === "success");
|
|
1830
|
+
const quality = successfulRuns.filter((entry) => typeof entry.verificationScore === "number");
|
|
1831
|
+
const appliedRunIds = new Set(successfulRuns.filter((entry) => typeof entry.runId === "string" && entry.runId.length >= 8).map((entry) => entry.runId));
|
|
1832
|
+
const observedScores = new Map;
|
|
1833
|
+
for (const observation of damage) {
|
|
1834
|
+
if (!observation.runId || !appliedRunIds.has(observation.runId) || typeof observation.damageScore !== "number" || !Number.isFinite(observation.damageScore))
|
|
1835
|
+
continue;
|
|
1836
|
+
observedScores.set(observation.runId, Math.max(observedScores.get(observation.runId) ?? 0, Math.max(0, Math.min(100, observation.damageScore))));
|
|
1837
|
+
}
|
|
1838
|
+
const damaging = [...observedScores.values()].filter((score) => score > 0).length;
|
|
1839
|
+
return {
|
|
1840
|
+
runs: entries.length,
|
|
1841
|
+
appliedRuns: evidence.length,
|
|
1842
|
+
successRate: evidence.length ? successfulRuns.length / evidence.length : 1,
|
|
1843
|
+
avgQuality: quality.length ? quality.reduce((sum, entry) => sum + (entry.verificationScore ?? 0), 0) / quality.length : null,
|
|
1844
|
+
qualityCoverage: evidence.length ? quality.length / evidence.length : 0,
|
|
1845
|
+
p95LatencyMs: p95(evidence.map((entry) => entry.durationMs ?? entry.avgLatency).filter(Number.isFinite)),
|
|
1846
|
+
avgTokens: evidence.length ? evidence.reduce((sum, entry) => sum + entry.totalInput + entry.totalCacheHit + (entry.totalCacheWrite ?? 0) + entry.totalOutput, 0) / evidence.length : 0,
|
|
1847
|
+
fallbackRate: evidence.length ? evidence.filter((entry) => entry.method === "heuristic" || Array.isArray(entry.providerRoutes) && entry.providerRoutes.some((route) => route.successes < route.calls)).length / evidence.length : 0,
|
|
1848
|
+
damageRate: observedScores.size ? damaging / observedScores.size : 0,
|
|
1849
|
+
damageCoverage: successfulRuns.length ? observedScores.size / successfulRuns.length : 0
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
function roundStats(value) {
|
|
1853
|
+
return {
|
|
1854
|
+
...value,
|
|
1855
|
+
successRate: Math.round(value.successRate * 1000) / 1000,
|
|
1856
|
+
avgQuality: value.avgQuality == null ? null : Math.round(value.avgQuality * 10) / 10,
|
|
1857
|
+
qualityCoverage: Math.round(value.qualityCoverage * 1000) / 1000,
|
|
1858
|
+
p95LatencyMs: Math.round(value.p95LatencyMs),
|
|
1859
|
+
avgTokens: Math.round(value.avgTokens),
|
|
1860
|
+
fallbackRate: Math.round(value.fallbackRate * 1000) / 1000,
|
|
1861
|
+
damageRate: Math.round(value.damageRate * 1000) / 1000,
|
|
1862
|
+
damageCoverage: Math.round(value.damageCoverage * 1000) / 1000
|
|
1863
|
+
};
|
|
1864
|
+
}
|
|
1865
|
+
function assessCanary(entries, damageEntries, options) {
|
|
1866
|
+
const minCanaryRuns = Math.max(5, options.minCanaryRuns ?? 20);
|
|
1867
|
+
const canaryEntries = entries.filter((entry) => entry.metricsSchemaVersion === 2 && entry.version === options.version && entry.releaseChannel === "canary").slice(-Math.max(100, minCanaryRuns));
|
|
1868
|
+
const baselineEntries = entries.filter((entry) => entry.metricsSchemaVersion === 2 && (entry.releaseChannel ?? "stable") === "stable").slice(-(options.baselineRuns ?? Math.max(50, minCanaryRuns * 2)));
|
|
1869
|
+
const baseline = stats(baselineEntries, damageEntries);
|
|
1870
|
+
const canary = stats(canaryEntries, damageEntries);
|
|
1871
|
+
const triggers = [];
|
|
1872
|
+
const failureBaseline = 1 - baseline.successRate;
|
|
1873
|
+
const failureCanary = 1 - canary.successRate;
|
|
1874
|
+
if (canary.appliedRuns >= 3 && (failureCanary > 0.050001 || failureCanary - failureBaseline >= 0.050001)) {
|
|
1875
|
+
triggers.push({
|
|
1876
|
+
metric: "failure-rate",
|
|
1877
|
+
baseline: failureBaseline,
|
|
1878
|
+
canary: failureCanary,
|
|
1879
|
+
threshold: failureCanary > 0.050001 ? ">5% absolute" : "+5pp regression"
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
if (canary.avgQuality != null && (canary.avgQuality < 85 || baseline.avgQuality != null && baseline.avgQuality - canary.avgQuality >= 5)) {
|
|
1883
|
+
triggers.push({
|
|
1884
|
+
metric: "quality",
|
|
1885
|
+
baseline: baseline.avgQuality ?? 0,
|
|
1886
|
+
canary: canary.avgQuality,
|
|
1887
|
+
threshold: canary.avgQuality < 85 ? "<85 absolute" : "-5 points"
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
if (baseline.p95LatencyMs >= 1000 && canary.p95LatencyMs >= baseline.p95LatencyMs * 1.5) {
|
|
1891
|
+
triggers.push({ metric: "latency", baseline: baseline.p95LatencyMs, canary: canary.p95LatencyMs, threshold: "+50% p95" });
|
|
1892
|
+
}
|
|
1893
|
+
if (baseline.avgTokens >= 1000 && canary.avgTokens >= baseline.avgTokens * 1.5) {
|
|
1894
|
+
triggers.push({ metric: "tokens", baseline: baseline.avgTokens, canary: canary.avgTokens, threshold: "+50%" });
|
|
1895
|
+
}
|
|
1896
|
+
if (canary.fallbackRate - baseline.fallbackRate >= 0.1) {
|
|
1897
|
+
triggers.push({ metric: "fallback", baseline: baseline.fallbackRate, canary: canary.fallbackRate, threshold: "+10pp" });
|
|
1898
|
+
}
|
|
1899
|
+
if (canary.damageRate - baseline.damageRate >= 0.1) {
|
|
1900
|
+
triggers.push({ metric: "damage", baseline: baseline.damageRate, canary: canary.damageRate, threshold: "+10pp" });
|
|
1901
|
+
}
|
|
1902
|
+
const canarySampleAdequacy = Math.min(1, canary.appliedRuns / minCanaryRuns);
|
|
1903
|
+
const baselineSampleAdequacy = Math.min(1, baseline.appliedRuns / Math.max(20, minCanaryRuns));
|
|
1904
|
+
const dataConfidence = Math.round(100 * (canarySampleAdequacy * 0.25 + baselineSampleAdequacy * 0.15 + canary.qualityCoverage * canarySampleAdequacy * 0.2 + canary.damageCoverage * canarySampleAdequacy * 0.2 + baseline.damageCoverage * baselineSampleAdequacy * 0.2));
|
|
1905
|
+
const reasons = [];
|
|
1906
|
+
let decision = "hold";
|
|
1907
|
+
if (triggers.length && canary.appliedRuns >= 3) {
|
|
1908
|
+
decision = "rollback";
|
|
1909
|
+
reasons.push(...triggers.map((trigger) => trigger.metric + " crossed " + trigger.threshold));
|
|
1910
|
+
} else if (canary.appliedRuns < minCanaryRuns) {
|
|
1911
|
+
reasons.push("need " + (minCanaryRuns - canary.appliedRuns) + " more canary runs with applied outcomes");
|
|
1912
|
+
} else if (baseline.appliedRuns < Math.max(20, minCanaryRuns)) {
|
|
1913
|
+
reasons.push("stable baseline is too small");
|
|
1914
|
+
} else if (canary.qualityCoverage < 0.7) {
|
|
1915
|
+
reasons.push("schema-v2 quality coverage is below 70%");
|
|
1916
|
+
} else if (canary.damageCoverage < 0.7) {
|
|
1917
|
+
reasons.push("correlated canary damage-observation coverage is below 70%");
|
|
1918
|
+
} else if (baseline.damageCoverage < 0.7) {
|
|
1919
|
+
reasons.push("correlated stable damage-observation coverage is below 70%");
|
|
1920
|
+
} else if ((canary.avgQuality ?? 0) < 85) {
|
|
1921
|
+
reasons.push("absolute verifier quality is below 85");
|
|
1922
|
+
} else if (canary.successRate < 0.949999) {
|
|
1923
|
+
reasons.push("absolute success rate is below 95%");
|
|
1924
|
+
} else {
|
|
1925
|
+
decision = "promote";
|
|
1926
|
+
reasons.push("sample, absolute quality, reliability, latency, token, fallback, and damage gates passed");
|
|
1927
|
+
}
|
|
1928
|
+
return {
|
|
1929
|
+
version: options.version,
|
|
1930
|
+
decision,
|
|
1931
|
+
dataConfidence,
|
|
1932
|
+
baseline: roundStats(baseline),
|
|
1933
|
+
canary: roundStats(canary),
|
|
1934
|
+
triggers,
|
|
1935
|
+
reasons
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1938
|
+
function safeMetricLabel(value, fallback) {
|
|
1939
|
+
if (typeof value !== "string" || !/^[\w./:@+-]{1,160}$/.test(value))
|
|
1940
|
+
return fallback;
|
|
1941
|
+
return value;
|
|
1942
|
+
}
|
|
1943
|
+
var TELEMETRY_FAILURE_KINDS = new Set([
|
|
1944
|
+
"cancelled",
|
|
1945
|
+
"timeout",
|
|
1946
|
+
"rate-limit",
|
|
1947
|
+
"authentication",
|
|
1948
|
+
"budget",
|
|
1949
|
+
"output-limit",
|
|
1950
|
+
"provider",
|
|
1951
|
+
"persistence",
|
|
1952
|
+
"validation",
|
|
1953
|
+
"verification",
|
|
1954
|
+
"yield",
|
|
1955
|
+
"internal"
|
|
1956
|
+
]);
|
|
1957
|
+
function isTelemetryFailureKind(value) {
|
|
1958
|
+
return typeof value === "string" && TELEMETRY_FAILURE_KINDS.has(value);
|
|
1959
|
+
}
|
|
1960
|
+
function buildPrivacySafeTelemetry(entries, damageEntries, options) {
|
|
1961
|
+
const groups = new Map;
|
|
1962
|
+
const failures = {};
|
|
1963
|
+
for (const entry of entries) {
|
|
1964
|
+
const version = safeMetricLabel(entry.version, "legacy");
|
|
1965
|
+
const channel = entry.releaseChannel === "canary" ? "canary" : "stable";
|
|
1966
|
+
const provider = safeMetricLabel(entry.provider, "unknown");
|
|
1967
|
+
const rawModel = safeMetricLabel(entry.model, "unknown");
|
|
1968
|
+
const model = rawModel.startsWith(provider + "/") ? rawModel.slice(provider.length + 1) : rawModel;
|
|
1969
|
+
const key = [version, channel, provider, model].join("\x00");
|
|
1970
|
+
const group = groups.get(key) ?? {
|
|
1971
|
+
version,
|
|
1972
|
+
channel,
|
|
1973
|
+
provider,
|
|
1974
|
+
model,
|
|
1975
|
+
runs: 0,
|
|
1976
|
+
successes: 0,
|
|
1977
|
+
quality: 0,
|
|
1978
|
+
qualityRuns: 0,
|
|
1979
|
+
latency: 0,
|
|
1980
|
+
input: 0,
|
|
1981
|
+
output: 0
|
|
1982
|
+
};
|
|
1983
|
+
group.runs++;
|
|
1984
|
+
if (entry.status === "success" || entry.status === "dry-run")
|
|
1985
|
+
group.successes++;
|
|
1986
|
+
if (entry.metricsSchemaVersion === 2 && typeof entry.verificationScore === "number") {
|
|
1987
|
+
group.quality += entry.verificationScore;
|
|
1988
|
+
group.qualityRuns++;
|
|
1989
|
+
}
|
|
1990
|
+
group.latency += entry.avgLatency;
|
|
1991
|
+
group.input += entry.totalInput + entry.totalCacheHit + (entry.totalCacheWrite ?? 0);
|
|
1992
|
+
group.output += entry.totalOutput;
|
|
1993
|
+
groups.set(key, group);
|
|
1994
|
+
if (isTelemetryFailureKind(entry.failureKind)) {
|
|
1995
|
+
failures[entry.failureKind] = (failures[entry.failureKind] ?? 0) + 1;
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
const aggregates = [...groups.values()].map((group) => ({
|
|
1999
|
+
version: group.version,
|
|
2000
|
+
channel: group.channel,
|
|
2001
|
+
provider: group.provider,
|
|
2002
|
+
model: group.model,
|
|
2003
|
+
runs: group.runs,
|
|
2004
|
+
successes: group.successes,
|
|
2005
|
+
avgQuality: group.qualityRuns ? Math.round(group.quality / group.qualityRuns * 10) / 10 : null,
|
|
2006
|
+
avgLatencyMs: group.runs ? Math.round(group.latency / group.runs) : 0,
|
|
2007
|
+
inputTokens: group.input,
|
|
2008
|
+
outputTokens: group.output
|
|
2009
|
+
})).sort((a, b) => b.runs - a.runs || a.version.localeCompare(b.version));
|
|
2010
|
+
return {
|
|
2011
|
+
generatedAt: new Date().toISOString(),
|
|
2012
|
+
totalRuns: entries.length,
|
|
2013
|
+
aggregates,
|
|
2014
|
+
failures,
|
|
2015
|
+
canary: assessCanary(entries, damageEntries, options),
|
|
2016
|
+
privacy: "aggregate-only; no session ids, project ids, prompts, summaries, paths, or error text"
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
function formatPrivacySafeTelemetry(report) {
|
|
2020
|
+
const lines = [
|
|
2021
|
+
"# Smart Compact Telemetry",
|
|
2022
|
+
"",
|
|
2023
|
+
"Privacy: " + report.privacy + ".",
|
|
2024
|
+
"",
|
|
2025
|
+
"| Version | Channel | Provider/model | Runs | Success | Quality | Latency | Input | Output |",
|
|
2026
|
+
"|---|---|---|---:|---:|---:|---:|---:|---:|"
|
|
2027
|
+
];
|
|
2028
|
+
for (const item of report.aggregates) {
|
|
2029
|
+
lines.push("| " + item.version + " | " + item.channel + " | " + item.provider + "/" + item.model + " | " + item.runs + " | " + item.successes + "/" + item.runs + " | " + (item.avgQuality == null ? "n/a" : item.avgQuality.toFixed(1)) + " | " + item.avgLatencyMs + "ms | " + item.inputTokens + " | " + item.outputTokens + " |");
|
|
2030
|
+
}
|
|
2031
|
+
lines.push("", "## Canary: " + report.canary.decision.toUpperCase() + " (data confidence " + report.canary.dataConfidence + "%)", "");
|
|
2032
|
+
const baseline = report.canary.baseline;
|
|
2033
|
+
const canary = report.canary.canary;
|
|
2034
|
+
lines.push("| Gate | Stable baseline | Canary |", "|---|---:|---:|", "| Runs (total/applied) | " + baseline.runs + "/" + baseline.appliedRuns + " | " + canary.runs + "/" + canary.appliedRuns + " |", "| Success | " + Math.round(baseline.successRate * 100) + "% | " + Math.round(canary.successRate * 100) + "% |", "| Verify quality | " + (baseline.avgQuality ?? "n/a") + " | " + (canary.avgQuality ?? "n/a") + " |", "| p95 duration | " + baseline.p95LatencyMs + "ms | " + canary.p95LatencyMs + "ms |", "| Avg tokens | " + baseline.avgTokens + " | " + canary.avgTokens + " |", "| Fallback | " + Math.round(baseline.fallbackRate * 100) + "% | " + Math.round(canary.fallbackRate * 100) + "% |", "| Damage | " + Math.round(baseline.damageRate * 100) + "% | " + Math.round(canary.damageRate * 100) + "% |", "| Damage observed | " + Math.round(baseline.damageCoverage * 100) + "% | " + Math.round(canary.damageCoverage * 100) + "% |", "");
|
|
2035
|
+
for (const reason of report.canary.reasons)
|
|
2036
|
+
lines.push("- " + reason);
|
|
2037
|
+
const failureText = Object.entries(report.failures).map(([kind, count]) => kind + "=" + count).join(", ");
|
|
2038
|
+
lines.push("", "Failures: " + (failureText || "none classified"));
|
|
2039
|
+
return lines.join(`
|
|
2040
|
+
`);
|
|
2041
|
+
}
|
|
2042
|
+
|
|
1818
2043
|
// src/utils/cache.ts
|
|
1819
2044
|
var INTERNAL_PHASES = new Set([
|
|
1820
2045
|
"explore-retry",
|