codex-multi-auth 1.3.2 → 2.0.1
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/README.md +40 -26
- package/config/README.md +4 -4
- package/config/codex-legacy.json +571 -646
- package/config/codex-modern.json +258 -274
- package/config/minimal-codex.json +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/auto-update-checker.d.ts +23 -1
- package/dist/lib/auto-update-checker.d.ts.map +1 -1
- package/dist/lib/auto-update-checker.js +481 -8
- package/dist/lib/auto-update-checker.js.map +1 -1
- package/dist/lib/cli.d.ts +5 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +1 -1
- package/dist/lib/codex-manager/commands/best.js.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +3 -3
- package/dist/lib/codex-manager/commands/forecast.js.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +3 -3
- package/dist/lib/codex-manager/commands/report.js.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.d.ts +26 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/rotation.js +313 -0
- package/dist/lib/codex-manager/commands/rotation.js.map +1 -0
- package/dist/lib/codex-manager/commands/status.d.ts +6 -0
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +64 -10
- package/dist/lib/codex-manager/commands/status.js.map +1 -1
- package/dist/lib/codex-manager/forecast-report-commands.js +4 -4
- package/dist/lib/codex-manager/forecast-report-commands.js.map +1 -1
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +3 -2
- package/dist/lib/codex-manager/help.js.map +1 -1
- package/dist/lib/codex-manager/rate-limit-markers.d.ts +2 -0
- package/dist/lib/codex-manager/rate-limit-markers.d.ts.map +1 -0
- package/dist/lib/codex-manager/rate-limit-markers.js +4 -0
- package/dist/lib/codex-manager/rate-limit-markers.js.map +1 -0
- package/dist/lib/codex-manager/repair-commands.js +3 -3
- package/dist/lib/codex-manager/repair-commands.js.map +1 -1
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +115 -87
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +9 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +2 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/fs-retry.d.ts +7 -0
- package/dist/lib/fs-retry.d.ts.map +1 -0
- package/dist/lib/fs-retry.js +35 -0
- package/dist/lib/fs-retry.js.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +1 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/prompts/codex.d.ts +1 -1
- package/dist/lib/prompts/codex.d.ts.map +1 -1
- package/dist/lib/prompts/codex.js +3 -3
- package/dist/lib/prompts/codex.js.map +1 -1
- package/dist/lib/quota-probe.js +1 -1
- package/dist/lib/quota-probe.js.map +1 -1
- package/dist/lib/quota-readiness.d.ts +16 -0
- package/dist/lib/quota-readiness.d.ts.map +1 -0
- package/dist/lib/quota-readiness.js +82 -0
- package/dist/lib/quota-readiness.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +19 -8
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/request/helpers/model-map.d.ts +2 -1
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
- package/dist/lib/request/helpers/model-map.js +52 -60
- package/dist/lib/request/helpers/model-map.js.map +1 -1
- package/dist/lib/request/request-transformer.d.ts +2 -2
- package/dist/lib/request/request-transformer.js +4 -3
- package/dist/lib/request/request-transformer.js.map +1 -1
- package/dist/lib/runtime/app-bind.d.ts +74 -0
- package/dist/lib/runtime/app-bind.d.ts.map +1 -0
- package/dist/lib/runtime/app-bind.js +620 -0
- package/dist/lib/runtime/app-bind.js.map +1 -0
- package/dist/lib/runtime/config-toml.d.ts +10 -0
- package/dist/lib/runtime/config-toml.d.ts.map +1 -0
- package/dist/lib/runtime/config-toml.js +128 -0
- package/dist/lib/runtime/config-toml.js.map +1 -0
- package/dist/lib/runtime/login-menu-accounts.d.ts +5 -0
- package/dist/lib/runtime/login-menu-accounts.d.ts.map +1 -1
- package/dist/lib/runtime/login-menu-accounts.js +7 -2
- package/dist/lib/runtime/login-menu-accounts.js.map +1 -1
- package/dist/lib/runtime/quota-probe.js +1 -1
- package/dist/lib/runtime/quota-probe.js.map +1 -1
- package/dist/lib/runtime/runtime-current-account.d.ts +52 -0
- package/dist/lib/runtime/runtime-current-account.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-current-account.js +252 -0
- package/dist/lib/runtime/runtime-current-account.js.map +1 -0
- package/dist/lib/runtime/runtime-observability.d.ts +5 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +5 -0
- package/dist/lib/runtime/runtime-observability.js.map +1 -1
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -0
- package/dist/lib/runtime-constants.js +3 -0
- package/dist/lib/runtime-constants.js.map +1 -0
- package/dist/lib/runtime-rotation-proxy.d.ts +36 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -0
- package/dist/lib/runtime-rotation-proxy.js +828 -0
- package/dist/lib/runtime-rotation-proxy.js.map +1 -0
- package/dist/lib/schemas.d.ts +1 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +1 -0
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts +6 -1
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +22 -2
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/package.json +13 -11
- package/scripts/bench-format/codex-host.mjs +142 -73
- package/scripts/bench-format/models.mjs +23 -24
- package/scripts/benchmark-edit-formats.mjs +9 -7
- package/scripts/check-pack-budget-lib.js +49 -6
- package/scripts/codex-app-launcher.js +653 -0
- package/scripts/codex-app-router.js +322 -0
- package/scripts/codex-multi-auth.js +3 -1
- package/scripts/codex-routing.js +6 -0
- package/scripts/codex.js +2428 -445
- package/scripts/postinstall.js +343 -0
|
@@ -1,20 +1,39 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
|
|
5
6
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const repoRoot = resolve(scriptDir, "..", "..");
|
|
7
8
|
|
|
8
|
-
export function getRepoRoot() {
|
|
9
|
-
return repoRoot;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
export function getRepoRoot() {
|
|
10
|
+
return repoRoot;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function resolveWindowsNpmShim(command) {
|
|
14
|
+
if (!/\.(cmd|bat)$/i.test(command)) {
|
|
15
|
+
return { command, shell: false };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const codexScript = join(dirname(command), "node_modules", "codex-multi-auth", "scripts", "codex.js");
|
|
19
|
+
if (existsSync(codexScript)) {
|
|
20
|
+
return {
|
|
21
|
+
command: process.execPath,
|
|
22
|
+
shell: false,
|
|
23
|
+
argsPrefix: [codexScript],
|
|
24
|
+
shimCommand: command,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return { command, shell: true };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function resolveCodexExecutable() {
|
|
32
|
+
const envOverride = process.env.CODEX_BIN;
|
|
33
|
+
if (envOverride && envOverride.trim().length > 0) {
|
|
34
|
+
const command = envOverride.trim();
|
|
35
|
+
return process.platform === "win32" ? resolveWindowsNpmShim(command) : { command, shell: false };
|
|
36
|
+
}
|
|
18
37
|
|
|
19
38
|
if (process.platform !== "win32") {
|
|
20
39
|
return { command: "codex", shell: false };
|
|
@@ -38,15 +57,15 @@ export function resolveCodexExecutable() {
|
|
|
38
57
|
return { command: exactExe, shell: false };
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
const exactCmd = candidates.find((candidate) => /npm\\Codex\.cmd$/i.test(candidate));
|
|
42
|
-
if (exactCmd) {
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const anyCmd = candidates.find((candidate) => /\.cmd$/i.test(candidate));
|
|
47
|
-
if (anyCmd) {
|
|
48
|
-
return
|
|
49
|
-
}
|
|
60
|
+
const exactCmd = candidates.find((candidate) => /npm\\Codex\.cmd$/i.test(candidate));
|
|
61
|
+
if (exactCmd) {
|
|
62
|
+
return resolveWindowsNpmShim(exactCmd);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const anyCmd = candidates.find((candidate) => /\.cmd$/i.test(candidate));
|
|
66
|
+
if (anyCmd) {
|
|
67
|
+
return resolveWindowsNpmShim(anyCmd);
|
|
68
|
+
}
|
|
50
69
|
|
|
51
70
|
return { command: candidates[0], shell: false };
|
|
52
71
|
}
|
|
@@ -67,23 +86,35 @@ export function parseNdjson(text) {
|
|
|
67
86
|
return events;
|
|
68
87
|
}
|
|
69
88
|
|
|
70
|
-
export function getToolEvents(events) {
|
|
71
|
-
|
|
72
|
-
.filter((event) => event?.type === "tool_use" && event?.part?.type === "tool")
|
|
73
|
-
.map((event) => ({
|
|
74
|
-
tool: event.part.tool,
|
|
75
|
-
input: event.part.state?.input ?? {},
|
|
76
|
-
output: event.part.state?.output,
|
|
89
|
+
export function getToolEvents(events) {
|
|
90
|
+
const legacyToolEvents = events
|
|
91
|
+
.filter((event) => event?.type === "tool_use" && event?.part?.type === "tool")
|
|
92
|
+
.map((event) => ({
|
|
93
|
+
tool: event.part.tool,
|
|
94
|
+
input: event.part.state?.input ?? {},
|
|
95
|
+
output: event.part.state?.output,
|
|
77
96
|
status: event.part.state?.status,
|
|
78
97
|
start: event.part.state?.time?.start,
|
|
79
98
|
end: event.part.state?.time?.end,
|
|
80
99
|
durationMs:
|
|
81
100
|
typeof event.part.state?.time?.start === "number" &&
|
|
82
101
|
typeof event.part.state?.time?.end === "number"
|
|
83
|
-
? event.part.state.time.end - event.part.state.time.start
|
|
84
|
-
: null,
|
|
85
|
-
}));
|
|
86
|
-
|
|
102
|
+
? event.part.state.time.end - event.part.state.time.start
|
|
103
|
+
: null,
|
|
104
|
+
}));
|
|
105
|
+
const execToolEvents = events
|
|
106
|
+
.filter((event) => event?.type === "item.completed" && event?.item?.type === "command_execution")
|
|
107
|
+
.map((event) => ({
|
|
108
|
+
tool: "command_execution",
|
|
109
|
+
input: { command: event.item.command },
|
|
110
|
+
output: event.item.aggregated_output,
|
|
111
|
+
status: event.item.status,
|
|
112
|
+
start: null,
|
|
113
|
+
end: null,
|
|
114
|
+
durationMs: null,
|
|
115
|
+
}));
|
|
116
|
+
return [...legacyToolEvents, ...execToolEvents];
|
|
117
|
+
}
|
|
87
118
|
|
|
88
119
|
export function getSessionDuration(events) {
|
|
89
120
|
const starts = events
|
|
@@ -98,11 +129,12 @@ export function getSessionDuration(events) {
|
|
|
98
129
|
return Math.max(...finishes) - Math.min(...starts);
|
|
99
130
|
}
|
|
100
131
|
|
|
101
|
-
export function getTokenTotals(events) {
|
|
102
|
-
const stepFinishes = events.filter((event) => event?.type === "step_finish" && event?.part?.tokens);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
132
|
+
export function getTokenTotals(events) {
|
|
133
|
+
const stepFinishes = events.filter((event) => event?.type === "step_finish" && event?.part?.tokens);
|
|
134
|
+
const turnCompletions = events.filter((event) => event?.type === "turn.completed" && event?.usage);
|
|
135
|
+
if (stepFinishes.length === 0 && turnCompletions.length === 0) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
106
138
|
const total = {
|
|
107
139
|
total: 0,
|
|
108
140
|
input: 0,
|
|
@@ -121,29 +153,49 @@ export function getTokenTotals(events) {
|
|
|
121
153
|
total.input += input;
|
|
122
154
|
total.output += output;
|
|
123
155
|
total.reasoning += reasoning;
|
|
124
|
-
total.cacheRead += Number(tokens.cache?.read ?? 0);
|
|
125
|
-
total.cacheWrite += Number(tokens.cache?.write ?? 0);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
}
|
|
156
|
+
total.cacheRead += Number(tokens.cache?.read ?? 0);
|
|
157
|
+
total.cacheWrite += Number(tokens.cache?.write ?? 0);
|
|
158
|
+
}
|
|
159
|
+
for (const event of turnCompletions) {
|
|
160
|
+
const usage = event.usage ?? {};
|
|
161
|
+
const input = Number(usage.input_tokens ?? 0);
|
|
162
|
+
const output = Number(usage.output_tokens ?? 0);
|
|
163
|
+
const reasoning = Number(usage.reasoning_output_tokens ?? 0);
|
|
164
|
+
total.total += input + output;
|
|
165
|
+
total.input += input;
|
|
166
|
+
total.output += output;
|
|
167
|
+
total.reasoning += reasoning;
|
|
168
|
+
total.cacheRead += Number(usage.cached_input_tokens ?? 0);
|
|
169
|
+
}
|
|
170
|
+
return total;
|
|
171
|
+
}
|
|
129
172
|
|
|
130
|
-
export function getTextOutput(events) {
|
|
131
|
-
|
|
132
|
-
.filter((event) => event?.type === "text" && typeof event?.part?.text === "string")
|
|
133
|
-
.map((event) => event.part.text)
|
|
134
|
-
.join("\n");
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
173
|
+
export function getTextOutput(events) {
|
|
174
|
+
const legacyText = events
|
|
175
|
+
.filter((event) => event?.type === "text" && typeof event?.part?.text === "string")
|
|
176
|
+
.map((event) => event.part.text)
|
|
177
|
+
.join("\n");
|
|
178
|
+
const execText = events
|
|
179
|
+
.filter((event) => event?.type === "item.completed" && event?.item?.type === "agent_message" && typeof event.item.text === "string")
|
|
180
|
+
.map((event) => event.item.text)
|
|
181
|
+
.join("\n");
|
|
182
|
+
return [legacyText, execText].filter(Boolean).join("\n");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function getEventError(events) {
|
|
186
|
+
const lastCompletedIndex = events.findLastIndex((event) => event?.type === "turn.completed");
|
|
187
|
+
const failureIndex = events.findLastIndex(
|
|
188
|
+
(event, index) => index > lastCompletedIndex && (event?.type === "error" || event?.type === "turn.failed"),
|
|
189
|
+
);
|
|
190
|
+
if (failureIndex < 0) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
const errorEvent = events[failureIndex];
|
|
194
|
+
return {
|
|
195
|
+
name: errorEvent.error?.name ?? errorEvent.type ?? "UnknownError",
|
|
196
|
+
message: errorEvent.error?.data?.message ?? errorEvent.error?.message ?? errorEvent.message ?? "Unknown error",
|
|
197
|
+
};
|
|
198
|
+
}
|
|
147
199
|
|
|
148
200
|
export function runCodexJson({
|
|
149
201
|
executable,
|
|
@@ -155,20 +207,33 @@ export function runCodexJson({
|
|
|
155
207
|
homeDir,
|
|
156
208
|
timeoutMs,
|
|
157
209
|
extraEnv,
|
|
158
|
-
}) {
|
|
159
|
-
const startWall = Date.now();
|
|
160
|
-
const args = [
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
210
|
+
}) {
|
|
211
|
+
const startWall = Date.now();
|
|
212
|
+
const args = [
|
|
213
|
+
"exec",
|
|
214
|
+
"--json",
|
|
215
|
+
"--model",
|
|
216
|
+
model,
|
|
217
|
+
"--skip-git-repo-check",
|
|
218
|
+
"--sandbox",
|
|
219
|
+
"danger-full-access",
|
|
220
|
+
"-c",
|
|
221
|
+
"approval_policy='never'",
|
|
222
|
+
];
|
|
223
|
+
if (variant) {
|
|
224
|
+
args.push("-c", `model_reasoning_effort='${variant}'`);
|
|
225
|
+
}
|
|
226
|
+
void agent;
|
|
227
|
+
args.push(prompt);
|
|
228
|
+
const childArgs = [...(executable.argsPrefix ?? []), ...args];
|
|
229
|
+
|
|
230
|
+
const child = spawnSync(executable.command, childArgs, {
|
|
167
231
|
cwd: cwd ?? repoRoot,
|
|
168
232
|
encoding: "utf8",
|
|
169
|
-
windowsHide: true,
|
|
170
|
-
shell: executable.shell,
|
|
171
|
-
|
|
233
|
+
windowsHide: true,
|
|
234
|
+
shell: executable.shell,
|
|
235
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
236
|
+
timeout: timeoutMs,
|
|
172
237
|
maxBuffer: 30 * 1024 * 1024,
|
|
173
238
|
env: {
|
|
174
239
|
...process.env,
|
|
@@ -189,7 +254,11 @@ export function runCodexJson({
|
|
|
189
254
|
if (child.error && !timedOut) {
|
|
190
255
|
throw child.error;
|
|
191
256
|
}
|
|
192
|
-
const
|
|
257
|
+
const failed = (child.status ?? 1) !== 0 || eventError !== null;
|
|
258
|
+
const modelNotFound =
|
|
259
|
+
failed &&
|
|
260
|
+
(/Model not found|ProviderModelNotFoundError|model is not supported|not supported when using Codex/i.test(`${stdout}\n${stderr}`) ||
|
|
261
|
+
/Model not found|model is not supported|not supported when using Codex/i.test(eventError?.message ?? ""));
|
|
193
262
|
|
|
194
263
|
return {
|
|
195
264
|
status: child.status ?? 1,
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { resolveCodexExecutable } from "./codex-host.mjs";
|
|
3
3
|
|
|
4
|
-
const FALLBACK_OPENAI_CODEX_STABLE = [
|
|
5
|
-
"openai/gpt-5-codex",
|
|
6
|
-
"openai/gpt-5.
|
|
7
|
-
"openai/gpt-5.
|
|
8
|
-
"openai/gpt-5.
|
|
9
|
-
|
|
10
|
-
"openai/gpt-5.3-codex",
|
|
11
|
-
];
|
|
4
|
+
const FALLBACK_OPENAI_CODEX_STABLE = [
|
|
5
|
+
"openai/gpt-5.3-codex",
|
|
6
|
+
"openai/gpt-5.4",
|
|
7
|
+
"openai/gpt-5.4-mini",
|
|
8
|
+
"openai/gpt-5.5",
|
|
9
|
+
];
|
|
12
10
|
|
|
13
11
|
const OPENAI_CODEX_PREFIXES = ["openai/", "openai-multi/"];
|
|
14
12
|
|
|
@@ -25,14 +23,14 @@ export function canonicalCodexModelId(modelId) {
|
|
|
25
23
|
return `openai/${codexTail(modelId)}`;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
export function aliasCandidatesForCodexModel(modelId) {
|
|
29
|
-
if (!isOpenAiCodexProviderPrefix(modelId)) {
|
|
30
|
-
return [modelId];
|
|
31
|
-
}
|
|
32
|
-
const tail = codexTail(modelId);
|
|
33
|
-
const candidates = [`openai/${tail}`, `openai-multi/${tail}`];
|
|
34
|
-
return [...new Set([modelId, ...candidates])];
|
|
35
|
-
}
|
|
26
|
+
export function aliasCandidatesForCodexModel(modelId) {
|
|
27
|
+
if (!isOpenAiCodexProviderPrefix(modelId)) {
|
|
28
|
+
return [modelId];
|
|
29
|
+
}
|
|
30
|
+
const tail = codexTail(modelId);
|
|
31
|
+
const candidates = [`openai/${tail}`, `openai-multi/${tail}`];
|
|
32
|
+
return [...new Set([tail, modelId, ...candidates])];
|
|
33
|
+
}
|
|
36
34
|
|
|
37
35
|
export function isStableOpenAiCodexModel(modelId) {
|
|
38
36
|
if (!isOpenAiCodexProviderPrefix(modelId)) {
|
|
@@ -47,14 +45,15 @@ export function isStableOpenAiCodexModel(modelId) {
|
|
|
47
45
|
return true;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
export function listCodexModels() {
|
|
51
|
-
const executable = resolveCodexExecutable();
|
|
52
|
-
const child = spawnSync(executable.command, ["models"], {
|
|
53
|
-
encoding: "utf8",
|
|
54
|
-
windowsHide: true,
|
|
55
|
-
shell: executable.shell,
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
export function listCodexModels() {
|
|
49
|
+
const executable = resolveCodexExecutable();
|
|
50
|
+
const child = spawnSync(executable.command, [...(executable.argsPrefix ?? []), "models"], {
|
|
51
|
+
encoding: "utf8",
|
|
52
|
+
windowsHide: true,
|
|
53
|
+
shell: executable.shell,
|
|
54
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
55
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
56
|
+
timeout: Number.parseInt(process.env.CODEX_MODELS_TIMEOUT_MS ?? "30000", 10),
|
|
58
57
|
killSignal: "SIGKILL",
|
|
59
58
|
});
|
|
60
59
|
if (child.error && child.error.code === "ETIMEDOUT") {
|
|
@@ -63,7 +63,7 @@ function printUsage() {
|
|
|
63
63
|
" --help Show this help",
|
|
64
64
|
"",
|
|
65
65
|
"Examples:",
|
|
66
|
-
" node scripts/benchmark-edit-formats.mjs --smoke --models=openai/gpt-5-codex",
|
|
66
|
+
" node scripts/benchmark-edit-formats.mjs --smoke --models=openai/gpt-5.3-codex",
|
|
67
67
|
" node scripts/benchmark-edit-formats.mjs --preset=codex-core --warmup-runs=1 --measured-runs=5",
|
|
68
68
|
].join("\n"));
|
|
69
69
|
}
|
|
@@ -588,12 +588,14 @@ function aggregateSummary({ options, runRecords, failures, startTime, endTime, e
|
|
|
588
588
|
warmupRunsPerTask: options.warmupRuns,
|
|
589
589
|
measuredRunsPerTask: options.measuredRuns,
|
|
590
590
|
timeoutMs: options.timeoutMs,
|
|
591
|
-
outputRoot: options.outputRoot,
|
|
592
|
-
runDir: options.runDir,
|
|
593
|
-
homeDir: options.homeDir || null,
|
|
594
|
-
CodexCommand: executable.command,
|
|
595
|
-
|
|
596
|
-
|
|
591
|
+
outputRoot: options.outputRoot,
|
|
592
|
+
runDir: options.runDir,
|
|
593
|
+
homeDir: options.homeDir || null,
|
|
594
|
+
CodexCommand: executable.command,
|
|
595
|
+
CodexArgsPrefix: executable.argsPrefix ?? [],
|
|
596
|
+
CodexShimCommand: executable.shimCommand ?? null,
|
|
597
|
+
CodexUsesShell: executable.shell,
|
|
598
|
+
keepRawLogs: options.keepRawLogs,
|
|
597
599
|
runCount: measuredRuns.length,
|
|
598
600
|
warmupCount: warmupRuns.length,
|
|
599
601
|
},
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { exec } from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {{ packageSize: number, paths: string[] }} ParsedPackMetadata
|
|
6
|
+
* @typedef {{ windowsHide: boolean, maxBuffer: number }} ExecOptions
|
|
7
|
+
* @typedef {{ stdout: string | Buffer, stderr?: string | Buffer }} ExecResult
|
|
8
|
+
* @typedef {(command: string, options: ExecOptions) => Promise<ExecResult>} ExecAsync
|
|
9
|
+
* @typedef {{ execAsync?: ExecAsync, log?: (message: string) => void }} RunPackBudgetDeps
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @type {ExecAsync} */
|
|
4
13
|
const execAsync = promisify(exec);
|
|
5
14
|
|
|
6
15
|
export const MAX_PACKAGE_SIZE = 8 * 1024 * 1024;
|
|
@@ -25,18 +34,35 @@ export const FORBIDDEN_PREFIXES = [
|
|
|
25
34
|
".codex/",
|
|
26
35
|
];
|
|
27
36
|
|
|
37
|
+
/**
|
|
38
|
+
* @param {unknown} value
|
|
39
|
+
* @returns {value is Record<string, unknown>}
|
|
40
|
+
*/
|
|
41
|
+
function isRecord(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} filePath
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
28
49
|
export function normalizePackPath(filePath) {
|
|
29
50
|
return filePath.replaceAll("\\", "/");
|
|
30
51
|
}
|
|
31
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} stdout
|
|
55
|
+
* @returns {ParsedPackMetadata}
|
|
56
|
+
*/
|
|
32
57
|
export function parsePackMetadata(stdout) {
|
|
58
|
+
/** @type {unknown} */
|
|
33
59
|
const packs = JSON.parse(stdout);
|
|
34
60
|
if (!Array.isArray(packs) || packs.length === 0) {
|
|
35
61
|
throw new Error("npm pack --dry-run --json returned no package metadata");
|
|
36
62
|
}
|
|
37
63
|
|
|
38
64
|
const pack = packs[0];
|
|
39
|
-
if (!pack || !Array.isArray(pack.files)) {
|
|
65
|
+
if (!isRecord(pack) || !Array.isArray(pack.files)) {
|
|
40
66
|
throw new Error("npm pack metadata did not include file list");
|
|
41
67
|
}
|
|
42
68
|
|
|
@@ -46,13 +72,17 @@ export function parsePackMetadata(stdout) {
|
|
|
46
72
|
}
|
|
47
73
|
|
|
48
74
|
const paths = pack.files
|
|
49
|
-
.map((file) => file
|
|
75
|
+
.map((file) => (isRecord(file) ? file.path : undefined))
|
|
50
76
|
.filter((value) => typeof value === "string")
|
|
51
77
|
.map((value) => normalizePackPath(value));
|
|
52
78
|
|
|
53
79
|
return { packageSize, paths };
|
|
54
80
|
}
|
|
55
81
|
|
|
82
|
+
/**
|
|
83
|
+
* @param {ParsedPackMetadata} metadata
|
|
84
|
+
* @returns {string}
|
|
85
|
+
*/
|
|
56
86
|
export function validatePackMetadata({ packageSize, paths }) {
|
|
57
87
|
if (packageSize > MAX_PACKAGE_SIZE) {
|
|
58
88
|
throw new Error(
|
|
@@ -83,20 +113,33 @@ export function validatePackMetadata({ packageSize, paths }) {
|
|
|
83
113
|
return `Pack budget ok: ${packageSize} bytes across ${paths.length} files`;
|
|
84
114
|
}
|
|
85
115
|
|
|
116
|
+
/**
|
|
117
|
+
* @param {RunPackBudgetDeps} [deps]
|
|
118
|
+
* @returns {Promise<string>}
|
|
119
|
+
*/
|
|
86
120
|
export async function runPackBudgetCheck(deps = {}) {
|
|
87
121
|
const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
88
122
|
const runExec = deps.execAsync ?? execAsync;
|
|
89
123
|
const log = deps.log ?? console.log;
|
|
90
124
|
let stdout = "";
|
|
91
125
|
try {
|
|
92
|
-
|
|
126
|
+
const result = await runExec(`${npmCommand} pack --dry-run --json`, {
|
|
93
127
|
windowsHide: true,
|
|
94
128
|
maxBuffer: 10 * 1024 * 1024,
|
|
95
|
-
})
|
|
129
|
+
});
|
|
130
|
+
if (result.stdout === null || result.stdout === undefined) {
|
|
131
|
+
throw new Error("npm pack --dry-run --json returned no stdout");
|
|
132
|
+
}
|
|
133
|
+
stdout =
|
|
134
|
+
typeof result.stdout === "string"
|
|
135
|
+
? result.stdout
|
|
136
|
+
: result.stdout.toString("utf8");
|
|
96
137
|
} catch (error) {
|
|
97
138
|
const message = error instanceof Error ? error.message : String(error);
|
|
98
|
-
const stdoutText =
|
|
99
|
-
|
|
139
|
+
const stdoutText =
|
|
140
|
+
isRecord(error) && "stdout" in error ? String(error.stdout ?? "") : "";
|
|
141
|
+
const stderrText =
|
|
142
|
+
isRecord(error) && "stderr" in error ? String(error.stderr ?? "") : "";
|
|
100
143
|
throw new Error(`npm pack --dry-run --json failed via ${npmCommand}: ${message}${stdoutText ? `
|
|
101
144
|
stdout: ${stdoutText.slice(0, 500)}` : ""}${stderrText ? `
|
|
102
145
|
stderr: ${stderrText.slice(0, 500)}` : ""}`);
|