Skip to content

Commit d0da75e

Browse files
committed
Redact reviewer transcript tool content
1 parent 10e57c3 commit d0da75e

2 files changed

Lines changed: 21 additions & 7 deletions

File tree

.github/scripts/run-agent-task/prepare-agent-task-upload.mjs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,28 @@ function safeTargetPath(value) {
171171
return path ? `workspace/${path}` : undefined
172172
}
173173

174+
function omittedText(value) {
175+
if (typeof value !== "string") return undefined
176+
const bytes = Buffer.byteLength(value)
177+
return { bytes, sha256: digest(Buffer.from(value)) }
178+
}
179+
180+
function projectArguments(value) {
181+
const entry = record(value)
182+
const paths = [entry.path, ...(Array.isArray(entry.paths) ? entry.paths : [])].map(safeTargetPath).filter(Boolean).slice(0, 32)
183+
const counts = Object.fromEntries(["bytes", "byte_count", "match_count", "matches", "change_count", "changes", "count"].flatMap((key) => typeof entry[key] === "number" ? [[key, entry[key]]] : []))
184+
const payloads = Object.fromEntries(["content", "patch", "diff", "write", "old_string", "new_string", "text"].flatMap((key) => omittedText(entry[key]) ? [[key, omittedText(entry[key])]] : []))
185+
return Object.fromEntries(Object.entries({ paths: paths.length ? paths : undefined, counts: Object.keys(counts).length ? counts : undefined, omitted_payloads: Object.keys(payloads).length ? payloads : undefined }).filter(([, item]) => item !== undefined))
186+
}
187+
174188
function projectToolCall(value) {
175189
const entry = record(value)
176190
const tool = boundedText(entry.tool_id ?? entry.toolId ?? entry.name ?? entry.tool_name)
177-
const path = safeTargetPath(record(entry.args ?? entry.arguments).path ?? entry.path)
191+
const args = projectArguments(entry.args ?? entry.arguments)
192+
const paths = [...(args.paths ?? []), ...[safeTargetPath(entry.path)].filter(Boolean)].slice(0, 32)
178193
const result = record(entry.result ?? entry.output)
179-
const rawContent = result.content ?? entry.content
180-
const content = path && /workspace/i.test(tool ?? "") && typeof rawContent === "string"
181-
? redact(sanitizeText(rawContent)).slice(0, MAX_REVIEW_TEXT_BYTES)
182-
: undefined
183-
return Object.fromEntries(Object.entries({ tool, path, status: boundedText(entry.status), arguments: path ? { path } : undefined, content, error: boundedText(record(entry.error).message ?? entry.error) }).filter(([, item]) => item !== undefined))
194+
const resultSummary = projectArguments({ ...result, content: result.content ?? entry.content, path: result.path ?? entry.path })
195+
return Object.fromEntries(Object.entries({ tool, paths: paths.length ? paths : undefined, status: boundedText(entry.status), arguments: Object.keys(args).length ? args : undefined, result: Object.keys(resultSummary).length ? resultSummary : undefined, error_code: boundedText(record(entry.error).code ?? entry.error_code), error: boundedText(record(entry.error).message ?? entry.error) }).filter(([, item]) => item !== undefined))
184196
}
185197

186198
function projectParsed(value) {

tests/runtime-sources-materialization.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,12 @@ await withTempDir("wp-codebox-runtime-source-upload-", async (directory) => {
172172
await writeFile(join(workspace, ".codebox", "agent-task-workflow-result.json"), JSON.stringify({ runtime_result: { agent_task_run_result: { refs: { transcripts: [{ kind: "codebox-transcript", path: "files/transcript.json", sha256: transcriptDigest }] } } }, typed_artifacts: [{ name: "reviewer-report", type: "report", artifact: { path: "prepared-plugins/agents-api/agents-api.php" } }] }))
173173
await execFileAsync(process.execPath, [script.pathname], { env: { ...process.env, AGENT_TASK_WORKSPACE: workspace, AGENT_TASK_UPLOAD_PATH: upload, WP_CODEBOX_RUNTIME_SOURCE_ROOT: privateRoot, OPENAI_API_KEY: "secret-transcript-value" } })
174174
const transcript = await readFile(join(upload, ".codebox", "agent-task-artifacts", "transcript.json"), "utf8")
175-
assert.match(transcript, /<\?php final class Target_Plugin/)
175+
assert.doesNotMatch(transcript, /<\?php final class Target_Plugin/)
176176
assert.match(transcript, /\[redacted-source-content\]/)
177177
assert.match(transcript, /Repeated workspace error/)
178178
assert.match(transcript, /workspace\/src\/plugin.php/)
179+
assert.match(transcript, /"bytes": 34/)
180+
assert.match(transcript, /"sha256": "[a-f0-9]{64}"/)
179181
assert.doesNotMatch(transcript, /private-runtime-source|secret-transcript-value|\/Users\/example/)
180182
const transcriptExclusions = await readFile(join(upload, ".codebox", "agent-task-artifacts", "exclusions.json"), "utf8")
181183
assert.match(transcriptExclusions, /canonical_transcripts/)

0 commit comments

Comments
 (0)