Skip to content

Commit beb9315

Browse files
committed
Require provider and model flags for the public SWE smoke
The one-shot smoke defaulted to a personal prepaid provider profile. Callers now pass --provider and --model so local eval accounts stay off the repo.
1 parent 3531b98 commit beb9315

4 files changed

Lines changed: 85 additions & 37 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ mid-session switches.
172172

173173
- **Public SWE-bench one-shot smoke.** `bun run eval:public-swe-one` runs Corbits
174174
product exec on a single SWE-bench Lite instance (default
175-
`psf__requests-3362`), pinned to prepaid `xai/thegreataxios` + `grok-4.5`, and
175+
`psf__requests-3362`), taking `--provider` and `--model` on the CLI, and
176176
writes `preds.jsonl` under `evals/public/results/`. Official Docker
177177
resolved/not-resolved grading stays optional/manual.
178178
- **Capability eval: `complex-stock-gate`.** Multi-file stock-gated `POST /orders`

‎evals/public/README.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ This directory is for **small public-bench smokes** so we can see how Corbits
66
stacks up against other coding harnesses (Claude Code, OpenHands, Aider, …)
77
without vendoring a full leaderboard runner into product CI.
88

9-
## Constraints (this machine)
9+
## Constraints
1010

11-
- Use prepaid **`xai/thegreataxios`** + **`grok-4.5`** unless explicitly overridden.
11+
- Provider and model are caller-supplied (`--provider` and `--model`).
1212
- Docker Desktop may be under-provisioned for full SWE-bench eval images
1313
(docs want ~120GB disk / 16GB RAM; arm64 is experimental).
1414
- Start with **one instance**, not Lite/Verified full.
@@ -21,11 +21,12 @@ bun scripts/eval-public-swe-one.ts --dry-run
2121

2222
# Default instance: psf__requests-3362 (small repo, single failing test)
2323
bun scripts/eval-public-swe-one.ts \
24-
--provider xai/thegreataxios \
24+
--provider xai \
2525
--model grok-4.5
2626

2727
# Pick any Lite instance_id
28-
bun scripts/eval-public-swe-one.ts --instance pallets__flask-4992
28+
bun scripts/eval-public-swe-one.ts --instance pallets__flask-4992 \
29+
--provider <provider> --model <model>
2930
```
3031

3132
What it does:
@@ -47,7 +48,7 @@ What it does **not** do yet:
4748

4849
Point the official SWE-bench / mini-SWE-agent eval harness at `preds.jsonl`.
4950
Until that runs, treat the smoke as: **did Corbits produce a non-empty patch on a
50-
real public issue under the prepaid xAI profile?**
51+
real public issue?**
5152

5253
## vs competitors
5354

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { describe, expect, test } from "bun:test";
2+
3+
import { parseArgs } from "./eval-public-swe-one.ts";
4+
5+
describe("parseArgs", () => {
6+
test("--help does not require provider or model", () => {
7+
const opts = parseArgs(["--help"]);
8+
expect(opts.help).toBe(true);
9+
expect(opts.provider).not.toBe("xai/thegreataxios");
10+
expect(opts.model).not.toBe("xai/thegreataxios");
11+
});
12+
13+
test("--dry-run does not require provider or model", () => {
14+
const opts = parseArgs(["--dry-run"]);
15+
expect(opts.dryRun).toBe(true);
16+
expect(opts.provider).not.toBe("xai/thegreataxios");
17+
expect(opts.model).not.toBe("xai/thegreataxios");
18+
});
19+
20+
test("agent run without --provider throws", () => {
21+
expect(() => parseArgs(["--model", "bar"])).toThrow(/--provider/);
22+
});
23+
24+
test("agent run without --model throws", () => {
25+
expect(() => parseArgs(["--provider", "foo"])).toThrow(/--model/);
26+
});
27+
28+
test("agent run without either flag throws naming both", () => {
29+
expect(() => parseArgs([])).toThrow(/--provider/);
30+
expect(() => parseArgs([])).toThrow(/--model/);
31+
});
32+
33+
test("--provider foo --model bar parses those values", () => {
34+
const opts = parseArgs(["--provider", "foo", "--model", "bar"]);
35+
expect(opts.provider).toBe("foo");
36+
expect(opts.model).toBe("bar");
37+
});
38+
39+
test("parsed defaults never equal xai/thegreataxios", () => {
40+
const help = parseArgs(["--help"]);
41+
const dry = parseArgs(["--dry-run"]);
42+
expect(help.provider).not.toBe("xai/thegreataxios");
43+
expect(help.model).not.toBe("xai/thegreataxios");
44+
expect(dry.provider).not.toBe("xai/thegreataxios");
45+
expect(dry.model).not.toBe("xai/thegreataxios");
46+
});
47+
});

‎scripts/eval-public-swe-one.ts‎

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
* One-shot public SWE-bench smoke: Corbits as the agent on a single Lite instance.
44
*
55
* Intentionally narrow:
6-
* - pins provider/model (default xai/thegreataxios + grok-4.5)
6+
* - provider/model come from required --provider / --model CLI flags
77
* - host-side agent run (product exec path), not a full SWE Docker fleet
88
* - captures a git patch + trajectory report for later official eval
99
*
1010
* Usage:
11-
* bun scripts/eval-public-swe-one.ts
12-
* bun scripts/eval-public-swe-one.ts --instance psf__requests-3362
13-
* bun scripts/eval-public-swe-one.ts --provider xai/thegreataxios --model grok-4.5
11+
* bun scripts/eval-public-swe-one.ts --provider <name> --model <id>
12+
* bun scripts/eval-public-swe-one.ts --instance psf__requests-3362 --provider <name> --model <id>
13+
* bun scripts/eval-public-swe-one.ts --dry-run
1414
*
1515
* Optional official grading (heavy; needs Docker resources):
16-
* bun scripts/eval-public-swe-one.ts --instance … --evaluate
16+
* bun scripts/eval-public-swe-one.ts --instance … --provider <name> --model <id> --evaluate
1717
*/
1818

1919
import { mkdir, writeFile, readFile, mkdtemp, rm, cp } from "node:fs/promises";
@@ -25,8 +25,6 @@ import { loadConfig } from "../src/config/index.js";
2525
import { runExec } from "../src/exec/runner.js";
2626

2727
const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
28-
const DEFAULT_PROVIDER = "xai/thegreataxios";
29-
const DEFAULT_MODEL = "grok-4.5";
3028
const DEFAULT_INSTANCE = "psf__requests-3362";
3129
const DEFAULT_SUBSET = "princeton-nlp/SWE-bench_Lite";
3230
const DEFAULT_SPLIT = "test";
@@ -40,7 +38,6 @@ type CliOptions = {
4038
split: string;
4139
agentTimeoutMs: number;
4240
evaluate: boolean;
43-
allowOtherProvider: boolean;
4441
dryRun: boolean;
4542
outDir: string;
4643
help: boolean;
@@ -59,35 +56,33 @@ type SweInstance = {
5956
};
6057

6158
function printHelp(): void {
62-
console.log(`Usage: bun scripts/eval-public-swe-one.ts [options]
59+
console.log(`Usage: bun scripts/eval-public-swe-one.ts --provider <name> --model <id> [options]
6360
6461
One public SWE-bench Lite instance via Corbits product exec.
6562
6663
Options:
6764
--instance <id> SWE-bench instance_id (default: ${DEFAULT_INSTANCE})
68-
--provider <name> Must be ${DEFAULT_PROVIDER} unless --allow-other-provider
69-
--model <id> Model id (default: ${DEFAULT_MODEL})
65+
--provider <name> Provider name (required except --help / --dry-run)
66+
--model <id> Model id (required except --help / --dry-run)
7067
--subset <hf> HF dataset id (default: ${DEFAULT_SUBSET})
7168
--split <name> Dataset split (default: ${DEFAULT_SPLIT})
7269
--timeout-ms <n> Agent wall-clock timeout (default: ${DEFAULT_AGENT_TIMEOUT_MS})
7370
--out <dir> Results directory (default: evals/public/results/<run-id>)
7471
--evaluate After the agent, attempt official SWE-bench Docker eval (heavy)
75-
--allow-other-provider Permit a non-default provider (not recommended here)
7672
--dry-run Load instance + print plan; do not clone or run the agent
7773
-h, --help Show this help
7874
`);
7975
}
8076

