claudish 7.55.0 → 7.57.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/index.js +851 -410
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -729,7 +729,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
729
729
|
});
|
|
730
730
|
|
|
731
731
|
// src/version.ts
|
|
732
|
-
var VERSION = "7.
|
|
732
|
+
var VERSION = "7.57.0";
|
|
733
733
|
|
|
734
734
|
// src/logger.ts
|
|
735
735
|
var exports_logger = {};
|
|
@@ -28057,6 +28057,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28057
28057
|
{ prefix: "antigravity/", stripPrefix: true },
|
|
28058
28058
|
{ prefix: "go/", stripPrefix: true }
|
|
28059
28059
|
],
|
|
28060
|
+
modelDiscovery: { path: "", format: "antigravity" },
|
|
28060
28061
|
isDirectApi: true,
|
|
28061
28062
|
description: "Antigravity subscription (ag@; go@ deprecated)"
|
|
28062
28063
|
},
|
|
@@ -28076,6 +28077,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28076
28077
|
{ prefix: "dv/", stripPrefix: true },
|
|
28077
28078
|
{ prefix: "devin/", stripPrefix: true }
|
|
28078
28079
|
],
|
|
28080
|
+
nativeModelPatterns: [{ pattern: /^swe-/i }],
|
|
28079
28081
|
modelDiscovery: { path: "", format: "devin-connect" },
|
|
28080
28082
|
isDirectApi: true,
|
|
28081
28083
|
description: "Devin subscription (dv@, devin@)"
|
|
@@ -28213,6 +28215,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28213
28215
|
baseUrl: "https://api.minimax.io",
|
|
28214
28216
|
baseUrlEnvVars: ["MINIMAX_CODING_BASE_URL"],
|
|
28215
28217
|
apiPath: "/anthropic/v1/messages",
|
|
28218
|
+
modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
|
|
28216
28219
|
apiKeyEnvVar: "MINIMAX_CODING_API_KEY",
|
|
28217
28220
|
apiKeyDescription: "MiniMax Coding Plan API Key",
|
|
28218
28221
|
apiKeyUrl: "https://platform.minimax.io/user-center/basic-information/interface-key",
|
|
@@ -28249,6 +28252,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28249
28252
|
baseUrl: "https://api.moonshot.ai",
|
|
28250
28253
|
baseUrlEnvVars: ["MOONSHOT_BASE_URL", "KIMI_BASE_URL"],
|
|
28251
28254
|
apiPath: "/anthropic/v1/messages",
|
|
28255
|
+
modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
|
|
28252
28256
|
apiKeyEnvVar: "MOONSHOT_API_KEY",
|
|
28253
28257
|
apiKeyAliases: ["KIMI_API_KEY"],
|
|
28254
28258
|
apiKeyDescription: "Kimi/Moonshot API Key",
|
|
@@ -28300,6 +28304,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28300
28304
|
tokenStrategy: "delta-aware",
|
|
28301
28305
|
baseUrl: "https://api.z.ai",
|
|
28302
28306
|
apiPath: "/api/coding/paas/v4/chat/completions",
|
|
28307
|
+
modelDiscovery: { path: "/api/coding/paas/v4/models", format: "openai-models-list" },
|
|
28303
28308
|
apiKeyEnvVar: "GLM_CODING_API_KEY",
|
|
28304
28309
|
apiKeyAliases: ["ZAI_CODING_API_KEY"],
|
|
28305
28310
|
apiKeyDescription: "GLM Coding Plan API Key",
|
|
@@ -28376,6 +28381,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28376
28381
|
baseUrl: "https://opencode.ai/zen/go",
|
|
28377
28382
|
baseUrlEnvVars: ["OPENCODE_GO_BASE_URL"],
|
|
28378
28383
|
apiPath: "/v1/chat/completions",
|
|
28384
|
+
modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
|
|
28379
28385
|
apiKeyEnvVar: "OPENCODE_GO_API_KEY",
|
|
28380
28386
|
apiKeyAliases: ["OPENCODE_API_KEY"],
|
|
28381
28387
|
apiKeyDescription: "OpenCode Zen Go (Lite Plan) API Key",
|
|
@@ -28593,6 +28599,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28593
28599
|
baseUrl: "https://api.sakana.ai",
|
|
28594
28600
|
baseUrlEnvVars: ["SAKANA_BASE_URL"],
|
|
28595
28601
|
apiPath: "/v1/chat/completions",
|
|
28602
|
+
modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
|
|
28596
28603
|
apiKeyEnvVar: "SAKANA_SUBSCRIPTION_API_KEY",
|
|
28597
28604
|
apiKeyAliases: ["SAKANA_CODING_API_KEY"],
|
|
28598
28605
|
apiKeyDescription: "Sakana Fugu Subscription API Key",
|
|
@@ -28740,6 +28747,8 @@ var init_all_models_cache = __esm(() => {
|
|
|
28740
28747
|
|
|
28741
28748
|
// src/providers/catalog-client.ts
|
|
28742
28749
|
function getCatalogEntries() {
|
|
28750
|
+
if (_catalogEntriesForTest !== undefined)
|
|
28751
|
+
return _catalogEntriesForTest;
|
|
28743
28752
|
if (_memCache)
|
|
28744
28753
|
return _memCache;
|
|
28745
28754
|
const cache = readAllModelsCache();
|
|
@@ -28759,6 +28768,26 @@ function getCatalogEntries() {
|
|
|
28759
28768
|
}
|
|
28760
28769
|
return null;
|
|
28761
28770
|
}
|
|
28771
|
+
function latestAnthropicTierModelId(tier) {
|
|
28772
|
+
const entries = getCatalogEntries();
|
|
28773
|
+
if (!entries)
|
|
28774
|
+
return null;
|
|
28775
|
+
const family = new RegExp(`^claude-${tier}-`, "i");
|
|
28776
|
+
const opus = entries.filter((e) => family.test(e.modelId));
|
|
28777
|
+
if (opus.length === 0)
|
|
28778
|
+
return null;
|
|
28779
|
+
opus.sort((a, b) => {
|
|
28780
|
+
const byDate = (b.releaseDate ?? "").localeCompare(a.releaseDate ?? "");
|
|
28781
|
+
if (byDate !== 0)
|
|
28782
|
+
return byDate;
|
|
28783
|
+
const aFast = /-fast$/i.test(a.modelId) ? 1 : 0;
|
|
28784
|
+
const bFast = /-fast$/i.test(b.modelId) ? 1 : 0;
|
|
28785
|
+
if (aFast !== bFast)
|
|
28786
|
+
return aFast - bFast;
|
|
28787
|
+
return b.modelId.localeCompare(a.modelId);
|
|
28788
|
+
});
|
|
28789
|
+
return opus[0].modelId;
|
|
28790
|
+
}
|
|
28762
28791
|
function isCatalogWarm() {
|
|
28763
28792
|
return _memCache !== null && _memCache.length > 0;
|
|
28764
28793
|
}
|
|
@@ -28901,7 +28930,7 @@ async function ensureCatalogReady(timeoutMs = 5000) {
|
|
|
28901
28930
|
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
28902
28931
|
]);
|
|
28903
28932
|
}
|
|
28904
|
-
var FIREBASE_CATALOG_URL, _memCache = null, _warmPromise = null;
|
|
28933
|
+
var FIREBASE_CATALOG_URL, _memCache = null, _catalogEntriesForTest, _warmPromise = null;
|
|
28905
28934
|
var init_catalog_client = __esm(() => {
|
|
28906
28935
|
init_all_models_cache();
|
|
28907
28936
|
FIREBASE_CATALOG_URL = process.env.CLAUDISH_CATALOG_URL ?? process.env.FIREBASE_CATALOG_URL ?? "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=active&catalog=slim&limit=1000";
|
|
@@ -30105,6 +30134,17 @@ var init_openai_api_format = __esm(() => {
|
|
|
30105
30134
|
});
|
|
30106
30135
|
|
|
30107
30136
|
// src/auth/antigravity-token.ts
|
|
30137
|
+
var exports_antigravity_token = {};
|
|
30138
|
+
__export(exports_antigravity_token, {
|
|
30139
|
+
writeSharedAntigravityToken: () => writeSharedAntigravityToken,
|
|
30140
|
+
readSharedAntigravityToken: () => readSharedAntigravityToken,
|
|
30141
|
+
locateAgyBinary: () => locateAgyBinary,
|
|
30142
|
+
hasSharedAntigravityToken: () => hasSharedAntigravityToken,
|
|
30143
|
+
getValidAntigravityAccessToken: () => getValidAntigravityAccessToken,
|
|
30144
|
+
forceRefreshAntigravityToken: () => forceRefreshAntigravityToken,
|
|
30145
|
+
deleteSharedAntigravityToken: () => deleteSharedAntigravityToken,
|
|
30146
|
+
_resetAntigravityTokenState: () => _resetAntigravityTokenState
|
|
30147
|
+
});
|
|
30108
30148
|
import { execFileSync } from "child_process";
|
|
30109
30149
|
import { existsSync as existsSync7 } from "fs";
|
|
30110
30150
|
import { homedir as homedir9 } from "os";
|
|
@@ -30298,6 +30338,17 @@ var init_antigravity_token = __esm(() => {
|
|
|
30298
30338
|
});
|
|
30299
30339
|
|
|
30300
30340
|
// src/auth/antigravity-user.ts
|
|
30341
|
+
var exports_antigravity_user = {};
|
|
30342
|
+
__export(exports_antigravity_user, {
|
|
30343
|
+
setupAntigravityUser: () => setupAntigravityUser,
|
|
30344
|
+
retrieveUserQuota: () => retrieveUserQuota,
|
|
30345
|
+
resetAntigravityUserCache: () => resetAntigravityUserCache,
|
|
30346
|
+
getServedAntigravityModels: () => getServedAntigravityModels,
|
|
30347
|
+
getAntigravityTierFullName: () => getAntigravityTierFullName,
|
|
30348
|
+
getAntigravityTierDisplayName: () => getAntigravityTierDisplayName,
|
|
30349
|
+
buildAntigravityUserAgent: () => buildAntigravityUserAgent,
|
|
30350
|
+
_resetAntigravityServedModelsCache: () => _resetAntigravityServedModelsCache
|
|
30351
|
+
});
|
|
30301
30352
|
function makeTerminalSetupError(message) {
|
|
30302
30353
|
const err = new Error(message);
|
|
30303
30354
|
err.terminal = true;
|
|
@@ -30357,6 +30408,9 @@ function getAntigravityTierDisplayName() {
|
|
|
30357
30408
|
return "Antigravity Free";
|
|
30358
30409
|
return cachedAgTierName || "Antigravity";
|
|
30359
30410
|
}
|
|
30411
|
+
function getAntigravityTierFullName() {
|
|
30412
|
+
return cachedAgTierName || getAntigravityTierDisplayName();
|
|
30413
|
+
}
|
|
30360
30414
|
async function retrieveUserQuota(accessToken, projectId) {
|
|
30361
30415
|
try {
|
|
30362
30416
|
const res = await fetch(`${ANTIGRAVITY_API_BASE}:retrieveUserQuota`, {
|
|
@@ -30364,7 +30418,7 @@ async function retrieveUserQuota(accessToken, projectId) {
|
|
|
30364
30418
|
headers: {
|
|
30365
30419
|
Authorization: `Bearer ${accessToken}`,
|
|
30366
30420
|
"Content-Type": "application/json",
|
|
30367
|
-
"User-Agent":
|
|
30421
|
+
"User-Agent": buildAntigravityUserAgent()
|
|
30368
30422
|
},
|
|
30369
30423
|
body: JSON.stringify({ project: projectId })
|
|
30370
30424
|
});
|
|
@@ -30398,7 +30452,21 @@ async function getServedAntigravityModels(accessToken, projectId, opts) {
|
|
|
30398
30452
|
const servedIds = data.models ? Object.keys(data.models) : [];
|
|
30399
30453
|
const defaultId = typeof data.defaultAgentModelId === "string" ? data.defaultAgentModelId : null;
|
|
30400
30454
|
if (servedIds.length > 0) {
|
|
30401
|
-
|
|
30455
|
+
const meta3 = {};
|
|
30456
|
+
for (const [id, record4] of Object.entries(data.models ?? {})) {
|
|
30457
|
+
const entry = {};
|
|
30458
|
+
if (typeof record4?.maxTokens === "number" && record4.maxTokens > 0) {
|
|
30459
|
+
entry.contextWindow = record4.maxTokens;
|
|
30460
|
+
}
|
|
30461
|
+
if (typeof record4?.maxOutputTokens === "number" && record4.maxOutputTokens > 0) {
|
|
30462
|
+
entry.maxOutputTokens = record4.maxOutputTokens;
|
|
30463
|
+
}
|
|
30464
|
+
if (typeof record4?.displayName === "string" && record4.displayName) {
|
|
30465
|
+
entry.displayName = record4.displayName;
|
|
30466
|
+
}
|
|
30467
|
+
meta3[id] = entry;
|
|
30468
|
+
}
|
|
30469
|
+
agServedCache = { servedIds, defaultId, meta: meta3 };
|
|
30402
30470
|
agServedCacheAt = now;
|
|
30403
30471
|
return agServedCache;
|
|
30404
30472
|
}
|
|
@@ -30410,7 +30478,11 @@ async function getServedAntigravityModels(accessToken, projectId, opts) {
|
|
|
30410
30478
|
}
|
|
30411
30479
|
if (agServedCache)
|
|
30412
30480
|
return agServedCache;
|
|
30413
|
-
return { servedIds: [], defaultId: null };
|
|
30481
|
+
return { servedIds: [], defaultId: null, meta: {} };
|
|
30482
|
+
}
|
|
30483
|
+
function _resetAntigravityServedModelsCache() {
|
|
30484
|
+
agServedCache = null;
|
|
30485
|
+
agServedCacheAt = 0;
|
|
30414
30486
|
}
|
|
30415
30487
|
var ANTIGRAVITY_API_BASE = "https://cloudcode-pa.googleapis.com/v1internal", SERVED_MODELS_TTL_MS, ANTIGRAVITY_IDE_TYPE = "ANTIGRAVITY", cachedAgProjectId = null, cachedAgTierId = null, cachedAgTierName = null, agServedCache = null, agServedCacheAt = 0;
|
|
30416
30488
|
var init_antigravity_user = __esm(() => {
|
|
@@ -32142,6 +32214,10 @@ async function resolveGrokClientVersion() {
|
|
|
32142
32214
|
} catch {}
|
|
32143
32215
|
return FALLBACK_GROK_CLIENT_VERSION;
|
|
32144
32216
|
}
|
|
32217
|
+
function readGrokProxyUrl() {
|
|
32218
|
+
const fromEnv = process.env[GROK_PROXY_URL_ENV]?.trim();
|
|
32219
|
+
return (fromEnv || DEFAULT_GROK_PROXY_URL).replace(/\/+$/, "");
|
|
32220
|
+
}
|
|
32145
32221
|
function grokAuthHeaders(token, version2 = readGrokClientVersion()) {
|
|
32146
32222
|
return {
|
|
32147
32223
|
Authorization: `Bearer ${token}`,
|
|
@@ -32254,7 +32330,7 @@ function refreshShared(cred) {
|
|
|
32254
32330
|
}
|
|
32255
32331
|
return refreshInFlight;
|
|
32256
32332
|
}
|
|
32257
|
-
var GROK_CLIENT_IDENTIFIER = "grok-shell", FALLBACK_GROK_CLIENT_VERSION = "1.0.4", LEGACY_SCOPE = "https://accounts.x.ai/sign-in", EXPIRY_SKEW_MS2, grokHomeOverride = null, claudishOAuthPathOverride = null, GROK_CHANNEL_URL = "https://x.ai/cli/stable", liveClientVersion = null, SIGN_IN_HINT, refreshInFlight = null;
|
|
32333
|
+
var GROK_PROXY_URL_ENV = "GROK_PROXY_URL", DEFAULT_GROK_PROXY_URL = "https://cli-chat-proxy.grok.com/v1", GROK_CLIENT_IDENTIFIER = "grok-shell", FALLBACK_GROK_CLIENT_VERSION = "1.0.4", LEGACY_SCOPE = "https://accounts.x.ai/sign-in", EXPIRY_SKEW_MS2, grokHomeOverride = null, claudishOAuthPathOverride = null, GROK_CHANNEL_URL = "https://x.ai/cli/stable", liveClientVersion = null, SIGN_IN_HINT, refreshInFlight = null;
|
|
32258
32334
|
var init_grok_credentials = __esm(() => {
|
|
32259
32335
|
init_grok_oauth();
|
|
32260
32336
|
EXPIRY_SKEW_MS2 = 5 * 60 * 1000;
|
|
@@ -32976,15 +33052,22 @@ function validateVertexOAuthConfig() {
|
|
|
32976
33052
|
}
|
|
32977
33053
|
return null;
|
|
32978
33054
|
}
|
|
33055
|
+
function vertexApiHost(location) {
|
|
33056
|
+
if (location === "global")
|
|
33057
|
+
return "aiplatform.googleapis.com";
|
|
33058
|
+
if (location === "eu")
|
|
33059
|
+
return "aiplatform.eu.rep.googleapis.com";
|
|
33060
|
+
return `${location}-aiplatform.googleapis.com`;
|
|
33061
|
+
}
|
|
32979
33062
|
function buildVertexOAuthEndpoint(config2, publisher, model, streaming = true) {
|
|
32980
33063
|
const method = streaming ? "streamGenerateContent" : "generateContent";
|
|
32981
33064
|
if (publisher === "google") {
|
|
32982
33065
|
const sseParam = streaming ? "?alt=sse" : "";
|
|
32983
|
-
return `https://${config2.location}
|
|
33066
|
+
return `https://${vertexApiHost(config2.location)}/v1/` + `projects/${config2.projectId}/locations/${config2.location}/` + `publishers/${publisher}/models/${model}:${method}${sseParam}`;
|
|
32984
33067
|
}
|
|
32985
33068
|
if (publisher === "mistralai") {
|
|
32986
33069
|
const mistralMethod = streaming ? "streamRawPredict" : "rawPredict";
|
|
32987
|
-
return `https://${config2.location}
|
|
33070
|
+
return `https://${vertexApiHost(config2.location)}/v1/` + `projects/${config2.projectId}/locations/${config2.location}/` + `publishers/mistralai/models/${model}:${mistralMethod}`;
|
|
32988
33071
|
}
|
|
32989
33072
|
return `https://aiplatform.googleapis.com/v1/projects/${config2.projectId}/locations/global/endpoints/openapi/chat/completions`;
|
|
32990
33073
|
}
|
|
@@ -35368,6 +35451,27 @@ function windowFromBucket(bucket) {
|
|
|
35368
35451
|
}
|
|
35369
35452
|
return window2;
|
|
35370
35453
|
}
|
|
35454
|
+
function parseModelVersion(modelId) {
|
|
35455
|
+
const match = modelId.match(/(?:^|-)(\d+(?:[.-]\d+)*)(?![0-9a-z])/i);
|
|
35456
|
+
if (!match)
|
|
35457
|
+
return;
|
|
35458
|
+
const [major, minor] = match[1].split(/[.-]/);
|
|
35459
|
+
const value = Number(`${major}.${(minor ?? "0").slice(0, 3)}`);
|
|
35460
|
+
return Number.isFinite(value) ? value : undefined;
|
|
35461
|
+
}
|
|
35462
|
+
function compareModelRecency(a, b) {
|
|
35463
|
+
const va = parseModelVersion(a.id);
|
|
35464
|
+
const vb = parseModelVersion(b.id);
|
|
35465
|
+
if (va === undefined && vb === undefined)
|
|
35466
|
+
return a.id.localeCompare(b.id);
|
|
35467
|
+
if (va === undefined)
|
|
35468
|
+
return 1;
|
|
35469
|
+
if (vb === undefined)
|
|
35470
|
+
return -1;
|
|
35471
|
+
if (vb !== va)
|
|
35472
|
+
return vb - va;
|
|
35473
|
+
return a.id.localeCompare(b.id);
|
|
35474
|
+
}
|
|
35371
35475
|
function planFromBuckets(buckets, activeModelId) {
|
|
35372
35476
|
const windows = [];
|
|
35373
35477
|
if (activeModelId) {
|
|
@@ -35383,6 +35487,7 @@ function planFromBuckets(buckets, activeModelId) {
|
|
|
35383
35487
|
if (w)
|
|
35384
35488
|
windows.push(w);
|
|
35385
35489
|
}
|
|
35490
|
+
windows.sort(compareModelRecency);
|
|
35386
35491
|
}
|
|
35387
35492
|
if (windows.length === 0)
|
|
35388
35493
|
return;
|
|
@@ -35601,6 +35706,106 @@ var init_codex = __esm(() => {
|
|
|
35601
35706
|
};
|
|
35602
35707
|
});
|
|
35603
35708
|
|
|
35709
|
+
// src/auth/quota/sources/grok.ts
|
|
35710
|
+
function periodLabel(type) {
|
|
35711
|
+
switch (type) {
|
|
35712
|
+
case "USAGE_PERIOD_TYPE_WEEKLY":
|
|
35713
|
+
return "7d";
|
|
35714
|
+
case "USAGE_PERIOD_TYPE_DAILY":
|
|
35715
|
+
return "24h";
|
|
35716
|
+
case "USAGE_PERIOD_TYPE_MONTHLY":
|
|
35717
|
+
return "30d";
|
|
35718
|
+
default:
|
|
35719
|
+
if (!type)
|
|
35720
|
+
return "period";
|
|
35721
|
+
return type.replace(/^USAGE_PERIOD_TYPE_/, "").toLowerCase() || "period";
|
|
35722
|
+
}
|
|
35723
|
+
}
|
|
35724
|
+
function windowsFromBilling(config2) {
|
|
35725
|
+
const resetsAt = config2.currentPeriod?.end ?? config2.billingPeriodEnd;
|
|
35726
|
+
const label = periodLabel(config2.currentPeriod?.type);
|
|
35727
|
+
const windows = [];
|
|
35728
|
+
for (const entry of config2.productUsage ?? []) {
|
|
35729
|
+
if (typeof entry?.usagePercent !== "number" || !entry.product)
|
|
35730
|
+
continue;
|
|
35731
|
+
const used = toUsedPct(entry.usagePercent);
|
|
35732
|
+
if (used === undefined)
|
|
35733
|
+
continue;
|
|
35734
|
+
const w = { id: entry.product, used_pct: used };
|
|
35735
|
+
if (resetsAt)
|
|
35736
|
+
w.resets_at = resetsAt;
|
|
35737
|
+
windows.push(w);
|
|
35738
|
+
}
|
|
35739
|
+
if (windows.length === 0 && typeof config2.creditUsagePercent === "number") {
|
|
35740
|
+
const used = toUsedPct(config2.creditUsagePercent);
|
|
35741
|
+
if (used !== undefined) {
|
|
35742
|
+
const w = { id: label, used_pct: used };
|
|
35743
|
+
if (resetsAt)
|
|
35744
|
+
w.resets_at = resetsAt;
|
|
35745
|
+
windows.push(w);
|
|
35746
|
+
}
|
|
35747
|
+
}
|
|
35748
|
+
return windows;
|
|
35749
|
+
}
|
|
35750
|
+
async function fetchPlan2() {
|
|
35751
|
+
try {
|
|
35752
|
+
const [token, version2] = await Promise.all([
|
|
35753
|
+
resolveGrokAccessToken(),
|
|
35754
|
+
resolveGrokClientVersion()
|
|
35755
|
+
]);
|
|
35756
|
+
const res = await fetch(`${readGrokProxyUrl()}${BILLING_PATH}`, {
|
|
35757
|
+
method: "GET",
|
|
35758
|
+
headers: grokAuthHeaders(token, version2)
|
|
35759
|
+
});
|
|
35760
|
+
if (!res.ok) {
|
|
35761
|
+
log(`[quota:grok] billing fetch failed: ${res.status}`);
|
|
35762
|
+
return;
|
|
35763
|
+
}
|
|
35764
|
+
const body = await res.json();
|
|
35765
|
+
const config2 = body?.config;
|
|
35766
|
+
if (!config2)
|
|
35767
|
+
return;
|
|
35768
|
+
const windows = windowsFromBilling(config2);
|
|
35769
|
+
if (windows.length === 0)
|
|
35770
|
+
return;
|
|
35771
|
+
return {
|
|
35772
|
+
label: "Grok Build",
|
|
35773
|
+
windows,
|
|
35774
|
+
source: "provider",
|
|
35775
|
+
observed_at: new Date().toISOString()
|
|
35776
|
+
};
|
|
35777
|
+
} catch (err) {
|
|
35778
|
+
log(`[quota:grok] billing fetch error: ${err}`);
|
|
35779
|
+
return;
|
|
35780
|
+
}
|
|
35781
|
+
}
|
|
35782
|
+
var BILLING_PATH = "/billing?format=credits", grokQuotaAdapter;
|
|
35783
|
+
var init_grok = __esm(() => {
|
|
35784
|
+
init_logger();
|
|
35785
|
+
init_grok_credentials();
|
|
35786
|
+
init_types2();
|
|
35787
|
+
grokQuotaAdapter = {
|
|
35788
|
+
providerId: "grok-subscription",
|
|
35789
|
+
label: "Grok Build",
|
|
35790
|
+
capability() {
|
|
35791
|
+
return { kind: "endpoint" };
|
|
35792
|
+
},
|
|
35793
|
+
isAvailable() {
|
|
35794
|
+
try {
|
|
35795
|
+
return hasGrokCredentials();
|
|
35796
|
+
} catch {
|
|
35797
|
+
return false;
|
|
35798
|
+
}
|
|
35799
|
+
},
|
|
35800
|
+
poll(_ctx) {
|
|
35801
|
+
return fetchPlan2();
|
|
35802
|
+
},
|
|
35803
|
+
fetchExplicit(_ctx) {
|
|
35804
|
+
return fetchPlan2();
|
|
35805
|
+
}
|
|
35806
|
+
};
|
|
35807
|
+
});
|
|
35808
|
+
|
|
35604
35809
|
// src/auth/quota/registry.ts
|
|
35605
35810
|
function unsupported(providerId, label, evidence) {
|
|
35606
35811
|
return {
|
|
@@ -35624,6 +35829,7 @@ var PROBED_ON = "2026-08-05", NO_SURFACE, ADAPTERS, BY_ID;
|
|
|
35624
35829
|
var init_registry = __esm(() => {
|
|
35625
35830
|
init_antigravity2();
|
|
35626
35831
|
init_codex();
|
|
35832
|
+
init_grok();
|
|
35627
35833
|
NO_SURFACE = [
|
|
35628
35834
|
{
|
|
35629
35835
|
id: "glm-coding",
|
|
@@ -35753,6 +35959,7 @@ var init_registry = __esm(() => {
|
|
|
35753
35959
|
ADAPTERS = [
|
|
35754
35960
|
codexQuotaAdapter,
|
|
35755
35961
|
antigravityQuotaAdapter,
|
|
35962
|
+
grokQuotaAdapter,
|
|
35756
35963
|
...NO_SURFACE.map((p) => unsupported(p.id, p.label, p.evidence))
|
|
35757
35964
|
];
|
|
35758
35965
|
BY_ID = new Map(ADAPTERS.map((a) => [a.providerId, a]));
|
|
@@ -39535,6 +39742,24 @@ var init_devin_stream_head_sniffer = __esm(() => {
|
|
|
39535
39742
|
QUOTA_MESSAGE_RE = /quota|out of credits|credit balance|billing|plan limit|exceeded your/i;
|
|
39536
39743
|
});
|
|
39537
39744
|
|
|
39745
|
+
// src/handlers/shared/model-unsupported.ts
|
|
39746
|
+
function hasModelUnsupportedWording(errorBody) {
|
|
39747
|
+
const lower = (errorBody || "").toLowerCase();
|
|
39748
|
+
return UNSUPPORTED_PHRASES.some((phrase) => lower.includes(phrase));
|
|
39749
|
+
}
|
|
39750
|
+
var UNSUPPORTED_PHRASES;
|
|
39751
|
+
var init_model_unsupported = __esm(() => {
|
|
39752
|
+
UNSUPPORTED_PHRASES = [
|
|
39753
|
+
"not supported",
|
|
39754
|
+
"unsupported model",
|
|
39755
|
+
"unsupported_model",
|
|
39756
|
+
"model not found",
|
|
39757
|
+
"model_not_found",
|
|
39758
|
+
"unknown model",
|
|
39759
|
+
"no such model"
|
|
39760
|
+
];
|
|
39761
|
+
});
|
|
39762
|
+
|
|
39538
39763
|
// src/handlers/shared/stream-head-sniffer.ts
|
|
39539
39764
|
function isRetryableStreamError(code, type, message) {
|
|
39540
39765
|
if (RETRYABLE_ERROR_CODES.has(code))
|
|
@@ -42336,7 +42561,7 @@ function getRecoveryHint(status, errorText, providerName, transportTerminal429)
|
|
|
42336
42561
|
return "Rate limited. Wait, reduce concurrency, or check plan limits.";
|
|
42337
42562
|
}
|
|
42338
42563
|
if (status === 401 || status === 403) {
|
|
42339
|
-
if (
|
|
42564
|
+
if (hasModelUnsupportedWording(errorText)) {
|
|
42340
42565
|
return "Model not supported by this provider. Verify model name.";
|
|
42341
42566
|
}
|
|
42342
42567
|
if (isQuotaExhaustionError(status, errorText)) {
|
|
@@ -42379,6 +42604,7 @@ var init_composed_handler = __esm(() => {
|
|
|
42379
42604
|
init_collect_sse_message();
|
|
42380
42605
|
init_connection_error();
|
|
42381
42606
|
init_devin_stream_head_sniffer();
|
|
42607
|
+
init_model_unsupported();
|
|
42382
42608
|
init_openai_compat();
|
|
42383
42609
|
init_quota_exhaustion();
|
|
42384
42610
|
init_stream_head_sniffer();
|
|
@@ -43036,6 +43262,27 @@ async function discoverProviderModels(providerName) {
|
|
|
43036
43262
|
_cache.set(providerName, { models: models2, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
43037
43263
|
return models2;
|
|
43038
43264
|
}
|
|
43265
|
+
if (descriptor.format === "antigravity") {
|
|
43266
|
+
const { getValidAntigravityAccessToken: getValidAntigravityAccessToken2 } = await Promise.resolve().then(() => (init_antigravity_token(), exports_antigravity_token));
|
|
43267
|
+
const { setupAntigravityUser: setupAntigravityUser2, getServedAntigravityModels: getServedAntigravityModels2 } = await Promise.resolve().then(() => (init_antigravity_user(), exports_antigravity_user));
|
|
43268
|
+
const token = await getValidAntigravityAccessToken2();
|
|
43269
|
+
if (!token) {
|
|
43270
|
+
return recordFailure({ kind: "no-credentials", provider: providerName });
|
|
43271
|
+
}
|
|
43272
|
+
const { projectId } = await setupAntigravityUser2(token);
|
|
43273
|
+
const { servedIds, meta: meta3 } = await getServedAntigravityModels2(token, projectId);
|
|
43274
|
+
if (servedIds.length === 0) {
|
|
43275
|
+
return recordFailure({ kind: "empty-roster", provider: providerName });
|
|
43276
|
+
}
|
|
43277
|
+
const models2 = servedIds.map((id) => {
|
|
43278
|
+
const m = meta3[id];
|
|
43279
|
+
return m?.contextWindow ? { id, contextWindow: m.contextWindow } : { id };
|
|
43280
|
+
});
|
|
43281
|
+
_failures.delete(providerName);
|
|
43282
|
+
log(`[model-discovery:${providerName}] discovered ${models2.length} models`);
|
|
43283
|
+
_cache.set(providerName, { models: models2, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
43284
|
+
return models2;
|
|
43285
|
+
}
|
|
43039
43286
|
if (descriptor.format === "ollama-tags") {
|
|
43040
43287
|
const { fetchOllamaModels: fetchOllamaModels2 } = await Promise.resolve().then(() => exports_ollama_discovery);
|
|
43041
43288
|
const installed = await fetchOllamaModels2({ enrichCapabilities: false });
|
|
@@ -43077,6 +43324,11 @@ async function discoverProviderModels(providerName) {
|
|
|
43077
43324
|
return recordFailure({ kind: "no-credentials", provider: providerName, endpoint });
|
|
43078
43325
|
}
|
|
43079
43326
|
}
|
|
43327
|
+
headers = {
|
|
43328
|
+
"User-Agent": `claudish/${VERSION}`,
|
|
43329
|
+
...def.headers ?? {},
|
|
43330
|
+
...headers
|
|
43331
|
+
};
|
|
43080
43332
|
let response;
|
|
43081
43333
|
try {
|
|
43082
43334
|
response = await fetch(endpoint, {
|
|
@@ -44754,6 +45006,7 @@ var init_default_routing_rules = __esm(() => {
|
|
|
44754
45006
|
"ministral-*": ["mistralai", "openrouter"],
|
|
44755
45007
|
"codestral-*": ["mistralai", "openrouter"],
|
|
44756
45008
|
"labs-*": ["mistralai"],
|
|
45009
|
+
"swe-*": ["devin"],
|
|
44757
45010
|
fugu: ["sakana-subscription", "sakana"],
|
|
44758
45011
|
"fugu-*": ["sakana-subscription", "sakana"],
|
|
44759
45012
|
"*-zen": ["opencode-zen"],
|
|
@@ -46169,6 +46422,15 @@ function normalizePricingDisplay(raw) {
|
|
|
46169
46422
|
return "FREE";
|
|
46170
46423
|
return pricing;
|
|
46171
46424
|
}
|
|
46425
|
+
function formatListingPrice(entry, opts) {
|
|
46426
|
+
const rate = normalizePricingDisplay(entry.pricing?.average);
|
|
46427
|
+
if (rate !== "N/A")
|
|
46428
|
+
return rate;
|
|
46429
|
+
const plan = entry.subscription?.plan;
|
|
46430
|
+
if (!plan)
|
|
46431
|
+
return "N/A";
|
|
46432
|
+
return opts?.compact ? "SUB" : `SUB (${plan})`;
|
|
46433
|
+
}
|
|
46172
46434
|
function computeQuickPicks(primaries) {
|
|
46173
46435
|
if (primaries.length === 0) {
|
|
46174
46436
|
return {
|
|
@@ -46403,6 +46665,412 @@ async function isPortAvailable(port) {
|
|
|
46403
46665
|
}
|
|
46404
46666
|
var init_port_manager = () => {};
|
|
46405
46667
|
|
|
46668
|
+
// src/providers/probe-live.ts
|
|
46669
|
+
function effortForProvider(provider) {
|
|
46670
|
+
return MINIMAL_EFFORT_UNSUPPORTED.has(provider) ? "low" : "minimal";
|
|
46671
|
+
}
|
|
46672
|
+
async function probeLink(proxyUrl, link, timeoutMs) {
|
|
46673
|
+
const isOAuth = OAUTH_PROVIDERS2.has(link.provider);
|
|
46674
|
+
if (!link.hasCredentials && !isOAuth) {
|
|
46675
|
+
return {
|
|
46676
|
+
state: "key-missing",
|
|
46677
|
+
latencyMs: 0,
|
|
46678
|
+
errorMessage: link.credentialHint
|
|
46679
|
+
};
|
|
46680
|
+
}
|
|
46681
|
+
const startedAt = Date.now();
|
|
46682
|
+
let response;
|
|
46683
|
+
try {
|
|
46684
|
+
response = await fetch(`${proxyUrl}/v1/messages`, {
|
|
46685
|
+
method: "POST",
|
|
46686
|
+
headers: {
|
|
46687
|
+
"Content-Type": "application/json"
|
|
46688
|
+
},
|
|
46689
|
+
body: JSON.stringify({
|
|
46690
|
+
model: link.modelSpec,
|
|
46691
|
+
system: "You are a helpful assistant.",
|
|
46692
|
+
messages: [{ role: "user", content: PROBE_PROMPT }],
|
|
46693
|
+
max_tokens: PROBE_MAX_TOKENS,
|
|
46694
|
+
output_config: { effort: effortForProvider(link.provider) },
|
|
46695
|
+
stream: true
|
|
46696
|
+
}),
|
|
46697
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
46698
|
+
});
|
|
46699
|
+
} catch (e) {
|
|
46700
|
+
const latencyMs = Date.now() - startedAt;
|
|
46701
|
+
const name = e?.name || "";
|
|
46702
|
+
const msg2 = String(e?.message || e);
|
|
46703
|
+
if (name === "TimeoutError" || name === "AbortError" || /timeout/i.test(msg2)) {
|
|
46704
|
+
return { state: "timeout", latencyMs, errorMessage: msg2 };
|
|
46705
|
+
}
|
|
46706
|
+
return { state: "network-error", latencyMs, errorMessage: msg2 };
|
|
46707
|
+
}
|
|
46708
|
+
const ttfbMs = Date.now() - startedAt;
|
|
46709
|
+
if (!response.ok) {
|
|
46710
|
+
const body = await safeReadBody(response);
|
|
46711
|
+
return annotateOAuthHint(classifyHttpError(response.status, body, ttfbMs), link.provider, isOAuth);
|
|
46712
|
+
}
|
|
46713
|
+
const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
|
|
46714
|
+
const totalMs = Date.now() - startedAt;
|
|
46715
|
+
let timing2;
|
|
46716
|
+
if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
|
|
46717
|
+
const ttftMs = streamResult.ttftMs;
|
|
46718
|
+
const tokens = streamResult.tokens ?? 0;
|
|
46719
|
+
const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
|
|
46720
|
+
const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
|
|
46721
|
+
timing2 = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
|
|
46722
|
+
}
|
|
46723
|
+
const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
|
|
46724
|
+
return annotateOAuthHint({
|
|
46725
|
+
...rest,
|
|
46726
|
+
latencyMs: totalMs,
|
|
46727
|
+
timing: timing2
|
|
46728
|
+
}, link.provider, isOAuth);
|
|
46729
|
+
}
|
|
46730
|
+
function annotateOAuthHint(result, provider, isOAuth) {
|
|
46731
|
+
if (!isOAuth)
|
|
46732
|
+
return result;
|
|
46733
|
+
if (result.state === "live")
|
|
46734
|
+
return result;
|
|
46735
|
+
const loginCommand = provider === "antigravity" ? "claudish login antigravity" : provider === "vertex" ? "gcloud auth application-default login" : provider === "devin" ? "devin login" : undefined;
|
|
46736
|
+
if (!loginCommand)
|
|
46737
|
+
return result;
|
|
46738
|
+
if (result.httpStatus === 403)
|
|
46739
|
+
return result;
|
|
46740
|
+
const looksLikeAuthFailure = result.state === "auth-failed" || /auth|token|login|credential|unauthor/i.test(result.errorMessage || "");
|
|
46741
|
+
if (!looksLikeAuthFailure)
|
|
46742
|
+
return result;
|
|
46743
|
+
return {
|
|
46744
|
+
...result,
|
|
46745
|
+
state: "auth-failed",
|
|
46746
|
+
actionHint: `run: ${loginCommand}`
|
|
46747
|
+
};
|
|
46748
|
+
}
|
|
46749
|
+
async function safeReadBody(response) {
|
|
46750
|
+
try {
|
|
46751
|
+
const text = await response.text();
|
|
46752
|
+
return text.slice(0, 500);
|
|
46753
|
+
} catch {
|
|
46754
|
+
return "";
|
|
46755
|
+
}
|
|
46756
|
+
}
|
|
46757
|
+
function extractUpstreamStatus(body) {
|
|
46758
|
+
if (!body)
|
|
46759
|
+
return;
|
|
46760
|
+
try {
|
|
46761
|
+
const parsed = JSON.parse(body);
|
|
46762
|
+
const status = parsed?.error?.upstream_status;
|
|
46763
|
+
return typeof status === "number" ? status : undefined;
|
|
46764
|
+
} catch {
|
|
46765
|
+
return;
|
|
46766
|
+
}
|
|
46767
|
+
}
|
|
46768
|
+
function extractErrorType(body) {
|
|
46769
|
+
if (!body)
|
|
46770
|
+
return;
|
|
46771
|
+
try {
|
|
46772
|
+
const parsed = JSON.parse(body);
|
|
46773
|
+
const t = parsed?.error?.type;
|
|
46774
|
+
return typeof t === "string" ? t : undefined;
|
|
46775
|
+
} catch {
|
|
46776
|
+
return;
|
|
46777
|
+
}
|
|
46778
|
+
}
|
|
46779
|
+
function classifyHttpError(status, body, latencyMs) {
|
|
46780
|
+
const lowered = body.toLowerCase();
|
|
46781
|
+
if (extractErrorType(body) === "connection_error") {
|
|
46782
|
+
return {
|
|
46783
|
+
state: "network-error",
|
|
46784
|
+
latencyMs,
|
|
46785
|
+
httpStatus: status,
|
|
46786
|
+
errorMessage: extractErrorMessage(body) || "Cannot reach provider"
|
|
46787
|
+
};
|
|
46788
|
+
}
|
|
46789
|
+
const upstream = status === 400 ? extractUpstreamStatus(body) : undefined;
|
|
46790
|
+
if (status === 401 || status === 403 || upstream === 401 || upstream === 403) {
|
|
46791
|
+
const authStatus = upstream ?? status;
|
|
46792
|
+
if (hasModelUnsupportedWording(body)) {
|
|
46793
|
+
return {
|
|
46794
|
+
state: "model-not-found",
|
|
46795
|
+
latencyMs,
|
|
46796
|
+
httpStatus: authStatus,
|
|
46797
|
+
errorMessage: extractErrorMessage(body) || `HTTP ${authStatus}`
|
|
46798
|
+
};
|
|
46799
|
+
}
|
|
46800
|
+
return {
|
|
46801
|
+
state: "auth-failed",
|
|
46802
|
+
latencyMs,
|
|
46803
|
+
httpStatus: authStatus,
|
|
46804
|
+
errorMessage: extractErrorMessage(body) || `HTTP ${authStatus}`
|
|
46805
|
+
};
|
|
46806
|
+
}
|
|
46807
|
+
if (status === 404 || /model[_ ]not[_ ]found|no such model|unknown model/.test(lowered)) {
|
|
46808
|
+
return {
|
|
46809
|
+
state: "model-not-found",
|
|
46810
|
+
latencyMs,
|
|
46811
|
+
httpStatus: status,
|
|
46812
|
+
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
46813
|
+
};
|
|
46814
|
+
}
|
|
46815
|
+
if (status === 429) {
|
|
46816
|
+
return {
|
|
46817
|
+
state: "rate-limited",
|
|
46818
|
+
latencyMs,
|
|
46819
|
+
httpStatus: status,
|
|
46820
|
+
errorMessage: extractErrorMessage(body) || "Rate limited"
|
|
46821
|
+
};
|
|
46822
|
+
}
|
|
46823
|
+
if (upstream === 429 || status === 402) {
|
|
46824
|
+
return {
|
|
46825
|
+
state: "out-of-credit",
|
|
46826
|
+
latencyMs,
|
|
46827
|
+
httpStatus: upstream ?? status,
|
|
46828
|
+
errorMessage: extractErrorMessage(body) || "Out of credit \u2014 account balance or plan exhausted"
|
|
46829
|
+
};
|
|
46830
|
+
}
|
|
46831
|
+
if (status >= 500) {
|
|
46832
|
+
return {
|
|
46833
|
+
state: "server-error",
|
|
46834
|
+
latencyMs,
|
|
46835
|
+
httpStatus: status,
|
|
46836
|
+
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
46837
|
+
};
|
|
46838
|
+
}
|
|
46839
|
+
return {
|
|
46840
|
+
state: "error",
|
|
46841
|
+
latencyMs,
|
|
46842
|
+
httpStatus: status,
|
|
46843
|
+
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
46844
|
+
};
|
|
46845
|
+
}
|
|
46846
|
+
function extractErrorMessage(body) {
|
|
46847
|
+
if (!body)
|
|
46848
|
+
return;
|
|
46849
|
+
try {
|
|
46850
|
+
const parsed = JSON.parse(body);
|
|
46851
|
+
const msg2 = parsed?.error?.message || parsed?.error?.error?.message || parsed?.message || parsed?.detail;
|
|
46852
|
+
if (typeof msg2 === "string" && msg2.length > 0) {
|
|
46853
|
+
return msg2.length > 160 ? `${msg2.slice(0, 157)}...` : msg2;
|
|
46854
|
+
}
|
|
46855
|
+
} catch {}
|
|
46856
|
+
const trimmed2 = body.trim();
|
|
46857
|
+
if (!trimmed2)
|
|
46858
|
+
return;
|
|
46859
|
+
return trimmed2.length > 160 ? `${trimmed2.slice(0, 157)}...` : trimmed2;
|
|
46860
|
+
}
|
|
46861
|
+
async function consumeProbeStream(response, timeoutMs, startedAt) {
|
|
46862
|
+
const body = response.body;
|
|
46863
|
+
if (!body) {
|
|
46864
|
+
return { state: "error", errorMessage: "empty response body" };
|
|
46865
|
+
}
|
|
46866
|
+
const reader = body.getReader();
|
|
46867
|
+
const decoder = new TextDecoder;
|
|
46868
|
+
let buffered = "";
|
|
46869
|
+
const deadline = Date.now() + timeoutMs;
|
|
46870
|
+
let ttftMs;
|
|
46871
|
+
let sawContent = false;
|
|
46872
|
+
let textChars = 0;
|
|
46873
|
+
let reportedTokens;
|
|
46874
|
+
let stopReason;
|
|
46875
|
+
let errorVerdict = null;
|
|
46876
|
+
let completed = false;
|
|
46877
|
+
try {
|
|
46878
|
+
while (Date.now() < deadline) {
|
|
46879
|
+
const { value, done } = await reader.read();
|
|
46880
|
+
if (done) {
|
|
46881
|
+
completed = true;
|
|
46882
|
+
break;
|
|
46883
|
+
}
|
|
46884
|
+
buffered += decoder.decode(value, { stream: true });
|
|
46885
|
+
const events = buffered.split(`
|
|
46886
|
+
|
|
46887
|
+
`);
|
|
46888
|
+
buffered = events.pop() ?? "";
|
|
46889
|
+
for (const event of events) {
|
|
46890
|
+
const verdict = interpretSseEvent(event);
|
|
46891
|
+
if (verdict && typeof verdict === "object" && verdict.state !== "live") {
|
|
46892
|
+
errorVerdict = verdict;
|
|
46893
|
+
break;
|
|
46894
|
+
}
|
|
46895
|
+
const acct = accountStreamEvent(event);
|
|
46896
|
+
if (acct.contentDelta) {
|
|
46897
|
+
if (ttftMs === undefined)
|
|
46898
|
+
ttftMs = Date.now() - startedAt;
|
|
46899
|
+
sawContent = true;
|
|
46900
|
+
}
|
|
46901
|
+
if (acct.textChars)
|
|
46902
|
+
textChars += acct.textChars;
|
|
46903
|
+
if (acct.outputTokens !== undefined)
|
|
46904
|
+
reportedTokens = acct.outputTokens;
|
|
46905
|
+
if (acct.stopReason)
|
|
46906
|
+
stopReason = acct.stopReason;
|
|
46907
|
+
}
|
|
46908
|
+
if (errorVerdict)
|
|
46909
|
+
break;
|
|
46910
|
+
}
|
|
46911
|
+
} catch (e) {
|
|
46912
|
+
if (!sawContent) {
|
|
46913
|
+
return { state: "network-error", errorMessage: String(e?.message || e) };
|
|
46914
|
+
}
|
|
46915
|
+
} finally {
|
|
46916
|
+
try {
|
|
46917
|
+
await reader.cancel();
|
|
46918
|
+
} catch {}
|
|
46919
|
+
}
|
|
46920
|
+
if (errorVerdict)
|
|
46921
|
+
return errorVerdict;
|
|
46922
|
+
if (sawContent) {
|
|
46923
|
+
const tokens = reportedTokens ?? Math.max(1, Math.round(textChars / 4));
|
|
46924
|
+
return { state: "live", ttftMs, tokens, truncated: !completed };
|
|
46925
|
+
}
|
|
46926
|
+
const truncationReason = stopReason === "max_tokens" || stopReason === "length" ? stopReason : undefined;
|
|
46927
|
+
if (truncationReason || reportedTokens !== undefined && reportedTokens >= PROBE_MAX_TOKENS) {
|
|
46928
|
+
const cause = truncationReason ? `finish: ${truncationReason}` : `${reportedTokens} tokens consumed, none visible`;
|
|
46929
|
+
return {
|
|
46930
|
+
state: "error",
|
|
46931
|
+
errorMessage: `no visible output within probe budget (${cause})`
|
|
46932
|
+
};
|
|
46933
|
+
}
|
|
46934
|
+
return { state: "error", errorMessage: "stream ended without content" };
|
|
46935
|
+
}
|
|
46936
|
+
function accountStreamEvent(rawEvent) {
|
|
46937
|
+
let dataPayload = "";
|
|
46938
|
+
for (const line of rawEvent.split(`
|
|
46939
|
+
`)) {
|
|
46940
|
+
if (line.startsWith("data:"))
|
|
46941
|
+
dataPayload += line.slice(5).trim();
|
|
46942
|
+
}
|
|
46943
|
+
if (!dataPayload || dataPayload === "[DONE]") {
|
|
46944
|
+
return { contentDelta: false, textChars: 0 };
|
|
46945
|
+
}
|
|
46946
|
+
let parsed;
|
|
46947
|
+
try {
|
|
46948
|
+
parsed = JSON.parse(dataPayload);
|
|
46949
|
+
} catch {
|
|
46950
|
+
return { contentDelta: false, textChars: 0 };
|
|
46951
|
+
}
|
|
46952
|
+
let textChars = 0;
|
|
46953
|
+
let contentDelta = false;
|
|
46954
|
+
const text = parsed?.delta?.text ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.delta?.content : undefined);
|
|
46955
|
+
if (typeof text === "string" && text.length > 0) {
|
|
46956
|
+
contentDelta = true;
|
|
46957
|
+
textChars = text.length;
|
|
46958
|
+
} else if (parsed?.type === "content_block_delta" || parsed?.type === "content_block_start") {
|
|
46959
|
+
contentDelta = true;
|
|
46960
|
+
}
|
|
46961
|
+
const outputTokens = parsed?.usage?.output_tokens ?? parsed?.message?.usage?.output_tokens ?? parsed?.usage?.completion_tokens;
|
|
46962
|
+
const stopReason = parsed?.delta?.stop_reason ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.finish_reason : undefined);
|
|
46963
|
+
return {
|
|
46964
|
+
contentDelta,
|
|
46965
|
+
textChars,
|
|
46966
|
+
outputTokens: typeof outputTokens === "number" ? outputTokens : undefined,
|
|
46967
|
+
stopReason: typeof stopReason === "string" ? stopReason : undefined
|
|
46968
|
+
};
|
|
46969
|
+
}
|
|
46970
|
+
function interpretSseEvent(rawEvent) {
|
|
46971
|
+
const lines = rawEvent.split(`
|
|
46972
|
+
`);
|
|
46973
|
+
let eventType = "";
|
|
46974
|
+
let dataPayload = "";
|
|
46975
|
+
for (const line of lines) {
|
|
46976
|
+
if (line.startsWith("event:"))
|
|
46977
|
+
eventType = line.slice(6).trim();
|
|
46978
|
+
else if (line.startsWith("data:"))
|
|
46979
|
+
dataPayload += line.slice(5).trim();
|
|
46980
|
+
}
|
|
46981
|
+
if (!dataPayload)
|
|
46982
|
+
return null;
|
|
46983
|
+
if (dataPayload === "[DONE]")
|
|
46984
|
+
return null;
|
|
46985
|
+
let parsed;
|
|
46986
|
+
try {
|
|
46987
|
+
parsed = JSON.parse(dataPayload);
|
|
46988
|
+
} catch {
|
|
46989
|
+
return null;
|
|
46990
|
+
}
|
|
46991
|
+
if (parsed?.type === "error" || eventType === "error" || parsed?.error) {
|
|
46992
|
+
const message = parsed?.error?.message || parsed?.error?.error?.message || parsed?.message || "provider returned error event";
|
|
46993
|
+
const status = parsed?.error?.status || parsed?.status;
|
|
46994
|
+
if (typeof status === "number") {
|
|
46995
|
+
return {
|
|
46996
|
+
state: status === 401 || status === 403 ? "auth-failed" : "error",
|
|
46997
|
+
httpStatus: status,
|
|
46998
|
+
errorMessage: message
|
|
46999
|
+
};
|
|
47000
|
+
}
|
|
47001
|
+
return { state: "error", errorMessage: message };
|
|
47002
|
+
}
|
|
47003
|
+
if (isContentEvent(parsed, eventType)) {
|
|
47004
|
+
return "live";
|
|
47005
|
+
}
|
|
47006
|
+
return null;
|
|
47007
|
+
}
|
|
47008
|
+
function isContentEvent(parsed, eventType) {
|
|
47009
|
+
if (eventType === "content_block_start" || eventType === "content_block_delta")
|
|
47010
|
+
return true;
|
|
47011
|
+
if (eventType === "message_start")
|
|
47012
|
+
return true;
|
|
47013
|
+
if (parsed?.type === "content_block_start")
|
|
47014
|
+
return true;
|
|
47015
|
+
if (parsed?.type === "content_block_delta")
|
|
47016
|
+
return true;
|
|
47017
|
+
if (parsed?.type === "message_start")
|
|
47018
|
+
return true;
|
|
47019
|
+
if (parsed?.type === "message_delta")
|
|
47020
|
+
return true;
|
|
47021
|
+
if (Array.isArray(parsed?.choices) && parsed.choices.length > 0) {
|
|
47022
|
+
const choice = parsed.choices[0];
|
|
47023
|
+
if (choice?.delta || choice?.message || choice?.text || choice?.finish_reason)
|
|
47024
|
+
return true;
|
|
47025
|
+
}
|
|
47026
|
+
if (parsed?.candidates)
|
|
47027
|
+
return true;
|
|
47028
|
+
return false;
|
|
47029
|
+
}
|
|
47030
|
+
function withDetail(base, message) {
|
|
47031
|
+
return message ? `${base} \u2014 ${message}` : base;
|
|
47032
|
+
}
|
|
47033
|
+
function describeProbeState(result) {
|
|
47034
|
+
const status = result.httpStatus ?? "";
|
|
47035
|
+
const latency = result.latencyMs ? ` \xB7 ${result.latencyMs}ms` : "";
|
|
47036
|
+
switch (result.state) {
|
|
47037
|
+
case "live":
|
|
47038
|
+
return `live \xB7 ${result.latencyMs}ms`;
|
|
47039
|
+
case "key-missing":
|
|
47040
|
+
return result.errorMessage ? `missing (${result.errorMessage})` : "missing";
|
|
47041
|
+
case "auth-failed":
|
|
47042
|
+
return withDetail(`auth failed \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
47043
|
+
case "model-not-found":
|
|
47044
|
+
return withDetail(`model not found \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
47045
|
+
case "rate-limited":
|
|
47046
|
+
return withDetail(`rate limited \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
47047
|
+
case "out-of-credit":
|
|
47048
|
+
return withDetail(`out of credit \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
47049
|
+
case "server-error":
|
|
47050
|
+
return withDetail(`server error \xB7 ${status} \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
47051
|
+
case "timeout":
|
|
47052
|
+
return withDetail(`timeout \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
47053
|
+
case "network-error":
|
|
47054
|
+
return withDetail(`network error \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
47055
|
+
case "error": {
|
|
47056
|
+
const base = `error${result.httpStatus ? ` \xB7 ${result.httpStatus}` : ""}${latency}`;
|
|
47057
|
+
return withDetail(base, result.errorMessage);
|
|
47058
|
+
}
|
|
47059
|
+
}
|
|
47060
|
+
}
|
|
47061
|
+
function isReadyState(state) {
|
|
47062
|
+
return state === "live";
|
|
47063
|
+
}
|
|
47064
|
+
function isFailureState(state) {
|
|
47065
|
+
return state === "auth-failed" || state === "model-not-found" || state === "rate-limited" || state === "out-of-credit" || state === "server-error" || state === "timeout" || state === "network-error" || state === "error";
|
|
47066
|
+
}
|
|
47067
|
+
var STREAM_MS_FLOOR = 50, OAUTH_PROVIDERS2, PROBE_PROMPT = "Count from one to twenty in words, one per line.", PROBE_MAX_TOKENS = 512, MINIMAL_EFFORT_UNSUPPORTED;
|
|
47068
|
+
var init_probe_live = __esm(() => {
|
|
47069
|
+
init_model_unsupported();
|
|
47070
|
+
OAUTH_PROVIDERS2 = new Set(["vertex", "antigravity", "devin"]);
|
|
47071
|
+
MINIMAL_EFFORT_UNSUPPORTED = new Set(["native-anthropic", "anthropic"]);
|
|
47072
|
+
});
|
|
47073
|
+
|
|
46406
47074
|
// ../../node_modules/.bun/hono@4.10.6/node_modules/hono/dist/compose.js
|
|
46407
47075
|
var compose = (middleware, onError, onNotFound) => {
|
|
46408
47076
|
return (context, next) => {
|
|
@@ -52852,7 +53520,7 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
|
52852
53520
|
};
|
|
52853
53521
|
const renderGroup = (group) => {
|
|
52854
53522
|
const m = group.primary;
|
|
52855
|
-
const pricing =
|
|
53523
|
+
const pricing = formatListingPrice(m);
|
|
52856
53524
|
const ctx = m.context || "N/A";
|
|
52857
53525
|
const caps = [];
|
|
52858
53526
|
if (m.supportsTools)
|
|
@@ -53057,6 +53725,112 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
53057
53725
|
return { content: [{ type: "text", text: output }] };
|
|
53058
53726
|
}
|
|
53059
53727
|
});
|
|
53728
|
+
tools.push({
|
|
53729
|
+
name: "preflight",
|
|
53730
|
+
description: "Check a roster of models BEFORE spending a run on it. For each model: which provider " + "will actually serve it, whether that hop is covered by a SUBSCRIPTION or billed per " + "token, and whether it is reachable right now. Call this before `team` or a batch of " + "`create_session` calls \u2014 a dead or unexpectedly-metered model is then caught while " + "the roster can still be adjusted, instead of costing a slot minutes into the run.",
|
|
53731
|
+
inputSchema: {
|
|
53732
|
+
type: "object",
|
|
53733
|
+
properties: {
|
|
53734
|
+
models: {
|
|
53735
|
+
type: "array",
|
|
53736
|
+
items: { type: "string" },
|
|
53737
|
+
description: "Model ids to check \u2014 bare (`glm-5.2`) or explicit (`dv@swe-1.7`). Bare names go " + "through the SAME routing rules and credential filter a real run would use, so " + "the provider reported here is the provider that would serve it."
|
|
53738
|
+
},
|
|
53739
|
+
probe: {
|
|
53740
|
+
type: "boolean",
|
|
53741
|
+
description: "Send a real short request to each resolved route (default true). Set false for " + "a routing/billing answer only \u2014 far faster, but it cannot tell you the provider " + "is actually reachable, which is the failure this tool exists to catch."
|
|
53742
|
+
},
|
|
53743
|
+
timeout_ms: {
|
|
53744
|
+
type: "number",
|
|
53745
|
+
description: "Per-model probe timeout in ms (default 20000)."
|
|
53746
|
+
}
|
|
53747
|
+
},
|
|
53748
|
+
required: ["models"]
|
|
53749
|
+
},
|
|
53750
|
+
group: "agentic",
|
|
53751
|
+
heartbeat: true,
|
|
53752
|
+
handler: async (args, ctx) => {
|
|
53753
|
+
const models = Array.isArray(args.models) ? args.models : [];
|
|
53754
|
+
if (models.length === 0) {
|
|
53755
|
+
return {
|
|
53756
|
+
content: [{ type: "text", text: "preflight: no models given." }],
|
|
53757
|
+
isError: true
|
|
53758
|
+
};
|
|
53759
|
+
}
|
|
53760
|
+
const doProbe = args.probe !== false;
|
|
53761
|
+
const timeoutMs = typeof args.timeout_ms === "number" ? args.timeout_ms : 20000;
|
|
53762
|
+
const proxy = doProbe ? await getProxy() : null;
|
|
53763
|
+
const rows = [];
|
|
53764
|
+
const readyModels = [];
|
|
53765
|
+
const failedModels = [];
|
|
53766
|
+
let subCount = 0;
|
|
53767
|
+
let meteredCount = 0;
|
|
53768
|
+
for (const model of models) {
|
|
53769
|
+
ctx.reportProgress(`preflight: ${model}`);
|
|
53770
|
+
let plan;
|
|
53771
|
+
try {
|
|
53772
|
+
plan = await route(model);
|
|
53773
|
+
} catch (err) {
|
|
53774
|
+
failedModels.push(model);
|
|
53775
|
+
rows.push(`| \`${model}\` | \u2014 | \u2014 | \u274C route error | ${err instanceof Error ? err.message : String(err)} |`);
|
|
53776
|
+
continue;
|
|
53777
|
+
}
|
|
53778
|
+
if (plan.kind === "no-route") {
|
|
53779
|
+
failedModels.push(model);
|
|
53780
|
+
rows.push(`| \`${model}\` | \u2014 | \u2014 | \u274C no route | ${plan.reason} |`);
|
|
53781
|
+
continue;
|
|
53782
|
+
}
|
|
53783
|
+
const primary = plan.primary;
|
|
53784
|
+
const billing = isLocalProviderName(primary.provider) ? "local" : isSubscriptionProvider(primary.provider) ? "SUB" : "metered";
|
|
53785
|
+
if (billing === "SUB")
|
|
53786
|
+
subCount++;
|
|
53787
|
+
else if (billing === "metered")
|
|
53788
|
+
meteredCount++;
|
|
53789
|
+
let status = "not probed";
|
|
53790
|
+
let ok = true;
|
|
53791
|
+
if (proxy) {
|
|
53792
|
+
try {
|
|
53793
|
+
const result = await probeLink(proxy.url, {
|
|
53794
|
+
provider: primary.provider,
|
|
53795
|
+
modelSpec: primary.modelSpec,
|
|
53796
|
+
hasCredentials: true
|
|
53797
|
+
}, timeoutMs);
|
|
53798
|
+
ok = isReadyState(result.state);
|
|
53799
|
+
status = ok ? `\u2705 ${result.state}` : `\u274C ${result.state}${result.errorMessage ? ` \u2014 ${result.errorMessage}` : ""}`;
|
|
53800
|
+
} catch (err) {
|
|
53801
|
+
ok = false;
|
|
53802
|
+
status = `\u274C probe error \u2014 ${err instanceof Error ? err.message : String(err)}`;
|
|
53803
|
+
}
|
|
53804
|
+
}
|
|
53805
|
+
if (ok)
|
|
53806
|
+
readyModels.push(model);
|
|
53807
|
+
else
|
|
53808
|
+
failedModels.push(model);
|
|
53809
|
+
const fallbacks = plan.fallbacks.length > 0 ? ` (+${plan.fallbacks.length} fallback)` : "";
|
|
53810
|
+
rows.push(`| \`${model}\` | ${primary.displayName}${fallbacks} | ${billing} | ${status} | \`${primary.modelSpec}\` |`);
|
|
53811
|
+
}
|
|
53812
|
+
const lines = [
|
|
53813
|
+
`# Preflight \u2014 ${models.length} model${models.length === 1 ? "" : "s"}`,
|
|
53814
|
+
"",
|
|
53815
|
+
`**Ready: ${readyModels.length}** \xB7 **Failed: ${failedModels.length}** \xB7 ` + `subscription: ${subCount} \xB7 metered: ${meteredCount}`,
|
|
53816
|
+
"",
|
|
53817
|
+
"| Model | Provider | Billing | Status | Wire id |",
|
|
53818
|
+
"|---|---|---|---|---|",
|
|
53819
|
+
...rows
|
|
53820
|
+
];
|
|
53821
|
+
if (failedModels.length > 0) {
|
|
53822
|
+
lines.push("", `\u26A0\uFE0F Drop or replace before running: ${failedModels.map((m) => `\`${m}\``).join(", ")}`);
|
|
53823
|
+
}
|
|
53824
|
+
if (meteredCount > 0) {
|
|
53825
|
+
lines.push("", `\uD83D\uDCB8 ${meteredCount} model${meteredCount === 1 ? "" : "s"} will be billed PER TOKEN. ` + "A bare name can land on a metered provider when the subscription that covers it " + "has no credential configured \u2014 name the provider explicitly to pin it.");
|
|
53826
|
+
}
|
|
53827
|
+
if (!doProbe) {
|
|
53828
|
+
lines.push("", "\u2139\uFE0F `probe: false` \u2014 routing and billing only. Reachability was NOT checked.");
|
|
53829
|
+
}
|
|
53830
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
53831
|
+
`) }] };
|
|
53832
|
+
}
|
|
53833
|
+
});
|
|
53060
53834
|
tools.push({
|
|
53061
53835
|
name: "team",
|
|
53062
53836
|
description: "Run AI models on a task with anonymized outputs and optional blind judging. Modes: 'run' (execute models), 'judge' (blind-vote on existing outputs), 'run-and-judge' (full pipeline), 'status' (check progress).",
|
|
@@ -53651,11 +54425,15 @@ var init_mcp_server = __esm(() => {
|
|
|
53651
54425
|
init_prehydrate();
|
|
53652
54426
|
init_diagnostics();
|
|
53653
54427
|
init_channel();
|
|
54428
|
+
init_remote_provider_types();
|
|
53654
54429
|
init_progress_heartbeat();
|
|
53655
54430
|
init_model_loader();
|
|
53656
54431
|
init_port_manager();
|
|
54432
|
+
init_model_parser();
|
|
53657
54433
|
init_onepassword();
|
|
54434
|
+
init_probe_live();
|
|
53658
54435
|
init_provider_definitions();
|
|
54436
|
+
init_routing_rules();
|
|
53659
54437
|
init_proxy_server();
|
|
53660
54438
|
init_redact();
|
|
53661
54439
|
init_team_orchestrator();
|
|
@@ -67277,12 +68055,16 @@ function renderPlan(adapter, plan) {
|
|
|
67277
68055
|
console.log("");
|
|
67278
68056
|
console.log(` ${peakColor}${B}${peak}%${R} ${D}peak usage across ${plan.windows.length} window${plan.windows.length === 1 ? "" : "s"}${R}`);
|
|
67279
68057
|
console.log("");
|
|
68058
|
+
const NAME_MIN = 14;
|
|
68059
|
+
const NAME_MAX = 28;
|
|
68060
|
+
const widest = plan.windows.reduce((m, w) => Math.max(m, w.id.length), 0);
|
|
68061
|
+
const nameWidth = Math.min(NAME_MAX, Math.max(NAME_MIN, widest + 1));
|
|
67280
68062
|
for (const w of plan.windows) {
|
|
67281
68063
|
const color = colorFor(w.used_pct);
|
|
67282
68064
|
const bar = buildUsageBar(w.used_pct / 100, color, 24);
|
|
67283
68065
|
const reset = w.resets_at ? formatRelativeReset(w.resets_at) : "";
|
|
67284
|
-
const name = w.id.length >
|
|
67285
|
-
console.log(` ${GRY}\u2502${R} ${WHT}${name.padEnd(
|
|
68066
|
+
const name = w.id.length > nameWidth ? `${w.id.slice(0, nameWidth - 1)}\u2026` : w.id;
|
|
68067
|
+
console.log(` ${GRY}\u2502${R} ${WHT}${name.padEnd(nameWidth)}${R}${bar} ${color}${String(w.used_pct).padStart(3)}%${R} ${GRY}${I}${reset}${R}`);
|
|
67286
68068
|
}
|
|
67287
68069
|
console.log("");
|
|
67288
68070
|
console.log(` ${GRN}\u2588${R}${GRY} <50%${R} ${YEL}\u2588${R}${GRY} 50-80%${R} ${RED}\u2588${R}${GRY} >80%${R} ${D}\u2591 available${R}`);
|
|
@@ -67370,7 +68152,9 @@ var init_quota_command = __esm(() => {
|
|
|
67370
68152
|
sakana: "sakana-subscription",
|
|
67371
68153
|
fugu: "sakana-subscription",
|
|
67372
68154
|
zen: "opencode-zen-go",
|
|
67373
|
-
qwen: "qwen-cloud"
|
|
68155
|
+
qwen: "qwen-cloud",
|
|
68156
|
+
grok: "grok-subscription",
|
|
68157
|
+
supergrok: "grok-subscription"
|
|
67374
68158
|
};
|
|
67375
68159
|
});
|
|
67376
68160
|
|
|
@@ -68478,399 +69262,6 @@ var init_model_selector = __esm(() => {
|
|
|
68478
69262
|
};
|
|
68479
69263
|
});
|
|
68480
69264
|
|
|
68481
|
-
// src/providers/probe-live.ts
|
|
68482
|
-
async function probeLink(proxyUrl, link, timeoutMs) {
|
|
68483
|
-
const isOAuth = OAUTH_PROVIDERS2.has(link.provider);
|
|
68484
|
-
if (!link.hasCredentials && !isOAuth) {
|
|
68485
|
-
return {
|
|
68486
|
-
state: "key-missing",
|
|
68487
|
-
latencyMs: 0,
|
|
68488
|
-
errorMessage: link.credentialHint
|
|
68489
|
-
};
|
|
68490
|
-
}
|
|
68491
|
-
const startedAt = Date.now();
|
|
68492
|
-
let response;
|
|
68493
|
-
try {
|
|
68494
|
-
response = await fetch(`${proxyUrl}/v1/messages`, {
|
|
68495
|
-
method: "POST",
|
|
68496
|
-
headers: {
|
|
68497
|
-
"Content-Type": "application/json"
|
|
68498
|
-
},
|
|
68499
|
-
body: JSON.stringify({
|
|
68500
|
-
model: link.modelSpec,
|
|
68501
|
-
system: "You are a helpful assistant.",
|
|
68502
|
-
messages: [{ role: "user", content: PROBE_PROMPT }],
|
|
68503
|
-
max_tokens: PROBE_MAX_TOKENS,
|
|
68504
|
-
output_config: { effort: "minimal" },
|
|
68505
|
-
stream: true
|
|
68506
|
-
}),
|
|
68507
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
68508
|
-
});
|
|
68509
|
-
} catch (e) {
|
|
68510
|
-
const latencyMs = Date.now() - startedAt;
|
|
68511
|
-
const name = e?.name || "";
|
|
68512
|
-
const msg2 = String(e?.message || e);
|
|
68513
|
-
if (name === "TimeoutError" || name === "AbortError" || /timeout/i.test(msg2)) {
|
|
68514
|
-
return { state: "timeout", latencyMs, errorMessage: msg2 };
|
|
68515
|
-
}
|
|
68516
|
-
return { state: "network-error", latencyMs, errorMessage: msg2 };
|
|
68517
|
-
}
|
|
68518
|
-
const ttfbMs = Date.now() - startedAt;
|
|
68519
|
-
if (!response.ok) {
|
|
68520
|
-
const body = await safeReadBody(response);
|
|
68521
|
-
return annotateOAuthHint(classifyHttpError(response.status, body, ttfbMs), link.provider, isOAuth);
|
|
68522
|
-
}
|
|
68523
|
-
const streamResult = await consumeProbeStream(response, timeoutMs, startedAt);
|
|
68524
|
-
const totalMs = Date.now() - startedAt;
|
|
68525
|
-
let timing2;
|
|
68526
|
-
if (streamResult.state === "live" && streamResult.ttftMs !== undefined && !streamResult.truncated) {
|
|
68527
|
-
const ttftMs = streamResult.ttftMs;
|
|
68528
|
-
const tokens = streamResult.tokens ?? 0;
|
|
68529
|
-
const streamMs = Math.max(STREAM_MS_FLOOR, totalMs - ttftMs);
|
|
68530
|
-
const tokensPerSec = tokens > 0 ? tokens / streamMs * 1000 : 0;
|
|
68531
|
-
timing2 = { ttfbMs, ttftMs, totalMs, tokens, tokensPerSec };
|
|
68532
|
-
}
|
|
68533
|
-
const { ttftMs: _ttft, tokens: _tok, truncated: _trunc, ...rest } = streamResult;
|
|
68534
|
-
return annotateOAuthHint({
|
|
68535
|
-
...rest,
|
|
68536
|
-
latencyMs: totalMs,
|
|
68537
|
-
timing: timing2
|
|
68538
|
-
}, link.provider, isOAuth);
|
|
68539
|
-
}
|
|
68540
|
-
function annotateOAuthHint(result, provider, isOAuth) {
|
|
68541
|
-
if (!isOAuth)
|
|
68542
|
-
return result;
|
|
68543
|
-
if (result.state === "live")
|
|
68544
|
-
return result;
|
|
68545
|
-
const loginCommand2 = provider === "antigravity" ? "claudish login antigravity" : provider === "vertex" ? "gcloud auth application-default login" : provider === "devin" ? "devin login" : undefined;
|
|
68546
|
-
if (!loginCommand2)
|
|
68547
|
-
return result;
|
|
68548
|
-
if (result.httpStatus === 403)
|
|
68549
|
-
return result;
|
|
68550
|
-
const looksLikeAuthFailure = result.state === "auth-failed" || /auth|token|login|credential|unauthor/i.test(result.errorMessage || "");
|
|
68551
|
-
if (!looksLikeAuthFailure)
|
|
68552
|
-
return result;
|
|
68553
|
-
return {
|
|
68554
|
-
...result,
|
|
68555
|
-
state: "auth-failed",
|
|
68556
|
-
actionHint: `run: ${loginCommand2}`
|
|
68557
|
-
};
|
|
68558
|
-
}
|
|
68559
|
-
async function safeReadBody(response) {
|
|
68560
|
-
try {
|
|
68561
|
-
const text = await response.text();
|
|
68562
|
-
return text.slice(0, 500);
|
|
68563
|
-
} catch {
|
|
68564
|
-
return "";
|
|
68565
|
-
}
|
|
68566
|
-
}
|
|
68567
|
-
function extractUpstreamStatus(body) {
|
|
68568
|
-
if (!body)
|
|
68569
|
-
return;
|
|
68570
|
-
try {
|
|
68571
|
-
const parsed = JSON.parse(body);
|
|
68572
|
-
const status = parsed?.error?.upstream_status;
|
|
68573
|
-
return typeof status === "number" ? status : undefined;
|
|
68574
|
-
} catch {
|
|
68575
|
-
return;
|
|
68576
|
-
}
|
|
68577
|
-
}
|
|
68578
|
-
function extractErrorType(body) {
|
|
68579
|
-
if (!body)
|
|
68580
|
-
return;
|
|
68581
|
-
try {
|
|
68582
|
-
const parsed = JSON.parse(body);
|
|
68583
|
-
const t = parsed?.error?.type;
|
|
68584
|
-
return typeof t === "string" ? t : undefined;
|
|
68585
|
-
} catch {
|
|
68586
|
-
return;
|
|
68587
|
-
}
|
|
68588
|
-
}
|
|
68589
|
-
function classifyHttpError(status, body, latencyMs) {
|
|
68590
|
-
const lowered = body.toLowerCase();
|
|
68591
|
-
if (extractErrorType(body) === "connection_error") {
|
|
68592
|
-
return {
|
|
68593
|
-
state: "network-error",
|
|
68594
|
-
latencyMs,
|
|
68595
|
-
httpStatus: status,
|
|
68596
|
-
errorMessage: extractErrorMessage(body) || "Cannot reach provider"
|
|
68597
|
-
};
|
|
68598
|
-
}
|
|
68599
|
-
const upstream = status === 400 ? extractUpstreamStatus(body) : undefined;
|
|
68600
|
-
if (status === 401 || status === 403 || upstream === 401 || upstream === 403) {
|
|
68601
|
-
const authStatus = upstream ?? status;
|
|
68602
|
-
return {
|
|
68603
|
-
state: "auth-failed",
|
|
68604
|
-
latencyMs,
|
|
68605
|
-
httpStatus: authStatus,
|
|
68606
|
-
errorMessage: extractErrorMessage(body) || `HTTP ${authStatus}`
|
|
68607
|
-
};
|
|
68608
|
-
}
|
|
68609
|
-
if (status === 404 || /model[_ ]not[_ ]found|no such model|unknown model/.test(lowered)) {
|
|
68610
|
-
return {
|
|
68611
|
-
state: "model-not-found",
|
|
68612
|
-
latencyMs,
|
|
68613
|
-
httpStatus: status,
|
|
68614
|
-
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
68615
|
-
};
|
|
68616
|
-
}
|
|
68617
|
-
if (status === 429) {
|
|
68618
|
-
return {
|
|
68619
|
-
state: "rate-limited",
|
|
68620
|
-
latencyMs,
|
|
68621
|
-
httpStatus: status,
|
|
68622
|
-
errorMessage: extractErrorMessage(body) || "Rate limited"
|
|
68623
|
-
};
|
|
68624
|
-
}
|
|
68625
|
-
if (upstream === 429 || status === 402) {
|
|
68626
|
-
return {
|
|
68627
|
-
state: "out-of-credit",
|
|
68628
|
-
latencyMs,
|
|
68629
|
-
httpStatus: upstream ?? status,
|
|
68630
|
-
errorMessage: extractErrorMessage(body) || "Out of credit \u2014 account balance or plan exhausted"
|
|
68631
|
-
};
|
|
68632
|
-
}
|
|
68633
|
-
if (status >= 500) {
|
|
68634
|
-
return {
|
|
68635
|
-
state: "server-error",
|
|
68636
|
-
latencyMs,
|
|
68637
|
-
httpStatus: status,
|
|
68638
|
-
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
68639
|
-
};
|
|
68640
|
-
}
|
|
68641
|
-
return {
|
|
68642
|
-
state: "error",
|
|
68643
|
-
latencyMs,
|
|
68644
|
-
httpStatus: status,
|
|
68645
|
-
errorMessage: extractErrorMessage(body) || `HTTP ${status}`
|
|
68646
|
-
};
|
|
68647
|
-
}
|
|
68648
|
-
function extractErrorMessage(body) {
|
|
68649
|
-
if (!body)
|
|
68650
|
-
return;
|
|
68651
|
-
try {
|
|
68652
|
-
const parsed = JSON.parse(body);
|
|
68653
|
-
const msg2 = parsed?.error?.message || parsed?.error?.error?.message || parsed?.message || parsed?.detail;
|
|
68654
|
-
if (typeof msg2 === "string" && msg2.length > 0) {
|
|
68655
|
-
return msg2.length > 160 ? `${msg2.slice(0, 157)}...` : msg2;
|
|
68656
|
-
}
|
|
68657
|
-
} catch {}
|
|
68658
|
-
const trimmed2 = body.trim();
|
|
68659
|
-
if (!trimmed2)
|
|
68660
|
-
return;
|
|
68661
|
-
return trimmed2.length > 160 ? `${trimmed2.slice(0, 157)}...` : trimmed2;
|
|
68662
|
-
}
|
|
68663
|
-
async function consumeProbeStream(response, timeoutMs, startedAt) {
|
|
68664
|
-
const body = response.body;
|
|
68665
|
-
if (!body) {
|
|
68666
|
-
return { state: "error", errorMessage: "empty response body" };
|
|
68667
|
-
}
|
|
68668
|
-
const reader = body.getReader();
|
|
68669
|
-
const decoder = new TextDecoder;
|
|
68670
|
-
let buffered = "";
|
|
68671
|
-
const deadline = Date.now() + timeoutMs;
|
|
68672
|
-
let ttftMs;
|
|
68673
|
-
let sawContent = false;
|
|
68674
|
-
let textChars = 0;
|
|
68675
|
-
let reportedTokens;
|
|
68676
|
-
let stopReason;
|
|
68677
|
-
let errorVerdict = null;
|
|
68678
|
-
let completed = false;
|
|
68679
|
-
try {
|
|
68680
|
-
while (Date.now() < deadline) {
|
|
68681
|
-
const { value, done } = await reader.read();
|
|
68682
|
-
if (done) {
|
|
68683
|
-
completed = true;
|
|
68684
|
-
break;
|
|
68685
|
-
}
|
|
68686
|
-
buffered += decoder.decode(value, { stream: true });
|
|
68687
|
-
const events = buffered.split(`
|
|
68688
|
-
|
|
68689
|
-
`);
|
|
68690
|
-
buffered = events.pop() ?? "";
|
|
68691
|
-
for (const event of events) {
|
|
68692
|
-
const verdict = interpretSseEvent(event);
|
|
68693
|
-
if (verdict && typeof verdict === "object" && verdict.state !== "live") {
|
|
68694
|
-
errorVerdict = verdict;
|
|
68695
|
-
break;
|
|
68696
|
-
}
|
|
68697
|
-
const acct = accountStreamEvent(event);
|
|
68698
|
-
if (acct.contentDelta) {
|
|
68699
|
-
if (ttftMs === undefined)
|
|
68700
|
-
ttftMs = Date.now() - startedAt;
|
|
68701
|
-
sawContent = true;
|
|
68702
|
-
}
|
|
68703
|
-
if (acct.textChars)
|
|
68704
|
-
textChars += acct.textChars;
|
|
68705
|
-
if (acct.outputTokens !== undefined)
|
|
68706
|
-
reportedTokens = acct.outputTokens;
|
|
68707
|
-
if (acct.stopReason)
|
|
68708
|
-
stopReason = acct.stopReason;
|
|
68709
|
-
}
|
|
68710
|
-
if (errorVerdict)
|
|
68711
|
-
break;
|
|
68712
|
-
}
|
|
68713
|
-
} catch (e) {
|
|
68714
|
-
if (!sawContent) {
|
|
68715
|
-
return { state: "network-error", errorMessage: String(e?.message || e) };
|
|
68716
|
-
}
|
|
68717
|
-
} finally {
|
|
68718
|
-
try {
|
|
68719
|
-
await reader.cancel();
|
|
68720
|
-
} catch {}
|
|
68721
|
-
}
|
|
68722
|
-
if (errorVerdict)
|
|
68723
|
-
return errorVerdict;
|
|
68724
|
-
if (sawContent) {
|
|
68725
|
-
const tokens = reportedTokens ?? Math.max(1, Math.round(textChars / 4));
|
|
68726
|
-
return { state: "live", ttftMs, tokens, truncated: !completed };
|
|
68727
|
-
}
|
|
68728
|
-
const truncationReason = stopReason === "max_tokens" || stopReason === "length" ? stopReason : undefined;
|
|
68729
|
-
if (truncationReason || reportedTokens !== undefined && reportedTokens >= PROBE_MAX_TOKENS) {
|
|
68730
|
-
const cause = truncationReason ? `finish: ${truncationReason}` : `${reportedTokens} tokens consumed, none visible`;
|
|
68731
|
-
return {
|
|
68732
|
-
state: "error",
|
|
68733
|
-
errorMessage: `no visible output within probe budget (${cause})`
|
|
68734
|
-
};
|
|
68735
|
-
}
|
|
68736
|
-
return { state: "error", errorMessage: "stream ended without content" };
|
|
68737
|
-
}
|
|
68738
|
-
function accountStreamEvent(rawEvent) {
|
|
68739
|
-
let dataPayload = "";
|
|
68740
|
-
for (const line of rawEvent.split(`
|
|
68741
|
-
`)) {
|
|
68742
|
-
if (line.startsWith("data:"))
|
|
68743
|
-
dataPayload += line.slice(5).trim();
|
|
68744
|
-
}
|
|
68745
|
-
if (!dataPayload || dataPayload === "[DONE]") {
|
|
68746
|
-
return { contentDelta: false, textChars: 0 };
|
|
68747
|
-
}
|
|
68748
|
-
let parsed;
|
|
68749
|
-
try {
|
|
68750
|
-
parsed = JSON.parse(dataPayload);
|
|
68751
|
-
} catch {
|
|
68752
|
-
return { contentDelta: false, textChars: 0 };
|
|
68753
|
-
}
|
|
68754
|
-
let textChars = 0;
|
|
68755
|
-
let contentDelta = false;
|
|
68756
|
-
const text = parsed?.delta?.text ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.delta?.content : undefined);
|
|
68757
|
-
if (typeof text === "string" && text.length > 0) {
|
|
68758
|
-
contentDelta = true;
|
|
68759
|
-
textChars = text.length;
|
|
68760
|
-
} else if (parsed?.type === "content_block_delta" || parsed?.type === "content_block_start") {
|
|
68761
|
-
contentDelta = true;
|
|
68762
|
-
}
|
|
68763
|
-
const outputTokens = parsed?.usage?.output_tokens ?? parsed?.message?.usage?.output_tokens ?? parsed?.usage?.completion_tokens;
|
|
68764
|
-
const stopReason = parsed?.delta?.stop_reason ?? (Array.isArray(parsed?.choices) ? parsed.choices[0]?.finish_reason : undefined);
|
|
68765
|
-
return {
|
|
68766
|
-
contentDelta,
|
|
68767
|
-
textChars,
|
|
68768
|
-
outputTokens: typeof outputTokens === "number" ? outputTokens : undefined,
|
|
68769
|
-
stopReason: typeof stopReason === "string" ? stopReason : undefined
|
|
68770
|
-
};
|
|
68771
|
-
}
|
|
68772
|
-
function interpretSseEvent(rawEvent) {
|
|
68773
|
-
const lines = rawEvent.split(`
|
|
68774
|
-
`);
|
|
68775
|
-
let eventType = "";
|
|
68776
|
-
let dataPayload = "";
|
|
68777
|
-
for (const line of lines) {
|
|
68778
|
-
if (line.startsWith("event:"))
|
|
68779
|
-
eventType = line.slice(6).trim();
|
|
68780
|
-
else if (line.startsWith("data:"))
|
|
68781
|
-
dataPayload += line.slice(5).trim();
|
|
68782
|
-
}
|
|
68783
|
-
if (!dataPayload)
|
|
68784
|
-
return null;
|
|
68785
|
-
if (dataPayload === "[DONE]")
|
|
68786
|
-
return null;
|
|
68787
|
-
let parsed;
|
|
68788
|
-
try {
|
|
68789
|
-
parsed = JSON.parse(dataPayload);
|
|
68790
|
-
} catch {
|
|
68791
|
-
return null;
|
|
68792
|
-
}
|
|
68793
|
-
if (parsed?.type === "error" || eventType === "error" || parsed?.error) {
|
|
68794
|
-
const message = parsed?.error?.message || parsed?.error?.error?.message || parsed?.message || "provider returned error event";
|
|
68795
|
-
const status = parsed?.error?.status || parsed?.status;
|
|
68796
|
-
if (typeof status === "number") {
|
|
68797
|
-
return {
|
|
68798
|
-
state: status === 401 || status === 403 ? "auth-failed" : "error",
|
|
68799
|
-
httpStatus: status,
|
|
68800
|
-
errorMessage: message
|
|
68801
|
-
};
|
|
68802
|
-
}
|
|
68803
|
-
return { state: "error", errorMessage: message };
|
|
68804
|
-
}
|
|
68805
|
-
if (isContentEvent(parsed, eventType)) {
|
|
68806
|
-
return "live";
|
|
68807
|
-
}
|
|
68808
|
-
return null;
|
|
68809
|
-
}
|
|
68810
|
-
function isContentEvent(parsed, eventType) {
|
|
68811
|
-
if (eventType === "content_block_start" || eventType === "content_block_delta")
|
|
68812
|
-
return true;
|
|
68813
|
-
if (eventType === "message_start")
|
|
68814
|
-
return true;
|
|
68815
|
-
if (parsed?.type === "content_block_start")
|
|
68816
|
-
return true;
|
|
68817
|
-
if (parsed?.type === "content_block_delta")
|
|
68818
|
-
return true;
|
|
68819
|
-
if (parsed?.type === "message_start")
|
|
68820
|
-
return true;
|
|
68821
|
-
if (parsed?.type === "message_delta")
|
|
68822
|
-
return true;
|
|
68823
|
-
if (Array.isArray(parsed?.choices) && parsed.choices.length > 0) {
|
|
68824
|
-
const choice = parsed.choices[0];
|
|
68825
|
-
if (choice?.delta || choice?.message || choice?.text || choice?.finish_reason)
|
|
68826
|
-
return true;
|
|
68827
|
-
}
|
|
68828
|
-
if (parsed?.candidates)
|
|
68829
|
-
return true;
|
|
68830
|
-
return false;
|
|
68831
|
-
}
|
|
68832
|
-
function withDetail(base, message) {
|
|
68833
|
-
return message ? `${base} \u2014 ${message}` : base;
|
|
68834
|
-
}
|
|
68835
|
-
function describeProbeState(result) {
|
|
68836
|
-
const status = result.httpStatus ?? "";
|
|
68837
|
-
const latency = result.latencyMs ? ` \xB7 ${result.latencyMs}ms` : "";
|
|
68838
|
-
switch (result.state) {
|
|
68839
|
-
case "live":
|
|
68840
|
-
return `live \xB7 ${result.latencyMs}ms`;
|
|
68841
|
-
case "key-missing":
|
|
68842
|
-
return result.errorMessage ? `missing (${result.errorMessage})` : "missing";
|
|
68843
|
-
case "auth-failed":
|
|
68844
|
-
return withDetail(`auth failed \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
68845
|
-
case "model-not-found":
|
|
68846
|
-
return withDetail(`model not found \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
68847
|
-
case "rate-limited":
|
|
68848
|
-
return withDetail(`rate limited \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
68849
|
-
case "out-of-credit":
|
|
68850
|
-
return withDetail(`out of credit \xB7 ${status}${latency}`.trim(), result.errorMessage);
|
|
68851
|
-
case "server-error":
|
|
68852
|
-
return withDetail(`server error \xB7 ${status} \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
68853
|
-
case "timeout":
|
|
68854
|
-
return withDetail(`timeout \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
68855
|
-
case "network-error":
|
|
68856
|
-
return withDetail(`network error \xB7 ${result.latencyMs}ms`, result.errorMessage);
|
|
68857
|
-
case "error": {
|
|
68858
|
-
const base = `error${result.httpStatus ? ` \xB7 ${result.httpStatus}` : ""}${latency}`;
|
|
68859
|
-
return withDetail(base, result.errorMessage);
|
|
68860
|
-
}
|
|
68861
|
-
}
|
|
68862
|
-
}
|
|
68863
|
-
function isReadyState(state) {
|
|
68864
|
-
return state === "live";
|
|
68865
|
-
}
|
|
68866
|
-
function isFailureState(state) {
|
|
68867
|
-
return state === "auth-failed" || state === "model-not-found" || state === "rate-limited" || state === "out-of-credit" || state === "server-error" || state === "timeout" || state === "network-error" || state === "error";
|
|
68868
|
-
}
|
|
68869
|
-
var STREAM_MS_FLOOR = 50, OAUTH_PROVIDERS2, PROBE_PROMPT = "Count from one to twenty in words, one per line.", PROBE_MAX_TOKENS = 512;
|
|
68870
|
-
var init_probe_live = __esm(() => {
|
|
68871
|
-
OAUTH_PROVIDERS2 = new Set(["vertex", "antigravity", "devin"]);
|
|
68872
|
-
});
|
|
68873
|
-
|
|
68874
69265
|
// src/tui/theme.ts
|
|
68875
69266
|
import { createTextAttributes } from "@opentui/core";
|
|
68876
69267
|
function latencyBucket(ms) {
|
|
@@ -71144,6 +71535,21 @@ var init_api_key_map = __esm(() => {
|
|
|
71144
71535
|
};
|
|
71145
71536
|
});
|
|
71146
71537
|
|
|
71538
|
+
// src/providers/claude-code-aliases.ts
|
|
71539
|
+
function claudeCodeTierAlias(model) {
|
|
71540
|
+
return TIER_ALIASES[model.trim().toLowerCase()] ?? null;
|
|
71541
|
+
}
|
|
71542
|
+
var TIER_ALIASES;
|
|
71543
|
+
var init_claude_code_aliases = __esm(() => {
|
|
71544
|
+
TIER_ALIASES = {
|
|
71545
|
+
opus: "opus",
|
|
71546
|
+
sonnet: "sonnet",
|
|
71547
|
+
haiku: "haiku",
|
|
71548
|
+
internal: "opus",
|
|
71549
|
+
default: "opus"
|
|
71550
|
+
};
|
|
71551
|
+
});
|
|
71552
|
+
|
|
71147
71553
|
// src/providers/probe-runner.ts
|
|
71148
71554
|
function pinProbeModelSpec(link) {
|
|
71149
71555
|
if (link.provider === "native-anthropic")
|
|
@@ -71835,7 +72241,7 @@ async function printRecommendedModels(jsonOutput, forceUpdate) {
|
|
|
71835
72241
|
const rawId = m.id;
|
|
71836
72242
|
const modelId = rawId.length > 28 ? `${rawId.substring(0, 25)}...` : rawId;
|
|
71837
72243
|
const modelIdPadded = modelId.padEnd(28);
|
|
71838
|
-
const pricing =
|
|
72244
|
+
const pricing = formatListingPrice(m, { compact: true });
|
|
71839
72245
|
const pricingPadded = pricing.padEnd(10);
|
|
71840
72246
|
const context = m.context || "N/A";
|
|
71841
72247
|
const contextPadded = context.padEnd(6);
|
|
@@ -71927,13 +72333,19 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
71927
72333
|
};
|
|
71928
72334
|
}
|
|
71929
72335
|
if (parsed.provider === "native-anthropic") {
|
|
71930
|
-
const
|
|
72336
|
+
const tier = claudeCodeTierAlias(parsed.model);
|
|
72337
|
+
const tierEnv = {
|
|
72338
|
+
opus: process.env[ENV.CLAUDISH_MODEL_OPUS] || process.env[ENV.ANTHROPIC_DEFAULT_OPUS_MODEL],
|
|
72339
|
+
sonnet: process.env[ENV.CLAUDISH_MODEL_SONNET] || process.env[ENV.ANTHROPIC_DEFAULT_SONNET_MODEL],
|
|
72340
|
+
haiku: process.env[ENV.CLAUDISH_MODEL_HAIKU] || process.env[ENV.ANTHROPIC_DEFAULT_HAIKU_MODEL]
|
|
72341
|
+
};
|
|
72342
|
+
const opusModel = tier ? tierEnv[tier] || latestAnthropicTierModelId(tier) || "claude-opus-5" : parsed.model;
|
|
71931
72343
|
return {
|
|
71932
72344
|
routes: [
|
|
71933
72345
|
{
|
|
71934
72346
|
provider: "native-anthropic",
|
|
71935
72347
|
modelSpec: opusModel,
|
|
71936
|
-
displayName:
|
|
72348
|
+
displayName: tier ? `Claude Code (${tier})` : "Claude Code"
|
|
71937
72349
|
}
|
|
71938
72350
|
],
|
|
71939
72351
|
source: "auto-chain",
|
|
@@ -72027,6 +72439,33 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
72027
72439
|
}
|
|
72028
72440
|
return chain.source;
|
|
72029
72441
|
}
|
|
72442
|
+
function buildDirectChainEntry(parsed, directProbe) {
|
|
72443
|
+
const providerDef = getProviderByName(parsed.provider);
|
|
72444
|
+
const keyInfo = API_KEY_MAP[parsed.provider];
|
|
72445
|
+
if (!providerDef && !keyInfo)
|
|
72446
|
+
return [];
|
|
72447
|
+
let hasCredentials;
|
|
72448
|
+
let provenance;
|
|
72449
|
+
if (providerDef?.isLocal) {
|
|
72450
|
+
hasCredentials = isLocalProviderEnabled(parsed.provider);
|
|
72451
|
+
} else if (!keyInfo?.envVar) {
|
|
72452
|
+
hasCredentials = true;
|
|
72453
|
+
} else {
|
|
72454
|
+
provenance = resolveApiKeyProvenance(keyInfo.envVar, keyInfo.aliases);
|
|
72455
|
+
hasCredentials = provenance.hasValue || (keyInfo.aliases?.some((a) => !!process.env[a]) ?? false);
|
|
72456
|
+
}
|
|
72457
|
+
return [
|
|
72458
|
+
{
|
|
72459
|
+
provider: parsed.provider,
|
|
72460
|
+
displayName: providerDef?.displayName ?? parsed.provider,
|
|
72461
|
+
modelSpec: parsed.model,
|
|
72462
|
+
hasCredentials,
|
|
72463
|
+
credentialHint: !hasCredentials ? providerDef?.isLocal ? "enable local provider in global config" : keyInfo?.envVar : undefined,
|
|
72464
|
+
provenance,
|
|
72465
|
+
probe: directProbe
|
|
72466
|
+
}
|
|
72467
|
+
];
|
|
72468
|
+
}
|
|
72030
72469
|
function buildResultLinks(parsed, chainDetails, directProbe) {
|
|
72031
72470
|
if (chainDetails.length === 0) {
|
|
72032
72471
|
const directProviderDef = getProviderByName(parsed.provider);
|
|
@@ -72177,7 +72616,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
72177
72616
|
isExplicit: parsed.isExplicitProvider,
|
|
72178
72617
|
routingSource: chain.source,
|
|
72179
72618
|
matchedPattern: chain.matchedPattern,
|
|
72180
|
-
chain: chainDetails,
|
|
72619
|
+
chain: chainDetails.length > 0 ? chainDetails : buildDirectChainEntry(parsed, directProbeResult),
|
|
72181
72620
|
directProbe: directProbeResult,
|
|
72182
72621
|
wiring
|
|
72183
72622
|
});
|
|
@@ -72804,6 +73243,8 @@ var init_cli = __esm(() => {
|
|
|
72804
73243
|
init_profile_config();
|
|
72805
73244
|
init_api_key_map();
|
|
72806
73245
|
init_api_key_provenance();
|
|
73246
|
+
init_catalog_client();
|
|
73247
|
+
init_claude_code_aliases();
|
|
72807
73248
|
init_endpoint_registration();
|
|
72808
73249
|
init_model_parser();
|
|
72809
73250
|
init_probe_live();
|