Skip to content

Commit 6c24c54

Browse files
committed
Format after rebase onto main
1 parent 5f56cc5 commit 6c24c54

37 files changed

Lines changed: 855 additions & 268 deletions

evals/compaction/fixtures.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,28 @@ export const REQUIRED_EVIDENCE: readonly Evidence[] = [
2020
{ id: "constraint", source: "operator:initial", value: "no-schema-change" },
2121
{ id: "decision", source: "operator:correction", value: "west-not-east" },
2222
{ id: "failure", source: "command:diagnose", value: "unsupported-format-7" },
23-
{ id: "decisive", source: "file:diagnostic.log:middle", value: "route-cobalt" },
23+
{
24+
id: "decisive",
25+
source: "file:diagnostic.log:middle",
26+
value: "route-cobalt",
27+
},
2428
];
2529

2630
export function evidenceText(facts: readonly Evidence[]): string {
27-
return facts.map((fact) => `[[evidence:${fact.id}|${fact.source}|${fact.value}]]`).join("\n");
31+
return facts
32+
.map((fact) => `[[evidence:${fact.id}|${fact.source}|${fact.value}]]`)
33+
.join("\n");
2834
}
2935

3036
export const INITIAL =
31-
"Audit the deployment. Preserve this constraint: " + evidenceText(REQUIRED_EVIDENCE.slice(0, 1));
37+
"Audit the deployment. Preserve this constraint: " +
38+
evidenceText(REQUIRED_EVIDENCE.slice(0, 1));
3239
export const CORRECTION =
33-
"Correction: target west instead of east. " + evidenceText(REQUIRED_EVIDENCE.slice(1, 2));
40+
"Correction: target west instead of east. " +
41+
evidenceText(REQUIRED_EVIDENCE.slice(1, 2));
3442
export const FAILED_OUTPUT =
35-
"Diagnostic preamble.\n".repeat(250) + evidenceText(REQUIRED_EVIDENCE.slice(2, 3));
43+
"Diagnostic preamble.\n".repeat(250) +
44+
evidenceText(REQUIRED_EVIDENCE.slice(2, 3));
3645
export const OVERSIZED_OUTPUT =
3746
"Unrelated diagnostic row.\n".repeat(1500) +
3847
evidenceText(REQUIRED_EVIDENCE.slice(3)) +

