self-bench 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +0 -1
- package/Dockerfile +2 -1
- package/Dockerfile.sandbox +1 -1
- package/README.md +114 -170
- package/bun.lock +60 -12
- package/compose.yaml +11 -5
- package/dist/agent-smoke-main.js +3 -2
- package/dist/agent-smoke-main.js.map +1 -1
- package/dist/agent-smoke.d.ts +2 -1
- package/dist/agent-smoke.d.ts.map +1 -1
- package/dist/agent-smoke.js +6 -1
- package/dist/agent-smoke.js.map +1 -1
- package/dist/api.d.ts +24 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +65 -20
- package/dist/api.js.map +1 -1
- package/dist/artifacts.d.ts +0 -1
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +0 -3
- package/dist/artifacts.js.map +1 -1
- package/dist/build-metadata.js +1 -1
- package/dist/cli.js +75 -11
- package/dist/cli.js.map +1 -1
- package/dist/codex-review.d.ts +2 -1
- package/dist/codex-review.d.ts.map +1 -1
- package/dist/codex-review.js +26 -22
- package/dist/codex-review.js.map +1 -1
- package/dist/config.d.ts +36 -11
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +89 -17
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +23 -3
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +31 -6
- package/dist/contracts.js.map +1 -1
- package/dist/eval-main.js +5 -4
- package/dist/eval-main.js.map +1 -1
- package/dist/evaluate.d.ts +2 -1
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +14 -8
- package/dist/evaluate.js.map +1 -1
- package/dist/harbor-environment.d.ts +2 -0
- package/dist/harbor-environment.d.ts.map +1 -0
- package/dist/harbor-environment.js +15 -0
- package/dist/harbor-environment.js.map +1 -0
- package/dist/harbor-results.d.ts.map +1 -1
- package/dist/harbor-results.js +2 -0
- package/dist/harbor-results.js.map +1 -1
- package/dist/process.d.ts +2 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js.map +1 -1
- package/dist/provenance.d.ts +0 -1
- package/dist/provenance.d.ts.map +1 -1
- package/dist/provenance.js.map +1 -1
- package/dist/providers.d.ts +8 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +14 -0
- package/dist/providers.js.map +1 -0
- package/dist/reaudit-main.js +14 -11
- package/dist/reaudit-main.js.map +1 -1
- package/dist/repair-main.js +12 -9
- package/dist/repair-main.js.map +1 -1
- package/dist/review/assets/index-CZ3G759O.js +1568 -0
- package/dist/review/assets/index-DgSLzX8l.css +1 -0
- package/dist/review/assets/{mojo-Blby8dQK.js → mojo-DJz3ZmWd.js} +1 -1
- package/dist/review/assets/typst-BUadGCkm.js +1 -0
- package/dist/review/index.html +2 -2
- package/dist/sandbox-author.bundle.js +40 -6
- package/dist/sandbox-repair.bundle.js +8 -7
- package/dist/sandbox-repair.js +7 -7
- package/dist/sandbox-repair.js.map +1 -1
- package/dist/sandbox-review.bundle.js +29 -25
- package/dist/sandbox-review.js +5 -3
- package/dist/sandbox-review.js.map +1 -1
- package/dist/sandbox-timeout.d.ts +11 -0
- package/dist/sandbox-timeout.d.ts.map +1 -0
- package/dist/sandbox-timeout.js +41 -0
- package/dist/sandbox-timeout.js.map +1 -0
- package/dist/sandbox-validation-repair.bundle.js +49 -15
- package/dist/sandbox-validation-repair.js +11 -9
- package/dist/sandbox-validation-repair.js.map +1 -1
- package/dist/sandbox.d.ts +2 -2
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +10 -3
- package/dist/sandbox.js.map +1 -1
- package/dist/subscription-auth.d.ts +12 -1
- package/dist/subscription-auth.d.ts.map +1 -1
- package/dist/subscription-auth.js +16 -16
- package/dist/subscription-auth.js.map +1 -1
- package/dist/{activities.d.ts → temporal/activities.d.ts} +3 -4
- package/dist/temporal/activities.d.ts.map +1 -0
- package/dist/{activities.js → temporal/activities.js} +51 -34
- package/dist/temporal/activities.js.map +1 -0
- package/dist/{temporal.d.ts → temporal/connection.d.ts} +2 -2
- package/dist/temporal/connection.d.ts.map +1 -0
- package/dist/{temporal.js → temporal/connection.js} +1 -1
- package/dist/temporal/connection.js.map +1 -0
- package/dist/{worker-main.d.ts.map → temporal/worker-main.d.ts.map} +1 -1
- package/dist/{worker-main.js → temporal/worker-main.js} +6 -10
- package/dist/temporal/worker-main.js.map +1 -0
- package/dist/{workflow.d.ts → temporal/workflow.d.ts} +1 -1
- package/dist/temporal/workflow.d.ts.map +1 -0
- package/dist/temporal/workflow.js.map +1 -0
- package/dist/terminal-prompts.d.ts +26 -0
- package/dist/terminal-prompts.d.ts.map +1 -0
- package/dist/terminal-prompts.js +137 -0
- package/dist/terminal-prompts.js.map +1 -0
- package/dist/terminal-reporter.d.ts +30 -0
- package/dist/terminal-reporter.d.ts.map +1 -0
- package/dist/terminal-reporter.js +90 -0
- package/dist/terminal-reporter.js.map +1 -0
- package/dist/validate-main.js +8 -2
- package/dist/validate-main.js.map +1 -1
- package/dist/vercel-cli.d.ts +64 -0
- package/dist/vercel-cli.d.ts.map +1 -0
- package/dist/vercel-cli.js +303 -0
- package/dist/vercel-cli.js.map +1 -0
- package/dist/vercel-command.d.ts +14 -0
- package/dist/vercel-command.d.ts.map +1 -0
- package/dist/vercel-command.js +93 -0
- package/dist/vercel-command.js.map +1 -0
- package/dist/vercel-executor.d.ts +14 -0
- package/dist/vercel-executor.d.ts.map +1 -0
- package/dist/vercel-executor.js +356 -0
- package/dist/vercel-executor.js.map +1 -0
- package/dist/vercel-fetch.d.ts +6 -0
- package/dist/vercel-fetch.d.ts.map +1 -0
- package/dist/vercel-fetch.js +39 -0
- package/dist/vercel-fetch.js.map +1 -0
- package/dist/vercel-profile.d.ts +34 -0
- package/dist/vercel-profile.d.ts.map +1 -0
- package/dist/vercel-profile.js +244 -0
- package/dist/vercel-profile.js.map +1 -0
- package/dist/vercel-runtime-image.d.ts +51 -0
- package/dist/vercel-runtime-image.d.ts.map +1 -0
- package/dist/vercel-runtime-image.js +123 -0
- package/dist/vercel-runtime-image.js.map +1 -0
- package/dist/vercel-setup-probe.d.ts +49 -0
- package/dist/vercel-setup-probe.d.ts.map +1 -0
- package/dist/vercel-setup-probe.js +151 -0
- package/dist/vercel-setup-probe.js.map +1 -0
- package/dist/vercel-setup.d.ts +42 -0
- package/dist/vercel-setup.d.ts.map +1 -0
- package/dist/vercel-setup.js +280 -0
- package/dist/vercel-setup.js.map +1 -0
- package/docs/evaluations.md +15 -12
- package/docs/operations.md +134 -21
- package/package.json +8 -6
- package/src/agent-smoke-main.ts +3 -2
- package/src/agent-smoke.ts +8 -2
- package/src/api.ts +71 -20
- package/src/artifacts.ts +0 -4
- package/src/cli.ts +81 -11
- package/src/codex-review.ts +63 -54
- package/src/config.ts +150 -28
- package/src/contracts.ts +33 -11
- package/src/eval-main.ts +5 -4
- package/src/evaluate.ts +18 -11
- package/src/harbor-environment.ts +17 -0
- package/src/harbor-results.ts +2 -0
- package/src/process.ts +3 -1
- package/src/provenance.ts +0 -1
- package/src/providers.ts +22 -0
- package/src/reaudit-main.ts +17 -11
- package/src/repair-main.ts +15 -9
- package/src/sandbox-repair.ts +7 -11
- package/src/sandbox-review.ts +5 -3
- package/src/sandbox-timeout.ts +56 -0
- package/src/sandbox-validation-repair.ts +13 -10
- package/src/sandbox.ts +15 -5
- package/src/subscription-auth.ts +30 -17
- package/src/{activities.ts → temporal/activities.ts} +53 -42
- package/src/{temporal.ts → temporal/connection.ts} +1 -1
- package/src/{worker-main.ts → temporal/worker-main.ts} +6 -10
- package/src/{workflow.ts → temporal/workflow.ts} +10 -10
- package/src/terminal-prompts.ts +197 -0
- package/src/terminal-reporter.ts +126 -0
- package/src/validate-main.ts +9 -3
- package/src/vercel-cli.ts +403 -0
- package/src/vercel-command.ts +127 -0
- package/src/vercel-executor.ts +448 -0
- package/src/vercel-fetch.ts +45 -0
- package/src/vercel-profile.ts +319 -0
- package/src/vercel-runtime-image.ts +204 -0
- package/src/vercel-setup-probe.ts +229 -0
- package/src/vercel-setup.ts +419 -0
- package/dist/activities.d.ts.map +0 -1
- package/dist/activities.js.map +0 -1
- package/dist/extensions/review.d.ts +0 -3
- package/dist/extensions/review.d.ts.map +0 -1
- package/dist/extensions/review.js +0 -44
- package/dist/extensions/review.js.map +0 -1
- package/dist/review/assets/index-Dq-6DFzI.css +0 -1
- package/dist/review/assets/index-DurW_RD7.js +0 -1567
- package/dist/review/assets/typst-DHCkPAjA.js +0 -1
- package/dist/temporal.d.ts.map +0 -1
- package/dist/temporal.js.map +0 -1
- package/dist/worker-main.js.map +0 -1
- package/dist/workflow.d.ts.map +0 -1
- package/dist/workflow.js.map +0 -1
- package/src/extensions/review.ts +0 -54
- /package/dist/{worker-main.d.ts → temporal/worker-main.d.ts} +0 -0
- /package/dist/{workflow.js → temporal/workflow.js} +0 -0
package/src/reaudit-main.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
couplingReviewInput,
|
|
11
11
|
couplingReviewSchema,
|
|
12
12
|
} from "./codex-review.js";
|
|
13
|
-
import {
|
|
13
|
+
import { defaultStandaloneConcurrency, loadWorkerConfig } from "./config.js";
|
|
14
14
|
import {
|
|
15
15
|
buildCouplingEvidence,
|
|
16
16
|
discoverContractArtifacts,
|
|
@@ -20,14 +20,14 @@ import {
|
|
|
20
20
|
import { parallelMap } from "./parallel.js";
|
|
21
21
|
import { runCommand } from "./process.js";
|
|
22
22
|
import { createSandboxExecutor, type SandboxExecutor } from "./sandbox.js";
|
|
23
|
-
import {
|
|
23
|
+
import { loadPiModelAuth } from "./subscription-auth.js";
|
|
24
24
|
|
|
25
25
|
const parsed = parseArgs({
|
|
26
26
|
options: {
|
|
27
27
|
tasks: { type: "string" },
|
|
28
28
|
task: { type: "string" },
|
|
29
29
|
output: { type: "string" },
|
|
30
|
-
concurrency: { type: "string"
|
|
30
|
+
concurrency: { type: "string" },
|
|
31
31
|
help: { type: "boolean", short: "h" },
|
|
32
32
|
},
|
|
33
33
|
strict: true,
|
|
@@ -39,7 +39,7 @@ Usage:
|
|
|
39
39
|
self-bench-reaudit --tasks DIRECTORY --output REPORT.json [options]
|
|
40
40
|
|
|
41
41
|
Options:
|
|
42
|
-
--concurrency N Concurrent Sol reviews (default: 10)
|
|
42
|
+
--concurrency N Concurrent Sol reviews (default: 10; Vercel: worker setting, default 4)
|
|
43
43
|
--task ID Review only one task ID
|
|
44
44
|
-h, --help Show this help`);
|
|
45
45
|
process.exit(0);
|
|
@@ -47,12 +47,15 @@ Options:
|
|
|
47
47
|
|
|
48
48
|
const tasksDirectory = resolve(parsed.values.tasks ?? fail("--tasks is required"));
|
|
49
49
|
const outputPath = resolve(parsed.values.output ?? fail("--output is required"));
|
|
50
|
-
const
|
|
51
|
-
const
|
|
50
|
+
const config = loadWorkerConfig();
|
|
51
|
+
const concurrency = positiveInteger(
|
|
52
|
+
parsed.values.concurrency ?? String(defaultStandaloneConcurrency(config, 10)),
|
|
53
|
+
"--concurrency",
|
|
54
|
+
);
|
|
52
55
|
const sandbox = createSandboxExecutor(config.execution);
|
|
53
|
-
const [taskIds,
|
|
56
|
+
const [taskIds, modelAuth, reviewer] = await Promise.all([
|
|
54
57
|
readdir(tasksDirectory),
|
|
55
|
-
|
|
58
|
+
loadPiModelAuth(),
|
|
56
59
|
readFile(join(assetRoot(), "dist/sandbox-review.bundle.js")),
|
|
57
60
|
]);
|
|
58
61
|
const directories = (
|
|
@@ -79,7 +82,7 @@ const tasks = await parallelMap(directories, concurrency, async (taskDirectory)
|
|
|
79
82
|
const taskId = basename(taskDirectory);
|
|
80
83
|
console.error(`reviewing ${taskId}`);
|
|
81
84
|
try {
|
|
82
|
-
const report = await auditTask(taskDirectory, taskId,
|
|
85
|
+
const report = await auditTask(taskDirectory, taskId, modelAuth, reviewer, sandbox);
|
|
83
86
|
console.error(`${taskId}: ${report.resolution.verdict}`);
|
|
84
87
|
return report;
|
|
85
88
|
} catch (error) {
|
|
@@ -113,7 +116,7 @@ console.log(JSON.stringify({ output: outputPath, ...report.summary }, null, 2));
|
|
|
113
116
|
async function auditTask(
|
|
114
117
|
taskDirectory: string,
|
|
115
118
|
taskId: string,
|
|
116
|
-
|
|
119
|
+
modelAuth: { apiKey?: string; authJson?: string },
|
|
117
120
|
reviewer: Uint8Array,
|
|
118
121
|
sandbox: SandboxExecutor,
|
|
119
122
|
) {
|
|
@@ -151,7 +154,10 @@ async function auditTask(
|
|
|
151
154
|
},
|
|
152
155
|
],
|
|
153
156
|
outputPaths: ["/work/review.json"],
|
|
154
|
-
secrets: {
|
|
157
|
+
secrets: {
|
|
158
|
+
...(modelAuth.apiKey ? { OPENAI_API_KEY: modelAuth.apiKey } : {}),
|
|
159
|
+
...(modelAuth.authJson ? { SELFBENCH_PI_AUTH_JSON: modelAuth.authJson } : {}),
|
|
160
|
+
},
|
|
155
161
|
environment: { SELFBENCH_REVIEW_OUTPUT: "/work/review.json" },
|
|
156
162
|
command: ["node", "/work/sandbox-review.js"],
|
|
157
163
|
});
|
package/src/repair-main.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { tmpdir } from "node:os";
|
|
|
5
5
|
import { basename, dirname, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
|
-
import {
|
|
8
|
+
import { defaultStandaloneConcurrency, loadWorkerConfig } from "./config.js";
|
|
9
9
|
import { parallelMap } from "./parallel.js";
|
|
10
10
|
import { runCommand } from "./process.js";
|
|
11
11
|
import { createSandboxExecutor } from "./sandbox.js";
|
|
12
|
-
import {
|
|
12
|
+
import { loadCodexModelAuth } from "./subscription-auth.js";
|
|
13
13
|
|
|
14
14
|
const parsed = parseArgs({
|
|
15
15
|
options: {
|
|
@@ -17,7 +17,7 @@ const parsed = parseArgs({
|
|
|
17
17
|
review: { type: "string" },
|
|
18
18
|
output: { type: "string" },
|
|
19
19
|
task: { type: "string" },
|
|
20
|
-
concurrency: { type: "string"
|
|
20
|
+
concurrency: { type: "string" },
|
|
21
21
|
model: { type: "string", default: "gpt-5.6-sol" },
|
|
22
22
|
help: { type: "boolean", short: "h" },
|
|
23
23
|
},
|
|
@@ -30,7 +30,7 @@ Usage:
|
|
|
30
30
|
self-bench-repair --tasks DIRECTORY --review REPORT.json --output DIRECTORY [options]
|
|
31
31
|
|
|
32
32
|
Options:
|
|
33
|
-
--concurrency N Concurrent repair sandboxes (default: 9)
|
|
33
|
+
--concurrency N Concurrent repair sandboxes (default: 9; Vercel: worker setting, default 4)
|
|
34
34
|
--model MODEL Codex subscription model (default: gpt-5.6-sol)
|
|
35
35
|
--task ID Repair only one coupled task
|
|
36
36
|
-h, --help Show this help`);
|
|
@@ -43,7 +43,11 @@ const outputDirectory = resolve(parsed.values.output ?? fail("--output is requir
|
|
|
43
43
|
if (outputDirectory === tasksDirectory || outputDirectory.startsWith(`${tasksDirectory}/`)) {
|
|
44
44
|
throw new Error("--output must be outside --tasks");
|
|
45
45
|
}
|
|
46
|
-
const
|
|
46
|
+
const config = loadWorkerConfig();
|
|
47
|
+
const concurrency = positiveInteger(
|
|
48
|
+
parsed.values.concurrency ?? String(defaultStandaloneConcurrency(config, 9)),
|
|
49
|
+
"--concurrency",
|
|
50
|
+
);
|
|
47
51
|
const rawReview = JSON.parse(await readFile(reviewPath, "utf8")) as unknown;
|
|
48
52
|
const review = reviewReport(rawReview);
|
|
49
53
|
const coupled = new Map(
|
|
@@ -77,10 +81,9 @@ for (const source of sourceTasks) {
|
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
const config = loadConfig();
|
|
81
84
|
const sandbox = createSandboxExecutor(config.execution);
|
|
82
|
-
const [
|
|
83
|
-
|
|
85
|
+
const [modelAuth, repairer] = await Promise.all([
|
|
86
|
+
loadCodexModelAuth(),
|
|
84
87
|
readFile(join(assetRoot(), "dist/sandbox-repair.bundle.js")),
|
|
85
88
|
]);
|
|
86
89
|
const results = await parallelMap([...coupled.values()], concurrency, async (taskReview) => {
|
|
@@ -103,7 +106,10 @@ const results = await parallelMap([...coupled.values()], concurrency, async (tas
|
|
|
103
106
|
{ path: "/work/sandbox-repair.js", contents: repairer },
|
|
104
107
|
],
|
|
105
108
|
outputPaths: ["/work/repaired-task.tar.gz", "/work/repair-report.json"],
|
|
106
|
-
secrets: {
|
|
109
|
+
secrets: {
|
|
110
|
+
...(modelAuth.apiKey ? { OPENAI_API_KEY: modelAuth.apiKey } : {}),
|
|
111
|
+
...(modelAuth.authJson ? { SELFBENCH_CODEX_AUTH_JSON: modelAuth.authJson } : {}),
|
|
112
|
+
},
|
|
107
113
|
environment: { SELFBENCH_REPAIR_MODEL: parsed.values.model ?? "gpt-5.6-sol" },
|
|
108
114
|
command: [
|
|
109
115
|
"node",
|
package/src/sandbox-repair.ts
CHANGED
|
@@ -50,13 +50,15 @@ await runCommand("git", [
|
|
|
50
50
|
]);
|
|
51
51
|
await runCommand("git", ["-C", repositoryDirectory, "add", "-N", "--all"]);
|
|
52
52
|
|
|
53
|
+
const codexAuth = process.env.SELFBENCH_CODEX_AUTH_JSON;
|
|
54
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
55
|
+
if (!apiKey && !codexAuth) {
|
|
56
|
+
fail("OPENAI_API_KEY or SELFBENCH_CODEX_AUTH_JSON is required");
|
|
57
|
+
}
|
|
53
58
|
const codexHome = join(homedir(), ".codex");
|
|
54
59
|
const authPath = join(codexHome, "auth.json");
|
|
55
60
|
await mkdir(codexHome, { recursive: true });
|
|
56
|
-
await writeFile(
|
|
57
|
-
authPath,
|
|
58
|
-
process.env.SELFBENCH_CODEX_AUTH_JSON ?? fail("SELFBENCH_CODEX_AUTH_JSON is required"),
|
|
59
|
-
);
|
|
61
|
+
await writeFile(authPath, codexAuth ?? `${JSON.stringify({ OPENAI_API_KEY: apiKey })}\n`);
|
|
60
62
|
await chmod(authPath, 0o600);
|
|
61
63
|
const promptPath = join(tmpdir(), `selfbench-repair-${taskId}.md`);
|
|
62
64
|
await writeFile(
|
|
@@ -86,7 +88,7 @@ const codex = await runCommand(
|
|
|
86
88
|
{
|
|
87
89
|
allowFailure: true,
|
|
88
90
|
timeoutMs: 90 * 60 * 1000,
|
|
89
|
-
env:
|
|
91
|
+
env: process.env,
|
|
90
92
|
input: await readFile(promptPath, "utf8"),
|
|
91
93
|
onOutput: (stream, chunk) => {
|
|
92
94
|
(stream === "stdout" ? process.stdout : process.stderr).write(chunk);
|
|
@@ -149,12 +151,6 @@ await writeFile(
|
|
|
149
151
|
)}\n`,
|
|
150
152
|
);
|
|
151
153
|
|
|
152
|
-
function withoutApiKey(environment: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
|
153
|
-
const output = { ...environment };
|
|
154
|
-
delete output.OPENAI_API_KEY;
|
|
155
|
-
return output;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
154
|
function fail(message: string): never {
|
|
159
155
|
throw new Error(message);
|
|
160
156
|
}
|
package/src/sandbox-review.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { reviewCouplingWithCodex } from "./codex-review.js";
|
|
3
3
|
|
|
4
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
4
5
|
const authJson = process.env.SELFBENCH_PI_AUTH_JSON;
|
|
5
6
|
const outputPath = process.env.SELFBENCH_REVIEW_OUTPUT;
|
|
6
|
-
if (!authJson) {
|
|
7
|
-
throw new Error("SELFBENCH_PI_AUTH_JSON is required");
|
|
7
|
+
if (!apiKey && !authJson) {
|
|
8
|
+
throw new Error("OPENAI_API_KEY or SELFBENCH_PI_AUTH_JSON is required");
|
|
8
9
|
}
|
|
9
10
|
if (!outputPath) {
|
|
10
11
|
throw new Error("SELFBENCH_REVIEW_OUTPUT is required");
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
const review = await reviewCouplingWithCodex({
|
|
14
|
-
|
|
15
|
+
...(apiKey ? { apiKey } : {}),
|
|
16
|
+
...(authJson ? { authJson } : {}),
|
|
15
17
|
prompt: await readFile("/work/review-input.md", "utf8"),
|
|
16
18
|
});
|
|
17
19
|
await writeFile(outputPath, `${JSON.stringify(review, null, 2)}\n`, { flag: "wx" });
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SandboxExecutor,
|
|
3
|
+
SandboxRequest,
|
|
4
|
+
SandboxResult,
|
|
5
|
+
SandboxRunOptions,
|
|
6
|
+
} from "./sandbox.js";
|
|
7
|
+
|
|
8
|
+
export const STANDARD_VERCEL_TIMEOUT_CAP_MS = 2 * 60 * 60 * 1_000;
|
|
9
|
+
export const HOBBY_VERCEL_TIMEOUT_CAP_MS = 45 * 60 * 1_000;
|
|
10
|
+
|
|
11
|
+
export function parseSandboxTimeoutCapText(value: string): number | undefined {
|
|
12
|
+
const normalized = value.trim().toLowerCase();
|
|
13
|
+
if (normalized === "") {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const match = /^(\d+)(ms|s|m|h)?$/.exec(normalized);
|
|
17
|
+
if (!match?.[1]) {
|
|
18
|
+
return Number.NaN;
|
|
19
|
+
}
|
|
20
|
+
const amount = Number(match[1]);
|
|
21
|
+
const multiplier =
|
|
22
|
+
match[2] === "h"
|
|
23
|
+
? 60 * 60 * 1_000
|
|
24
|
+
: match[2] === "m"
|
|
25
|
+
? 60 * 1_000
|
|
26
|
+
: match[2] === "s"
|
|
27
|
+
? 1_000
|
|
28
|
+
: 1;
|
|
29
|
+
return amount * multiplier;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class TimeoutCappedSandboxExecutor implements SandboxExecutor {
|
|
33
|
+
readonly #delegate: SandboxExecutor;
|
|
34
|
+
readonly #timeoutCapMs: number;
|
|
35
|
+
|
|
36
|
+
constructor(delegate: SandboxExecutor, timeoutCapMs: number) {
|
|
37
|
+
if (!Number.isInteger(timeoutCapMs) || timeoutCapMs < 100) {
|
|
38
|
+
throw new Error("sandbox timeout cap must be an integer of at least 100ms");
|
|
39
|
+
}
|
|
40
|
+
this.#delegate = delegate;
|
|
41
|
+
this.#timeoutCapMs = timeoutCapMs;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async run(request: SandboxRequest, options?: SandboxRunOptions): Promise<SandboxResult> {
|
|
45
|
+
return await this.#delegate.run(
|
|
46
|
+
request.timeoutMs > this.#timeoutCapMs
|
|
47
|
+
? { ...request, timeoutMs: this.#timeoutCapMs }
|
|
48
|
+
: request,
|
|
49
|
+
options,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
close(): void {
|
|
54
|
+
this.#delegate.close();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -68,10 +68,19 @@ await Promise.all([
|
|
|
68
68
|
]);
|
|
69
69
|
|
|
70
70
|
const piHome = join(homedir(), ".pi/agent");
|
|
71
|
-
const piAuth = process.env.SELFBENCH_PI_AUTH_JSON
|
|
71
|
+
const piAuth = process.env.SELFBENCH_PI_AUTH_JSON;
|
|
72
|
+
if (!process.env.OPENAI_API_KEY && !piAuth) {
|
|
73
|
+
fail("OPENAI_API_KEY or SELFBENCH_PI_AUTH_JSON is required");
|
|
74
|
+
}
|
|
72
75
|
await mkdir(piHome, { recursive: true });
|
|
73
76
|
await Promise.all([
|
|
74
|
-
|
|
77
|
+
...(piAuth
|
|
78
|
+
? [
|
|
79
|
+
writeFile(join(piHome, "auth.json"), piAuth).then(() =>
|
|
80
|
+
chmod(join(piHome, "auth.json"), 0o600),
|
|
81
|
+
),
|
|
82
|
+
]
|
|
83
|
+
: []),
|
|
75
84
|
writeFile(join(piHome, "settings.json"), `${JSON.stringify({ transport: "auto" })}\n`),
|
|
76
85
|
]);
|
|
77
86
|
const promptPath = join(tmpdir(), `selfbench-validation-repair-${originalDefinition.taskId}.md`);
|
|
@@ -98,7 +107,7 @@ const pi = await runCommand(
|
|
|
98
107
|
"--no-context-files",
|
|
99
108
|
"--no-extensions",
|
|
100
109
|
"--provider",
|
|
101
|
-
"openai-codex",
|
|
110
|
+
process.env.OPENAI_API_KEY ? "openai" : "openai-codex",
|
|
102
111
|
"--model",
|
|
103
112
|
process.env.SELFBENCH_REPAIR_MODEL ?? "gpt-5.6-sol",
|
|
104
113
|
"--thinking",
|
|
@@ -111,7 +120,7 @@ const pi = await runCommand(
|
|
|
111
120
|
allowFailure: true,
|
|
112
121
|
timeoutMs: 90 * 60 * 1000,
|
|
113
122
|
cwd: repositoryDirectory,
|
|
114
|
-
env:
|
|
123
|
+
env: process.env,
|
|
115
124
|
onOutput: (stream, chunk) => {
|
|
116
125
|
(stream === "stdout" ? process.stdout : process.stderr).write(chunk);
|
|
117
126
|
},
|
|
@@ -163,12 +172,6 @@ await Promise.all([
|
|
|
163
172
|
),
|
|
164
173
|
]);
|
|
165
174
|
|
|
166
|
-
function withoutApiKey(environment: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
|
167
|
-
const output = { ...environment };
|
|
168
|
-
delete output.OPENAI_API_KEY;
|
|
169
|
-
return output;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
175
|
function fail(message: string): never {
|
|
173
176
|
throw new Error(message);
|
|
174
177
|
}
|
package/src/sandbox.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SelfBenchWorkerConfig } from "./config.js";
|
|
2
2
|
import { DockerSandboxExecutor } from "./docker-executor.js";
|
|
3
3
|
import { ModalSandboxExecutor } from "./modal-executor.js";
|
|
4
|
+
import { TimeoutCappedSandboxExecutor } from "./sandbox-timeout.js";
|
|
5
|
+
import { VercelSandboxExecutor } from "./vercel-executor.js";
|
|
4
6
|
|
|
5
7
|
export interface SandboxFile {
|
|
6
8
|
readonly path: string;
|
|
@@ -44,8 +46,16 @@ export interface SandboxExecutor {
|
|
|
44
46
|
close(): void;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
export function createSandboxExecutor(config:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
export function createSandboxExecutor(config: SelfBenchWorkerConfig["execution"]): SandboxExecutor {
|
|
50
|
+
switch (config.kind) {
|
|
51
|
+
case "docker":
|
|
52
|
+
return new DockerSandboxExecutor(config);
|
|
53
|
+
case "modal":
|
|
54
|
+
return new ModalSandboxExecutor(config);
|
|
55
|
+
case "vercel":
|
|
56
|
+
return new TimeoutCappedSandboxExecutor(
|
|
57
|
+
new VercelSandboxExecutor(config),
|
|
58
|
+
config.timeoutCapMs,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
51
61
|
}
|
package/src/subscription-auth.ts
CHANGED
|
@@ -3,6 +3,34 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { runCommand } from "./process.js";
|
|
5
5
|
|
|
6
|
+
export interface PiModelAuth {
|
|
7
|
+
readonly provider: "openai" | "openai-codex";
|
|
8
|
+
readonly apiKey?: string;
|
|
9
|
+
readonly authJson?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CodexModelAuth {
|
|
13
|
+
readonly apiKey?: string;
|
|
14
|
+
readonly authJson?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function openAiApiKey(): string | undefined {
|
|
18
|
+
const key = process.env.OPENAI_API_KEY?.trim();
|
|
19
|
+
return key || undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function loadPiModelAuth(): Promise<PiModelAuth> {
|
|
23
|
+
const apiKey = openAiApiKey();
|
|
24
|
+
return apiKey
|
|
25
|
+
? { provider: "openai", apiKey }
|
|
26
|
+
: { provider: "openai-codex", authJson: await loadPiSubscriptionAuth() };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function loadCodexModelAuth(): Promise<CodexModelAuth> {
|
|
30
|
+
const apiKey = openAiApiKey();
|
|
31
|
+
return apiKey ? { apiKey } : { authJson: await loadCodexSubscriptionAuth() };
|
|
32
|
+
}
|
|
33
|
+
|
|
6
34
|
export async function loadPiSubscriptionAuth(): Promise<string> {
|
|
7
35
|
const raw =
|
|
8
36
|
process.env.SELFBENCH_PI_AUTH_JSON ??
|
|
@@ -28,7 +56,8 @@ export function assertCodexSubscriptionAuth(value: unknown, source = "Codex auth
|
|
|
28
56
|
|
|
29
57
|
export async function loadCodexSubscriptionAuth(): Promise<string> {
|
|
30
58
|
const path = process.env.CODEX_AUTH_JSON_PATH ?? join(homedir(), ".codex/auth.json");
|
|
31
|
-
const
|
|
59
|
+
const raw = process.env.SELFBENCH_CODEX_AUTH_JSON ?? (await readFile(path, "utf8"));
|
|
60
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
32
61
|
assertCodexSubscriptionAuth(parsed, path);
|
|
33
62
|
const auth = parsed as Record<string, unknown>;
|
|
34
63
|
return JSON.stringify({
|
|
@@ -38,22 +67,6 @@ export async function loadCodexSubscriptionAuth(): Promise<string> {
|
|
|
38
67
|
});
|
|
39
68
|
}
|
|
40
69
|
|
|
41
|
-
export async function subscriptionBearerToken(model: string): Promise<string> {
|
|
42
|
-
const result = await runCommand("pi", [
|
|
43
|
-
"auth",
|
|
44
|
-
"print-bearer-token",
|
|
45
|
-
"--provider",
|
|
46
|
-
"openai-codex",
|
|
47
|
-
"--model",
|
|
48
|
-
model,
|
|
49
|
-
]);
|
|
50
|
-
const token = result.stdout.trim();
|
|
51
|
-
if (!token) {
|
|
52
|
-
throw new Error(`Pi returned no openai-codex subscription bearer token for ${model}`);
|
|
53
|
-
}
|
|
54
|
-
return token;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
70
|
export async function githubToken(): Promise<string | undefined> {
|
|
58
71
|
if (process.env.GH_TOKEN) {
|
|
59
72
|
return process.env.GH_TOKEN;
|
|
@@ -5,20 +5,19 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { CancelledFailure, Context } from "@temporalio/activity";
|
|
6
6
|
import { ApplicationFailure } from "@temporalio/common";
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
import { type ArtifactStore, createArtifactStore } from "
|
|
9
|
-
import { auditTaskDefinition } from "
|
|
8
|
+
import { type ArtifactStore, createArtifactStore } from "../artifacts.js";
|
|
9
|
+
import { auditTaskDefinition } from "../audit.js";
|
|
10
10
|
import {
|
|
11
11
|
COUPLING_REVIEW_MODEL,
|
|
12
12
|
couplingReviewInput,
|
|
13
13
|
couplingReviewSchema,
|
|
14
|
-
} from "
|
|
15
|
-
import type { SelfBenchConfig } from "
|
|
14
|
+
} from "../codex-review.js";
|
|
15
|
+
import type { SelfBenchConfig, SelfBenchWorkerConfig } from "../config.js";
|
|
16
16
|
import {
|
|
17
17
|
type ArtifactRef,
|
|
18
18
|
type AuditResult,
|
|
19
19
|
type AuthoredTask,
|
|
20
20
|
type AuthorOutcome,
|
|
21
|
-
artifactRefSchema,
|
|
22
21
|
type Candidate,
|
|
23
22
|
candidateSchema,
|
|
24
23
|
type Difficulty,
|
|
@@ -27,29 +26,26 @@ import {
|
|
|
27
26
|
type RunRequest,
|
|
28
27
|
taskDefinitionSchema,
|
|
29
28
|
type ValidationResult,
|
|
30
|
-
} from "
|
|
29
|
+
} from "../contracts.js";
|
|
31
30
|
import {
|
|
32
31
|
buildCouplingEvidence,
|
|
33
32
|
discoverContractArtifacts,
|
|
34
33
|
resolveCouplingReview,
|
|
35
34
|
scanBaseContractArtifacts,
|
|
36
|
-
} from "
|
|
37
|
-
import { assertPullRequestBelongsToRepository } from "
|
|
35
|
+
} from "../coupling.js";
|
|
36
|
+
import { assertPullRequestBelongsToRepository } from "../github.js";
|
|
37
|
+
import { harborChildEnvironment } from "../harbor-environment.js";
|
|
38
38
|
import {
|
|
39
39
|
type HarborJobResult,
|
|
40
40
|
harborInfrastructureError,
|
|
41
41
|
readHarborJobResult,
|
|
42
|
-
} from "
|
|
43
|
-
import { refreshHarborTask } from "
|
|
44
|
-
import { sha256 } from "
|
|
45
|
-
import { runCommand } from "
|
|
46
|
-
import { assertProvenanceMatchesPullRequest, type ProvenanceMessage } from "
|
|
47
|
-
import { createSandboxExecutor, type SandboxExecutor, type SandboxRunOptions } from "
|
|
48
|
-
import {
|
|
49
|
-
githubToken,
|
|
50
|
-
loadCodexSubscriptionAuth,
|
|
51
|
-
loadPiSubscriptionAuth,
|
|
52
|
-
} from "./subscription-auth.js";
|
|
42
|
+
} from "../harbor-results.js";
|
|
43
|
+
import { refreshHarborTask } from "../harbor-task.js";
|
|
44
|
+
import { sha256 } from "../hash.js";
|
|
45
|
+
import { runCommand } from "../process.js";
|
|
46
|
+
import { assertProvenanceMatchesPullRequest, type ProvenanceMessage } from "../provenance.js";
|
|
47
|
+
import { createSandboxExecutor, type SandboxExecutor, type SandboxRunOptions } from "../sandbox.js";
|
|
48
|
+
import { githubToken, loadCodexModelAuth, loadPiModelAuth } from "../subscription-auth.js";
|
|
53
49
|
|
|
54
50
|
const HARBOR_INFRASTRUCTURE_FAILURE_TYPE = "HarborInfrastructureFailure";
|
|
55
51
|
const DISCOVERY_TIMEOUT_MS = 45 * 60 * 1000;
|
|
@@ -119,7 +115,7 @@ export interface SelfBenchActivities {
|
|
|
119
115
|
buildExport(input: ExportInput): Promise<ArtifactRef>;
|
|
120
116
|
}
|
|
121
117
|
|
|
122
|
-
export function createActivities(config:
|
|
118
|
+
export function createActivities(config: SelfBenchWorkerConfig): SelfBenchActivities {
|
|
123
119
|
const store = createArtifactStore(config.artifact);
|
|
124
120
|
const sandbox = createSandboxExecutor(config.execution);
|
|
125
121
|
return {
|
|
@@ -178,7 +174,7 @@ async function discoverCandidateShard(
|
|
|
178
174
|
} else {
|
|
179
175
|
const [extension, piAuth, ghToken] = await Promise.all([
|
|
180
176
|
readAsset("src/extensions/discovery.ts"),
|
|
181
|
-
|
|
177
|
+
loadPiModelAuth(),
|
|
182
178
|
githubToken(),
|
|
183
179
|
]);
|
|
184
180
|
Context.current().heartbeat(
|
|
@@ -200,7 +196,8 @@ async function discoverCandidateShard(
|
|
|
200
196
|
],
|
|
201
197
|
outputPaths: ["/work/discovery.json"],
|
|
202
198
|
secrets: {
|
|
203
|
-
|
|
199
|
+
...(piAuth.apiKey ? { OPENAI_API_KEY: piAuth.apiKey } : {}),
|
|
200
|
+
...(piAuth.authJson ? { SELFBENCH_PI_AUTH_JSON: piAuth.authJson } : {}),
|
|
204
201
|
...(ghToken ? { GH_TOKEN: ghToken } : {}),
|
|
205
202
|
},
|
|
206
203
|
environment: {
|
|
@@ -356,7 +353,7 @@ async function authorCandidate(
|
|
|
356
353
|
readAsset("src/extensions/authoring.ts"),
|
|
357
354
|
readAsset("src/skills/selfbench/SKILL.md"),
|
|
358
355
|
readAsset("dist/sandbox-author.bundle.js"),
|
|
359
|
-
|
|
356
|
+
loadPiModelAuth(),
|
|
360
357
|
githubToken(),
|
|
361
358
|
]);
|
|
362
359
|
const prompt = authoringPrompt(run, candidate);
|
|
@@ -378,7 +375,8 @@ async function authorCandidate(
|
|
|
378
375
|
],
|
|
379
376
|
outputPaths: ["/work/task.tar.gz", "/work/definition.json"],
|
|
380
377
|
secrets: {
|
|
381
|
-
|
|
378
|
+
...(piAuth.apiKey ? { OPENAI_API_KEY: piAuth.apiKey } : {}),
|
|
379
|
+
...(piAuth.authJson ? { SELFBENCH_PI_AUTH_JSON: piAuth.authJson } : {}),
|
|
382
380
|
...(ghToken ? { GH_TOKEN: ghToken } : {}),
|
|
383
381
|
},
|
|
384
382
|
environment: {
|
|
@@ -591,9 +589,8 @@ async function repairValidationTask(
|
|
|
591
589
|
store.get(input.task.bundle),
|
|
592
590
|
store.get(input.task.definition),
|
|
593
591
|
readAsset("dist/sandbox-validation-repair.bundle.js"),
|
|
594
|
-
|
|
595
|
-
]);
|
|
596
|
-
// Full verifier logs remain durable artifacts. The validation reason already carries bounded
|
|
592
|
+
loadPiModelAuth(),
|
|
593
|
+
]); // Full verifier logs remain durable artifacts. The validation reason already carries bounded
|
|
597
594
|
// tails for failed gates, which keeps the repair prompt within the model context window.
|
|
598
595
|
const diagnostics = Buffer.from(input.validation.reason ?? "validation failed without a reason");
|
|
599
596
|
const result = await withActivityHeartbeats(
|
|
@@ -616,7 +613,10 @@ async function repairValidationTask(
|
|
|
616
613
|
"/work/repaired-test.patch",
|
|
617
614
|
"/work/repair-report.json",
|
|
618
615
|
],
|
|
619
|
-
secrets: {
|
|
616
|
+
secrets: {
|
|
617
|
+
...(authJson.apiKey ? { OPENAI_API_KEY: authJson.apiKey } : {}),
|
|
618
|
+
...(authJson.authJson ? { SELFBENCH_PI_AUTH_JSON: authJson.authJson } : {}),
|
|
619
|
+
},
|
|
620
620
|
environment: { SELFBENCH_REPAIR_MODEL: input.run.authoring.model },
|
|
621
621
|
command: [
|
|
622
622
|
"node",
|
|
@@ -704,7 +704,7 @@ async function reviewTask(
|
|
|
704
704
|
});
|
|
705
705
|
const [reviewer, authJson] = await Promise.all([
|
|
706
706
|
readAsset("dist/sandbox-review.bundle.js"),
|
|
707
|
-
|
|
707
|
+
loadPiModelAuth(),
|
|
708
708
|
]);
|
|
709
709
|
const result = await withActivityHeartbeats(
|
|
710
710
|
`running sandboxed coupling review for ${input.task.taskId}`,
|
|
@@ -728,7 +728,10 @@ async function reviewTask(
|
|
|
728
728
|
},
|
|
729
729
|
],
|
|
730
730
|
outputPaths: ["/work/review.json"],
|
|
731
|
-
secrets: {
|
|
731
|
+
secrets: {
|
|
732
|
+
...(authJson.apiKey ? { OPENAI_API_KEY: authJson.apiKey } : {}),
|
|
733
|
+
...(authJson.authJson ? { SELFBENCH_PI_AUTH_JSON: authJson.authJson } : {}),
|
|
734
|
+
},
|
|
732
735
|
environment: { SELFBENCH_REVIEW_OUTPUT: "/work/review.json" },
|
|
733
736
|
command: ["node", "/work/sandbox-review.js"],
|
|
734
737
|
},
|
|
@@ -796,7 +799,7 @@ async function repairTask(
|
|
|
796
799
|
store.get(input.task.bundle),
|
|
797
800
|
store.get(input.review),
|
|
798
801
|
readAsset("dist/sandbox-repair.bundle.js"),
|
|
799
|
-
|
|
802
|
+
loadCodexModelAuth(),
|
|
800
803
|
]);
|
|
801
804
|
const result = await withActivityHeartbeats(
|
|
802
805
|
`running test repair sandbox for ${input.task.taskId}`,
|
|
@@ -813,7 +816,10 @@ async function repairTask(
|
|
|
813
816
|
{ path: "/work/sandbox-repair.js", contents: repairer },
|
|
814
817
|
],
|
|
815
818
|
outputPaths: ["/work/repaired-task.tar.gz", "/work/repair-report.json"],
|
|
816
|
-
secrets: {
|
|
819
|
+
secrets: {
|
|
820
|
+
...(authJson.apiKey ? { OPENAI_API_KEY: authJson.apiKey } : {}),
|
|
821
|
+
...(authJson.authJson ? { SELFBENCH_CODEX_AUTH_JSON: authJson.authJson } : {}),
|
|
822
|
+
},
|
|
817
823
|
environment: { SELFBENCH_REPAIR_MODEL: input.run.authoring.model },
|
|
818
824
|
command: [
|
|
819
825
|
"node",
|
|
@@ -980,7 +986,7 @@ function modalAgentScript(extension: string, tool: string): string {
|
|
|
980
986
|
clone_source
|
|
981
987
|
cd /work/repo
|
|
982
988
|
pi --print --mode json --no-session --no-approve --no-skills --no-prompt-templates --no-context-files --no-extensions \\
|
|
983
|
-
--extension /work/${extension} --provider
|
|
989
|
+
--extension /work/${extension} --provider "$(model_provider)" --model "$AUTHOR_MODEL" --thinking high \\
|
|
984
990
|
--tools read,bash,grep,find,ls,${tool} "$(cat /work/prompt.txt)" 2>&1`;
|
|
985
991
|
}
|
|
986
992
|
|
|
@@ -991,7 +997,7 @@ mkdir -p /work/tasks
|
|
|
991
997
|
cd /work/repo
|
|
992
998
|
pi --print --mode json --no-session --no-approve --no-prompt-templates --no-context-files --no-extensions \\
|
|
993
999
|
--skill /work/selfbench-skill --extension /work/authoring.ts \\
|
|
994
|
-
--provider
|
|
1000
|
+
--provider "$(model_provider)" --model "$AUTHOR_MODEL" --thinking high \\
|
|
995
1001
|
--tools read,bash,grep,find,ls,submit_task "$(cat /work/prompt.txt)" 2>&1
|
|
996
1002
|
node /work/sandbox-author.js /work/tasks /work/repo /work/harbor-task
|
|
997
1003
|
cp /work/tasks/*/definition.json /work/definition.json
|
|
@@ -1001,9 +1007,13 @@ tar -czf /work/task.tar.gz -C /work harbor-task`;
|
|
|
1001
1007
|
function sandboxBootstrap(): string {
|
|
1002
1008
|
return `set -euo pipefail
|
|
1003
1009
|
mkdir -p "$HOME/.pi/agent"
|
|
1004
|
-
|
|
1010
|
+
if [ -n "\${SELFBENCH_PI_AUTH_JSON:-}" ]; then
|
|
1011
|
+
printf '%s' "$SELFBENCH_PI_AUTH_JSON" > "$HOME/.pi/agent/auth.json"
|
|
1012
|
+
chmod 600 "$HOME/.pi/agent/auth.json"
|
|
1013
|
+
fi
|
|
1005
1014
|
printf '%s\n' '{"transport":"auto"}' > "$HOME/.pi/agent/settings.json"
|
|
1006
|
-
chmod 600 "$HOME/.pi/agent/
|
|
1015
|
+
chmod 600 "$HOME/.pi/agent/settings.json"
|
|
1016
|
+
model_provider() { [ -n "\${OPENAI_API_KEY:-}" ] && printf openai || printf openai-codex; }
|
|
1007
1017
|
cleanup() { rm -f "$HOME/.pi/agent/auth.json" "$HOME/.pi/agent/settings.json" "$HOME/.git-credentials"; }
|
|
1008
1018
|
trap cleanup EXIT
|
|
1009
1019
|
clone_source() {
|
|
@@ -1045,7 +1055,12 @@ async function runHarborGate(
|
|
|
1045
1055
|
"--yes",
|
|
1046
1056
|
"--quiet",
|
|
1047
1057
|
],
|
|
1048
|
-
{
|
|
1058
|
+
{
|
|
1059
|
+
allowFailure: true,
|
|
1060
|
+
env: harborChildEnvironment(),
|
|
1061
|
+
timeoutMs: 3 * 60 * 60 * 1000,
|
|
1062
|
+
signal,
|
|
1063
|
+
},
|
|
1049
1064
|
);
|
|
1050
1065
|
if (result.exitCode !== 0) {
|
|
1051
1066
|
throw ApplicationFailure.create({
|
|
@@ -1204,7 +1219,7 @@ function parseProvenance(value: Uint8Array): ProvenanceMessage[] {
|
|
|
1204
1219
|
}
|
|
1205
1220
|
|
|
1206
1221
|
function readAsset(relativePath: string): Promise<Buffer> {
|
|
1207
|
-
const root = resolve(dirname(fileURLToPath(import.meta.url)), "
|
|
1222
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
1208
1223
|
return readFile(join(root, relativePath));
|
|
1209
1224
|
}
|
|
1210
1225
|
|
|
@@ -1230,7 +1245,3 @@ function numberValue(value: unknown): number {
|
|
|
1230
1245
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
1231
1246
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1232
1247
|
}
|
|
1233
|
-
|
|
1234
|
-
export function parseArtifactReference(value: unknown): ArtifactRef {
|
|
1235
|
-
return artifactRefSchema.parse(value);
|
|
1236
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Connection } from "@temporalio/client";
|
|
2
2
|
import { NativeConnection } from "@temporalio/worker";
|
|
3
|
-
import type { SelfBenchConfig } from "
|
|
3
|
+
import type { SelfBenchConfig } from "../config.js";
|
|
4
4
|
|
|
5
5
|
export async function connectTemporalClient(
|
|
6
6
|
config: SelfBenchConfig["temporal"],
|