codex-multi-auth 2.1.8 → 2.1.10
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 +413 -411
- package/dist/lib/accounts.d.ts +2 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +26 -2
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/device-auth.d.ts +1 -0
- package/dist/lib/auth/device-auth.d.ts.map +1 -1
- package/dist/lib/auth/device-auth.js +6 -2
- package/dist/lib/auth/device-auth.js.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts +5 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +14 -1
- package/dist/lib/codex-manager/commands/forecast.js.map +1 -1
- package/dist/lib/codex-manager/commands/report.d.ts +2 -0
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +17 -1
- package/dist/lib/codex-manager/commands/report.js.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.d.ts +1 -1
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.js +71 -1
- package/dist/lib/codex-manager/commands/rotation.js.map +1 -1
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/repair-commands.js +35 -0
- 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 +36 -2
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/forecast.d.ts +9 -0
- package/dist/lib/forecast.d.ts.map +1 -1
- package/dist/lib/forecast.js +36 -0
- package/dist/lib/forecast.js.map +1 -1
- package/dist/lib/runtime/runtime-observability.d.ts +17 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +48 -0
- package/dist/lib/runtime/runtime-observability.js.map +1 -1
- package/dist/lib/runtime-rotation-proxy.d.ts +1 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +119 -20
- package/dist/lib/runtime-rotation-proxy.js.map +1 -1
- package/package.json +193 -185
- package/scripts/audit-dev-allowlist.js +0 -220
- package/scripts/bench-format/codex-host.mjs +0 -275
- package/scripts/bench-format/hashline-v2.mjs +0 -642
- package/scripts/bench-format/models.mjs +0 -110
- package/scripts/bench-format/render.mjs +0 -496
- package/scripts/bench-format/stats.mjs +0 -54
- package/scripts/bench-format/tasks.mjs +0 -151
- package/scripts/benchmark-edit-formats.mjs +0 -1164
- package/scripts/benchmark-render-dashboard.mjs +0 -49
- package/scripts/benchmark-runtime-path.mjs +0 -166
- package/scripts/check-pack-budget-lib.js +0 -157
- package/scripts/check-pack-budget.mjs +0 -10
- package/scripts/copy-oauth-success.js +0 -76
- package/scripts/install-codex-auth.js +0 -258
- package/scripts/repo-hygiene.js +0 -320
- package/scripts/test-all-models.sh +0 -7
- package/scripts/test-model-matrix.js +0 -687
- package/scripts/update-vendor-provenance.mjs +0 -96
- package/scripts/validate-model-map.sh +0 -7
- package/scripts/verify-vendor-provenance.mjs +0 -53
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
|
-
|
|
4
|
-
const ALLOWED_HIGH_OR_CRITICAL_ADVISORIES = new Map([
|
|
5
|
-
// Example:
|
|
6
|
-
// ["1113465", { package: "minimatch", expiresOn: "2026-06-30" }],
|
|
7
|
-
]);
|
|
8
|
-
|
|
9
|
-
export function summarizeVia(via) {
|
|
10
|
-
if (!Array.isArray(via)) return [];
|
|
11
|
-
return via
|
|
12
|
-
.map((item) => {
|
|
13
|
-
if (typeof item === "string") return item;
|
|
14
|
-
if (!item || typeof item !== "object") return "unknown";
|
|
15
|
-
const name = typeof item.name === "string" ? item.name : "unknown";
|
|
16
|
-
const range = typeof item.range === "string" ? item.range : "";
|
|
17
|
-
return range ? `${name}:${range}` : name;
|
|
18
|
-
})
|
|
19
|
-
.slice(0, 5);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function extractAdvisoryIds(via) {
|
|
23
|
-
if (!Array.isArray(via)) return [];
|
|
24
|
-
const advisoryIds = [];
|
|
25
|
-
for (const item of via) {
|
|
26
|
-
if (!item || typeof item !== "object") {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
const source = "source" in item ? item.source : undefined;
|
|
30
|
-
if (typeof source === "number" || typeof source === "string") {
|
|
31
|
-
advisoryIds.push(String(source));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return advisoryIds;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function isAdvisoryAllowed(packageName, advisoryId, now = Date.now()) {
|
|
38
|
-
const rule = ALLOWED_HIGH_OR_CRITICAL_ADVISORIES.get(advisoryId);
|
|
39
|
-
if (!rule || typeof rule !== "object") {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
if (typeof rule.package === "string" && rule.package !== packageName) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
if (typeof rule.expiresOn === "string") {
|
|
46
|
-
const expiresAt = Date.parse(rule.expiresOn);
|
|
47
|
-
if (!Number.isFinite(expiresAt) || now > expiresAt) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function getAuditCommand(platform = process.platform, env = process.env) {
|
|
55
|
-
const isWindows = platform === "win32";
|
|
56
|
-
return {
|
|
57
|
-
command: isWindows ? env.ComSpec || "cmd.exe" : "npm",
|
|
58
|
-
commandArgs: isWindows
|
|
59
|
-
? ["/d", "/s", "/c", "npm audit --json"]
|
|
60
|
-
: ["audit", "--json"],
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function resolveVulnerabilities(auditJson) {
|
|
65
|
-
if (
|
|
66
|
-
auditJson &&
|
|
67
|
-
typeof auditJson === "object" &&
|
|
68
|
-
auditJson.vulnerabilities &&
|
|
69
|
-
typeof auditJson.vulnerabilities === "object"
|
|
70
|
-
) {
|
|
71
|
-
return auditJson.vulnerabilities;
|
|
72
|
-
}
|
|
73
|
-
return {};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function partitionHighCriticalVulnerabilities(
|
|
77
|
-
vulnerabilities,
|
|
78
|
-
advisoryAllowed = isAdvisoryAllowed,
|
|
79
|
-
) {
|
|
80
|
-
const unexpected = [];
|
|
81
|
-
const allowlisted = [];
|
|
82
|
-
for (const [name, details] of Object.entries(vulnerabilities)) {
|
|
83
|
-
if (!details || typeof details !== "object") continue;
|
|
84
|
-
const severity = typeof details.severity === "string" ? details.severity : "unknown";
|
|
85
|
-
if (severity !== "high" && severity !== "critical") continue;
|
|
86
|
-
const entry = {
|
|
87
|
-
name,
|
|
88
|
-
severity,
|
|
89
|
-
via: summarizeVia(details.via),
|
|
90
|
-
advisoryIds: extractAdvisoryIds(details.via),
|
|
91
|
-
fixAvailable: details.fixAvailable ?? false,
|
|
92
|
-
};
|
|
93
|
-
const hasAdvisories = entry.advisoryIds.length > 0;
|
|
94
|
-
const allAdvisoriesAllowlisted =
|
|
95
|
-
hasAdvisories &&
|
|
96
|
-
entry.advisoryIds.every((advisoryId) => advisoryAllowed(name, advisoryId));
|
|
97
|
-
if (allAdvisoriesAllowlisted) {
|
|
98
|
-
allowlisted.push(entry);
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
unexpected.push(entry);
|
|
102
|
-
}
|
|
103
|
-
return { unexpected, allowlisted };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function parseAuditOutput(audit) {
|
|
107
|
-
const stdout = (audit.stdout ?? "").trim();
|
|
108
|
-
const stderr = (audit.stderr ?? "").trim();
|
|
109
|
-
const combined = [stdout, stderr].filter(Boolean).join("\n");
|
|
110
|
-
if (!combined) {
|
|
111
|
-
return {
|
|
112
|
-
type: "empty",
|
|
113
|
-
ok: (audit.status ?? 1) === 0,
|
|
114
|
-
stderr,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
if (!combined.includes("{") && /found 0 vulnerabilities/i.test(combined)) {
|
|
118
|
-
return { type: "none" };
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const jsonCandidate =
|
|
122
|
-
(stdout.startsWith("{") ? stdout : "") ||
|
|
123
|
-
(stderr.startsWith("{") ? stderr : "") ||
|
|
124
|
-
combined.slice(combined.indexOf("{"));
|
|
125
|
-
return {
|
|
126
|
-
type: "json",
|
|
127
|
-
json: JSON.parse(jsonCandidate.replace(/^\uFEFF/, "")),
|
|
128
|
-
};
|
|
129
|
-
} catch (error) {
|
|
130
|
-
return {
|
|
131
|
-
type: "parse_error",
|
|
132
|
-
stderr,
|
|
133
|
-
message: error instanceof Error ? error.message : String(error),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function runAuditDevAllowlist(options = {}) {
|
|
139
|
-
const {
|
|
140
|
-
platform = process.platform,
|
|
141
|
-
env = process.env,
|
|
142
|
-
spawn = spawnSync,
|
|
143
|
-
log = console.log,
|
|
144
|
-
warn = console.warn,
|
|
145
|
-
error = console.error,
|
|
146
|
-
now = Date.now,
|
|
147
|
-
} = options;
|
|
148
|
-
|
|
149
|
-
const { command, commandArgs } = getAuditCommand(platform, env);
|
|
150
|
-
const audit = spawn(command, commandArgs, {
|
|
151
|
-
encoding: "utf8",
|
|
152
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
153
|
-
env: {
|
|
154
|
-
...env,
|
|
155
|
-
// npm run -s can suppress child npm JSON output; force a readable level.
|
|
156
|
-
npm_config_loglevel:
|
|
157
|
-
env.npm_config_loglevel === "silent"
|
|
158
|
-
? "notice"
|
|
159
|
-
: env.npm_config_loglevel || "notice",
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const parsed = parseAuditOutput(audit);
|
|
164
|
-
if (parsed.type === "empty") {
|
|
165
|
-
if (parsed.ok) {
|
|
166
|
-
log("No vulnerabilities found in npm audit output.");
|
|
167
|
-
return 0;
|
|
168
|
-
}
|
|
169
|
-
error("Failed to read npm audit output.");
|
|
170
|
-
return 1;
|
|
171
|
-
}
|
|
172
|
-
if (parsed.type === "none") {
|
|
173
|
-
log("No vulnerabilities found in npm audit output.");
|
|
174
|
-
return 0;
|
|
175
|
-
}
|
|
176
|
-
if (parsed.type === "parse_error") {
|
|
177
|
-
error("Failed to parse npm audit JSON output.");
|
|
178
|
-
if (parsed.stderr) {
|
|
179
|
-
error(parsed.stderr);
|
|
180
|
-
}
|
|
181
|
-
error(parsed.message);
|
|
182
|
-
return 1;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const vulnerabilities = resolveVulnerabilities(parsed.json);
|
|
186
|
-
const { unexpected, allowlisted } = partitionHighCriticalVulnerabilities(
|
|
187
|
-
vulnerabilities,
|
|
188
|
-
(packageName, advisoryId) => isAdvisoryAllowed(packageName, advisoryId, now()),
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
if (unexpected.length > 0) {
|
|
192
|
-
error("Unexpected high/critical vulnerabilities detected in dev dependency audit:");
|
|
193
|
-
for (const entry of unexpected) {
|
|
194
|
-
error(
|
|
195
|
-
`- ${entry.name} (${entry.severity}) advisories=${entry.advisoryIds.join(", ") || "none"} via ${entry.via.join(", ") || "unknown"} fixAvailable=${String(entry.fixAvailable)}`,
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
return 1;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (allowlisted.length > 0) {
|
|
202
|
-
warn("Allowlisted high/critical dev vulnerabilities detected:");
|
|
203
|
-
for (const entry of allowlisted) {
|
|
204
|
-
warn(
|
|
205
|
-
`- ${entry.name} (${entry.severity}) advisories=${entry.advisoryIds.join(", ") || "none"} via ${entry.via.join(", ") || "unknown"} fixAvailable=${String(entry.fixAvailable)}`,
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
warn("No unexpected high/critical vulnerabilities found.");
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return 0;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const isEntryPoint =
|
|
215
|
-
typeof process.argv[1] === "string" &&
|
|
216
|
-
import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
217
|
-
|
|
218
|
-
if (isEntryPoint) {
|
|
219
|
-
process.exit(runAuditDevAllowlist());
|
|
220
|
-
}
|
|
@@ -1,275 +0,0 @@
|
|
|
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";
|
|
5
|
-
|
|
6
|
-
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const repoRoot = resolve(scriptDir, "..", "..");
|
|
8
|
-
|
|
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
|
-
}
|
|
37
|
-
|
|
38
|
-
if (process.platform !== "win32") {
|
|
39
|
-
return { command: "codex", shell: false };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const whereResult = spawnSync("where", ["Codex"], {
|
|
43
|
-
encoding: "utf8",
|
|
44
|
-
windowsHide: true,
|
|
45
|
-
});
|
|
46
|
-
const candidates = `${whereResult.stdout ?? ""}`
|
|
47
|
-
.split(/\r?\n/)
|
|
48
|
-
.map((line) => line.trim())
|
|
49
|
-
.filter((line) => /^[A-Za-z]:\\.+\.(exe|cmd)$/i.test(line));
|
|
50
|
-
|
|
51
|
-
if (candidates.length === 0) {
|
|
52
|
-
return { command: "codex", shell: false };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const exactExe = candidates.find((candidate) => /npm\\Codex\.exe$/i.test(candidate));
|
|
56
|
-
if (exactExe) {
|
|
57
|
-
return { command: exactExe, shell: false };
|
|
58
|
-
}
|
|
59
|
-
|
|
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
|
-
}
|
|
69
|
-
|
|
70
|
-
return { command: candidates[0], shell: false };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function parseNdjson(text) {
|
|
74
|
-
const events = [];
|
|
75
|
-
for (const line of text.split(/\r?\n/)) {
|
|
76
|
-
const trimmed = line.trim();
|
|
77
|
-
if (!trimmed) {
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
events.push(JSON.parse(trimmed));
|
|
82
|
-
} catch {
|
|
83
|
-
// Ignore non-JSON lines emitted by wrappers (bun install, warnings, etc.).
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return events;
|
|
87
|
-
}
|
|
88
|
-
|
|
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,
|
|
96
|
-
status: event.part.state?.status,
|
|
97
|
-
start: event.part.state?.time?.start,
|
|
98
|
-
end: event.part.state?.time?.end,
|
|
99
|
-
durationMs:
|
|
100
|
-
typeof event.part.state?.time?.start === "number" &&
|
|
101
|
-
typeof event.part.state?.time?.end === "number"
|
|
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
|
-
}
|
|
118
|
-
|
|
119
|
-
export function getSessionDuration(events) {
|
|
120
|
-
const starts = events
|
|
121
|
-
.filter((event) => event?.type === "step_start" && typeof event.timestamp === "number")
|
|
122
|
-
.map((event) => event.timestamp);
|
|
123
|
-
const finishes = events
|
|
124
|
-
.filter((event) => event?.type === "step_finish" && typeof event.timestamp === "number")
|
|
125
|
-
.map((event) => event.timestamp);
|
|
126
|
-
if (starts.length === 0 || finishes.length === 0) {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
return Math.max(...finishes) - Math.min(...starts);
|
|
130
|
-
}
|
|
131
|
-
|
|
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
|
-
}
|
|
138
|
-
const total = {
|
|
139
|
-
total: 0,
|
|
140
|
-
input: 0,
|
|
141
|
-
output: 0,
|
|
142
|
-
reasoning: 0,
|
|
143
|
-
cacheRead: 0,
|
|
144
|
-
cacheWrite: 0,
|
|
145
|
-
};
|
|
146
|
-
for (const event of stepFinishes) {
|
|
147
|
-
const tokens = event.part.tokens ?? {};
|
|
148
|
-
const input = Number(tokens.input ?? 0);
|
|
149
|
-
const output = Number(tokens.output ?? 0);
|
|
150
|
-
const reasoning = Number(tokens.reasoning ?? 0);
|
|
151
|
-
const explicitTotal = Number(tokens.total ?? NaN);
|
|
152
|
-
total.total += Number.isFinite(explicitTotal) ? explicitTotal : input + output + reasoning;
|
|
153
|
-
total.input += input;
|
|
154
|
-
total.output += output;
|
|
155
|
-
total.reasoning += reasoning;
|
|
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
|
-
}
|
|
172
|
-
|
|
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
|
-
}
|
|
199
|
-
|
|
200
|
-
export function runCodexJson({
|
|
201
|
-
executable,
|
|
202
|
-
prompt,
|
|
203
|
-
model,
|
|
204
|
-
variant,
|
|
205
|
-
agent,
|
|
206
|
-
cwd,
|
|
207
|
-
homeDir,
|
|
208
|
-
timeoutMs,
|
|
209
|
-
extraEnv,
|
|
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, {
|
|
231
|
-
cwd: cwd ?? repoRoot,
|
|
232
|
-
encoding: "utf8",
|
|
233
|
-
windowsHide: true,
|
|
234
|
-
shell: executable.shell,
|
|
235
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
236
|
-
timeout: timeoutMs,
|
|
237
|
-
maxBuffer: 30 * 1024 * 1024,
|
|
238
|
-
env: {
|
|
239
|
-
...process.env,
|
|
240
|
-
...(homeDir ? { HOME: homeDir, USERPROFILE: homeDir } : {}),
|
|
241
|
-
...extraEnv,
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
const wallMs = Date.now() - startWall;
|
|
246
|
-
const stdout = child.stdout ?? "";
|
|
247
|
-
const stderr = child.stderr ?? "";
|
|
248
|
-
const events = parseNdjson(stdout);
|
|
249
|
-
const eventError = getEventError(events);
|
|
250
|
-
const timedOut =
|
|
251
|
-
child.error?.code === "ETIMEDOUT" ||
|
|
252
|
-
child.signal === "SIGTERM" ||
|
|
253
|
-
/timed out/i.test(String(child.error?.message ?? ""));
|
|
254
|
-
if (child.error && !timedOut) {
|
|
255
|
-
throw child.error;
|
|
256
|
-
}
|
|
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 ?? ""));
|
|
262
|
-
|
|
263
|
-
return {
|
|
264
|
-
status: child.status ?? 1,
|
|
265
|
-
signal: child.signal ?? null,
|
|
266
|
-
stdout,
|
|
267
|
-
stderr,
|
|
268
|
-
wallMs,
|
|
269
|
-
events,
|
|
270
|
-
eventError,
|
|
271
|
-
timedOut,
|
|
272
|
-
modelNotFound,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
|