codex-multi-auth 0.1.5 → 0.1.8
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/LICENSE +21 -1
- package/README.md +19 -6
- package/assets/readme-hero.svg +31 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/codex-cli/state.js +4 -4
- package/dist/lib/codex-cli/state.js.map +1 -1
- package/dist/lib/codex-cli/sync.d.ts +9 -16
- package/dist/lib/codex-cli/sync.d.ts.map +1 -1
- package/dist/lib/codex-cli/sync.js +51 -284
- package/dist/lib/codex-cli/sync.js.map +1 -1
- package/dist/lib/codex-cli/writer.d.ts.map +1 -1
- package/dist/lib/codex-cli/writer.js +62 -5
- package/dist/lib/codex-cli/writer.js.map +1 -1
- package/dist/lib/codex-manager/settings-hub.d.ts +44 -2
- package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
- package/dist/lib/codex-manager/settings-hub.js +746 -117
- package/dist/lib/codex-manager/settings-hub.js.map +1 -1
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +3 -8
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/named-backup-export.d.ts +69 -0
- package/dist/lib/named-backup-export.d.ts.map +1 -0
- package/dist/lib/named-backup-export.js +207 -0
- package/dist/lib/named-backup-export.js.map +1 -0
- package/dist/lib/oauth-success.html +66 -210
- package/dist/lib/oc-chatgpt-import-adapter.d.ts +64 -0
- package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-import-adapter.js +506 -0
- package/dist/lib/oc-chatgpt-import-adapter.js.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts +80 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.js +130 -0
- package/dist/lib/oc-chatgpt-orchestrator.js.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts +59 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.js +327 -0
- package/dist/lib/oc-chatgpt-target-detection.js.map +1 -0
- package/dist/lib/prompts/codex.js +2 -2
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +44 -2
- package/dist/lib/runtime-paths.js.map +1 -1
- package/dist/lib/storage.d.ts +42 -3
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +634 -49
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +13 -1
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/dist/lib/ui/copy.d.ts +15 -1
- package/dist/lib/ui/copy.d.ts.map +1 -1
- package/dist/lib/ui/copy.js +15 -1
- package/dist/lib/ui/copy.js.map +1 -1
- package/node_modules/@codex-ai/plugin/dist/index.d.ts +1 -1
- package/node_modules/@codex-ai/plugin/dist/tool.d.ts +41 -41
- package/node_modules/@codex-ai/plugin/dist/tool.js +28 -28
- package/package.json +132 -133
- package/scripts/bench-format/hashline-v2.mjs +642 -642
- package/scripts/bench-format/render.mjs +496 -496
- package/scripts/bench-format/stats.mjs +54 -54
- package/scripts/bench-format/tasks.mjs +151 -151
- package/scripts/benchmark-render-dashboard.mjs +49 -49
- package/scripts/codex-multi-auth.js +12 -0
- package/scripts/codex.js +315 -2
- package/scripts/install-codex-auth.js +9 -9
- package/scripts/test-all-models.sh +7 -7
- package/scripts/test-model-matrix.js +247 -148
- package/scripts/validate-model-map.sh +7 -7
- package/vendor/codex-ai-plugin/dist/index.d.ts +1 -1
- package/vendor/codex-ai-plugin/dist/tool.d.ts +41 -41
- package/vendor/codex-ai-plugin/dist/tool.js +28 -28
- package/vendor/codex-ai-sdk/dist/index.d.ts +3 -3
|
@@ -1,62 +1,66 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { dirname, join, resolve } from "node:path";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
8
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
const repoRoot = resolve(scriptDir, "..");
|
|
10
|
-
const localConfigPaths = [
|
|
10
|
+
const localConfigPaths = [
|
|
11
|
+
join(repoRoot, ".codex.json"),
|
|
12
|
+
join(repoRoot, "Codex.json"),
|
|
13
|
+
];
|
|
11
14
|
const scenarioTemplates = {
|
|
12
15
|
legacy: join(repoRoot, "config", "codex-legacy.json"),
|
|
13
16
|
modern: join(repoRoot, "config", "codex-modern.json"),
|
|
14
17
|
};
|
|
15
18
|
|
|
16
|
-
const pluginPackageName = "codex-multi-auth";
|
|
17
|
-
const DEFAULT_MATRIX_TIMEOUT_MS = 120000;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
19
|
+
const pluginPackageName = "codex-multi-auth";
|
|
20
|
+
const DEFAULT_MATRIX_TIMEOUT_MS = 120000;
|
|
21
|
+
const DEFAULT_SMOKE_MATRIX_TIMEOUT_MS = 15000;
|
|
22
|
+
|
|
23
|
+
function resolveCmdScriptEntry(commandPath) {
|
|
24
|
+
if (!/\.cmd$/i.test(commandPath)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const raw = readFileSync(commandPath, "utf8");
|
|
29
|
+
const match = raw.match(/"%dp0%\\([^"\r\n]+\.js)"/i);
|
|
30
|
+
if (!match || typeof match[1] !== "string") {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const relScriptPath = match[1].replace(/[\\/]+/g, "/");
|
|
34
|
+
const scriptPath = resolve(dirname(commandPath), relScriptPath);
|
|
35
|
+
return existsSync(scriptPath) ? scriptPath : null;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildExecutable(command) {
|
|
42
|
+
const scriptEntry = resolveCmdScriptEntry(command);
|
|
43
|
+
if (scriptEntry) {
|
|
44
|
+
return {
|
|
45
|
+
command: process.execPath,
|
|
46
|
+
shell: false,
|
|
47
|
+
prefixArgs: [scriptEntry],
|
|
48
|
+
displayCommand: command,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return { command, shell: /\.cmd$/i.test(command) };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function resolveCodexExecutable() {
|
|
55
|
+
const envOverride = process.env.CODEX_BIN;
|
|
56
|
+
if (envOverride && envOverride.trim().length > 0) {
|
|
57
|
+
const command = envOverride.trim();
|
|
58
|
+
return buildExecutable(command);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (process.platform !== "win32") {
|
|
62
|
+
return { command: "codex", shell: false };
|
|
63
|
+
}
|
|
60
64
|
|
|
61
65
|
const whereResult = spawnSync("where", ["Codex"], {
|
|
62
66
|
encoding: "utf8",
|
|
@@ -71,27 +75,27 @@ export function resolveCodexExecutable() {
|
|
|
71
75
|
return { command: "codex", shell: false };
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
const exactExe = candidates.find((candidate) =>
|
|
75
|
-
/npm\\Codex\.exe$/i.test(candidate),
|
|
76
|
-
);
|
|
77
|
-
if (exactExe) {
|
|
78
|
-
return { command: exactExe, shell: false };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const exactCmd = candidates.find((candidate) =>
|
|
82
|
-
/npm\\Codex\.cmd$/i.test(candidate),
|
|
83
|
-
);
|
|
84
|
-
if (exactCmd) {
|
|
85
|
-
return buildExecutable(exactCmd);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const anyCmd = candidates.find((candidate) => /\.cmd$/i.test(candidate));
|
|
89
|
-
if (anyCmd) {
|
|
90
|
-
return buildExecutable(anyCmd);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return { command: candidates[0], shell: false };
|
|
94
|
-
}
|
|
78
|
+
const exactExe = candidates.find((candidate) =>
|
|
79
|
+
/npm\\Codex\.exe$/i.test(candidate),
|
|
80
|
+
);
|
|
81
|
+
if (exactExe) {
|
|
82
|
+
return { command: exactExe, shell: false };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const exactCmd = candidates.find((candidate) =>
|
|
86
|
+
/npm\\Codex\.cmd$/i.test(candidate),
|
|
87
|
+
);
|
|
88
|
+
if (exactCmd) {
|
|
89
|
+
return buildExecutable(exactCmd);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const anyCmd = candidates.find((candidate) => /\.cmd$/i.test(candidate));
|
|
93
|
+
if (anyCmd) {
|
|
94
|
+
return buildExecutable(anyCmd);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { command: candidates[0], shell: false };
|
|
98
|
+
}
|
|
95
99
|
|
|
96
100
|
const CodexExecutable = resolveCodexExecutable();
|
|
97
101
|
|
|
@@ -130,6 +134,9 @@ function toFileUri(pathValue) {
|
|
|
130
134
|
return `file:///${normalized}`;
|
|
131
135
|
}
|
|
132
136
|
|
|
137
|
+
let stopCodexServersQueue = Promise.resolve();
|
|
138
|
+
const spawnedCodexPids = new Set();
|
|
139
|
+
|
|
133
140
|
function runQuiet(command, commandArgs) {
|
|
134
141
|
try {
|
|
135
142
|
spawnSync(command, commandArgs, {
|
|
@@ -141,9 +148,6 @@ function runQuiet(command, commandArgs) {
|
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
let stopCodexServersQueue = Promise.resolve();
|
|
145
|
-
const spawnedCodexPids = new Set();
|
|
146
|
-
|
|
147
151
|
export function registerSpawnedCodex(pid) {
|
|
148
152
|
if (!Number.isInteger(pid) || pid <= 0) return;
|
|
149
153
|
spawnedCodexPids.add(pid);
|
|
@@ -153,14 +157,72 @@ export function __resetTrackedCodexPidsForTests() {
|
|
|
153
157
|
spawnedCodexPids.clear();
|
|
154
158
|
}
|
|
155
159
|
|
|
156
|
-
export function resolveMatrixTimeoutMs() {
|
|
157
|
-
const
|
|
160
|
+
export function resolveMatrixTimeoutMs(smoke = false) {
|
|
161
|
+
const fallback = smoke
|
|
162
|
+
? DEFAULT_SMOKE_MATRIX_TIMEOUT_MS
|
|
163
|
+
: DEFAULT_MATRIX_TIMEOUT_MS;
|
|
164
|
+
const parsedTimeout = Number.parseInt(
|
|
165
|
+
process.env.CODEX_MATRIX_TIMEOUT_MS ?? String(fallback),
|
|
166
|
+
10,
|
|
167
|
+
);
|
|
158
168
|
if (!Number.isFinite(parsedTimeout) || parsedTimeout <= 0) {
|
|
159
|
-
return
|
|
169
|
+
return fallback;
|
|
160
170
|
}
|
|
161
171
|
return parsedTimeout;
|
|
162
172
|
}
|
|
163
173
|
|
|
174
|
+
function hasCompletedSuccessfully(output, token) {
|
|
175
|
+
return (
|
|
176
|
+
output.includes(token) ||
|
|
177
|
+
output.includes('"type":"turn.completed"') ||
|
|
178
|
+
output.includes('"type":"response.completed"')
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function getSmokeSkipReason(exitCode, output) {
|
|
183
|
+
if (exitCode === 124) {
|
|
184
|
+
return "timed-out";
|
|
185
|
+
}
|
|
186
|
+
if (/not supported when using codex with a chatgpt account/i.test(output)) {
|
|
187
|
+
return "unsupported-model";
|
|
188
|
+
}
|
|
189
|
+
if (
|
|
190
|
+
/unsupported value:\s*['"]xhigh['"]/i.test(output) ||
|
|
191
|
+
/unsupported_value/i.test(output)
|
|
192
|
+
) {
|
|
193
|
+
return "unsupported-reasoning";
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function finalizeModelCaseResult(caseInfo, exitCode, output, token, smoke) {
|
|
199
|
+
const hasToken = output.includes(token);
|
|
200
|
+
const completed = hasCompletedSuccessfully(output, token);
|
|
201
|
+
const ok = exitCode === 0 && completed;
|
|
202
|
+
const skipReason = !ok && smoke ? getSmokeSkipReason(exitCode, output) : null;
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
...caseInfo,
|
|
206
|
+
ok,
|
|
207
|
+
exitCode,
|
|
208
|
+
hasToken,
|
|
209
|
+
completed,
|
|
210
|
+
skipped: skipReason !== null,
|
|
211
|
+
skipReason,
|
|
212
|
+
output,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function __finalizeModelCaseResultForTests(
|
|
217
|
+
caseInfo,
|
|
218
|
+
exitCode,
|
|
219
|
+
output,
|
|
220
|
+
token,
|
|
221
|
+
smoke = false,
|
|
222
|
+
) {
|
|
223
|
+
return finalizeModelCaseResult(caseInfo, exitCode, output, token, smoke);
|
|
224
|
+
}
|
|
225
|
+
|
|
164
226
|
function stopCodexServersInternal() {
|
|
165
227
|
const tracked = [...spawnedCodexPids];
|
|
166
228
|
spawnedCodexPids.clear();
|
|
@@ -244,28 +306,36 @@ function enumerateCases(models, smoke, maxCases) {
|
|
|
244
306
|
return selected;
|
|
245
307
|
}
|
|
246
308
|
|
|
247
|
-
function
|
|
248
|
-
const token = `MODEL_MATRIX_OK_${index}`;
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
"--
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
309
|
+
function buildModelCaseArgs(caseInfo, index) {
|
|
310
|
+
const token = `MODEL_MATRIX_OK_${index}`;
|
|
311
|
+
const args = [
|
|
312
|
+
"exec",
|
|
313
|
+
token,
|
|
314
|
+
"--model",
|
|
315
|
+
caseInfo.model,
|
|
316
|
+
"--json",
|
|
317
|
+
"--skip-git-repo-check",
|
|
318
|
+
];
|
|
319
|
+
if (caseInfo.variant) {
|
|
320
|
+
args.push("-c", `model_reasoning_effort="${caseInfo.variant}"`);
|
|
321
|
+
}
|
|
322
|
+
return { token, args };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export function __buildModelCaseArgsForTests(caseInfo, index) {
|
|
326
|
+
return buildModelCaseArgs(caseInfo, index);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function executeModelCase(caseInfo, index) {
|
|
330
|
+
const { token, args } = buildModelCaseArgs(caseInfo, index);
|
|
331
|
+
|
|
332
|
+
const timeoutMs = resolveMatrixTimeoutMs(caseInfo.smoke === true);
|
|
333
|
+
const commandArgs = [...(CodexExecutable.prefixArgs ?? []), ...args];
|
|
334
|
+
const finalized = spawnSync(CodexExecutable.command, commandArgs, {
|
|
335
|
+
cwd: repoRoot,
|
|
336
|
+
encoding: "utf8",
|
|
337
|
+
windowsHide: true,
|
|
338
|
+
shell: CodexExecutable.shell,
|
|
269
339
|
timeout: timeoutMs,
|
|
270
340
|
killSignal: "SIGKILL",
|
|
271
341
|
env: {
|
|
@@ -277,27 +347,25 @@ function executeModelCase(caseInfo, index) {
|
|
|
277
347
|
});
|
|
278
348
|
|
|
279
349
|
if (finalized.error && finalized.error.code === "ETIMEDOUT") {
|
|
280
|
-
return
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
350
|
+
return finalizeModelCaseResult(
|
|
351
|
+
caseInfo,
|
|
352
|
+
124,
|
|
353
|
+
`Timed out after ${timeoutMs}ms`,
|
|
354
|
+
token,
|
|
355
|
+
caseInfo.smoke === true,
|
|
356
|
+
);
|
|
287
357
|
}
|
|
288
358
|
|
|
289
|
-
const combinedOutput =
|
|
290
|
-
|
|
291
|
-
const exitCode = finalized.status ?? 1;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return {
|
|
295
|
-
...caseInfo,
|
|
296
|
-
ok,
|
|
359
|
+
const combinedOutput =
|
|
360
|
+
`${finalized.stdout ?? ""}\n${finalized.stderr ?? ""}`.trim();
|
|
361
|
+
const exitCode = finalized.status ?? 1;
|
|
362
|
+
return finalizeModelCaseResult(
|
|
363
|
+
caseInfo,
|
|
297
364
|
exitCode,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
365
|
+
combinedOutput,
|
|
366
|
+
token,
|
|
367
|
+
caseInfo.smoke === true,
|
|
368
|
+
);
|
|
301
369
|
}
|
|
302
370
|
|
|
303
371
|
async function readJson(pathValue) {
|
|
@@ -357,31 +425,43 @@ async function prepareScenarioConfig(templatePath, pluginRef) {
|
|
|
357
425
|
async function runScenario(scenario, options) {
|
|
358
426
|
const templatePath = scenarioTemplates[scenario];
|
|
359
427
|
if (!templatePath || !existsSync(templatePath)) {
|
|
360
|
-
throw new Error(
|
|
428
|
+
throw new Error(
|
|
429
|
+
`Template not found for scenario '${scenario}': ${templatePath}`,
|
|
430
|
+
);
|
|
361
431
|
}
|
|
362
432
|
|
|
363
433
|
const config = await prepareScenarioConfig(templatePath, options.pluginRef);
|
|
364
434
|
const models = config?.provider?.openai?.models;
|
|
365
435
|
if (!models || typeof models !== "object") {
|
|
366
|
-
throw new Error(
|
|
436
|
+
throw new Error(
|
|
437
|
+
`Scenario '${scenario}' has no provider.openai.models object`,
|
|
438
|
+
);
|
|
367
439
|
}
|
|
368
440
|
|
|
369
|
-
const cases = enumerateCases(models, options.smoke, options.maxCases)
|
|
441
|
+
const cases = enumerateCases(models, options.smoke, options.maxCases).map(
|
|
442
|
+
(caseInfo) => ({
|
|
443
|
+
...caseInfo,
|
|
444
|
+
smoke: options.smoke,
|
|
445
|
+
}),
|
|
446
|
+
);
|
|
370
447
|
console.log(`\n=== ${scenario.toUpperCase()} (${cases.length} cases) ===`);
|
|
371
448
|
|
|
372
449
|
const results = [];
|
|
373
450
|
for (let i = 0; i < cases.length; i += 1) {
|
|
374
|
-
const caseInfo = cases[i];
|
|
375
|
-
const result = executeModelCase(
|
|
376
|
-
caseInfo,
|
|
377
|
-
i + 1,
|
|
378
|
-
);
|
|
451
|
+
const caseInfo = cases[i];
|
|
452
|
+
const result = executeModelCase(caseInfo, i + 1);
|
|
379
453
|
results.push(result);
|
|
380
454
|
const variantLabel = result.variant ? ` [variant=${result.variant}]` : "";
|
|
381
455
|
if (result.ok) {
|
|
382
456
|
console.log(`PASS ${result.model}${variantLabel}`);
|
|
457
|
+
} else if (result.skipped) {
|
|
458
|
+
console.log(
|
|
459
|
+
`SKIP ${result.model}${variantLabel} (${result.skipReason})`,
|
|
460
|
+
);
|
|
383
461
|
} else {
|
|
384
|
-
console.log(
|
|
462
|
+
console.log(
|
|
463
|
+
`FAIL ${result.model}${variantLabel} (exit=${result.exitCode}, token=${result.hasToken})`,
|
|
464
|
+
);
|
|
385
465
|
const tail = result.output.split(/\r?\n/).slice(-12).join("\n");
|
|
386
466
|
if (tail.trim().length > 0) {
|
|
387
467
|
console.log(tail);
|
|
@@ -399,8 +479,9 @@ async function main() {
|
|
|
399
479
|
return;
|
|
400
480
|
}
|
|
401
481
|
|
|
402
|
-
const scenarioValue = parseArgValue(args, "--scenario") ?? "all";
|
|
403
482
|
const smoke = args.includes("--smoke");
|
|
483
|
+
const scenarioValue =
|
|
484
|
+
parseArgValue(args, "--scenario") ?? (smoke ? "modern" : "all");
|
|
404
485
|
const pluginMode = parseArgValue(args, "--plugin") ?? "dist";
|
|
405
486
|
const noRestore = args.includes("--no-restore");
|
|
406
487
|
const maxCasesRaw = parseArgValue(args, "--max-cases");
|
|
@@ -411,13 +492,19 @@ async function main() {
|
|
|
411
492
|
: undefined;
|
|
412
493
|
|
|
413
494
|
if (!["all", "legacy", "modern"].includes(scenarioValue)) {
|
|
414
|
-
throw new Error(
|
|
495
|
+
throw new Error(
|
|
496
|
+
`Invalid --scenario value '${scenarioValue}'. Use legacy, modern, or all.`,
|
|
497
|
+
);
|
|
415
498
|
}
|
|
416
499
|
if (!["dist", "package"].includes(pluginMode)) {
|
|
417
|
-
throw new Error(
|
|
500
|
+
throw new Error(
|
|
501
|
+
`Invalid --plugin value '${pluginMode}'. Use dist or package.`,
|
|
502
|
+
);
|
|
418
503
|
}
|
|
419
504
|
if (Number.isNaN(maxCases) || maxCases < 0) {
|
|
420
|
-
throw new Error(
|
|
505
|
+
throw new Error(
|
|
506
|
+
`Invalid --max-cases value '${maxCasesRaw}'. Use a non-negative integer.`,
|
|
507
|
+
);
|
|
421
508
|
}
|
|
422
509
|
|
|
423
510
|
const pluginRef = resolvePluginReference(pluginMode);
|
|
@@ -426,10 +513,12 @@ async function main() {
|
|
|
426
513
|
|
|
427
514
|
console.log("Codex Model Matrix Audit");
|
|
428
515
|
console.log(`Repo: ${repoRoot}`);
|
|
429
|
-
console.log(`Scenarios: ${scenarios.join(", ")}`);
|
|
430
|
-
console.log(`Mode: ${smoke ? "smoke" : "full"}`);
|
|
431
|
-
console.log(`Plugin: ${pluginRef}`);
|
|
432
|
-
console.log(
|
|
516
|
+
console.log(`Scenarios: ${scenarios.join(", ")}`);
|
|
517
|
+
console.log(`Mode: ${smoke ? "smoke" : "full"}`);
|
|
518
|
+
console.log(`Plugin: ${pluginRef}`);
|
|
519
|
+
console.log(
|
|
520
|
+
`Codex command: ${CodexExecutable.displayCommand ?? CodexExecutable.command}`,
|
|
521
|
+
);
|
|
433
522
|
|
|
434
523
|
const backups = await backupLocalConfigs();
|
|
435
524
|
const allResults = [];
|
|
@@ -441,9 +530,10 @@ async function main() {
|
|
|
441
530
|
smoke,
|
|
442
531
|
maxCases,
|
|
443
532
|
pluginRef,
|
|
444
|
-
portStart: 47000 + i * 500,
|
|
445
533
|
});
|
|
446
|
-
allResults.push(
|
|
534
|
+
allResults.push(
|
|
535
|
+
...scenarioResults.map((item) => ({ ...item, scenario })),
|
|
536
|
+
);
|
|
447
537
|
}
|
|
448
538
|
} finally {
|
|
449
539
|
if (!noRestore) {
|
|
@@ -451,11 +541,13 @@ async function main() {
|
|
|
451
541
|
}
|
|
452
542
|
}
|
|
453
543
|
|
|
454
|
-
const
|
|
455
|
-
const
|
|
544
|
+
const passed = allResults.filter((result) => result.ok);
|
|
545
|
+
const skipped = allResults.filter((result) => result.skipped);
|
|
546
|
+
const failed = allResults.filter((result) => !result.ok && !result.skipped);
|
|
456
547
|
console.log("\n=== SUMMARY ===");
|
|
457
548
|
console.log(`Total: ${allResults.length}`);
|
|
458
|
-
console.log(`Passed: ${passed}`);
|
|
549
|
+
console.log(`Passed: ${passed.length}`);
|
|
550
|
+
console.log(`Skipped: ${skipped.length}`);
|
|
459
551
|
console.log(`Failed: ${failed.length}`);
|
|
460
552
|
|
|
461
553
|
if (reportJsonPath) {
|
|
@@ -463,18 +555,23 @@ async function main() {
|
|
|
463
555
|
generatedAt: new Date().toISOString(),
|
|
464
556
|
repoRoot,
|
|
465
557
|
scenarios,
|
|
466
|
-
mode: smoke ? "smoke" : "full",
|
|
467
|
-
plugin: pluginRef,
|
|
468
|
-
CodexCommand: CodexExecutable.displayCommand ?? CodexExecutable.command,
|
|
469
|
-
totals: {
|
|
558
|
+
mode: smoke ? "smoke" : "full",
|
|
559
|
+
plugin: pluginRef,
|
|
560
|
+
CodexCommand: CodexExecutable.displayCommand ?? CodexExecutable.command,
|
|
561
|
+
totals: {
|
|
470
562
|
total: allResults.length,
|
|
471
|
-
passed,
|
|
563
|
+
passed: passed.length,
|
|
564
|
+
skipped: skipped.length,
|
|
472
565
|
failed: failed.length,
|
|
473
566
|
},
|
|
474
567
|
results: allResults,
|
|
475
568
|
};
|
|
476
569
|
await mkdir(dirname(reportJsonPath), { recursive: true });
|
|
477
|
-
await writeFile(
|
|
570
|
+
await writeFile(
|
|
571
|
+
reportJsonPath,
|
|
572
|
+
`${JSON.stringify(report, null, 2)}\n`,
|
|
573
|
+
"utf8",
|
|
574
|
+
);
|
|
478
575
|
console.log(`Report written: ${reportJsonPath}`);
|
|
479
576
|
}
|
|
480
577
|
|
|
@@ -485,6 +582,10 @@ async function main() {
|
|
|
485
582
|
console.log(`- ${result.scenario}: ${result.model}${variantLabel}`);
|
|
486
583
|
}
|
|
487
584
|
process.exitCode = 1;
|
|
585
|
+
} else if (smoke && passed.length === 0) {
|
|
586
|
+
console.log(
|
|
587
|
+
"\nSmoke matrix was inconclusive: all cases were skipped for this current runtime/account capability set.",
|
|
588
|
+
);
|
|
488
589
|
}
|
|
489
590
|
}
|
|
490
591
|
|
|
@@ -500,5 +601,3 @@ if (isDirectRun) {
|
|
|
500
601
|
process.exit(1);
|
|
501
602
|
});
|
|
502
603
|
}
|
|
503
|
-
|
|
504
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
node "${SCRIPT_DIR}/test-model-matrix.js" --smoke "$@"
|
|
7
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
node "${SCRIPT_DIR}/test-model-matrix.js" --smoke "$@"
|
|
7
|
+
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type PluginInput = any;
|
|
1
|
+
export type PluginInput = any;
|
|
2
2
|
export type Plugin = any;
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
export interface ToolContext {
|
|
2
|
-
[key: string]: any;
|
|
3
|
-
directory: string;
|
|
4
|
-
worktree: string;
|
|
5
|
-
ask: (request: any) => Promise<any> | any;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface ToolDefinition<TArgs = any, TResult = any> {
|
|
9
|
-
description?: string;
|
|
10
|
-
args?: Record<string, any>;
|
|
11
|
-
parameters?: unknown;
|
|
12
|
-
execute: (args: TArgs, context: ToolContext) => Promise<TResult> | TResult;
|
|
13
|
-
[key: string]: any;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface SchemaNode {
|
|
17
|
-
optional: () => SchemaNode;
|
|
18
|
-
describe: (_text: string) => SchemaNode;
|
|
19
|
-
min: (_value: number) => SchemaNode;
|
|
20
|
-
max: (_value: number) => SchemaNode;
|
|
21
|
-
default: (_value: unknown) => SchemaNode;
|
|
22
|
-
int: () => SchemaNode;
|
|
23
|
-
array: (_node?: unknown) => SchemaNode;
|
|
24
|
-
[key: string]: any;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ToolFactory {
|
|
28
|
-
<TArgs = any, TResult = any>(definition: ToolDefinition<TArgs, TResult>): ToolDefinition<TArgs, TResult>;
|
|
29
|
-
schema: {
|
|
30
|
-
string: () => SchemaNode;
|
|
31
|
-
number: () => SchemaNode;
|
|
32
|
-
boolean: () => SchemaNode;
|
|
33
|
-
object: (shape: Record<string, unknown>) => SchemaNode;
|
|
34
|
-
enum: (values: readonly unknown[]) => SchemaNode;
|
|
35
|
-
literal: (value: unknown) => SchemaNode;
|
|
36
|
-
array: (node: unknown) => SchemaNode;
|
|
37
|
-
any: () => SchemaNode;
|
|
38
|
-
unknown: () => SchemaNode;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
1
|
+
export interface ToolContext {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
directory: string;
|
|
4
|
+
worktree: string;
|
|
5
|
+
ask: (request: any) => Promise<any> | any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ToolDefinition<TArgs = any, TResult = any> {
|
|
9
|
+
description?: string;
|
|
10
|
+
args?: Record<string, any>;
|
|
11
|
+
parameters?: unknown;
|
|
12
|
+
execute: (args: TArgs, context: ToolContext) => Promise<TResult> | TResult;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SchemaNode {
|
|
17
|
+
optional: () => SchemaNode;
|
|
18
|
+
describe: (_text: string) => SchemaNode;
|
|
19
|
+
min: (_value: number) => SchemaNode;
|
|
20
|
+
max: (_value: number) => SchemaNode;
|
|
21
|
+
default: (_value: unknown) => SchemaNode;
|
|
22
|
+
int: () => SchemaNode;
|
|
23
|
+
array: (_node?: unknown) => SchemaNode;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ToolFactory {
|
|
28
|
+
<TArgs = any, TResult = any>(definition: ToolDefinition<TArgs, TResult>): ToolDefinition<TArgs, TResult>;
|
|
29
|
+
schema: {
|
|
30
|
+
string: () => SchemaNode;
|
|
31
|
+
number: () => SchemaNode;
|
|
32
|
+
boolean: () => SchemaNode;
|
|
33
|
+
object: (shape: Record<string, unknown>) => SchemaNode;
|
|
34
|
+
enum: (values: readonly unknown[]) => SchemaNode;
|
|
35
|
+
literal: (value: unknown) => SchemaNode;
|
|
36
|
+
array: (node: unknown) => SchemaNode;
|
|
37
|
+
any: () => SchemaNode;
|
|
38
|
+
unknown: () => SchemaNode;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
42
|
export declare const tool: ToolFactory;
|