81-
function parseArgs(argv: string[]): CliOptions {
77+
export function parseArgs(argv: string[]): CliOptions {
8278
const opts: CliOptions = {
83-
provider: DEFAULT_PROVIDER,
84-
model: DEFAULT_MODEL,
79+
provider: "",
80+
model: "",
8581
instanceId: DEFAULT_INSTANCE,
8682
subset: DEFAULT_SUBSET,
8783
split: DEFAULT_SPLIT,
8884
agentTimeoutMs: DEFAULT_AGENT_TIMEOUT_MS,
8985
evaluate: false,
90-
allowOtherProvider: false,
9186
dryRun: false,
9287
outDir: "",
9388
help: false,
@@ -131,16 +126,24 @@ function parseArgs(argv: string[]): CliOptions {
131126
case "--evaluate":
132127
opts.evaluate = true;
133128
break;
134-
case "--allow-other-provider":
135-
opts.allowOtherProvider = true;
136-
break;
137129
case "--dry-run":
138130
opts.dryRun = true;
139131
break;
140132
default:
141133
throw new Error(`unknown arg: ${a}`);
142134
}
143135
}
136+
if (!opts.help && !opts.dryRun) {
137+
if (!opts.provider && !opts.model) {
138+
throw new Error("missing required --provider and --model");
139+
}
140+
if (!opts.provider) {
141+
throw new Error("missing required --provider");
142+
}
143+
if (!opts.model) {
144+
throw new Error("missing required --model");
145+
}
146+
}
144147
return opts;
145148
}
146149

@@ -314,13 +317,6 @@ async function main(): Promise<void> {
314317
process.exit(0);
315318
}
316319

317-
if (!opts.allowOtherProvider && opts.provider !== DEFAULT_PROVIDER) {
318-
throw new Error(
319-
`provider must be ${DEFAULT_PROVIDER} for this prepaid smoke ` +
320-
`(got ${opts.provider}). Pass --allow-other-provider to override.`,
321-
);
322-
}
323-
324320
const runId = new Date().toISOString().replace(/[:.]/g, "-");
325321
const outDir =
326322
opts.outDir.length > 0
@@ -370,7 +366,9 @@ async function main(): Promise<void> {
370366

371367
const config = await loadConfig(argv, { allowUnconfigured: false });
372368
if (!config.configured) {
373-
throw new Error("Provider not configured — check xAI OAuth profile xai/thegreataxios");
369+
throw new Error(
370+
`Provider not configured for --provider ${opts.provider} --model ${opts.model}`,
371+
);
374372
}
375373
const resolvedProvider = config.providerName;
376374
const resolvedModel = config.model;
@@ -476,7 +474,9 @@ async function main(): Promise<void> {
476474
}
477475
}
478476

479-
main().catch((err) => {
480-
console.error(err instanceof Error ? err.message : err);
481-
process.exit(2);
482-
});
477+
if (import.meta.main) {
478+
main().catch((err) => {
479+
console.error(err instanceof Error ? err.message : err);
480+
process.exit(2);
481+
});
482+
}

0 commit comments

Comments
 (0)