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.
Files changed (2) hide show
  1. package/dist/index.js +851 -410
  2. 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.55.0";
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": `GeminiCLI/0.5.6/gemini-code-assist (${process.platform}; ${process.arch})`
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
- agServedCache = { servedIds, defaultId };
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}-aiplatform.googleapis.com/v1/` + `projects/${config2.projectId}/locations/${config2.location}/` + `publishers/${publisher}/models/${model}:${method}${sseParam}`;
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}-aiplatform.googleapis.com/v1/` + `projects/${config2.projectId}/locations/${config2.location}/` + `publishers/mistralai/models/${model}:${mistralMethod}`;
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 (lower.includes("not supported") || lower.includes("unsupported model") || lower.includes("model not found")) {
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 = normalizePricingDisplay(m.pricing?.average);
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 > 14 ? `${w.id.slice(0, 13)}\u2026` : w.id;
67285
- console.log(` ${GRY}\u2502${R} ${WHT}${name.padEnd(14)}${R}${bar} ${color}${String(w.used_pct).padStart(3)}%${R} ${GRY}${I}${reset}${R}`);
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 = normalizePricingDisplay(m.pricing?.average);
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 opusModel = process.env[ENV.CLAUDISH_MODEL_OPUS] || process.env[ENV.ANTHROPIC_DEFAULT_OPUS_MODEL] || "claude-opus-4-1";
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: "Claude Code (Opus)"
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();