diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index 074ab7a3d..58e3a4270 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -39,8 +39,9 @@ try { ``` `result.findings` contains this scan's findings; `repositoryFindings` also -includes earlier open findings when available. Matching earlier findings can -make one extra model call, even with a cost limit. +includes earlier open findings when available. Matching earlier findings uses +additional model calls, with large inputs split into batches. These calls are +outside the scan's recorded cost and `maxCostUsd` limit. Keep results outside the repository and restrict access: reports can contain source code, vulnerability details, and reproduction steps. diff --git a/sdk/typescript/src/api.ts b/sdk/typescript/src/api.ts index f966847dd..5e6e85fc1 100644 --- a/sdk/typescript/src/api.ts +++ b/sdk/typescript/src/api.ts @@ -1703,7 +1703,6 @@ export class CodexSecurity { ((input, comparisonOptions) => matchScanFindingsInternal(input, comparisonOptions, { surface: this.#surface, - allowBatching: false, })), environment, model, diff --git a/sdk/typescript/src/scan-comparison.ts b/sdk/typescript/src/scan-comparison.ts index 71a6af13e..75bde756c 100644 --- a/sdk/typescript/src/scan-comparison.ts +++ b/sdk/typescript/src/scan-comparison.ts @@ -174,7 +174,7 @@ export async function matchScanFindings( export async function matchScanFindingsInternal( input: ScanComparisonInput, options: ScanComparisonOptions = {}, - runtimeOptions: { surface: CodexSecuritySurface; allowBatching?: boolean }, + runtimeOptions: { surface: CodexSecuritySurface }, ): Promise { const comparisons: ScanComparisonResult[] = []; const allowHistoricalUncertainty = @@ -182,7 +182,7 @@ export async function matchScanFindingsInternal( const outputSchema = z.toJSONSchema(comparisonSchema.required(), { target: "openapi-3.0", }); - for (const batch of comparisonBatches(input, runtimeOptions.allowBatching)) { + for (const batch of comparisonBatches(input)) { options.signal?.throwIfAborted(); const finalResponse = await runReadOnlyCodex( batch.prompt, @@ -214,10 +214,9 @@ export async function matchScanFindingsInternal( function* comparisonBatches( input: ScanComparisonInput, - allowBatching = true, ): Generator<{ input: ScanComparisonInput; prompt: string }> { const prompt = comparisonPrompt(input); - if (allowBatching && prompt.length > CODEX_MAX_INPUT_CHARACTERS / 2) { + if (prompt.length > CODEX_MAX_INPUT_CHARACTERS / 2) { // Splitting one side at a time covers every before/after pair exactly once. const side = input.before.length > 1 && diff --git a/sdk/typescript/tests-ts/scan-comparison-batches.test.ts b/sdk/typescript/tests-ts/scan-comparison-batches.test.ts index 59fe913c9..82f98d733 100644 --- a/sdk/typescript/tests-ts/scan-comparison-batches.test.ts +++ b/sdk/typescript/tests-ts/scan-comparison-batches.test.ts @@ -1,7 +1,6 @@ import { expect, test } from "bun:test"; import { matchScanFindings, - matchScanFindingsInternal, type ScanComparisonInput, type ScanComparisonOptions, type ScanComparisonResult, @@ -252,36 +251,6 @@ test("uses Codex's full allowance for individual pairs without truncation", asyn expect(oversized.before[0]!.evidence).toHaveLength(1048576); }); -test.each([200000, 300000])( - "keeps automatic post-scan matching to at most one call (%p characters per finding)", - async (characters) => { - const input = { - before: Array.from({ length: 4 }, (_, index) => - finding(`before-${index}`, characters), - ), - after: [finding("after")], - }; - const calls: ScanComparisonInput[] = []; - const comparison = matchScanFindingsInternal( - input, - { - codex: codex((batch) => { - calls.push(batch); - return noMatches; - }), - }, - { surface: "sdk", allowBatching: false }, - ); - if (characters === 300000) { - await expect(comparison).rejects.toThrow("input limit"); - expect(calls).toEqual([]); - } else { - expect(await comparison).toEqual(noMatches); - expect(calls).toEqual([input]); - } - }, -); - test("stops between batches when canceled", async () => { const controller = new AbortController(); let calls = 0;