Skip to content

Commit 2779e05

Browse files
ianw-oaicopyberry
authored andcommitted
chore(codex-security): sync public projection
- [codex] Add direct Codex Security model selection (#11885... GitOrigin-Timestamp=2026-07-26T14:32:18-07:00 GitOrigin-RevId: cd6e33602ab57b4a90303f65db4a5e145eb3592d
1 parent f180f4e commit 2779e05

7 files changed

Lines changed: 1052 additions & 929 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ value, including when no stored sign-in exists.
5858
Scan a subset of a repository or write machine-readable results:
5959

6060
```bash
61+
npx codex-security scan /path/to/repo --model gpt-5.6-terra
6162
npx codex-security scan /path/to/repo --path src --path tests
6263
npx codex-security scan /path/to/repo --knowledge-base /path/to/threat-models --knowledge-base /path/to/architecture.pdf
6364
npx codex-security scan /path/to/repo --diff origin/main --json
@@ -148,11 +149,11 @@ JSON scans remain noninteractive, including when stderr is a terminal. Commands
148149
that run Codex interactively (`validate`, `patch`, `login`, and `logout`) reject
149150
`--json`. Write CSV exports to a file when JSON output is selected.
150151

151-
Scans use `gpt-5.6-sol` with extra-high reasoning effort by default. To override
152-
either setting, pass valid TOML values (including quotes for strings):
152+
Scans use `gpt-5.6-sol` with extra-high reasoning effort by default. Switch
153+
models with `--model`. Use `--codex` for other Codex settings:
153154

154155
```bash
155-
npx codex-security scan . --codex 'model="gpt-5.6-sol"' --codex 'model_reasoning_effort="high"'
156+
npx codex-security scan . --model gpt-5.6-terra --codex 'model_reasoning_effort="high"'
156157
```
157158

158159
Scans report their requested paths and actual ranking, file-review, validation,

sdk/typescript/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ stored sign-in exists.
9696

9797
```bash
9898
npx codex-security scan /path/to/repository
99+
npx codex-security scan /path/to/repository --model gpt-5.6-terra
99100
npx codex-security scan /path/to/repository --path src --path tests
100101
npx codex-security scan /path/to/repository --knowledge-base /path/to/threat-models --knowledge-base /path/to/architecture.pdf
101102
npx codex-security scan /path/to/repository --diff origin/main --json
@@ -150,9 +151,10 @@ for a passing policy. Incomplete scans still write the available human or JSON
150151
result to stdout and a coverage warning to stderr, including in report-only
151152
mode.
152153

153-
Scans use `gpt-5.6-sol` with extra-high reasoning effort by default. Override
154-
either setting with repeatable `--codex KEY=VALUE` options, for example
155-
`--codex 'model="gpt-5.6-sol"' --codex 'model_reasoning_effort="high"'`.
154+
Scans use `gpt-5.6-sol` with extra-high reasoning effort by default. Use
155+
`--model gpt-5.6-terra` to switch models. Use repeatable `--codex KEY=VALUE`
156+
options for other Codex settings, such as
157+
`--codex 'model_reasoning_effort="high"'`.
156158

157159
Scan progress identifies the requested paths and reports actual ranking,
158160
file-review, validation, and attack-path phases as they become available.

sdk/typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"generate:models": "node scripts/generate-models.cjs",
4747
"generate:models:check": "node scripts/generate-models.cjs --check",
4848
"lint": "tsc --noEmit",
49-
"test": "bun test --timeout 30000 tests-ts/api.test.ts tests-ts/auth.test.ts tests-ts/bulk-scan-discovery.test.ts tests-ts/cli.test.ts tests-ts/config.test.ts tests-ts/contract.test.ts tests-ts/knowledge-base.test.ts tests-ts/multiscan.test.ts tests-ts/result.test.ts tests-ts/runtime.test.ts tests-ts/scan-comparison.test.ts tests-ts/scan-history-renderer.test.ts tests-ts/skeleton.test.ts tests-ts/targets.test.ts tests-ts/trusted-executable.test.ts tests-ts/worker-progress.test.ts",
49+
"test": "bun test --timeout 30000 tests-ts/api.test.ts tests-ts/auth.test.ts tests-ts/bulk-scan-discovery.test.ts tests-ts/cli-export.test.ts tests-ts/cli.test.ts tests-ts/config.test.ts tests-ts/contract.test.ts tests-ts/knowledge-base.test.ts tests-ts/multiscan.test.ts tests-ts/result.test.ts tests-ts/runtime.test.ts tests-ts/scan-comparison.test.ts tests-ts/scan-history-renderer.test.ts tests-ts/skeleton.test.ts tests-ts/targets.test.ts tests-ts/trusted-executable.test.ts tests-ts/worker-progress.test.ts",
5050
"types": "pnpm run generate:models:check && tsc --noEmit"
5151
},
5252
"dependencies": {

sdk/typescript/src/cli.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ const VALUE_OPTIONS = new Set([
125125
"--head",
126126
"--base",
127127
"--mode",
128+
"--model",
128129
"--output-dir",
129130
"--plugin-path",
130131
"--python",
@@ -155,6 +156,7 @@ interface ScanArguments {
155156
head?: string;
156157
base?: string;
157158
mode: ScanMode;
159+
model?: string;
158160
outputDir?: string;
159161
archiveExisting: boolean;
160162
pluginPath?: string;
@@ -796,6 +798,9 @@ export async function main(
796798
.enum(["standard", "deep"])
797799
.default("standard")
798800
.describe("Scan mode."),
801+
model: optionValue("--model")
802+
.optional()
803+
.describe("Model to use for the scan."),
799804
outputDir: optionValue("--output-dir")
800805
.optional()
801806
.describe("Write scan artifacts to DIR."),
@@ -852,6 +857,7 @@ export async function main(
852857
),
853858
examples: [
854859
{ args: { repository: "." } },
860+
{ args: { repository: "." }, options: { model: "gpt-5.6-terra" } },
855861
{ args: { repository: "." }, options: { path: ["src", "tests"] } },
856862
{ args: { repository: "." }, options: { diff: "origin/main" } },
857863
],
@@ -874,6 +880,7 @@ export async function main(
874880
head: options.head,
875881
base: options.base,
876882
mode: options.mode,
883+
model: options.model,
877884
outputDir: options.outputDir,
878885
archiveExisting: options.archiveExisting,
879886
pluginPath: options.pluginPath,
@@ -918,6 +925,9 @@ export async function main(
918925
.describe("Directory for scan artifacts and resumable results."),
919926
workers: z.number().int().positive().default(4),
920927
mode: z.enum(["standard", "deep"]).default("standard"),
928+
model: optionValue("--model")
929+
.optional()
930+
.describe("Model to use for each repository."),
921931
maxAttempts: z
922932
.number()
923933
.int()
@@ -947,9 +957,16 @@ export async function main(
947957
let outputDir: string;
948958
let githubHost: string | undefined;
949959
if (args.input === undefined) {
950-
if (argv.length !== 1 || argv[0] !== "bulk-scan") {
960+
if (
961+
argv[0] !== "bulk-scan" ||
962+
!(
963+
argv.length === 1 ||
964+
(argv.length === 3 && argv[1] === "--model") ||
965+
(argv.length === 2 && argv[1] === `--model=${options.model}`)
966+
)
967+
) {
951968
throw new Error(
952-
"Run 'codex-security bulk-scan' without options to discover repositories, or provide a CSV and --output-dir.",
969+
"Run 'codex-security bulk-scan [--model MODEL]' to discover repositories, or provide a CSV and --output-dir.",
953970
);
954971
}
955972
const wizard = await runBulkScanWizard(
@@ -984,7 +1001,7 @@ export async function main(
9841001
config: {
9851002
pluginPath: options.pluginPath,
9861003
pythonPath: options.python,
987-
codexOverrides: parseCodexOverrides(options.codex),
1004+
codexOverrides: parseCodexOverrides(options.codex, options.model),
9881005
},
9891006
createSecurity: dependencies.createSecurity,
9901007
signal: controller.signal,
@@ -2021,7 +2038,8 @@ async function runScan(
20212038
pluginPath: arguments_.pluginPath,
20222039
pythonPath: arguments_.pythonPath,
20232040
codexOverrides:
2024-
arguments_.codexOverrides ?? parseCodexOverrides(arguments_.codex),
2041+
arguments_.codexOverrides ??
2042+
parseCodexOverrides(arguments_.codex, arguments_.model),
20252043
};
20262044
progress = new Progress(errorOutput, dependencies, interactive);
20272045
const scope = scanScope(arguments_);
@@ -2402,8 +2420,12 @@ function targetFromArguments(arguments_: ScanArguments): ScanTarget {
24022420
return "repository";
24032421
}
24042422

2405-
export function parseCodexOverrides(values: readonly string[]): JsonObject {
2423+
export function parseCodexOverrides(
2424+
values: readonly string[],
2425+
model?: string,
2426+
): JsonObject {
24062427
const result = Object.create(null) as JsonObject;
2428+
if (model !== undefined) result["model"] = model;
24072429
for (const value of values) {
24082430
const separator = value.indexOf("=");
24092431
const key = separator < 0 ? "" : value.slice(0, separator);
@@ -2451,7 +2473,11 @@ export function parseCodexOverrides(values: readonly string[]): JsonObject {
24512473
}
24522474
const final = parts.at(-1)!;
24532475
if (Object.hasOwn(cursor, final)) {
2454-
throw new CodexSecurityError("Duplicate --codex key");
2476+
throw new CodexSecurityError(
2477+
model !== undefined && key === "model"
2478+
? "--model conflicts with --codex model"
2479+
: "Duplicate --codex key",
2480+
);
24552481
}
24562482
cursor[final] = parsed;
24572483
}

0 commit comments

Comments
 (0)