@jacobbd/relay-ai 0.12.10 → 0.13.0
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/dist/{chunk-2KEDU24N.js → chunk-37GQTWDJ.js} +175 -627
- package/dist/chunk-37GQTWDJ.js.map +1 -0
- package/dist/{chunk-YIEEHFVL.js → chunk-4WUSKTVR.js} +2 -2
- package/dist/{chunk-OIL75EGI.js → chunk-LGQWKQKL.js} +542 -60
- package/dist/chunk-LGQWKQKL.js.map +1 -0
- package/dist/cli.js +313 -226
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +185 -32
- package/dist/core/index.js.map +1 -1
- package/dist/{manual-models-XV4TB7FB.js → manual-models-7BXJVEYR.js} +3 -3
- package/dist/{ui-command-CJYKHNG6.js → ui-command-QGVVDO63.js} +24 -24
- package/package.json +4 -3
- package/dist/chunk-2KEDU24N.js.map +0 -1
- package/dist/chunk-OIL75EGI.js.map +0 -1
- /package/dist/{chunk-YIEEHFVL.js.map → chunk-4WUSKTVR.js.map} +0 -0
- /package/dist/{manual-models-XV4TB7FB.js.map → manual-models-7BXJVEYR.js.map} +0 -0
- /package/dist/{ui-command-CJYKHNG6.js.map → ui-command-QGVVDO63.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import { join } from "path";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@jacobbd/relay-ai",
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "0.13.0",
|
|
11
11
|
publishConfig: {
|
|
12
12
|
access: "public"
|
|
13
13
|
},
|
|
@@ -32,7 +32,9 @@ var package_default = {
|
|
|
32
32
|
],
|
|
33
33
|
type: "module",
|
|
34
34
|
bin: {
|
|
35
|
-
"relay-ai": "dist/cli.js"
|
|
35
|
+
"relay-ai": "dist/cli.js",
|
|
36
|
+
relayai: "dist/cli.js",
|
|
37
|
+
relai: "dist/cli.js"
|
|
36
38
|
},
|
|
37
39
|
files: [
|
|
38
40
|
"dist",
|
|
@@ -68,7 +70,6 @@ var package_default = {
|
|
|
68
70
|
"@ai-sdk/openai-compatible": "^3.0.44",
|
|
69
71
|
"@ai-sdk/perplexity": "^4.0.39",
|
|
70
72
|
"@ai-sdk/togetherai": "^3.0.45",
|
|
71
|
-
"@ai-sdk/vercel": "^3.0.30",
|
|
72
73
|
"@ai-sdk/xai": "^4.0.54",
|
|
73
74
|
"@clack/prompts": "^0.9.1",
|
|
74
75
|
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
@@ -126,7 +127,7 @@ var BACKENDS = {
|
|
|
126
127
|
}
|
|
127
128
|
};
|
|
128
129
|
var CODEX_RESPONSES_LITE_WS_URL = "wss://chatgpt.com/backend-api/codex/responses";
|
|
129
|
-
var CODEX_RESPONSES_LITE_VERSION = "0.
|
|
130
|
+
var CODEX_RESPONSES_LITE_VERSION = "0.155.1";
|
|
130
131
|
var CODEX_RESPONSES_WEBSOCKETS_BETA = "responses_websockets=2026-02-06";
|
|
131
132
|
var CONFLICTING_ENV_VARS = [
|
|
132
133
|
"CLAUDE_CODE_USE_VERTEX",
|
|
@@ -219,8 +220,271 @@ function getLegacyConfPath(env = process.env, platform = process.platform) {
|
|
|
219
220
|
return join2(env.XDG_CONFIG_HOME ?? join2(home, ".config"), appName, "config.json");
|
|
220
221
|
}
|
|
221
222
|
|
|
223
|
+
// src/config.ts
|
|
224
|
+
import { dirname, join as join3 } from "path";
|
|
225
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
226
|
+
function readJsonFile(path) {
|
|
227
|
+
try {
|
|
228
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
229
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
230
|
+
} catch {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function ensureAppHomeMigrated() {
|
|
235
|
+
const configPath = getConfigPath();
|
|
236
|
+
if (existsSync(configPath)) return;
|
|
237
|
+
const legacyConfig = join3(getLegacyAppHome(), "config.json");
|
|
238
|
+
if (!existsSync(legacyConfig)) return;
|
|
239
|
+
mkdirSync(getAppHome(), { recursive: true, mode: 448 });
|
|
240
|
+
copyFileSync(legacyConfig, configPath);
|
|
241
|
+
const legacyVertex = join3(getLegacyAppHome(), "vertex-models.json");
|
|
242
|
+
const vertexPath = join3(getAppHome(), "vertex-models.json");
|
|
243
|
+
if (existsSync(legacyVertex) && !existsSync(vertexPath)) {
|
|
244
|
+
copyFileSync(legacyVertex, vertexPath);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function ensureConfigMigrated() {
|
|
248
|
+
ensureAppHomeMigrated();
|
|
249
|
+
const configPath = getConfigPath();
|
|
250
|
+
if (existsSync(configPath)) return;
|
|
251
|
+
const legacyPath = getLegacyConfPath();
|
|
252
|
+
if (!existsSync(legacyPath)) return;
|
|
253
|
+
const legacy = readJsonFile(legacyPath);
|
|
254
|
+
if (!legacy) return;
|
|
255
|
+
mkdirSync(dirname(configPath), { recursive: true, mode: 448 });
|
|
256
|
+
writeFileSync(configPath, `${JSON.stringify(legacy, null, 2)}
|
|
257
|
+
`, { encoding: "utf8", mode: 384 });
|
|
258
|
+
try {
|
|
259
|
+
renameSync(legacyPath, `${legacyPath}.migrated`);
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function readConfig() {
|
|
264
|
+
ensureConfigMigrated();
|
|
265
|
+
return readJsonFile(getConfigPath()) ?? {};
|
|
266
|
+
}
|
|
267
|
+
function writeConfig(config) {
|
|
268
|
+
const configPath = getConfigPath();
|
|
269
|
+
mkdirSync(dirname(configPath), { recursive: true, mode: 448 });
|
|
270
|
+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
271
|
+
`, { encoding: "utf8", mode: 384 });
|
|
272
|
+
}
|
|
273
|
+
function loadPreferences() {
|
|
274
|
+
const config = readConfig();
|
|
275
|
+
const lastProvider = config.lastProvider === "opencode" ? "zen" : config.lastProvider;
|
|
276
|
+
return {
|
|
277
|
+
lastBackend: config.lastBackend,
|
|
278
|
+
lastModel: config.lastModel,
|
|
279
|
+
lastProvider,
|
|
280
|
+
lastCodexProvider: config.lastCodexProvider,
|
|
281
|
+
lastCodexModel: config.lastCodexModel,
|
|
282
|
+
lastGeminiProvider: config.lastGeminiProvider,
|
|
283
|
+
lastGeminiModel: config.lastGeminiModel,
|
|
284
|
+
lastAntigravityProvider: config.lastAntigravityProvider,
|
|
285
|
+
lastAntigravityModel: config.lastAntigravityModel,
|
|
286
|
+
lastClaudeTransparentMode: config.lastClaudeTransparentMode,
|
|
287
|
+
recentModelsByProvider: config.recentModelsByProvider,
|
|
288
|
+
favoriteModels: config.favoriteModels,
|
|
289
|
+
codexSubagentModels: Array.isArray(config.codexSubagentModels) ? config.codexSubagentModels.slice(0, CODEX_SUBAGENT_MODEL_CAP) : void 0,
|
|
290
|
+
antigravityCliFavoriteModels: config.antigravityCliFavoriteModels,
|
|
291
|
+
antigravityCliFavoritesHintShown: config.antigravityCliFavoritesHintShown,
|
|
292
|
+
appPathOverrides: config.appPathOverrides,
|
|
293
|
+
recentLaunchFolders: config.recentLaunchFolders,
|
|
294
|
+
server: config.server
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function savePreferences(prefs) {
|
|
298
|
+
const config = readConfig();
|
|
299
|
+
if (prefs.lastBackend !== void 0) config.lastBackend = prefs.lastBackend;
|
|
300
|
+
if (prefs.lastModel !== void 0) config.lastModel = prefs.lastModel;
|
|
301
|
+
if (prefs.lastProvider !== void 0) config.lastProvider = prefs.lastProvider;
|
|
302
|
+
if (prefs.lastCodexProvider !== void 0) config.lastCodexProvider = prefs.lastCodexProvider;
|
|
303
|
+
if (prefs.lastCodexModel !== void 0) config.lastCodexModel = prefs.lastCodexModel;
|
|
304
|
+
if (prefs.lastGeminiProvider !== void 0) config.lastGeminiProvider = prefs.lastGeminiProvider;
|
|
305
|
+
if (prefs.lastGeminiModel !== void 0) config.lastGeminiModel = prefs.lastGeminiModel;
|
|
306
|
+
if (prefs.lastAntigravityProvider !== void 0) config.lastAntigravityProvider = prefs.lastAntigravityProvider;
|
|
307
|
+
if (prefs.lastAntigravityModel !== void 0) config.lastAntigravityModel = prefs.lastAntigravityModel;
|
|
308
|
+
if (prefs.lastClaudeTransparentMode !== void 0) config.lastClaudeTransparentMode = prefs.lastClaudeTransparentMode;
|
|
309
|
+
if (prefs.recentModelsByProvider !== void 0) config.recentModelsByProvider = prefs.recentModelsByProvider;
|
|
310
|
+
if (prefs.favoriteModels !== void 0) config.favoriteModels = prefs.favoriteModels;
|
|
311
|
+
if (prefs.codexSubagentModels !== void 0) {
|
|
312
|
+
config.codexSubagentModels = prefs.codexSubagentModels.slice(0, CODEX_SUBAGENT_MODEL_CAP);
|
|
313
|
+
}
|
|
314
|
+
if (prefs.antigravityCliFavoriteModels !== void 0) config.antigravityCliFavoriteModels = prefs.antigravityCliFavoriteModels;
|
|
315
|
+
if (prefs.antigravityCliFavoritesHintShown !== void 0) config.antigravityCliFavoritesHintShown = prefs.antigravityCliFavoritesHintShown;
|
|
316
|
+
if (prefs.appPathOverrides !== void 0) config.appPathOverrides = prefs.appPathOverrides;
|
|
317
|
+
if (prefs.recentLaunchFolders !== void 0) config.recentLaunchFolders = prefs.recentLaunchFolders;
|
|
318
|
+
writeConfig(config);
|
|
319
|
+
}
|
|
320
|
+
function getAppPathOverride(appId) {
|
|
321
|
+
const value = loadPreferences().appPathOverrides?.[appId];
|
|
322
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
323
|
+
}
|
|
324
|
+
function setAppPathOverride(appId, path) {
|
|
325
|
+
const config = readConfig();
|
|
326
|
+
const next = { ...config.appPathOverrides ?? {} };
|
|
327
|
+
const trimmed = path?.trim() ?? "";
|
|
328
|
+
if (trimmed) next[appId] = trimmed;
|
|
329
|
+
else delete next[appId];
|
|
330
|
+
config.appPathOverrides = next;
|
|
331
|
+
if (Object.keys(next).length === 0) delete config.appPathOverrides;
|
|
332
|
+
writeConfig(config);
|
|
333
|
+
return next;
|
|
334
|
+
}
|
|
335
|
+
var MAX_RECENT_MODELS = 3;
|
|
336
|
+
var MAX_RECENT_LAUNCH_FOLDERS = 6;
|
|
337
|
+
function recordLaunchFolder(folder) {
|
|
338
|
+
const trimmed = folder.trim();
|
|
339
|
+
if (!trimmed) return loadPreferences().recentLaunchFolders ?? [];
|
|
340
|
+
const config = readConfig();
|
|
341
|
+
const prev = config.recentLaunchFolders ?? [];
|
|
342
|
+
const next = [trimmed, ...prev.filter((path) => path !== trimmed)].slice(0, MAX_RECENT_LAUNCH_FOLDERS);
|
|
343
|
+
config.recentLaunchFolders = next;
|
|
344
|
+
writeConfig(config);
|
|
345
|
+
return next;
|
|
346
|
+
}
|
|
347
|
+
function recordLaunchSelection(agent, providerId, modelId, prefs) {
|
|
348
|
+
const prevRecent = prefs.recentModelsByProvider?.[providerId] ?? [];
|
|
349
|
+
const updatedRecent = [modelId, ...prevRecent.filter((id) => id !== modelId)].slice(0, MAX_RECENT_MODELS);
|
|
350
|
+
savePreferences({
|
|
351
|
+
...agent === "claude" ? { lastProvider: providerId, lastModel: modelId } : agent === "codex" ? { lastCodexProvider: providerId, lastCodexModel: modelId } : { lastGeminiProvider: providerId, lastGeminiModel: modelId },
|
|
352
|
+
recentModelsByProvider: { ...prefs.recentModelsByProvider, [providerId]: updatedRecent }
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
var SERVER_PASSWORD_SERVICE = "relay-ai-server-password";
|
|
356
|
+
var SERVER_PASSWORD_ACCOUNT = "server-password";
|
|
357
|
+
async function getServerPasswordKeyring() {
|
|
358
|
+
try {
|
|
359
|
+
const { Entry } = await import("@napi-rs/keyring");
|
|
360
|
+
return new Entry(SERVER_PASSWORD_SERVICE, SERVER_PASSWORD_ACCOUNT);
|
|
361
|
+
} catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
async function getSavedServerPassword() {
|
|
366
|
+
const config = readConfig();
|
|
367
|
+
if (config.server?.savedPassword) {
|
|
368
|
+
const pwd = config.server.savedPassword;
|
|
369
|
+
const keyring2 = await getServerPasswordKeyring();
|
|
370
|
+
if (keyring2) {
|
|
371
|
+
try {
|
|
372
|
+
await keyring2.setPassword(pwd);
|
|
373
|
+
delete config.server.savedPassword;
|
|
374
|
+
if (Object.keys(config.server).length === 0) delete config.server;
|
|
375
|
+
writeConfig(config);
|
|
376
|
+
} catch {
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return pwd;
|
|
380
|
+
}
|
|
381
|
+
const keyring = await getServerPasswordKeyring();
|
|
382
|
+
if (keyring) {
|
|
383
|
+
try {
|
|
384
|
+
return await keyring.getPassword();
|
|
385
|
+
} catch {
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
function getEnvServerPassword() {
|
|
392
|
+
const value = process.env["RELAY_AI_SERVER_PASSWORD"]?.trim();
|
|
393
|
+
return value || null;
|
|
394
|
+
}
|
|
395
|
+
async function setSavedServerPassword(password) {
|
|
396
|
+
const keyring = await getServerPasswordKeyring();
|
|
397
|
+
if (keyring) {
|
|
398
|
+
try {
|
|
399
|
+
await keyring.setPassword(password);
|
|
400
|
+
return;
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const config = readConfig();
|
|
405
|
+
config.server = {
|
|
406
|
+
...config.server ?? {},
|
|
407
|
+
savedPassword: password
|
|
408
|
+
};
|
|
409
|
+
writeConfig(config);
|
|
410
|
+
}
|
|
411
|
+
function getServerExposedProviders() {
|
|
412
|
+
const list = readConfig().server?.exposedProviders;
|
|
413
|
+
return list && list.length > 0 ? list : null;
|
|
414
|
+
}
|
|
415
|
+
function setServerExposedProviders(providerIds) {
|
|
416
|
+
const config = readConfig();
|
|
417
|
+
config.server = {
|
|
418
|
+
...config.server ?? {},
|
|
419
|
+
exposedProviders: providerIds
|
|
420
|
+
};
|
|
421
|
+
writeConfig(config);
|
|
422
|
+
}
|
|
423
|
+
function getServerMaskGatewayIds() {
|
|
424
|
+
return readConfig().server?.maskGatewayIds ?? true;
|
|
425
|
+
}
|
|
426
|
+
function setServerMaskGatewayIds(mask) {
|
|
427
|
+
const config = readConfig();
|
|
428
|
+
config.server = {
|
|
429
|
+
...config.server ?? {},
|
|
430
|
+
maskGatewayIds: mask
|
|
431
|
+
};
|
|
432
|
+
writeConfig(config);
|
|
433
|
+
}
|
|
434
|
+
function getServerFavoritesOnly() {
|
|
435
|
+
return readConfig().server?.favoritesOnly ?? false;
|
|
436
|
+
}
|
|
437
|
+
function setServerFavoritesOnly(favoritesOnly) {
|
|
438
|
+
const config = readConfig();
|
|
439
|
+
config.server = {
|
|
440
|
+
...config.server ?? {},
|
|
441
|
+
favoritesOnly
|
|
442
|
+
};
|
|
443
|
+
writeConfig(config);
|
|
444
|
+
}
|
|
445
|
+
function getServerFreeModelsOnly() {
|
|
446
|
+
return readConfig().server?.freeModelsOnly ?? false;
|
|
447
|
+
}
|
|
448
|
+
function setServerFreeModelsOnly(freeModelsOnly) {
|
|
449
|
+
const config = readConfig();
|
|
450
|
+
config.server = {
|
|
451
|
+
...config.server ?? {},
|
|
452
|
+
freeModelsOnly
|
|
453
|
+
};
|
|
454
|
+
writeConfig(config);
|
|
455
|
+
}
|
|
456
|
+
function getServerListenMode() {
|
|
457
|
+
return readConfig().server?.listenMode === "network" ? "network" : "local";
|
|
458
|
+
}
|
|
459
|
+
function setServerListenMode(listenMode) {
|
|
460
|
+
const config = readConfig();
|
|
461
|
+
config.server = {
|
|
462
|
+
...config.server ?? {},
|
|
463
|
+
listenMode
|
|
464
|
+
};
|
|
465
|
+
writeConfig(config);
|
|
466
|
+
}
|
|
467
|
+
function getServerAutostart() {
|
|
468
|
+
return readConfig().server?.autostart ?? false;
|
|
469
|
+
}
|
|
470
|
+
function setServerAutostart(autostart) {
|
|
471
|
+
const config = readConfig();
|
|
472
|
+
config.server = {
|
|
473
|
+
...config.server ?? {},
|
|
474
|
+
autostart
|
|
475
|
+
};
|
|
476
|
+
writeConfig(config);
|
|
477
|
+
}
|
|
478
|
+
function resolveServerAutostart(env = process.env) {
|
|
479
|
+
const envVal = env["RELAY_AI_SERVER_AUTOSTART"]?.trim().toLowerCase();
|
|
480
|
+
if (envVal !== void 0 && envVal !== "") {
|
|
481
|
+
return ["1", "true", "yes", "on"].includes(envVal);
|
|
482
|
+
}
|
|
483
|
+
return getServerAutostart();
|
|
484
|
+
}
|
|
485
|
+
|
|
222
486
|
// src/context-window.ts
|
|
223
|
-
import { readFileSync } from "fs";
|
|
487
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
224
488
|
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
225
489
|
var CACHE_PROVIDER_PRIORITY = /* @__PURE__ */ new Set(["opencode", "opencode-go"]);
|
|
226
490
|
var HEURISTIC_RULES = [
|
|
@@ -258,7 +522,7 @@ var heuristicCache = /* @__PURE__ */ new Map();
|
|
|
258
522
|
function loadOpencodeCache() {
|
|
259
523
|
if (parsedCache === void 0) {
|
|
260
524
|
try {
|
|
261
|
-
parsedCache = JSON.parse(
|
|
525
|
+
parsedCache = JSON.parse(readFileSync2(OPENCODE_CACHE_PATH, "utf8"));
|
|
262
526
|
} catch {
|
|
263
527
|
parsedCache = null;
|
|
264
528
|
}
|
|
@@ -297,8 +561,8 @@ function getCacheIndex() {
|
|
|
297
561
|
return cacheIndex;
|
|
298
562
|
}
|
|
299
563
|
function contextWindowFromHeuristics(modelId) {
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
564
|
+
const cached2 = heuristicCache.get(modelId);
|
|
565
|
+
if (cached2 !== void 0) return cached2;
|
|
302
566
|
for (const [pattern, size] of HEURISTIC_RULES) {
|
|
303
567
|
if (pattern.test(modelId)) {
|
|
304
568
|
heuristicCache.set(modelId, size);
|
|
@@ -345,7 +609,7 @@ function routeLookupIds(id) {
|
|
|
345
609
|
|
|
346
610
|
// src/oauth/antigravity-oauth.ts
|
|
347
611
|
import open from "open";
|
|
348
|
-
import { readFileSync as
|
|
612
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
349
613
|
import { homedir as homedir3 } from "os";
|
|
350
614
|
import { join as pathJoin } from "path";
|
|
351
615
|
|
|
@@ -634,7 +898,7 @@ async function onboardUser(accessToken, tierId, maxAttempts = 10) {
|
|
|
634
898
|
function readAgyProjectId() {
|
|
635
899
|
try {
|
|
636
900
|
const cache = pathJoin(homedir3(), ".gemini", "antigravity-cli", "cache", "projects.json");
|
|
637
|
-
const data = JSON.parse(
|
|
901
|
+
const data = JSON.parse(readFileSync3(cache, "utf8"));
|
|
638
902
|
return data[homedir3()] ?? Object.values(data)[0] ?? "";
|
|
639
903
|
} catch {
|
|
640
904
|
return "";
|
|
@@ -680,15 +944,15 @@ async function completeAntigravityExchange(code, codeVerifier, redirectUri) {
|
|
|
680
944
|
}
|
|
681
945
|
|
|
682
946
|
// src/registry/opencode-auth.ts
|
|
683
|
-
import { existsSync, readFileSync as
|
|
947
|
+
import { existsSync as existsSync2, readFileSync as readFileSync4, statSync } from "fs";
|
|
684
948
|
import { homedir as homedir4 } from "os";
|
|
685
|
-
import { join as
|
|
949
|
+
import { join as join4 } from "path";
|
|
686
950
|
function resolveOpencodeAuthPath(env = process.env) {
|
|
687
|
-
const dataHome = env["XDG_DATA_HOME"] ??
|
|
951
|
+
const dataHome = env["XDG_DATA_HOME"] ?? join4(homedir4(), ".local", "share");
|
|
688
952
|
if (process.platform === "win32") {
|
|
689
|
-
return
|
|
953
|
+
return join4(env["APPDATA"] ?? join4(homedir4(), "AppData", "Roaming"), "opencode", "auth.json");
|
|
690
954
|
}
|
|
691
|
-
return
|
|
955
|
+
return join4(dataHome, "opencode", "auth.json");
|
|
692
956
|
}
|
|
693
957
|
function decodeAuthEntry(value) {
|
|
694
958
|
if (typeof value === "string" && value.trim()) return value.trim();
|
|
@@ -718,7 +982,7 @@ function decodeAuthEntry(value) {
|
|
|
718
982
|
return null;
|
|
719
983
|
}
|
|
720
984
|
function authFilePermissionWarning(path) {
|
|
721
|
-
if (!
|
|
985
|
+
if (!existsSync2(path)) return void 0;
|
|
722
986
|
if (process.platform === "win32") return void 0;
|
|
723
987
|
try {
|
|
724
988
|
const mode = statSync(path).mode & 511;
|
|
@@ -731,10 +995,10 @@ function authFilePermissionWarning(path) {
|
|
|
731
995
|
}
|
|
732
996
|
function readOpencodeAuthFile(env = process.env) {
|
|
733
997
|
const path = resolveOpencodeAuthPath(env);
|
|
734
|
-
if (!
|
|
998
|
+
if (!existsSync2(path)) return null;
|
|
735
999
|
let parsed;
|
|
736
1000
|
try {
|
|
737
|
-
parsed = JSON.parse(
|
|
1001
|
+
parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
738
1002
|
} catch {
|
|
739
1003
|
return { path, entries: {}, permissionWarning: authFilePermissionWarning(path) };
|
|
740
1004
|
}
|
|
@@ -1539,7 +1803,7 @@ async function refreshStoredOAuthCredential(providerId, cred) {
|
|
|
1539
1803
|
}
|
|
1540
1804
|
|
|
1541
1805
|
// src/secrets-file.ts
|
|
1542
|
-
import { chmodSync, existsSync as
|
|
1806
|
+
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
1543
1807
|
var DIR_MODE = 448;
|
|
1544
1808
|
var FILE_MODE = 384;
|
|
1545
1809
|
function emptySecrets() {
|
|
@@ -1547,9 +1811,9 @@ function emptySecrets() {
|
|
|
1547
1811
|
}
|
|
1548
1812
|
function readSecretsFile(env = process.env) {
|
|
1549
1813
|
const path = getSecretsPath(env);
|
|
1550
|
-
if (!
|
|
1814
|
+
if (!existsSync3(path)) return emptySecrets();
|
|
1551
1815
|
try {
|
|
1552
|
-
const raw = JSON.parse(
|
|
1816
|
+
const raw = JSON.parse(readFileSync5(path, "utf8"));
|
|
1553
1817
|
if (raw?.version !== 1 || !raw.accounts || typeof raw.accounts !== "object") {
|
|
1554
1818
|
return emptySecrets();
|
|
1555
1819
|
}
|
|
@@ -1564,13 +1828,13 @@ function readSecretsFile(env = process.env) {
|
|
|
1564
1828
|
}
|
|
1565
1829
|
function writeSecretsFile(data, env = process.env) {
|
|
1566
1830
|
const home = getAppHome(env);
|
|
1567
|
-
|
|
1831
|
+
mkdirSync2(home, { recursive: true, mode: DIR_MODE });
|
|
1568
1832
|
try {
|
|
1569
1833
|
chmodSync(home, DIR_MODE);
|
|
1570
1834
|
} catch {
|
|
1571
1835
|
}
|
|
1572
1836
|
const path = getSecretsPath(env);
|
|
1573
|
-
|
|
1837
|
+
writeFileSync2(path, `${JSON.stringify(data, null, 2)}
|
|
1574
1838
|
`, { encoding: "utf8", mode: FILE_MODE });
|
|
1575
1839
|
try {
|
|
1576
1840
|
chmodSync(path, FILE_MODE);
|
|
@@ -2021,16 +2285,16 @@ function parseManualModel(raw) {
|
|
|
2021
2285
|
// src/registry/io.ts
|
|
2022
2286
|
import {
|
|
2023
2287
|
chmodSync as chmodSync2,
|
|
2024
|
-
copyFileSync,
|
|
2025
|
-
existsSync as
|
|
2026
|
-
mkdirSync as
|
|
2288
|
+
copyFileSync as copyFileSync2,
|
|
2289
|
+
existsSync as existsSync4,
|
|
2290
|
+
mkdirSync as mkdirSync3,
|
|
2027
2291
|
openSync,
|
|
2028
|
-
readFileSync as
|
|
2029
|
-
renameSync,
|
|
2292
|
+
readFileSync as readFileSync6,
|
|
2293
|
+
renameSync as renameSync2,
|
|
2030
2294
|
writeSync,
|
|
2031
2295
|
closeSync
|
|
2032
2296
|
} from "fs";
|
|
2033
|
-
import { dirname } from "path";
|
|
2297
|
+
import { dirname as dirname2 } from "path";
|
|
2034
2298
|
|
|
2035
2299
|
// src/registry/types.ts
|
|
2036
2300
|
var REGISTRY_SCHEMA_VERSION = 1;
|
|
@@ -2121,7 +2385,7 @@ var DIR_MODE2 = 448;
|
|
|
2121
2385
|
var FILE_MODE2 = 384;
|
|
2122
2386
|
function ensureSecureAppHome() {
|
|
2123
2387
|
const home = getAppHome();
|
|
2124
|
-
|
|
2388
|
+
mkdirSync3(home, { recursive: true, mode: DIR_MODE2 });
|
|
2125
2389
|
try {
|
|
2126
2390
|
chmodSync2(home, DIR_MODE2);
|
|
2127
2391
|
} catch {
|
|
@@ -2129,7 +2393,7 @@ function ensureSecureAppHome() {
|
|
|
2129
2393
|
}
|
|
2130
2394
|
function writeSecureFile(path, content) {
|
|
2131
2395
|
ensureSecureAppHome();
|
|
2132
|
-
|
|
2396
|
+
mkdirSync3(dirname2(path), { recursive: true, mode: DIR_MODE2 });
|
|
2133
2397
|
const fd = openSync(path, "w", FILE_MODE2);
|
|
2134
2398
|
try {
|
|
2135
2399
|
writeSync(fd, content);
|
|
@@ -2205,11 +2469,11 @@ function parseRegistry(raw) {
|
|
|
2205
2469
|
return registry;
|
|
2206
2470
|
}
|
|
2207
2471
|
function loadRegistry(path = getProvidersPath(), { persist = true } = {}) {
|
|
2208
|
-
if (!
|
|
2472
|
+
if (!existsSync4(path)) {
|
|
2209
2473
|
return { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };
|
|
2210
2474
|
}
|
|
2211
2475
|
try {
|
|
2212
|
-
const raw = JSON.parse(
|
|
2476
|
+
const raw = JSON.parse(readFileSync6(path, "utf8"));
|
|
2213
2477
|
const registry = parseRegistry(raw);
|
|
2214
2478
|
let migrated = migrateLegacyCloudProviders(registry);
|
|
2215
2479
|
if (migrateOAuthOpenAiProvider(registry)) migrated = true;
|
|
@@ -2230,15 +2494,15 @@ function saveRegistry(registry, path = getProvidersPath()) {
|
|
|
2230
2494
|
const payload = `${JSON.stringify(registry, null, 2)}
|
|
2231
2495
|
`;
|
|
2232
2496
|
const backup = `${path}.bak`;
|
|
2233
|
-
if (
|
|
2497
|
+
if (existsSync4(path)) {
|
|
2234
2498
|
try {
|
|
2235
|
-
|
|
2499
|
+
copyFileSync2(path, backup);
|
|
2236
2500
|
} catch {
|
|
2237
2501
|
}
|
|
2238
2502
|
}
|
|
2239
2503
|
const tmp = `${path}.tmp`;
|
|
2240
2504
|
writeSecureFile(tmp, payload);
|
|
2241
|
-
|
|
2505
|
+
renameSync2(tmp, path);
|
|
2242
2506
|
}
|
|
2243
2507
|
|
|
2244
2508
|
// src/registry/url-security.ts
|
|
@@ -2353,6 +2617,81 @@ async function validateCustomEndpointUrl(rawUrl, opts = {}) {
|
|
|
2353
2617
|
return { ok: true, normalizedUrl };
|
|
2354
2618
|
}
|
|
2355
2619
|
|
|
2620
|
+
// src/codex/process.ts
|
|
2621
|
+
import spawn from "cross-spawn";
|
|
2622
|
+
function commandError(binaryPath, args, stdout, stderr, detail) {
|
|
2623
|
+
const error = new Error(`Command failed: ${binaryPath} ${args.join(" ")} (${detail})`);
|
|
2624
|
+
return Object.assign(error, { stdout, stderr });
|
|
2625
|
+
}
|
|
2626
|
+
function runCodexCommandSync(binaryPath, args, options = {}) {
|
|
2627
|
+
const result = spawn.sync(binaryPath, args, {
|
|
2628
|
+
encoding: "utf8",
|
|
2629
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2630
|
+
env: options.env,
|
|
2631
|
+
timeout: options.timeout,
|
|
2632
|
+
maxBuffer: options.maxBuffer
|
|
2633
|
+
});
|
|
2634
|
+
const stdout = result.stdout ?? "";
|
|
2635
|
+
const stderr = result.stderr ?? "";
|
|
2636
|
+
if (result.error) {
|
|
2637
|
+
throw Object.assign(result.error, { stdout, stderr });
|
|
2638
|
+
}
|
|
2639
|
+
if (result.status !== 0) {
|
|
2640
|
+
throw commandError(binaryPath, args, stdout, stderr, `exit ${result.status ?? result.signal ?? "unknown"}`);
|
|
2641
|
+
}
|
|
2642
|
+
return { stdout, stderr };
|
|
2643
|
+
}
|
|
2644
|
+
function runCodexCommand(binaryPath, args, options = {}) {
|
|
2645
|
+
return new Promise((resolve, reject) => {
|
|
2646
|
+
const child = spawn(binaryPath, args, {
|
|
2647
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2648
|
+
env: options.env
|
|
2649
|
+
});
|
|
2650
|
+
const stdoutChunks = [];
|
|
2651
|
+
const stderrChunks = [];
|
|
2652
|
+
let outputBytes = 0;
|
|
2653
|
+
let settled = false;
|
|
2654
|
+
const finishError = (error) => {
|
|
2655
|
+
if (settled) return;
|
|
2656
|
+
settled = true;
|
|
2657
|
+
reject(Object.assign(error, {
|
|
2658
|
+
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
2659
|
+
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
2660
|
+
}));
|
|
2661
|
+
};
|
|
2662
|
+
const collect = (target, chunk) => {
|
|
2663
|
+
target.push(chunk);
|
|
2664
|
+
outputBytes += chunk.length;
|
|
2665
|
+
if (options.maxBuffer !== void 0 && outputBytes > options.maxBuffer) {
|
|
2666
|
+
child.kill();
|
|
2667
|
+
finishError(commandError(binaryPath, args, "", "", `output exceeded ${options.maxBuffer} bytes`));
|
|
2668
|
+
}
|
|
2669
|
+
};
|
|
2670
|
+
child.stdout?.on("data", (chunk) => collect(stdoutChunks, chunk));
|
|
2671
|
+
child.stderr?.on("data", (chunk) => collect(stderrChunks, chunk));
|
|
2672
|
+
child.on("error", finishError);
|
|
2673
|
+
let timer;
|
|
2674
|
+
if (options.timeout !== void 0) {
|
|
2675
|
+
timer = setTimeout(() => {
|
|
2676
|
+
child.kill();
|
|
2677
|
+
finishError(commandError(binaryPath, args, "", "", `timed out after ${options.timeout}ms`));
|
|
2678
|
+
}, options.timeout);
|
|
2679
|
+
}
|
|
2680
|
+
child.on("close", (code, signal) => {
|
|
2681
|
+
if (timer) clearTimeout(timer);
|
|
2682
|
+
if (settled) return;
|
|
2683
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
2684
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
2685
|
+
if (code !== 0) {
|
|
2686
|
+
finishError(commandError(binaryPath, args, stdout, stderr, `exit ${code ?? signal ?? "unknown"}`));
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2689
|
+
settled = true;
|
|
2690
|
+
resolve({ stdout, stderr });
|
|
2691
|
+
});
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2356
2695
|
// src/oauth/claude-identity.ts
|
|
2357
2696
|
import { createHash, randomUUID } from "crypto";
|
|
2358
2697
|
var CLAUDE_CODE_CLI_VERSION2 = "2.1.195";
|
|
@@ -2470,6 +2809,125 @@ function injectClaudeIdentity(body, providerData, seed) {
|
|
|
2470
2809
|
// src/provider-factory.ts
|
|
2471
2810
|
import { wrapLanguageModel, extractReasoningMiddleware } from "ai";
|
|
2472
2811
|
|
|
2812
|
+
// src/codex/version.ts
|
|
2813
|
+
import { execSync } from "child_process";
|
|
2814
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2815
|
+
import { homedir as homedir5 } from "os";
|
|
2816
|
+
import { join as join5 } from "path";
|
|
2817
|
+
var isWindows = process.platform === "win32";
|
|
2818
|
+
var CODEX_NPM_LATEST_URL = "https://registry.npmjs.org/@openai/codex/latest";
|
|
2819
|
+
var CODEX_VERSION_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2820
|
+
var NPM_FETCH_TIMEOUT_MS = 3e3;
|
|
2821
|
+
var cached = null;
|
|
2822
|
+
var inflight = null;
|
|
2823
|
+
function parseCodexVersion(input) {
|
|
2824
|
+
const match = input.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
2825
|
+
return match ? `${match[1]}.${match[2]}.${match[3]}` : null;
|
|
2826
|
+
}
|
|
2827
|
+
function versionTuple(version) {
|
|
2828
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
2829
|
+
if (!match) return null;
|
|
2830
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
2831
|
+
}
|
|
2832
|
+
function maxCodexVersion(candidates) {
|
|
2833
|
+
let best = null;
|
|
2834
|
+
let bestTuple = null;
|
|
2835
|
+
for (const candidate of candidates) {
|
|
2836
|
+
if (!candidate) continue;
|
|
2837
|
+
const tuple = versionTuple(candidate);
|
|
2838
|
+
if (!tuple) continue;
|
|
2839
|
+
const greater = !bestTuple || (tuple[0] !== bestTuple[0] ? tuple[0] > bestTuple[0] : tuple[1] !== bestTuple[1] ? tuple[1] > bestTuple[1] : tuple[2] > bestTuple[2]);
|
|
2840
|
+
if (greater) {
|
|
2841
|
+
best = candidate;
|
|
2842
|
+
bestTuple = tuple;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
return best ?? candidates.find((c) => !!c) ?? CODEX_RESPONSES_LITE_VERSION;
|
|
2846
|
+
}
|
|
2847
|
+
async function fetchNpmCodexVersion(fetchImpl = fetch, timeoutMs = NPM_FETCH_TIMEOUT_MS) {
|
|
2848
|
+
try {
|
|
2849
|
+
const controller = new AbortController();
|
|
2850
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
2851
|
+
try {
|
|
2852
|
+
const res = await fetchImpl(CODEX_NPM_LATEST_URL, {
|
|
2853
|
+
headers: { Accept: "application/json" },
|
|
2854
|
+
signal: controller.signal
|
|
2855
|
+
});
|
|
2856
|
+
if (!res.ok) return null;
|
|
2857
|
+
const body = await res.json();
|
|
2858
|
+
return typeof body.version === "string" ? parseCodexVersion(body.version) : null;
|
|
2859
|
+
} finally {
|
|
2860
|
+
clearTimeout(timer);
|
|
2861
|
+
}
|
|
2862
|
+
} catch {
|
|
2863
|
+
return null;
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
var CODEX_VERSION_FALLBACK_PATHS = isWindows ? [
|
|
2867
|
+
join5(process.env["APPDATA"] ?? homedir5(), "npm", "codex.cmd"),
|
|
2868
|
+
join5(process.env["APPDATA"] ?? homedir5(), "npm", "codex")
|
|
2869
|
+
] : [
|
|
2870
|
+
join5(homedir5(), ".local", "bin", "codex"),
|
|
2871
|
+
join5(homedir5(), ".npm", "bin", "codex"),
|
|
2872
|
+
"/usr/local/bin/codex",
|
|
2873
|
+
"/opt/homebrew/bin/codex"
|
|
2874
|
+
];
|
|
2875
|
+
function codexBinaryCandidates() {
|
|
2876
|
+
const override = getAppPathOverride("codex");
|
|
2877
|
+
if (override) return [override];
|
|
2878
|
+
const candidates = [];
|
|
2879
|
+
try {
|
|
2880
|
+
const result = execSync(isWindows ? "where.exe codex" : "which codex", {
|
|
2881
|
+
encoding: "utf8",
|
|
2882
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2883
|
+
});
|
|
2884
|
+
candidates.push(...result.trim().split("\n").map((l) => l.trim()).filter(Boolean));
|
|
2885
|
+
} catch {
|
|
2886
|
+
}
|
|
2887
|
+
candidates.push(...CODEX_VERSION_FALLBACK_PATHS);
|
|
2888
|
+
return [...new Set(candidates)];
|
|
2889
|
+
}
|
|
2890
|
+
function installedCodexVersion() {
|
|
2891
|
+
for (const binary of codexBinaryCandidates()) {
|
|
2892
|
+
try {
|
|
2893
|
+
if (!existsSync5(binary)) continue;
|
|
2894
|
+
const { stdout } = runCodexCommandSync(binary, ["--version"], { timeout: 5e3 });
|
|
2895
|
+
const parsed = parseCodexVersion(stdout);
|
|
2896
|
+
if (parsed) return parsed;
|
|
2897
|
+
} catch {
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
return null;
|
|
2901
|
+
}
|
|
2902
|
+
async function resolveCodexClientVersion(opts = {}) {
|
|
2903
|
+
const override = process.env["RELAY_AI_CODEX_VERSION"]?.trim();
|
|
2904
|
+
if (override) return parseCodexVersion(override) ?? CODEX_RESPONSES_LITE_VERSION;
|
|
2905
|
+
if (process.env["VITEST"] || process.env["VITEST_WORKER_ID"]) {
|
|
2906
|
+
return cached?.version ?? CODEX_RESPONSES_LITE_VERSION;
|
|
2907
|
+
}
|
|
2908
|
+
const now = Date.now();
|
|
2909
|
+
if (!opts.forceRefresh && cached && now - cached.fetchedAt < CODEX_VERSION_CACHE_TTL_MS) {
|
|
2910
|
+
return cached.version;
|
|
2911
|
+
}
|
|
2912
|
+
if (inflight && !opts.forceRefresh) return inflight;
|
|
2913
|
+
inflight = (async () => {
|
|
2914
|
+
try {
|
|
2915
|
+
const [npm, local] = await Promise.all([
|
|
2916
|
+
fetchNpmCodexVersion(opts.fetchImpl),
|
|
2917
|
+
Promise.resolve().then(() => installedCodexVersion())
|
|
2918
|
+
]);
|
|
2919
|
+
const best = maxCodexVersion([npm, local, CODEX_RESPONSES_LITE_VERSION]);
|
|
2920
|
+
cached = { version: best, fetchedAt: Date.now() };
|
|
2921
|
+
return best;
|
|
2922
|
+
} catch {
|
|
2923
|
+
return cached?.version ?? CODEX_RESPONSES_LITE_VERSION;
|
|
2924
|
+
} finally {
|
|
2925
|
+
inflight = null;
|
|
2926
|
+
}
|
|
2927
|
+
})();
|
|
2928
|
+
return inflight;
|
|
2929
|
+
}
|
|
2930
|
+
|
|
2473
2931
|
// src/oauth/responses-websocket.ts
|
|
2474
2932
|
var RESPONSES_LITE_HEADER = "x-openai-internal-codex-responses-lite";
|
|
2475
2933
|
var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set(["response.completed", "response.failed", "response.incomplete", "error"]);
|
|
@@ -2946,8 +3404,8 @@ function createResponsesWebSocketFetch(wsUrl, log) {
|
|
|
2946
3404
|
|
|
2947
3405
|
// src/gateway-protocol.ts
|
|
2948
3406
|
import { createHash as createHash2 } from "crypto";
|
|
2949
|
-
import { existsSync as
|
|
2950
|
-
import { dirname as
|
|
3407
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
3408
|
+
import { dirname as dirname3, join as join6 } from "path";
|
|
2951
3409
|
var DUAL_PROVIDER_IDS = /* @__PURE__ */ new Set([
|
|
2952
3410
|
"zen",
|
|
2953
3411
|
"go",
|
|
@@ -3047,7 +3505,7 @@ var PREFERENCE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
|
3047
3505
|
var FAILURE_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
3048
3506
|
var loadedPersistentPath = null;
|
|
3049
3507
|
function persistentPath() {
|
|
3050
|
-
return
|
|
3508
|
+
return join6(getAppHome(), "protocol-cache.json");
|
|
3051
3509
|
}
|
|
3052
3510
|
function loadPersistent(now = Date.now()) {
|
|
3053
3511
|
const path = persistentPath();
|
|
@@ -3055,8 +3513,8 @@ function loadPersistent(now = Date.now()) {
|
|
|
3055
3513
|
remembered.clear();
|
|
3056
3514
|
loadedPersistentPath = path;
|
|
3057
3515
|
try {
|
|
3058
|
-
if (!
|
|
3059
|
-
const raw = JSON.parse(
|
|
3516
|
+
if (!existsSync6(path)) return;
|
|
3517
|
+
const raw = JSON.parse(readFileSync7(path, "utf8"));
|
|
3060
3518
|
for (const [key, entry] of Object.entries(raw)) {
|
|
3061
3519
|
if (!entry || entry.protocol !== void 0 && entry.protocol !== "openai" && entry.protocol !== "anthropic") continue;
|
|
3062
3520
|
if (typeof entry.expiresAt !== "number" || entry.expiresAt <= now) continue;
|
|
@@ -3069,16 +3527,16 @@ function loadPersistent(now = Date.now()) {
|
|
|
3069
3527
|
function savePersistent() {
|
|
3070
3528
|
const path = persistentPath();
|
|
3071
3529
|
try {
|
|
3072
|
-
|
|
3530
|
+
mkdirSync4(dirname3(path), { recursive: true, mode: 448 });
|
|
3073
3531
|
const live = {};
|
|
3074
3532
|
const now = Date.now();
|
|
3075
3533
|
for (const [key, entry] of remembered) {
|
|
3076
3534
|
if (entry.expiresAt > now) live[key] = entry;
|
|
3077
3535
|
}
|
|
3078
3536
|
const tempPath = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
3079
|
-
|
|
3537
|
+
writeFileSync3(tempPath, `${JSON.stringify(live)}
|
|
3080
3538
|
`, { mode: 384 });
|
|
3081
|
-
|
|
3539
|
+
renameSync3(tempPath, path);
|
|
3082
3540
|
} catch {
|
|
3083
3541
|
}
|
|
3084
3542
|
}
|
|
@@ -3203,9 +3661,9 @@ function findCreateFactory(mod) {
|
|
|
3203
3661
|
throw new Error("No create* factory export found in provider package");
|
|
3204
3662
|
}
|
|
3205
3663
|
async function loadSdkProviderFactory(npm) {
|
|
3206
|
-
let
|
|
3207
|
-
if (!
|
|
3208
|
-
|
|
3664
|
+
let cached2 = factoryCache.get(npm);
|
|
3665
|
+
if (!cached2) {
|
|
3666
|
+
cached2 = (async () => {
|
|
3209
3667
|
try {
|
|
3210
3668
|
const mod = await import(npm);
|
|
3211
3669
|
return findCreateFactory(mod);
|
|
@@ -3217,10 +3675,10 @@ async function loadSdkProviderFactory(npm) {
|
|
|
3217
3675
|
throw err;
|
|
3218
3676
|
}
|
|
3219
3677
|
})();
|
|
3220
|
-
factoryCache.set(npm,
|
|
3221
|
-
|
|
3678
|
+
factoryCache.set(npm, cached2);
|
|
3679
|
+
cached2.catch(() => factoryCache.delete(npm));
|
|
3222
3680
|
}
|
|
3223
|
-
return
|
|
3681
|
+
return cached2;
|
|
3224
3682
|
}
|
|
3225
3683
|
async function createLanguageModelSingle(spec) {
|
|
3226
3684
|
const npm = resolveProviderNpm(spec.npm);
|
|
@@ -3246,8 +3704,10 @@ async function createLanguageModelSingle(spec) {
|
|
|
3246
3704
|
...accountId ? { "ChatGPT-Account-Id": accountId } : {},
|
|
3247
3705
|
originator: "relay-ai",
|
|
3248
3706
|
// Responses-Lite models (backend prefer_websockets/use_responses_lite,
|
|
3249
|
-
// e.g. gpt-5.6-luna) require these on the request.
|
|
3250
|
-
|
|
3707
|
+
// e.g. gpt-5.6-luna) require these on the request. The version is
|
|
3708
|
+
// resolved at runtime (npm latest → installed CLI → bundled
|
|
3709
|
+
// fallback) so new model gates don't need a Relay release.
|
|
3710
|
+
...spec.useResponsesLite ? { version: await resolveCodexClientVersion(), "x-openai-internal-codex-responses-lite": "true" } : {}
|
|
3251
3711
|
},
|
|
3252
3712
|
// Models the backend flags with prefer_websockets are only served over
|
|
3253
3713
|
// the WebSocket Responses transport, not HTTP.
|
|
@@ -5257,6 +5717,35 @@ export {
|
|
|
5257
5717
|
VERTEX_ANTHROPIC_NPM,
|
|
5258
5718
|
classifyModelFormat,
|
|
5259
5719
|
VERSION,
|
|
5720
|
+
getAppHome,
|
|
5721
|
+
getConfigPath,
|
|
5722
|
+
getProvidersPath,
|
|
5723
|
+
getLogsPath,
|
|
5724
|
+
getVertexModelsPath,
|
|
5725
|
+
loadPreferences,
|
|
5726
|
+
savePreferences,
|
|
5727
|
+
getAppPathOverride,
|
|
5728
|
+
setAppPathOverride,
|
|
5729
|
+
recordLaunchFolder,
|
|
5730
|
+
recordLaunchSelection,
|
|
5731
|
+
getSavedServerPassword,
|
|
5732
|
+
getEnvServerPassword,
|
|
5733
|
+
setSavedServerPassword,
|
|
5734
|
+
getServerExposedProviders,
|
|
5735
|
+
setServerExposedProviders,
|
|
5736
|
+
getServerMaskGatewayIds,
|
|
5737
|
+
setServerMaskGatewayIds,
|
|
5738
|
+
getServerFavoritesOnly,
|
|
5739
|
+
setServerFavoritesOnly,
|
|
5740
|
+
getServerFreeModelsOnly,
|
|
5741
|
+
setServerFreeModelsOnly,
|
|
5742
|
+
getServerListenMode,
|
|
5743
|
+
setServerListenMode,
|
|
5744
|
+
setServerAutostart,
|
|
5745
|
+
resolveServerAutostart,
|
|
5746
|
+
runCodexCommandSync,
|
|
5747
|
+
runCodexCommand,
|
|
5748
|
+
resolveCodexClientVersion,
|
|
5260
5749
|
requestOpenAiDeviceCode,
|
|
5261
5750
|
openAiDeviceCodeUrl,
|
|
5262
5751
|
pollOpenAiDeviceCodeToken,
|
|
@@ -5270,13 +5759,6 @@ export {
|
|
|
5270
5759
|
CLINE_PASS_CATALOG_URL,
|
|
5271
5760
|
CLINE_PASS_VALIDATION_URL,
|
|
5272
5761
|
CLINE_PASS_LEGACY_DEFAULT_CONTEXT_WINDOW,
|
|
5273
|
-
getAppHome,
|
|
5274
|
-
getLegacyAppHome,
|
|
5275
|
-
getConfigPath,
|
|
5276
|
-
getProvidersPath,
|
|
5277
|
-
getLogsPath,
|
|
5278
|
-
getVertexModelsPath,
|
|
5279
|
-
getLegacyConfPath,
|
|
5280
5762
|
modelPrefersResponsesApi,
|
|
5281
5763
|
isSdkMigratedNpm,
|
|
5282
5764
|
maxToolsForNpm,
|
|
@@ -5367,4 +5849,4 @@ export {
|
|
|
5367
5849
|
streamAnthropicResponse,
|
|
5368
5850
|
generateAnthropicResponse
|
|
5369
5851
|
};
|
|
5370
|
-
//# sourceMappingURL=chunk-
|
|
5852
|
+
//# sourceMappingURL=chunk-LGQWKQKL.js.map
|