evals/compaction/metrics.test.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,25 @@ const baseline = {
3030

3131
describe("compaction baseline grading", () => {
3232
test("requires evidence actually visible to the scripted responder", () => {
33-
expect(recoverEvidence("[[evidence:region|operator:correction|west]]")).toEqual([fact]);
33+
expect(
34+
recoverEvidence("[[evidence:region|operator:correction|west]]"),
35+
).toEqual([fact]);
3436
expect(recoverEvidence("The region was mentioned earlier.")).toEqual([]);
3537
expect(
36-
grade({ ...baseline, recovered: recoverEvidence("evidence removed") }).factualRecovery,
38+
grade({ ...baseline, recovered: recoverEvidence("evidence removed") })
39+
.factualRecovery,
3740
).toBe(false);
3841
});
3942

4043
test("rejects wrong values, sources, and altered artifacts independently", () => {
4144
expect(grade(baseline).passed).toBe(true);
42-
expect(grade({ ...baseline, recovered: [{ ...fact, value: "east" }] }).passed).toBe(false);
43-
expect(grade({ ...baseline, recovered: [{ ...fact, source: "invented" }] }).passed).toBe(false);
45+
expect(
46+
grade({ ...baseline, recovered: [{ ...fact, value: "east" }] }).passed,
47+
).toBe(false);
48+
expect(
49+
grade({ ...baseline, recovered: [{ ...fact, source: "invented" }] })
50+
.passed,
51+
).toBe(false);
4452
const altered = grade({ ...baseline, artifact: "east\n" });
4553
expect(altered.completion).toBe(false);
4654
expect(altered.factualRecovery).toBe(true);
@@ -50,9 +58,13 @@ describe("compaction baseline grading", () => {
5058
expect(grade({ ...baseline, folds: [] }).qualifying).toBe(false);
5159
for (const fold of folds) {
5260
expect(qualifyingFold({ ...fold, persisted: false })).toBe(false);
53-
expect(qualifyingFold({ ...fold, afterHash: fold.beforeHash })).toBe(false);
61+
expect(qualifyingFold({ ...fold, afterHash: fold.beforeHash })).toBe(
62+
false,
63+
);
5464
expect(qualifyingFold({ ...fold, continuedAtCall: null })).toBe(false);
55-
expect(qualifyingFold({ ...fold, afterTurns: fold.beforeTurns })).toBe(false);
65+
expect(qualifyingFold({ ...fold, afterTurns: fold.beforeTurns })).toBe(
66+
false,
67+
);
5668
}
5769
expect(grade({ ...baseline, recovered: [] }).requiredFacts).toBe(1);
5870
});
@@ -89,16 +101,23 @@ describe("compaction baseline grading", () => {
89101
});
90102

91103
test("missing usage is unavailable, not zero or an unlabelled estimate", () => {
92-
expect(Measurement({ status: "unavailable", reason: "offline" }) instanceof type.errors).toBe(
93-
false,
94-
);
95104
expect(
96-
Measurement({ status: "reported", value: -1, unit: "tokens" }) instanceof type.errors,
97-
).toBe(true);
98-
expect(Measurement({ value: 0, unit: "tokens" }) instanceof type.errors).toBe(true);
105+
Measurement({ status: "unavailable", reason: "offline" }) instanceof
106+
type.errors,
107+
).toBe(false);
99108
expect(
100-
Measurement({ status: "synthetic", value: 200000, unit: "trigger tokens" }) instanceof
109+
Measurement({ status: "reported", value: -1, unit: "tokens" }) instanceof
101110
type.errors,
111+
).toBe(true);
112+
expect(
113+
Measurement({ value: 0, unit: "tokens" }) instanceof type.errors,
114+
).toBe(true);
115+
expect(
116+
Measurement({
117+
status: "synthetic",
118+
value: 200000,
119+
unit: "trigger tokens",
120+
}) instanceof type.errors,
102121
).toBe(false);
103122
});
104123
});

evals/compaction/metrics.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import { type } from "arktype";
22

3-
export const Evidence = type({ id: "string", source: "string", value: "string" });
3+
export const Evidence = type({
4+
id: "string",
5+
source: "string",
6+
value: "string",
7+
});
48
export type Evidence = typeof Evidence.infer;
59

610
export const Measurement = type.or(
711
{ status: "'unavailable'", reason: "string" },
8-
{ status: "'reported' | 'estimated' | 'synthetic'", value: "number >= 0", unit: "string" },
12+
{
13+
status: "'reported' | 'estimated' | 'synthetic'",
14+
value: "number >= 0",
15+
unit: "string",
16+
},
917
);
1018
export type Measurement = typeof Measurement.infer;
1119

@@ -54,8 +62,10 @@ export function repeatedWork(trace: readonly Work[]) {
5462
}
5563
if (seen.has(key)) {
5664
if (work.name === "read_file") repeatedReads++;
57-
if (["grep", "search_files", "web_search"].includes(work.name)) repeatedSearches++;
58-
if (["write_file", "edit_file", "apply_patch"].includes(work.name)) duplicatedEdits++;
65+
if (["grep", "search_files", "web_search"].includes(work.name))
66+
repeatedSearches++;
67+
if (["write_file", "edit_file", "apply_patch"].includes(work.name))
68+
duplicatedEdits++;
5969
}
6070
if (failures.has(key)) repeatedFailedAttempts++;
6171
seen.add(key);
@@ -81,15 +91,20 @@ export function grade(args: {
8191
const recoveredFacts = args.expected.filter((fact) =>
8292
args.recovered.some(
8393
(answer) =>
84-
answer.id === fact.id && answer.source === fact.source && answer.value === fact.value,
94+
answer.id === fact.id &&
95+
answer.source === fact.source &&
96+
answer.value === fact.value,
8597
),
8698
).length;
8799
const work = repeatedWork(args.trace);
88100
const persistedFolds = args.folds.filter(qualifyingFold).length;
89101
const completion = args.artifact === args.expectedArtifact;
90102
const factualRecovery = recoveredFacts === args.expected.length;
91103
const repeatedActions =
92-
work.repeatedReads + work.repeatedSearches + work.repeatedFailedAttempts + work.duplicatedEdits;
104+
work.repeatedReads +
105+
work.repeatedSearches +
106+
work.repeatedFailedAttempts +
107+
work.duplicatedEdits;
93108
return {
94109
completion,
95110
factualRecovery,
@@ -98,14 +113,20 @@ export function grade(args: {
98113
persistedFolds,
99114
qualifying: persistedFolds >= 3,
100115
...work,
101-
passed: completion && factualRecovery && persistedFolds >= 3 && repeatedActions === 0,
116+
passed:
117+
completion &&
118+
factualRecovery &&
119+
persistedFolds >= 3 &&
120+
repeatedActions === 0,
102121
};
103122
}
104123

105124
/** The responder receives only inference-visible text, never grader expectations. */
106125
export function recoverEvidence(context: string): Evidence[] {
107126
const facts = new Map<string, Evidence>();
108-
for (const match of context.matchAll(/\[\[evidence:([^|\]\n]+)\|([^|\]\n]+)\|([^\]\n]+)\]\]/g)) {
127+
for (const match of context.matchAll(
128+
/\[\[evidence:([^|\]\n]+)\|([^|\]\n]+)\|([^\]\n]+)\]\]/g,
129+
)) {
109130
const [, id, source, value] = match;
110131
if (id !== undefined && source !== undefined && value !== undefined) {
111132
facts.set(id, { id, source, value });

src/agent/posix-tool-plugins.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,10 @@ describe("buildCorePosixToolPlugins", () => {
393393
permissionGate: gate,
394394
getEvidenceArchive: () => undefined,
395395
});
396-
const shellGuardIndex = findMiddlewareIndex(plugins, "[command timed out after");
396+
const shellGuardIndex = findMiddlewareIndex(
397+
plugins,
398+
"[command timed out after",
399+
);
397400
const archiveIndex = findMiddlewareIndex(
398401
plugins,
399402
"evidence archive is not available in this session",

src/agent/posix-tool-plugins.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export function buildCorePosixToolPlugins(
9595
// regardless.
9696
const allowOutside = (): boolean => permissionGate.getSkipPermissions();
9797
const truncationOptions =
98-
getBlobWriter !== undefined || getContextDir !== undefined || getEvidenceArchive !== undefined
98+
getBlobWriter !== undefined ||
99+
getContextDir !== undefined ||
100+
getEvidenceArchive !== undefined
99101
? {
100102
...(getBlobWriter !== undefined ? { getBlobWriter } : {}),
101103
...(getContextDir !== undefined ? { getContextDir } : {}),

src/agent/tools.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,8 @@ export async function createAgentToolset(
562562
let definition = advertiseEditFileLineRange(
563563
advertiseShellGuardTimeout(tool.definition, shellTimeout?.defaultMs),
564564
);
565-
if (getEvidenceArchive !== undefined) definition = advertiseArchiveSurface(definition);
565+
if (getEvidenceArchive !== undefined)
566+
definition = advertiseArchiveSurface(definition);
566567
return { ...tool, definition };
567568
}),
568569
createListDirTool(cwd, {

src/context-compactor.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,10 @@ describe("createPruningCompactor — consolidated handoff (CL-7521)", () => {
846846
}),
847847
);
848848
turns.push(
849-
makeTurn({ role: "user", content: [{ type: "text", text: "recent ask" }] }),
849+
makeTurn({
850+
role: "user",
851+
content: [{ type: "text", text: "recent ask" }],
852+
}),
850853
);
851854

852855
const output1 = (await compactor.apply(turns, mockStrategyCtx)).output;
@@ -970,7 +973,9 @@ describe("createPruningCompactor — consolidated handoff (CL-7521)", () => {
970973
const result1 = await compactor.apply(turns, mockStrategyCtx);
971974
expect(result1.output).toBe(turns);
972975
expect(result1.record.reason).toBe("summarize failed");
973-
expect(firstText(defined(result1.output[0]))).not.toContain(COMPACTED_PREFIX);
976+
expect(firstText(defined(result1.output[0]))).not.toContain(
977+
COMPACTED_PREFIX,
978+
);
974979

975980
const result2 = await compactor.apply(
976981
grow(result1.output, 16, "ok"),

src/mcp/client.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,12 @@ async function finishClient(
546546
serverName,
547547
tools,
548548
async callBlocks(toolName, args, signal) {
549-
const context = authContext === undefined ? undefined : { ...authContext, signal };
549+
const context =
550+
authContext === undefined ? undefined : { ...authContext, signal };
550551
const result = await withHTTPAuthorizationRecovery(context, () =>
551-
client.callTool({ name: toolName, arguments: args }, undefined, { signal }),
552+
client.callTool({ name: toolName, arguments: args }, undefined, {
553+
signal,
554+
}),
552555
);
553556
return validateMcpContentBlocks(result.content);
554557
},

src/mcp/plugin.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ export function mcpClientTools(
6060
client: MCPClient,
6161
spillOptions: McpSpillOptions = {},
6262
): AgentTool[] {
63-
const { getBlobWriter, getContextDir, excludeToolNames = [], getEvidenceArchive } = spillOptions;
63+
const {
64+
getBlobWriter,
65+
getContextDir,
66+
excludeToolNames = [],
67+
getEvidenceArchive,
68+
} = spillOptions;
6469
const excluded = new Set(excludeToolNames);
6570

6671
return client.tools

src/plugins/evidence-archive-path-guard.test.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,42 @@ const nextHandler = async (call: ToolCall): Promise<ToolResult> => ({
1717

1818
describe("isProtectedEvidenceLocation", () => {
1919
test("matches evidence-archive and tool-output/archive-* forms", () => {
20-
expect(isProtectedEvidenceLocation("evidence-archive/index.jsonl")).toBe(true);
21-
expect(isProtectedEvidenceLocation("/tmp/context/evidence-archive")).toBe(true);
22-
expect(isProtectedEvidenceLocation("C:\\tmp\\evidence-archive\\index.jsonl")).toBe(true);
23-
expect(isProtectedEvidenceLocation("tool-output/archive-sess-occ-1")).toBe(true);
24-
expect(isProtectedEvidenceLocation("tool-output:///archive-sess-occ-1")).toBe(true);
25-
expect(isProtectedEvidenceLocation("src/session/compaction-archive.ts")).toBe(false);
26-
expect(isProtectedEvidenceLocation("tool-output:///other-spill")).toBe(false);
20+
expect(isProtectedEvidenceLocation("evidence-archive/index.jsonl")).toBe(
21+
true,
22+
);
23+
expect(isProtectedEvidenceLocation("/tmp/context/evidence-archive")).toBe(
24+
true,
25+
);
26+
expect(
27+
isProtectedEvidenceLocation("C:\\tmp\\evidence-archive\\index.jsonl"),
28+
).toBe(true);
29+
expect(isProtectedEvidenceLocation("tool-output/archive-sess-occ-1")).toBe(
30+
true,
31+
);
32+
expect(
33+
isProtectedEvidenceLocation("tool-output:///archive-sess-occ-1"),
34+
).toBe(true);
35+
expect(
36+
isProtectedEvidenceLocation("src/session/compaction-archive.ts"),
37+
).toBe(false);
38+
expect(isProtectedEvidenceLocation("tool-output:///other-spill")).toBe(
39+
false,
40+
);
2741
});
2842
});
2943

3044
describe("evidenceArchivePathGuardPlugin", () => {
3145
test("denies path tools targeting evidence-archive or tool-output/archive-*", async () => {
3246
const plugin = evidenceArchivePathGuardPlugin();
33-
const handler = plugin.middleware ? plugin.middleware(nextHandler) : nextHandler;
47+
const handler = plugin.middleware
48+
? plugin.middleware(nextHandler)
49+
: nextHandler;
3450
const denied = [
3551
makeCall("read_file", { path: "evidence-archive/index.jsonl" }),
36-
makeCall("grep", { path: "/tmp/context/evidence-archive", pattern: "foo" }),
52+
makeCall("grep", {
53+
path: "/tmp/context/evidence-archive",
54+
pattern: "foo",
55+
}),
3756
makeCall("search_files", { path: "evidence-archive" }),
3857
makeCall("list_dir", { path: "evidence-archive" }),
3958
makeCall("write_file", { path: "evidence-archive/x", content: "nope" }),
@@ -50,7 +69,9 @@ describe("evidenceArchivePathGuardPlugin", () => {
5069

5170
test("does not deny a grep pattern that mentions evidence-archive", async () => {
5271
const plugin = evidenceArchivePathGuardPlugin();
53-
const handler = plugin.middleware ? plugin.middleware(nextHandler) : nextHandler;
72+
const handler = plugin.middleware
73+
? plugin.middleware(nextHandler)
74+
: nextHandler;
5475
const result = await handler(
5576
makeCall("grep", { path: "src", pattern: "evidence-archive" }),
5677
new AbortController().signal,
@@ -61,7 +82,9 @@ describe("evidenceArchivePathGuardPlugin", () => {
6182

6283
test("passes ordinary workspace paths", async () => {
6384
const plugin = evidenceArchivePathGuardPlugin();
64-
const handler = plugin.middleware ? plugin.middleware(nextHandler) : nextHandler;
85+
const handler = plugin.middleware
86+
? plugin.middleware(nextHandler)
87+
: nextHandler;
6588
const result = await handler(
6689
makeCall("read_file", { path: "src/session/compaction-archive.ts" }),
6790
new AbortController().signal,

0 commit comments

Comments
 (0)