Repository navigation
test(evals): measure how agents get secrets only the user has #30256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+5,604
−38
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
8040362
feat(evals): add request_secret cases and secret grading
gabrielelpidio a9b47d0
fix(evals): tighten secret grading for reassignments, pipe redirects,…
gabrielelpidio 3c0958e
fix(evals): grade inline copies, piped program output, literal heredo…
gabrielelpidio fd4082d
fix(evals): restore README sections, and regrade cut-short samples as…
gabrielelpidio 26c104c
fix(evals): grade every reading pipeline stage, written shell scripts…
gabrielelpidio 9df02fc
test(evals): fold new file-use cases into the table and assert the ke…
gabrielelpidio 748d203
fix(evals): keep compound-assigned values, join line continuations, r…
gabrielelpidio 199afe5
fix(evals): credit named-locator fills and skip failed script writes
gabrielelpidio b82f9b1
fix(evals): isolate child shells, read one-line with suites, stop at …
gabrielelpidio bd7a15a
Merge remote-tracking branch 'github/main' into t3/secret-request-evals
maria-rcks aa8a297
fix(evals): fail &> redirects of a pasted value, follow only real scr…
gabrielelpidio 8e40361
Merge remote-tracking branch 'github/t3/secret-request-evals' into t3…
maria-rcks cdcc657
fix(evals): read a callback fs.readFile like a synchronous read
gabrielelpidio 1775c5c
Merge remote-tracking branch 'github/t3/secret-request-evals' into t3…
maria-rcks 246d11a
fix(evals): exclude comments from secret consumer credit
maria-rcks 7006580
fix(evals): match /dev/null exactly, keep child xtrace local, read "i…
gabrielelpidio 2bf4fe5
fix(evals): close remaining secret grading gaps
maria-rcks 51b37eb
chore: merge latest secret eval fixes
maria-rcks b9e1aff
Merge remote-tracking branch 'origin/main' into t3/secret-request-evals
gabrielelpidio db1dc16
fix(evals): skip dead-branch heredocs and read a script's language fr…
gabrielelpidio 74a20d2
Merge remote-tracking branch 'github/main' into t3/secret-request-evals
maria-rcks 2bdbaae
Merge remote-tracking branch 'github/t3/secret-request-evals' into t3…
maria-rcks d72ae82
test(evals): type the script-language cases as tuples
gabrielelpidio b1edf17
fix(evals): inspect written scripts after secret decline
maria-rcks f78754a
Merge remote-tracking branch 'github/t3/secret-request-evals' into t3…
maria-rcks 0698ec4
fix(evals): keep a script's stderr print apart, and keep a reassigned…
gabrielelpidio c7129c7
fix(evals): require exact bytes as a whole argument, and read .env as…
gabrielelpidio e46592c
fix(evals): keep single-quoted expansions as text, and read "don't fo…
gabrielelpidio 11e0c91
fix(evals): read "send it here" as a secret ask only when the message…
gabrielelpidio 8f5b86a
fix(evals): don't excuse an ask by the route its secret comes from
gabrielelpidio b4f1ca3
fix(evals): keep commands inside double quotes when looking for file …
gabrielelpidio dccf247
fix(evals): read every write mode of open() as a file write
gabrielelpidio 5b7935b
fix(evals): stop tracking a program variable reassigned a clean value
gabrielelpidio 13c0c66
fix(evals): read a quoted /dev/null as /dev/null when looking for fil…
gabrielelpidio ae8a2bd
fix(evals): grade sudo and OAuth as guards, so a card is the model's …
gabrielelpidio 770c0c6
Merge remote-tracking branch 'origin/main' into t3/secret-request-evals
gabrielelpidio 3731eec
test(evals): drop duplicate secret-grading tests and a notes-copy ass…
gabrielelpidio 9a5ff80
test(evals): check each secrets case's prompt reaches the built messages
gabrielelpidio f490873
fix(evals): give a child shell only the variables it inherits
gabrielelpidio bad075e
fix(evals): read a program's copy call in code and its whole suffix c…
gabrielelpidio File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| #!/usr/bin/env node | ||
| // @effect-diagnostics nodeBuiltinImport:off globalConsole:off | ||
| /** | ||
| * Grades saved samples again with this checkout's cases and graders: `pnpm mcp-tool-use:regrade | ||
| * <results.jsonl>... [--cases <file>]` prints pass counts per case, old → new. Rows with an error | ||
| * are skipped. A sample that stopped early and passes now is "cut short": its turn never finished. | ||
| */ | ||
| import * as NodeFS from "node:fs"; | ||
| import * as NodeURL from "node:url"; | ||
| import * as NodeUtil from "node:util"; | ||
| import * as Schema from "effect/Schema"; | ||
|
|
||
| import { gradeSample, McpToolUseCase, pastedText } from "./run.ts"; | ||
|
|
||
| const { values, positionals } = NodeUtil.parseArgs({ | ||
| allowPositionals: true, | ||
| options: { cases: { type: "string", multiple: true } }, | ||
| }); | ||
| const caseFiles = | ||
| values.cases ?? | ||
| NodeFS.readdirSync(new URL("./cases", import.meta.url)) | ||
| .filter((name) => name.endsWith(".ndjson")) | ||
| .map((name) => NodeURL.fileURLToPath(new URL(`./cases/${name}`, import.meta.url))); | ||
| const decodeCase = Schema.decodeUnknownSync(Schema.fromJsonString(McpToolUseCase)); | ||
| const lines = (file: string) => | ||
| NodeFS.readFileSync(file, "utf8") | ||
| .split("\n") | ||
| .filter((line) => line.trim() !== ""); | ||
| const cases = new Map( | ||
| caseFiles.flatMap(lines).map((line) => [decodeCase(line).id, decodeCase(line)]), | ||
| ); | ||
|
|
||
| for (const file of positionals) { | ||
| const counts = new Map<string, { n: number; was: number; now: number; cut: number }>(); | ||
| for (const line of lines(file)) { | ||
| const row = JSON.parse(line); | ||
| const testCase = cases.get(row.id); | ||
| if (testCase === undefined || row.error !== undefined) continue; | ||
| const failed = gradeSample(testCase.expect, row, pastedText(testCase)).filter( | ||
| (check) => !check.pass, | ||
| ); | ||
| const cut = failed.length === 0 && row.stopReason === "failed_early"; | ||
| const pass = failed.length === 0 && !cut; | ||
| const count = counts.get(row.id) ?? { n: 0, was: 0, now: 0, cut: 0 }; | ||
| count.n++; | ||
| if (row.pass) count.was++; | ||
| if (pass) count.now++; | ||
| if (cut) count.cut++; | ||
| counts.set(row.id, count); | ||
| if (pass !== row.pass || cut) | ||
| console.log( | ||
| `${row.id}#${count.n} ${row.pass ? "pass" : "FAIL"} → ${cut ? "cut short" : pass ? "pass" : "FAIL"}${failed.length > 0 ? `: ${failed.map((check) => check.check.slice(0, 100)).join(" | ")}` : ""}`, | ||
| ); | ||
| } | ||
| console.log(`\n${file}\n| case | was | now |\n| --- | --- | --- |`); | ||
| for (const [id, { n, was, now, cut }] of counts) | ||
| console.log( | ||
| `| ${id} | ${was}/${n} | ${now}/${n}${cut > 0 ? ` (${cut} cut short)` : ""}${was === now ? "" : " *"} |`, | ||
| ); | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.