@phamvuhoang/otto-core 0.32.0 → 0.33.1
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/dist/codebase-memory-adapter.d.ts +99 -0
- package/dist/codebase-memory-adapter.d.ts.map +1 -0
- package/dist/codebase-memory-adapter.js +127 -0
- package/dist/codebase-memory-adapter.js.map +1 -0
- package/dist/compression-survival.d.ts +46 -0
- package/dist/compression-survival.d.ts.map +1 -0
- package/dist/compression-survival.js +81 -0
- package/dist/compression-survival.js.map +1 -0
- package/dist/context-compressor.d.ts +20 -0
- package/dist/context-compressor.d.ts.map +1 -1
- package/dist/context-compressor.js +46 -0
- package/dist/context-compressor.js.map +1 -1
- package/dist/eval.d.ts +30 -0
- package/dist/eval.d.ts.map +1 -1
- package/dist/eval.js +42 -1
- package/dist/eval.js.map +1 -1
- package/dist/extension-profiles.d.ts.map +1 -1
- package/dist/extension-profiles.js +11 -0
- package/dist/extension-profiles.js.map +1 -1
- package/dist/fanout.d.ts +48 -1
- package/dist/fanout.d.ts.map +1 -1
- package/dist/fanout.js +121 -11
- package/dist/fanout.js.map +1 -1
- package/dist/handoff.d.ts +32 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +58 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +1 -1
- package/dist/inspect.js.map +1 -1
- package/dist/loop.d.ts.map +1 -1
- package/dist/loop.js +77 -4
- package/dist/loop.js.map +1 -1
- package/dist/panel.d.ts +10 -0
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +29 -4
- package/dist/panel.js.map +1 -1
- package/dist/plan-rubric.d.ts +1 -1
- package/dist/plan-rubric.d.ts.map +1 -1
- package/dist/plan-rubric.js +19 -0
- package/dist/plan-rubric.js.map +1 -1
- package/dist/plan-tasks.d.ts +39 -5
- package/dist/plan-tasks.d.ts.map +1 -1
- package/dist/plan-tasks.js +85 -12
- package/dist/plan-tasks.js.map +1 -1
- package/dist/report-finalize.d.ts +9 -0
- package/dist/report-finalize.d.ts.map +1 -1
- package/dist/report-finalize.js +32 -4
- package/dist/report-finalize.js.map +1 -1
- package/dist/run-bin.d.ts.map +1 -1
- package/dist/run-bin.js +5 -0
- package/dist/run-bin.js.map +1 -1
- package/dist/run-report.d.ts +49 -1
- package/dist/run-report.d.ts.map +1 -1
- package/dist/run-report.js +18 -0
- package/dist/run-report.js.map +1 -1
- package/dist/stage-exec.d.ts.map +1 -1
- package/dist/stage-exec.js +5 -1
- package/dist/stage-exec.js.map +1 -1
- package/dist/tools.d.ts +17 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +48 -0
- package/dist/tools.js.map +1 -1
- package/dist/verification-evidence.d.ts +4 -0
- package/dist/verification-evidence.d.ts.map +1 -1
- package/dist/verification-evidence.js +33 -4
- package/dist/verification-evidence.js.map +1 -1
- package/dist/verification-matrix.d.ts +31 -4
- package/dist/verification-matrix.d.ts.map +1 -1
- package/dist/verification-matrix.js +44 -5
- package/dist/verification-matrix.js.map +1 -1
- package/package.json +1 -1
- package/templates/plan.md +5 -0
- package/templates/subtask.md +17 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ToolDefinition } from "./tools.js";
|
|
2
|
+
/**
|
|
3
|
+
* Codebase Memory adapter (P26 spike, Task 2). Otto owns a local MCP stdio
|
|
4
|
+
* child (`codebase-memory`) that builds and queries a code-knowledge graph
|
|
5
|
+
* for the target repo — architecture summaries, call-path tracing, symbol
|
|
6
|
+
* search — without any runtime network access. The adapter follows the same
|
|
7
|
+
* house pattern as {@link ./headroom-adapter.js}: a {@link ToolDefinition}
|
|
8
|
+
* factory for the `.otto/tools/` registry (`otto-tools list/why/health`,
|
|
9
|
+
* policy authorization) plus an injectable transport ({@link CbmRunner}) so
|
|
10
|
+
* unit tests never spawn a real process.
|
|
11
|
+
*
|
|
12
|
+
* The tool is opt-in and inert until a repo registers + enables it:
|
|
13
|
+
* `stages: []` (no default injection into any stage template), `enabled:
|
|
14
|
+
* false` (registry-level off switch), `networkDomains: []` (no runtime
|
|
15
|
+
* network — the graph lives entirely in a local cache), and `writeRoots:
|
|
16
|
+
* [".codebase-memory"]` (writes confined to its own cache directory).
|
|
17
|
+
*/
|
|
18
|
+
/** One JSON-RPC request to the codebase-memory MCP child. */
|
|
19
|
+
export type CbmRequest = {
|
|
20
|
+
operation: string;
|
|
21
|
+
params: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
/** The structured response from a {@link CbmRunner} call. */
|
|
24
|
+
export type CbmResponse = {
|
|
25
|
+
ok: boolean;
|
|
26
|
+
result?: unknown;
|
|
27
|
+
error?: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* The injectable transport the adapter drives. The real implementation
|
|
31
|
+
* ({@link createStdioCbmRunner}) spawns the MCP child over stdio; unit tests
|
|
32
|
+
* inject a stub — this contract is the seam.
|
|
33
|
+
*/
|
|
34
|
+
export type CbmRunner = {
|
|
35
|
+
available(): boolean;
|
|
36
|
+
call(req: CbmRequest): CbmResponse;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The {@link ToolDefinition} a repo drops into `.otto/tools/codebase-memory.json`
|
|
40
|
+
* (mirrors {@link ./headroom-adapter.js}'s `headroomToolDefinition`). Declares
|
|
41
|
+
* no runtime network, cache-only writes, and the operation allowlist
|
|
42
|
+
* (`operations`) that a caller can gate calls against. `stages: []` and
|
|
43
|
+
* `enabled: false` keep it fully opt-in — a bare repo behaves as before.
|
|
44
|
+
*/
|
|
45
|
+
export declare function codebaseMemoryToolDefinition(command?: string): ToolDefinition;
|
|
46
|
+
/**
|
|
47
|
+
* Real transport: a minimal newline-delimited JSON-RPC client over stdio.
|
|
48
|
+
* Sends an `initialize` handshake followed by one `tools/call`, both
|
|
49
|
+
* newline-framed, and reads the child's stdout for the matching response.
|
|
50
|
+
* Synchronous (`spawnSync`) to fit the same render/`@spill`-boundary
|
|
51
|
+
* constraints as the Headroom runners. Only exercised under the gated e2e —
|
|
52
|
+
* unit tests inject a {@link CbmRunner} stub instead.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createStdioCbmRunner(command: string, cwd: string, timeoutMs: number): CbmRunner;
|
|
55
|
+
/**
|
|
56
|
+
* Identity stamp a persisted `.codebase-memory/` index carries, so a later
|
|
57
|
+
* run can tell whether it's safe to trust without re-indexing: which
|
|
58
|
+
* workspace it was built for, the source revision it was built at, whether
|
|
59
|
+
* the worktree was dirty at build time, and tool/index bookkeeping.
|
|
60
|
+
*/
|
|
61
|
+
export type CbmIndexIdentity = {
|
|
62
|
+
workspace: string;
|
|
63
|
+
sourceRevision: string;
|
|
64
|
+
worktreeDirty: boolean;
|
|
65
|
+
toolVersion: string;
|
|
66
|
+
indexStatus: string;
|
|
67
|
+
indexedAt: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Freshness verdict for a persisted index against the current workspace
|
|
71
|
+
* state: `absent` (no index or no current state to compare), `wrong-project`
|
|
72
|
+
* (index was built for a different workspace), `stale` (revision drift or a
|
|
73
|
+
* dirty worktree since indexing), `fresh` (safe to trust as-is).
|
|
74
|
+
*/
|
|
75
|
+
export type IndexFreshness = "fresh" | "stale" | "absent" | "wrong-project";
|
|
76
|
+
/**
|
|
77
|
+
* Classifies a persisted index's freshness against the current workspace
|
|
78
|
+
* identity. Pure — no filesystem or process access; callers gather
|
|
79
|
+
* `current`/`index` themselves.
|
|
80
|
+
*/
|
|
81
|
+
export declare function classifyIndexFreshness(current: {
|
|
82
|
+
workspace: string;
|
|
83
|
+
sourceRevision: string;
|
|
84
|
+
worktreeDirty: boolean;
|
|
85
|
+
} | null, index: CbmIndexIdentity | null): IndexFreshness;
|
|
86
|
+
/**
|
|
87
|
+
* New files written during a run (`after \ before`) plus which of those
|
|
88
|
+
* escaped the tool's declared write roots — i.e. wrote outside
|
|
89
|
+
* `.codebase-memory/` (see `writeRoots` on {@link codebaseMemoryToolDefinition}).
|
|
90
|
+
* A declared root matches itself exactly or any path under `root + "/"`, so
|
|
91
|
+
* a root doesn't accidentally prefix-match a sibling like `.codebase-memory-foo`.
|
|
92
|
+
*/
|
|
93
|
+
export type WriteInventory = {
|
|
94
|
+
files: string[];
|
|
95
|
+
escaped: string[];
|
|
96
|
+
};
|
|
97
|
+
/** Pure diff of two file-path snapshots against a set of declared write roots. */
|
|
98
|
+
export declare function diffWriteInventory(before: string[], after: string[], declaredRoots: string[]): WriteInventory;
|
|
99
|
+
//# sourceMappingURL=codebase-memory-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase-memory-adapter.d.ts","sourceRoot":"","sources":["../src/codebase-memory-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;;;;;GAeG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,IAAI,OAAO,CAAC;IACrB,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,CAAC;CACpC,CAAC;AAoBF;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,SAAoB,GAC1B,cAAc,CAwBhB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,SAAS,CA0CX;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,IAAI,EACR,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAC7B,cAAc,CAMhB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpE,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,cAAc,CAWhB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
/** Read-only operations the codebase-memory server exposes. */
|
|
3
|
+
const READ_OPS = [
|
|
4
|
+
"index_status",
|
|
5
|
+
"get_graph_schema",
|
|
6
|
+
"get_architecture",
|
|
7
|
+
"search_graph",
|
|
8
|
+
"trace_path",
|
|
9
|
+
"detect_changes",
|
|
10
|
+
"search_code",
|
|
11
|
+
"get_code_snippet",
|
|
12
|
+
];
|
|
13
|
+
/** The full operation allowlist: one write op + the read-only surface. */
|
|
14
|
+
const OPERATIONS = [
|
|
15
|
+
{ name: "index_repository", write: true },
|
|
16
|
+
...READ_OPS.map((name) => ({ name, write: false })),
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* The {@link ToolDefinition} a repo drops into `.otto/tools/codebase-memory.json`
|
|
20
|
+
* (mirrors {@link ./headroom-adapter.js}'s `headroomToolDefinition`). Declares
|
|
21
|
+
* no runtime network, cache-only writes, and the operation allowlist
|
|
22
|
+
* (`operations`) that a caller can gate calls against. `stages: []` and
|
|
23
|
+
* `enabled: false` keep it fully opt-in — a bare repo behaves as before.
|
|
24
|
+
*/
|
|
25
|
+
export function codebaseMemoryToolDefinition(command = "codebase-memory") {
|
|
26
|
+
return {
|
|
27
|
+
name: "codebase-memory",
|
|
28
|
+
kind: "mcp",
|
|
29
|
+
description: "Local code-knowledge graph via an Otto-owned MCP stdio child.",
|
|
30
|
+
capabilities: [
|
|
31
|
+
"architecture",
|
|
32
|
+
"call-path",
|
|
33
|
+
"change-impact",
|
|
34
|
+
"symbol-search",
|
|
35
|
+
],
|
|
36
|
+
stages: [], // opt-in via config; no default injection
|
|
37
|
+
command,
|
|
38
|
+
env: [],
|
|
39
|
+
networkDomains: [], // no runtime network
|
|
40
|
+
writeRoots: [".codebase-memory"], // cache-only
|
|
41
|
+
secretRefs: [],
|
|
42
|
+
timeoutMs: 120_000,
|
|
43
|
+
healthCheck: `${command} --version`,
|
|
44
|
+
approvalActions: [],
|
|
45
|
+
enabled: false,
|
|
46
|
+
operations: OPERATIONS,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Real transport: a minimal newline-delimited JSON-RPC client over stdio.
|
|
51
|
+
* Sends an `initialize` handshake followed by one `tools/call`, both
|
|
52
|
+
* newline-framed, and reads the child's stdout for the matching response.
|
|
53
|
+
* Synchronous (`spawnSync`) to fit the same render/`@spill`-boundary
|
|
54
|
+
* constraints as the Headroom runners. Only exercised under the gated e2e —
|
|
55
|
+
* unit tests inject a {@link CbmRunner} stub instead.
|
|
56
|
+
*/
|
|
57
|
+
export function createStdioCbmRunner(command, cwd, timeoutMs) {
|
|
58
|
+
const [bin, ...args] = command.split(" ");
|
|
59
|
+
const available = () => {
|
|
60
|
+
const probe = spawnSync(bin, ["--version"], { cwd, timeout: 5000 });
|
|
61
|
+
return probe.status === 0;
|
|
62
|
+
};
|
|
63
|
+
// One-shot request/response: initialize handshake + tools/call, newline-framed.
|
|
64
|
+
const call = (req) => {
|
|
65
|
+
const init = JSON.stringify({
|
|
66
|
+
jsonrpc: "2.0",
|
|
67
|
+
id: 1,
|
|
68
|
+
method: "initialize",
|
|
69
|
+
params: {},
|
|
70
|
+
});
|
|
71
|
+
const callMsg = JSON.stringify({
|
|
72
|
+
jsonrpc: "2.0",
|
|
73
|
+
id: 2,
|
|
74
|
+
method: "tools/call",
|
|
75
|
+
params: { name: req.operation, arguments: req.params },
|
|
76
|
+
});
|
|
77
|
+
const proc = spawnSync(bin, args, {
|
|
78
|
+
cwd,
|
|
79
|
+
timeout: timeoutMs,
|
|
80
|
+
input: `${init}\n${callMsg}\n`,
|
|
81
|
+
});
|
|
82
|
+
if (proc.status !== 0)
|
|
83
|
+
return { ok: false, error: proc.stderr?.toString() || "child failed" };
|
|
84
|
+
const lines = proc.stdout.toString().split("\n").filter(Boolean);
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
try {
|
|
87
|
+
const msg = JSON.parse(line);
|
|
88
|
+
if (msg.id === 2 && "result" in msg)
|
|
89
|
+
return { ok: true, result: msg.result };
|
|
90
|
+
if (msg.id === 2 && "error" in msg)
|
|
91
|
+
return { ok: false, error: String(msg.error.message ?? msg.error) };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* ignore non-JSON banner lines */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { ok: false, error: "no response for tools/call" };
|
|
98
|
+
};
|
|
99
|
+
return { available, call };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Classifies a persisted index's freshness against the current workspace
|
|
103
|
+
* identity. Pure — no filesystem or process access; callers gather
|
|
104
|
+
* `current`/`index` themselves.
|
|
105
|
+
*/
|
|
106
|
+
export function classifyIndexFreshness(current, index) {
|
|
107
|
+
if (!index || !current)
|
|
108
|
+
return "absent";
|
|
109
|
+
if (index.workspace !== current.workspace)
|
|
110
|
+
return "wrong-project";
|
|
111
|
+
if (index.sourceRevision !== current.sourceRevision || current.worktreeDirty)
|
|
112
|
+
return "stale";
|
|
113
|
+
return "fresh";
|
|
114
|
+
}
|
|
115
|
+
/** Pure diff of two file-path snapshots against a set of declared write roots. */
|
|
116
|
+
export function diffWriteInventory(before, after, declaredRoots) {
|
|
117
|
+
const beforeSet = new Set(before);
|
|
118
|
+
const files = after.filter((f) => !beforeSet.has(f));
|
|
119
|
+
const under = (f) => declaredRoots.some((raw) => {
|
|
120
|
+
// Normalize a trailing slash so a root declared as `.codebase-memory/`
|
|
121
|
+
// classifies the bare directory the same as `.codebase-memory` does.
|
|
122
|
+
const r = raw.replace(/\/+$/, "");
|
|
123
|
+
return f === r || f.startsWith(`${r}/`);
|
|
124
|
+
});
|
|
125
|
+
return { files, escaped: files.filter((f) => !under(f)) };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=codebase-memory-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase-memory-adapter.js","sourceRoot":"","sources":["../src/codebase-memory-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fact-survival measurement for context compression (issue #179 P22).
|
|
3
|
+
*
|
|
4
|
+
* The roadmap gates trusting (and later expanding) Headroom compression on one
|
|
5
|
+
* condition: *"use Headroom selectively for `retrievable` categories where **eval
|
|
6
|
+
* proves buried facts survive compression**."* Compression (`context-compressor.ts`,
|
|
7
|
+
* `headroom-adapter.ts`) already shrinks retrievable content and measures the
|
|
8
|
+
* token savings — but token savings alone cannot tell you whether a specific
|
|
9
|
+
* load-bearing fact (an error code, a version, a file path) *survived* the
|
|
10
|
+
* summarization. This module answers that orthogonal question.
|
|
11
|
+
*
|
|
12
|
+
* Pure: it takes a known set of "buried facts" and the compressed text and
|
|
13
|
+
* reports which facts still appear. Evals score survival against facts they
|
|
14
|
+
* supply; the runtime keep-decision (`context-compressor.ts`, issue #200)
|
|
15
|
+
* scores it against anchors mechanically extracted from the original via
|
|
16
|
+
* {@link extractAnchors}, so a compression that drops a load-bearing
|
|
17
|
+
* identifier is rejected instead of used.
|
|
18
|
+
*/
|
|
19
|
+
/** The outcome of scoring a fact set against one piece of compressed text. */
|
|
20
|
+
export type FactSurvival = {
|
|
21
|
+
/** How many facts were checked. */
|
|
22
|
+
total: number;
|
|
23
|
+
/** How many facts still appear in the compressed text. */
|
|
24
|
+
survived: number;
|
|
25
|
+
/** `survived / total`, or `1` for an empty fact set (vacuously all survive). */
|
|
26
|
+
survivalRate: number;
|
|
27
|
+
/** The facts that did not appear, in input order. */
|
|
28
|
+
missing: string[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Score how many `facts` survive in `compressedText`. A fact "survives" when it
|
|
32
|
+
* appears as a normalized (case-insensitive, whitespace-collapsed) substring —
|
|
33
|
+
* robust to a summarizer rephrasing *around* a distinctive identifier while still
|
|
34
|
+
* catching a token that is dropped entirely. Pure.
|
|
35
|
+
*/
|
|
36
|
+
export declare function assessFactSurvival(facts: string[], compressedText: string): FactSurvival;
|
|
37
|
+
/**
|
|
38
|
+
* Extract up to `limit` distinctive anchors from original text, deduplicated,
|
|
39
|
+
* in order of first appearance. The runtime survival floor checks these against
|
|
40
|
+
* the compressed text; an empty result means the text has no mechanically
|
|
41
|
+
* recognizable load-bearing tokens (survival is then vacuous). Pure.
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractAnchors(text: string, limit?: number): string[];
|
|
44
|
+
/** One-line human summary of a survival assessment for eval output. Pure. */
|
|
45
|
+
export declare function formatFactSurvival(s: FactSurvival): string;
|
|
46
|
+
//# sourceMappingURL=compression-survival.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression-survival.d.ts","sourceRoot":"","sources":["../src/compression-survival.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG;IACzB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,cAAc,EAAE,MAAM,GACrB,YAAY,CAUd;AAeD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAcjE;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAG1D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fact-survival measurement for context compression (issue #179 P22).
|
|
3
|
+
*
|
|
4
|
+
* The roadmap gates trusting (and later expanding) Headroom compression on one
|
|
5
|
+
* condition: *"use Headroom selectively for `retrievable` categories where **eval
|
|
6
|
+
* proves buried facts survive compression**."* Compression (`context-compressor.ts`,
|
|
7
|
+
* `headroom-adapter.ts`) already shrinks retrievable content and measures the
|
|
8
|
+
* token savings — but token savings alone cannot tell you whether a specific
|
|
9
|
+
* load-bearing fact (an error code, a version, a file path) *survived* the
|
|
10
|
+
* summarization. This module answers that orthogonal question.
|
|
11
|
+
*
|
|
12
|
+
* Pure: it takes a known set of "buried facts" and the compressed text and
|
|
13
|
+
* reports which facts still appear. Evals score survival against facts they
|
|
14
|
+
* supply; the runtime keep-decision (`context-compressor.ts`, issue #200)
|
|
15
|
+
* scores it against anchors mechanically extracted from the original via
|
|
16
|
+
* {@link extractAnchors}, so a compression that drops a load-bearing
|
|
17
|
+
* identifier is rejected instead of used.
|
|
18
|
+
*/
|
|
19
|
+
/** Lowercase + collapse internal whitespace + trim, so a summarizer that changes
|
|
20
|
+
* spacing/case around a salient token does not read as a dropped fact. */
|
|
21
|
+
function normalize(s) {
|
|
22
|
+
return s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Score how many `facts` survive in `compressedText`. A fact "survives" when it
|
|
26
|
+
* appears as a normalized (case-insensitive, whitespace-collapsed) substring —
|
|
27
|
+
* robust to a summarizer rephrasing *around* a distinctive identifier while still
|
|
28
|
+
* catching a token that is dropped entirely. Pure.
|
|
29
|
+
*/
|
|
30
|
+
export function assessFactSurvival(facts, compressedText) {
|
|
31
|
+
const haystack = normalize(compressedText);
|
|
32
|
+
const missing = facts.filter((f) => !haystack.includes(normalize(f)));
|
|
33
|
+
const survived = facts.length - missing.length;
|
|
34
|
+
return {
|
|
35
|
+
total: facts.length,
|
|
36
|
+
survived,
|
|
37
|
+
survivalRate: facts.length === 0 ? 1 : survived / facts.length,
|
|
38
|
+
missing,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The load-bearing token shapes a summarizer must not drop: slash file paths
|
|
43
|
+
* with an extension, uppercase identifier codes containing a digit or
|
|
44
|
+
* underscore (error codes, env keys — bare acronyms like `API` don't count),
|
|
45
|
+
* and version strings. Ordered by appearance so a capped list keeps the
|
|
46
|
+
* earliest (usually headline) anchors.
|
|
47
|
+
*/
|
|
48
|
+
const ANCHOR_PATTERNS = [
|
|
49
|
+
/\bv?\d+\.\d+(?:\.\d+)+\b/g,
|
|
50
|
+
/\b[\w-]+(?:\/[\w.-]+)*\/[\w-]+\.\w{1,8}\b/g,
|
|
51
|
+
/\b[A-Z][A-Z0-9]*[_0-9][A-Z0-9_]*\b/g,
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* Extract up to `limit` distinctive anchors from original text, deduplicated,
|
|
55
|
+
* in order of first appearance. The runtime survival floor checks these against
|
|
56
|
+
* the compressed text; an empty result means the text has no mechanically
|
|
57
|
+
* recognizable load-bearing tokens (survival is then vacuous). Pure.
|
|
58
|
+
*/
|
|
59
|
+
export function extractAnchors(text, limit = 12) {
|
|
60
|
+
const found = [];
|
|
61
|
+
for (const pattern of ANCHOR_PATTERNS) {
|
|
62
|
+
for (const m of text.matchAll(pattern)) {
|
|
63
|
+
found.push({ index: m.index ?? 0, value: m[0] });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
found.sort((a, b) => a.index - b.index);
|
|
67
|
+
const anchors = [];
|
|
68
|
+
for (const f of found) {
|
|
69
|
+
if (anchors.length >= limit)
|
|
70
|
+
break;
|
|
71
|
+
if (!anchors.includes(f.value))
|
|
72
|
+
anchors.push(f.value);
|
|
73
|
+
}
|
|
74
|
+
return anchors;
|
|
75
|
+
}
|
|
76
|
+
/** One-line human summary of a survival assessment for eval output. Pure. */
|
|
77
|
+
export function formatFactSurvival(s) {
|
|
78
|
+
const pct = Math.round(s.survivalRate * 100);
|
|
79
|
+
return `fact survival: ${s.survived}/${s.total} buried facts survived (${pct}%)`;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=compression-survival.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression-survival.js","sourceRoot":"","sources":["../src/compression-survival.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAcH;2EAC2E;AAC3E,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAe,EACf,cAAsB;IAEtB,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/C,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,QAAQ;QACR,YAAY,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM;QAC9D,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,eAAe,GAAG;IACtB,2BAA2B;IAC3B,4CAA4C;IAC5C,qCAAqC;CACtC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAK,GAAG,EAAE;IACrD,MAAM,KAAK,GAAuC,EAAE,CAAC;IACrD,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;QACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,CAAe;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;IAC7C,OAAO,kBAAkB,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,2BAA2B,GAAG,IAAI,CAAC;AACnF,CAAC"}
|
|
@@ -34,6 +34,15 @@ export type CompressorMode = "off" | "headroom";
|
|
|
34
34
|
*/
|
|
35
35
|
export declare const COMPRESSION_CATEGORIES: readonly ["issue-body", "command-log", "prior-iteration", "read-artifact", "memory-projection"];
|
|
36
36
|
export type CompressionCategory = (typeof COMPRESSION_CATEGORIES)[number];
|
|
37
|
+
/**
|
|
38
|
+
* Whether a category is authorized for live compression (issue #200). The
|
|
39
|
+
* roadmap scopes Headroom to the `retrievable` lifecycle class — today only
|
|
40
|
+
* `issue-body` (re-fetchable from the tracker). `command-log` diffs/patches
|
|
41
|
+
* feed the *current* decision (the reviewer reads `head.diff` line by line),
|
|
42
|
+
* and `read-artifact` is the unknown default bucket, so both stay verbatim.
|
|
43
|
+
* Pure.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isCompressibleCategory(category: CompressionCategory): boolean;
|
|
37
46
|
/** Content handed to the compressor, tagged by source category + a stable key. */
|
|
38
47
|
export type CompressInput = {
|
|
39
48
|
/** A run-unique key (used to name the retrieval artifact). */
|
|
@@ -164,6 +173,17 @@ export declare function summarizeToolCompression(usages: ToolUsage[]): {
|
|
|
164
173
|
tokensSaved: number;
|
|
165
174
|
retrievals: number;
|
|
166
175
|
};
|
|
176
|
+
/**
|
|
177
|
+
* Summarize the codebase-memory retrieval {@link ToolUsage} records on a run's
|
|
178
|
+
* stage records (name `codebase-memory`) — what a context report reads to show
|
|
179
|
+
* graph-retrieval evidence (P26). Pure. `undefined` when no such usage is
|
|
180
|
+
* present, so a non-CBM run's report omits the section entirely.
|
|
181
|
+
*/
|
|
182
|
+
export declare function summarizeGraphRetrieval(usages: ToolUsage[]): {
|
|
183
|
+
queries: number;
|
|
184
|
+
tokensAvoided: number;
|
|
185
|
+
fallbacks: number;
|
|
186
|
+
} | undefined;
|
|
167
187
|
/** One-line human summary of compression savings for the context report. Pure. */
|
|
168
188
|
export declare function formatCompressionSummary(s: CompressionSummary): string;
|
|
169
189
|
//# sourceMappingURL=context-compressor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-compressor.d.ts","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context-compressor.d.ts","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { assessFactSurvival, extractAnchors } from "./compression-survival.js";
|
|
3
4
|
import { estimateTokens } from "./context-report.js";
|
|
4
5
|
import { runReportDir } from "./run-report.js";
|
|
5
6
|
const MODES = new Set(["off", "headroom"]);
|
|
@@ -14,6 +15,17 @@ export const COMPRESSION_CATEGORIES = [
|
|
|
14
15
|
"read-artifact",
|
|
15
16
|
"memory-projection",
|
|
16
17
|
];
|
|
18
|
+
/**
|
|
19
|
+
* Whether a category is authorized for live compression (issue #200). The
|
|
20
|
+
* roadmap scopes Headroom to the `retrievable` lifecycle class — today only
|
|
21
|
+
* `issue-body` (re-fetchable from the tracker). `command-log` diffs/patches
|
|
22
|
+
* feed the *current* decision (the reviewer reads `head.diff` line by line),
|
|
23
|
+
* and `read-artifact` is the unknown default bucket, so both stay verbatim.
|
|
24
|
+
* Pure.
|
|
25
|
+
*/
|
|
26
|
+
export function isCompressibleCategory(category) {
|
|
27
|
+
return category === "issue-body";
|
|
28
|
+
}
|
|
17
29
|
/**
|
|
18
30
|
* Resolve the compressor mode from the flag/env/config precedence chain (flag >
|
|
19
31
|
* env > config > off). An unrecognized value resolves to `off`, so a typo never
|
|
@@ -63,6 +75,13 @@ export function runRetrievalStore(workspaceDir, runId) {
|
|
|
63
75
|
return join(".otto", "runs", runId, "compressed", `${safe}.orig`);
|
|
64
76
|
};
|
|
65
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Minimum share of extracted anchors that must survive for a compression to be
|
|
80
|
+
* kept. At the default 12-anchor cap this tolerates one dropped anchor —
|
|
81
|
+
* summarizers legitimately trim repetition, but losing more than that means
|
|
82
|
+
* load-bearing identifiers are being destroyed.
|
|
83
|
+
*/
|
|
84
|
+
const SURVIVAL_FLOOR = 0.9;
|
|
66
85
|
/**
|
|
67
86
|
* Turn a raw compression attempt into a measured {@link CompressOutput}, shared
|
|
68
87
|
* by the async ({@link compressContent}) and sync ({@link compressContentSync})
|
|
@@ -91,6 +110,17 @@ function assembleOutput(input, version, result, store, latencyMs) {
|
|
|
91
110
|
return passthrough(!result.ok, result.note ??
|
|
92
111
|
(result.ok ? "no token reduction — kept original" : undefined));
|
|
93
112
|
}
|
|
113
|
+
// Runtime fact-survival floor (issue #200): a compression that blanks the
|
|
114
|
+
// content or drops mechanically extracted load-bearing anchors (paths,
|
|
115
|
+
// identifier codes, versions) is rejected in favor of the original.
|
|
116
|
+
if (result.text.trim().length === 0) {
|
|
117
|
+
return passthrough(true, "blank compression result — kept original");
|
|
118
|
+
}
|
|
119
|
+
const survival = assessFactSurvival(extractAnchors(input.text), result.text);
|
|
120
|
+
if (survival.survivalRate < SURVIVAL_FLOOR) {
|
|
121
|
+
return passthrough(true, `survival floor: only ${survival.survived}/${survival.total} anchors ` +
|
|
122
|
+
`survived (missing: ${survival.missing.slice(0, 3).join(", ")}) — kept original`);
|
|
123
|
+
}
|
|
94
124
|
const retrievalHandle = store ? store(input.key, input.text) : undefined;
|
|
95
125
|
return {
|
|
96
126
|
text: result.text,
|
|
@@ -229,6 +259,22 @@ export function summarizeToolCompression(usages) {
|
|
|
229
259
|
}
|
|
230
260
|
return { invocations, tokensSaved, retrievals };
|
|
231
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Summarize the codebase-memory retrieval {@link ToolUsage} records on a run's
|
|
264
|
+
* stage records (name `codebase-memory`) — what a context report reads to show
|
|
265
|
+
* graph-retrieval evidence (P26). Pure. `undefined` when no such usage is
|
|
266
|
+
* present, so a non-CBM run's report omits the section entirely.
|
|
267
|
+
*/
|
|
268
|
+
export function summarizeGraphRetrieval(usages) {
|
|
269
|
+
const graph = usages.filter((u) => u.name === "codebase-memory");
|
|
270
|
+
if (graph.length === 0)
|
|
271
|
+
return undefined;
|
|
272
|
+
return {
|
|
273
|
+
queries: graph.length,
|
|
274
|
+
tokensAvoided: graph.reduce((s, u) => s + (u.tokensAvoided ?? 0), 0),
|
|
275
|
+
fallbacks: graph.filter((u) => u.fallbackReason).length,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
232
278
|
/** One-line human summary of compression savings for the context report. Pure. */
|
|
233
279
|
export function formatCompressionSummary(s) {
|
|
234
280
|
if (s.invocations === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-compressor.js","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAkC/C,MAAM,KAAK,GAAwB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,aAAa;IACb,iBAAiB;IACjB,eAAe;IACf,mBAAmB;CACX,CAAC;
|
|
1
|
+
{"version":3,"file":"context-compressor.js","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAkC/C,MAAM,KAAK,GAAwB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,aAAa;IACb,iBAAiB;IACjB,eAAe;IACf,mBAAmB;CACX,CAAC;AAGX;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAA6B;IAClE,OAAO,QAAQ,KAAK,YAAY,CAAC;AACnC,CAAC;AA+DD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAoB,CAAC,CAAC,CAAC,KAAK,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,MAAyB,OAAO,CAAC,GAAG,EACpC,IAAa;IAEb,IAAI,MAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CACtC,CAAC;QAC7B,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ;YAC3C,MAAM,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IACD,OAAO,qBAAqB,CAAC;QAC3B,IAAI;QACJ,GAAG,EAAE,GAAG,CAAC,uBAAuB;QAChC,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAAoB,EACpB,KAAa;IAEb,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;QACvB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC;AAKD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;;;GAOG;AACH,SAAS,cAAc,CACrB,KAAoB,EACpB,OAAe,EACf,MAAwB,EACxB,KAA4B,EAC5B,SAAiB;IAEjB,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,CAAC,QAAiB,EAAE,IAAa,EAAkB,EAAE,CAAC,CAAC;QACzE,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY;QACZ,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,CAAC;QACd,SAAS;QACT,iBAAiB,EAAE,OAAO;QAC1B,QAAQ;QACR,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1B,CAAC,CAAC;IAEH,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,IAAI,EACJ,eAAe,OAAO,+BAA+B,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;QAC9C,OAAO,WAAW,CAChB,CAAC,MAAM,CAAC,EAAE,EACV,MAAM,CAAC,IAAI;YACT,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,SAAS,CAAC,CACjE,CAAC;IACJ,CAAC;IACD,0EAA0E;IAC1E,uEAAuE;IACvE,oEAAoE;IACpE,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,WAAW,CAAC,IAAI,EAAE,0CAA0C,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7E,IAAI,QAAQ,CAAC,YAAY,GAAG,cAAc,EAAE,CAAC;QAC3C,OAAO,WAAW,CAChB,IAAI,EACJ,wBAAwB,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,WAAW;YACpE,sBAAsB,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY;QACZ,WAAW;QACX,WAAW,EAAE,YAAY,GAAG,WAAW;QACvC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,SAAS;QACT,iBAAiB,EAAE,OAAO;QAC1B,QAAQ,EAAE,KAAK;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAoC,EACpC,KAAoB,EACpB,KAA4B,EAC5B,OAA+B,EAAE;IAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,IAAI,CAAC,UAAU;QACb,OAAO,cAAc,CACnB,KAAK,EACL,KAAK,EACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAC9B,IAAI,EACJ,CAAC,CACF,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,IAAI,SAAkB,CAAC;IACvB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,SAAS;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAE9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB;YACE,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,qBAAsB,CAAW,CAAC,OAAO,IAAI,CAAC,EAAE;SACvD,EACD,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAwC,EACxC,KAAoB,EACpB,KAA4B,EAC5B,MAAoB,IAAI,CAAC,GAAG;IAE5B,IAAI,CAAC,UAAU;QACb,OAAO,cAAc,CACnB,KAAK,EACL,KAAK,EACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAC9B,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,IAAI,CAAC,UAAU,CAAC,SAAS;QACvB,OAAO,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB;YACE,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,qBAAsB,CAAW,CAAC,OAAO,IAAI,CAAC,EAAE;SACvD,EACD,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,QAA6B,EAC7B,KAAc;IAEd,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,GAAG,CAAC,MAAM,CAAC,eAAe;YACxB,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE;YAC7C,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,EAAE;YACP,cAAc,QAAQ,EAAE;YACxB,MAAM,CAAC,QAAQ;gBACb,CAAC,CAAC,yBAAyB;gBAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,SAAS;SACzC;KACF,CAAC;AACJ,CAAC;AAYD,iFAAiF;AACjF,MAAM,UAAU,oBAAoB,CAClC,OAAyB;IAEzB,MAAM,CAAC,GAAuB;QAC5B,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC;QACjC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QAC/B,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QAC/B,IAAI,CAAC,CAAC,eAAe;YAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC,QAAQ;YAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAmB;IAK1D,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACpC,WAAW,IAAI,CAAC,CAAC;QACjB,WAAW,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,eAAe;YAAE,UAAU,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAmB;IAOzD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACpE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM;KACxD,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAAC,CAAqB;IAC5D,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC;QAAE,OAAO,gCAAgC,CAAC;IACjE,MAAM,GAAG,GACP,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG;QACZ,wBAAwB,CAAC,CAAC,WAAW,kBAAkB,GAAG,aAAa,CAAC,CAAC,WAAW,UAAU;QAC9F,GAAG,CAAC,CAAC,UAAU,uBAAuB;KACvC,CAAC;IACF,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,2BAA2B,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAChC,CAAC"}
|
package/dist/eval.d.ts
CHANGED
|
@@ -47,6 +47,29 @@ export type EvalSignals = {
|
|
|
47
47
|
* trajectory), so this function stays pure.
|
|
48
48
|
*/
|
|
49
49
|
reportLegibilityRatio: number | null;
|
|
50
|
+
/**
|
|
51
|
+
* Count of external tool invocations recorded across the manifest and stage
|
|
52
|
+
* records (P26 codebase-memory spike). `0` when no tools were used.
|
|
53
|
+
*/
|
|
54
|
+
toolCallCount: number;
|
|
55
|
+
/**
|
|
56
|
+
* Sum of `tokensAvoided` reported by tool invocations (P26) — tokens that
|
|
57
|
+
* would have been spent inlining context the tool retrieved instead. `0`
|
|
58
|
+
* when no tool reported an estimate.
|
|
59
|
+
*/
|
|
60
|
+
tokensAvoided: number;
|
|
61
|
+
/**
|
|
62
|
+
* Fraction (0..1) of the benchmark's known-impacted files that the run's
|
|
63
|
+
* answer text surfaced, scored by {@link scoreImpactRecall} against a
|
|
64
|
+
* fixture's `impact.json` (P26). `0` when not scored from the trajectory
|
|
65
|
+
* alone — callers score this against a fixture's known-impact list.
|
|
66
|
+
*/
|
|
67
|
+
impactRecall: number;
|
|
68
|
+
/**
|
|
69
|
+
* Milliseconds spent building/refreshing the codebase-memory index for this
|
|
70
|
+
* run (P26), summed from `manifest.codebaseMemory`. `0` for non-CBM runs.
|
|
71
|
+
*/
|
|
72
|
+
indexingOverheadMs: number;
|
|
50
73
|
};
|
|
51
74
|
/**
|
|
52
75
|
* Derive {@link EvalSignals} from a recorded run trajectory. Pure: no I/O, no
|
|
@@ -58,6 +81,13 @@ export declare function scoreTrajectory(manifest: RunManifest, stages: StageReco
|
|
|
58
81
|
planScore?: PlanRubricScore;
|
|
59
82
|
reportScore?: ReportRubricScore;
|
|
60
83
|
}): EvalSignals;
|
|
84
|
+
/**
|
|
85
|
+
* Score how many `knownImpactedFiles` a run's answer text surfaced — a thin
|
|
86
|
+
* wrapper over {@link assessFactSurvival} treating each impacted file path as
|
|
87
|
+
* a "fact" that must survive into the answer (P26 codebase-memory spike).
|
|
88
|
+
* Vacuously `1` for an empty impact list. Pure.
|
|
89
|
+
*/
|
|
90
|
+
export declare function scoreImpactRecall(knownImpactedFiles: string[], answerText: string): number;
|
|
61
91
|
/** One Otto run's signals tagged with the configuration label that produced it. */
|
|
62
92
|
export type LabelledSignals = {
|
|
63
93
|
label: string;
|
package/dist/eval.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yEAAyE;IACzE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,WAAW,EAAE,EACrB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,eAAe,CAAC;IAAC,WAAW,CAAC,EAAE,iBAAiB,CAAA;CAAO,GAC1E,WAAW,CAoCb;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,kBAAkB,EAAE,MAAM,EAAE,EAC5B,UAAU,EAAE,MAAM,GACjB,MAAM,CAGR;AAUD,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AA8FtE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,MAAM,CAoCnE"}
|