claudish 7.19.2 → 7.20.1
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 +168 -19
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
651
651
|
});
|
|
652
652
|
|
|
653
653
|
// src/version.ts
|
|
654
|
-
var VERSION = "7.
|
|
654
|
+
var VERSION = "7.20.1";
|
|
655
655
|
|
|
656
656
|
// src/logger.ts
|
|
657
657
|
var exports_logger = {};
|
|
@@ -28326,8 +28326,8 @@ var init_provider_definitions = __esm(() => {
|
|
|
28326
28326
|
shortcuts: ["kc"],
|
|
28327
28327
|
shortestPrefix: "kc",
|
|
28328
28328
|
legacyPrefixes: [{ prefix: "kc/", stripPrefix: true }],
|
|
28329
|
-
nativeModelPatterns: [{ pattern: /^kimi-for-coding
|
|
28330
|
-
|
|
28329
|
+
nativeModelPatterns: [{ pattern: /^kimi-for-coding/i }, { pattern: /^k3(-|$)/i }],
|
|
28330
|
+
modelDiscovery: { path: "/models", format: "openai-models-list" },
|
|
28331
28331
|
isDirectApi: true,
|
|
28332
28332
|
description: "Kimi Coding Plan (kc@)"
|
|
28333
28333
|
},
|
|
@@ -30475,6 +30475,22 @@ function lookupModelForProvider(modelId, provider, cachePath) {
|
|
|
30475
30475
|
return;
|
|
30476
30476
|
return entry.aggregators?.find((a) => a.provider === provider)?.contextWindow ?? entry.contextWindow;
|
|
30477
30477
|
}
|
|
30478
|
+
function resolveSubscriptionRouting(modelId, provider, cachePath) {
|
|
30479
|
+
const entry = findCacheEntry(modelId, cachePath);
|
|
30480
|
+
if (!entry)
|
|
30481
|
+
return { kind: "unknown" };
|
|
30482
|
+
if (entry.subscriptionPlans?.includes(provider)) {
|
|
30483
|
+
const agg = entry.aggregators?.find((a) => a.provider === provider);
|
|
30484
|
+
return agg?.externalId ? { kind: "serves", externalId: agg.externalId } : { kind: "unknown" };
|
|
30485
|
+
}
|
|
30486
|
+
return isSubscriptionPlan(provider, cachePath) ? { kind: "not-served" } : { kind: "unknown" };
|
|
30487
|
+
}
|
|
30488
|
+
function isSubscriptionPlan(provider, cachePath) {
|
|
30489
|
+
const cache = readAllModelsCache(cachePath);
|
|
30490
|
+
if (!cache)
|
|
30491
|
+
return false;
|
|
30492
|
+
return cache.entries.some((e) => e.subscriptionPlans?.includes(provider));
|
|
30493
|
+
}
|
|
30478
30494
|
function findCacheEntry(modelId, cachePath) {
|
|
30479
30495
|
if (modelId.includes("@")) {
|
|
30480
30496
|
throw new Error(`model-catalog lookup received provider-routed ID "${modelId}" \u2014 callers must strip the "@" prefix before calling`);
|
|
@@ -42591,7 +42607,8 @@ var init_default_routing_rules = __esm(() => {
|
|
|
42591
42607
|
"o3-*": ["openai-codex", "openai", "openrouter"],
|
|
42592
42608
|
"gemini-*": ["gemini-codeassist", "google", "openrouter"],
|
|
42593
42609
|
"grok-*": ["x-ai", "openrouter"],
|
|
42594
|
-
"kimi-*": ["kimi-coding
|
|
42610
|
+
"kimi-*": ["kimi-coding", "kimi", "openrouter"],
|
|
42611
|
+
"k3*": ["kimi-coding", "kimi", "openrouter"],
|
|
42595
42612
|
"minimax-*": ["minimax-coding", "minimax", "openrouter"],
|
|
42596
42613
|
"glm-*": ["glm-coding", "glm", "openrouter"],
|
|
42597
42614
|
"z-ai-*": ["z-ai", "openrouter"],
|
|
@@ -42645,7 +42662,7 @@ function matchRoutingRule(modelName, rules) {
|
|
|
42645
42662
|
return rules["*"];
|
|
42646
42663
|
return null;
|
|
42647
42664
|
}
|
|
42648
|
-
function buildRoutingChain(entries, originalModelName) {
|
|
42665
|
+
function buildRoutingChain(entries, originalModelName, cachePath) {
|
|
42649
42666
|
const routes = [];
|
|
42650
42667
|
for (const entry of entries) {
|
|
42651
42668
|
const atIdx = entry.indexOf("@");
|
|
@@ -42659,6 +42676,13 @@ function buildRoutingChain(entries, originalModelName) {
|
|
|
42659
42676
|
modelName = originalModelName;
|
|
42660
42677
|
}
|
|
42661
42678
|
const provider = PROVIDER_SHORTCUTS[providerRaw.toLowerCase()] ?? providerRaw.toLowerCase();
|
|
42679
|
+
if (atIdx === -1) {
|
|
42680
|
+
const routing = resolveSubscriptionRouting(modelName, provider, cachePath);
|
|
42681
|
+
if (routing.kind === "not-served")
|
|
42682
|
+
continue;
|
|
42683
|
+
if (routing.kind === "serves")
|
|
42684
|
+
modelName = routing.externalId;
|
|
42685
|
+
}
|
|
42662
42686
|
let modelSpec;
|
|
42663
42687
|
if (provider === "openrouter") {
|
|
42664
42688
|
const resolution = resolveModelNameSync(modelName, "openrouter");
|
|
@@ -42685,7 +42709,7 @@ function globMatch(pattern, value) {
|
|
|
42685
42709
|
async function hasCredentialsForProvider(provider) {
|
|
42686
42710
|
return credentials.isAvailable(provider);
|
|
42687
42711
|
}
|
|
42688
|
-
async function routeExplicit(modelSpec, model, provider) {
|
|
42712
|
+
async function routeExplicit(modelSpec, model, provider, cachePath) {
|
|
42689
42713
|
if (!await hasCredentialsForProvider(provider)) {
|
|
42690
42714
|
return {
|
|
42691
42715
|
kind: "no-route",
|
|
@@ -42693,7 +42717,7 @@ async function routeExplicit(modelSpec, model, provider) {
|
|
|
42693
42717
|
hint: buildCredentialHint(model, [provider]) ?? undefined
|
|
42694
42718
|
};
|
|
42695
42719
|
}
|
|
42696
|
-
const built = buildRoutingChain([modelSpec], model)[0];
|
|
42720
|
+
const built = buildRoutingChain([modelSpec], model, cachePath)[0];
|
|
42697
42721
|
if (!built) {
|
|
42698
42722
|
return {
|
|
42699
42723
|
kind: "no-route",
|
|
@@ -42702,7 +42726,7 @@ async function routeExplicit(modelSpec, model, provider) {
|
|
|
42702
42726
|
}
|
|
42703
42727
|
return { kind: "ok", primary: built, fallbacks: [] };
|
|
42704
42728
|
}
|
|
42705
|
-
async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
42729
|
+
async function routeBare(model, nativeProvider, rules, defaultProvider, cachePath) {
|
|
42706
42730
|
const matched = matchRoutingRule(model, rules) ?? [];
|
|
42707
42731
|
const entries = [...matched];
|
|
42708
42732
|
if (defaultProvider && defaultProvider.length > 0) {
|
|
@@ -42723,7 +42747,7 @@ async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
|
42723
42747
|
hint: buildCredentialHint(model, [nativeProvider]) ?? undefined
|
|
42724
42748
|
};
|
|
42725
42749
|
}
|
|
42726
|
-
const candidates = buildRoutingChain(entries, model);
|
|
42750
|
+
const candidates = buildRoutingChain(entries, model, cachePath);
|
|
42727
42751
|
const credentialed = [];
|
|
42728
42752
|
const skipped = [];
|
|
42729
42753
|
const checks4 = await Promise.all(candidates.map((candidate) => hasCredentialsForProvider(candidate.provider)));
|
|
@@ -42744,16 +42768,17 @@ async function routeBare(model, nativeProvider, rules, defaultProvider) {
|
|
|
42744
42768
|
const [primary, ...fallbacks] = credentialed;
|
|
42745
42769
|
return { kind: "ok", primary, fallbacks };
|
|
42746
42770
|
}
|
|
42747
|
-
async function route(modelSpec, rulesOverride, defaultProviderOverride) {
|
|
42771
|
+
async function route(modelSpec, rulesOverride, defaultProviderOverride, cachePath) {
|
|
42748
42772
|
const parsed = parseModelSpec(modelSpec);
|
|
42749
42773
|
if (parsed.isExplicitProvider) {
|
|
42750
|
-
return routeExplicit(modelSpec, parsed.model, parsed.provider);
|
|
42774
|
+
return routeExplicit(modelSpec, parsed.model, parsed.provider, cachePath);
|
|
42751
42775
|
}
|
|
42752
42776
|
const rules = rulesOverride ?? loadRoutingRules();
|
|
42753
42777
|
const defaultProvider = defaultProviderOverride !== undefined ? defaultProviderOverride : rulesOverride !== undefined ? undefined : loadConfig().defaultProvider;
|
|
42754
|
-
return routeBare(parsed.model, parsed.provider, rules, defaultProvider);
|
|
42778
|
+
return routeBare(parsed.model, parsed.provider, rules, defaultProvider, cachePath);
|
|
42755
42779
|
}
|
|
42756
42780
|
var init_routing_rules = __esm(() => {
|
|
42781
|
+
init_model_catalog();
|
|
42757
42782
|
init_authority();
|
|
42758
42783
|
init_profile_config();
|
|
42759
42784
|
init_auto_route();
|
|
@@ -58584,6 +58609,114 @@ var init_model_catalog2 = __esm(() => {
|
|
|
58584
58609
|
NO_CATALOG_VENDOR_SLUGS = new Set(["litellm", "ollama", "lmstudio", "lm-studio"]);
|
|
58585
58610
|
});
|
|
58586
58611
|
|
|
58612
|
+
// src/providers/model-discovery.ts
|
|
58613
|
+
function resolveBaseUrl2(catalogName) {
|
|
58614
|
+
const def = getProviderByName(catalogName);
|
|
58615
|
+
if (!def)
|
|
58616
|
+
return null;
|
|
58617
|
+
for (const envVar of def.baseUrlEnvVars ?? []) {
|
|
58618
|
+
const v = process.env[envVar];
|
|
58619
|
+
if (v)
|
|
58620
|
+
return v.replace(/\/+$/, "");
|
|
58621
|
+
}
|
|
58622
|
+
return (def.baseUrl || "").replace(/\/+$/, "") || null;
|
|
58623
|
+
}
|
|
58624
|
+
function readContextWindow(row) {
|
|
58625
|
+
for (const field of ["context_length", "context_window", "max_context_length"]) {
|
|
58626
|
+
const v = row[field];
|
|
58627
|
+
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
58628
|
+
return v;
|
|
58629
|
+
}
|
|
58630
|
+
return;
|
|
58631
|
+
}
|
|
58632
|
+
function parseOpenAIModelsList(body) {
|
|
58633
|
+
const data = body?.data;
|
|
58634
|
+
if (!Array.isArray(data))
|
|
58635
|
+
return [];
|
|
58636
|
+
const models = [];
|
|
58637
|
+
for (const raw2 of data) {
|
|
58638
|
+
if (!raw2 || typeof raw2 !== "object")
|
|
58639
|
+
continue;
|
|
58640
|
+
const row = raw2;
|
|
58641
|
+
const id = row.id;
|
|
58642
|
+
if (typeof id !== "string" || id.trim().length === 0)
|
|
58643
|
+
continue;
|
|
58644
|
+
const displayName = typeof row.display_name === "string" ? row.display_name : undefined;
|
|
58645
|
+
models.push({ id, displayName, contextWindow: readContextWindow(row) });
|
|
58646
|
+
}
|
|
58647
|
+
return models;
|
|
58648
|
+
}
|
|
58649
|
+
async function discoverProviderModels(providerName) {
|
|
58650
|
+
const cached2 = _cache2.get(providerName);
|
|
58651
|
+
if (cached2 && cached2.expiresAt > Date.now())
|
|
58652
|
+
return cached2.models;
|
|
58653
|
+
const def = getProviderByName(providerName);
|
|
58654
|
+
const descriptor = def?.modelDiscovery;
|
|
58655
|
+
if (!def || !descriptor)
|
|
58656
|
+
return [];
|
|
58657
|
+
const baseUrl = resolveBaseUrl2(providerName);
|
|
58658
|
+
if (!baseUrl)
|
|
58659
|
+
return [];
|
|
58660
|
+
const endpoint = `${baseUrl}${descriptor.path}`;
|
|
58661
|
+
let headers = {};
|
|
58662
|
+
try {
|
|
58663
|
+
const auth = await credentials.getRequestAuth(providerName, { model: "" });
|
|
58664
|
+
headers = { ...auth.headers };
|
|
58665
|
+
} catch (e) {
|
|
58666
|
+
log(`[model-discovery:${providerName}] no credentials, skipping: ${e?.message}`);
|
|
58667
|
+
return [];
|
|
58668
|
+
}
|
|
58669
|
+
let response;
|
|
58670
|
+
try {
|
|
58671
|
+
response = await fetch(endpoint, {
|
|
58672
|
+
method: "GET",
|
|
58673
|
+
headers,
|
|
58674
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
58675
|
+
});
|
|
58676
|
+
} catch (e) {
|
|
58677
|
+
log(`[model-discovery:${providerName}] fetch failed: ${e?.message}`);
|
|
58678
|
+
return [];
|
|
58679
|
+
}
|
|
58680
|
+
if (!response.ok) {
|
|
58681
|
+
log(`[model-discovery:${providerName}] HTTP ${response.status} from ${endpoint}`);
|
|
58682
|
+
return [];
|
|
58683
|
+
}
|
|
58684
|
+
let body;
|
|
58685
|
+
try {
|
|
58686
|
+
body = await response.json();
|
|
58687
|
+
} catch {
|
|
58688
|
+
log(`[model-discovery:${providerName}] response was not JSON`);
|
|
58689
|
+
return [];
|
|
58690
|
+
}
|
|
58691
|
+
const models = parseOpenAIModelsList(body);
|
|
58692
|
+
if (models.length === 0) {
|
|
58693
|
+
log(`[model-discovery:${providerName}] endpoint reachable but listed no models`);
|
|
58694
|
+
return [];
|
|
58695
|
+
}
|
|
58696
|
+
log(`[model-discovery:${providerName}] discovered ${models.length} models: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
|
|
58697
|
+
_cache2.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS3 });
|
|
58698
|
+
return models;
|
|
58699
|
+
}
|
|
58700
|
+
async function discoverContextWindow(providerName, modelId) {
|
|
58701
|
+
const models = await discoverProviderModels(providerName);
|
|
58702
|
+
const match2 = models.find((m) => m.id.toLowerCase() === modelId.toLowerCase());
|
|
58703
|
+
return match2?.contextWindow;
|
|
58704
|
+
}
|
|
58705
|
+
function rankDiscoveredModels(models) {
|
|
58706
|
+
return [...models].sort((a, b) => {
|
|
58707
|
+
const diff = (b.contextWindow ?? 0) - (a.contextWindow ?? 0);
|
|
58708
|
+
return diff !== 0 ? diff : a.id.localeCompare(b.id);
|
|
58709
|
+
});
|
|
58710
|
+
}
|
|
58711
|
+
var CACHE_TTL_MS3, FETCH_TIMEOUT_MS2 = 5000, _cache2;
|
|
58712
|
+
var init_model_discovery = __esm(() => {
|
|
58713
|
+
init_authority();
|
|
58714
|
+
init_logger();
|
|
58715
|
+
init_provider_definitions();
|
|
58716
|
+
CACHE_TTL_MS3 = 5 * 60 * 1000;
|
|
58717
|
+
_cache2 = new Map;
|
|
58718
|
+
});
|
|
58719
|
+
|
|
58587
58720
|
// src/providers/ollama-discovery.ts
|
|
58588
58721
|
function ollamaBaseUrl() {
|
|
58589
58722
|
return process.env.OLLAMA_HOST || process.env.OLLAMA_BASE_URL || "http://localhost:11434";
|
|
@@ -59153,8 +59286,22 @@ async function selectModelFromProvider(provider, tierName, recommendedModels, _f
|
|
|
59153
59286
|
const prefix = PROVIDER_MODEL_PREFIX[provider] || `${provider}@`;
|
|
59154
59287
|
const displayName = getPickerDisplayName(provider);
|
|
59155
59288
|
const def = getProviderByName(provider);
|
|
59156
|
-
if (def?.
|
|
59157
|
-
|
|
59289
|
+
if (def?.modelDiscovery) {
|
|
59290
|
+
const discovered = rankDiscoveredModels(await discoverProviderModels(provider));
|
|
59291
|
+
if (discovered.length > 0) {
|
|
59292
|
+
const discoveredModels = discovered.map((m) => ({
|
|
59293
|
+
id: m.id,
|
|
59294
|
+
name: m.displayName || m.id,
|
|
59295
|
+
description: m.contextWindow ? `${m.displayName ?? m.id} \xB7 ${Math.round(m.contextWindow / 1024)}K context` : m.displayName ?? m.id,
|
|
59296
|
+
provider: displayName,
|
|
59297
|
+
supportsTools: true,
|
|
59298
|
+
isFree: true,
|
|
59299
|
+
source: displayName
|
|
59300
|
+
}));
|
|
59301
|
+
const picked = await pickModelFromList(provider, displayName, tierName, discoveredModels);
|
|
59302
|
+
if (picked)
|
|
59303
|
+
return picked;
|
|
59304
|
+
}
|
|
59158
59305
|
}
|
|
59159
59306
|
if (provider === "ollama") {
|
|
59160
59307
|
const ollamaModels = await fetchOllamaModels2({ enrichCapabilities: false });
|
|
@@ -59333,6 +59480,7 @@ var init_model_selector = __esm(() => {
|
|
|
59333
59480
|
init_authority();
|
|
59334
59481
|
init_model_loader();
|
|
59335
59482
|
init_model_catalog2();
|
|
59483
|
+
init_model_discovery();
|
|
59336
59484
|
init_provider_definitions();
|
|
59337
59485
|
pickerProviderToFirebaseSlug = {
|
|
59338
59486
|
openrouter: "openrouter",
|
|
@@ -64740,7 +64888,7 @@ function writeProbeModelsCache(data, path2 = PROBE_MODELS_CACHE_PATH) {
|
|
|
64740
64888
|
mkdirSync14(dirname7(path2), { recursive: true });
|
|
64741
64889
|
writeFileSync16(path2, JSON.stringify(data), "utf-8");
|
|
64742
64890
|
}
|
|
64743
|
-
function isCacheFresh(data, ttlMs =
|
|
64891
|
+
function isCacheFresh(data, ttlMs = CACHE_TTL_MS4) {
|
|
64744
64892
|
if (!data?.generatedAt)
|
|
64745
64893
|
return false;
|
|
64746
64894
|
const generatedMs = Date.parse(data.generatedAt);
|
|
@@ -64748,7 +64896,7 @@ function isCacheFresh(data, ttlMs = CACHE_TTL_MS3) {
|
|
|
64748
64896
|
return false;
|
|
64749
64897
|
return Date.now() - generatedMs < ttlMs;
|
|
64750
64898
|
}
|
|
64751
|
-
async function fetchProbeModels(url2 = PROBE_MODELS_URL, timeoutMs =
|
|
64899
|
+
async function fetchProbeModels(url2 = PROBE_MODELS_URL, timeoutMs = FETCH_TIMEOUT_MS3) {
|
|
64752
64900
|
let response;
|
|
64753
64901
|
try {
|
|
64754
64902
|
response = await fetch(url2, { signal: AbortSignal.timeout(timeoutMs) });
|
|
@@ -64854,9 +65002,9 @@ function isValidResponse(raw2) {
|
|
|
64854
65002
|
return false;
|
|
64855
65003
|
return true;
|
|
64856
65004
|
}
|
|
64857
|
-
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels",
|
|
65005
|
+
var PROBE_MODELS_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/probeModels", CACHE_TTL_MS4, FETCH_TIMEOUT_MS3 = 15000, PROBE_MODELS_CACHE_PATH, _inFlight = null;
|
|
64858
65006
|
var init_probe_catalog = __esm(() => {
|
|
64859
|
-
|
|
65007
|
+
CACHE_TTL_MS4 = 60 * 60 * 1000;
|
|
64860
65008
|
PROBE_MODELS_CACHE_PATH = join24(homedir23(), ".claudish", "probe-models.json");
|
|
64861
65009
|
});
|
|
64862
65010
|
|
|
@@ -71435,7 +71583,7 @@ async function computeMainThreadContextWindow(config3, cachePath) {
|
|
|
71435
71583
|
continue;
|
|
71436
71584
|
provider = plan.primary.provider;
|
|
71437
71585
|
}
|
|
71438
|
-
const win = lookupModelForProvider(parsed.model, provider, cachePath);
|
|
71586
|
+
const win = await discoverContextWindow(provider, parsed.model) ?? lookupModelForProvider(parsed.model, provider, cachePath);
|
|
71439
71587
|
if (typeof win === "number" && win > 0) {
|
|
71440
71588
|
min = Math.min(min, win);
|
|
71441
71589
|
}
|
|
@@ -71711,6 +71859,7 @@ var init_claude_runner = __esm(() => {
|
|
|
71711
71859
|
init_model_catalog();
|
|
71712
71860
|
init_config();
|
|
71713
71861
|
init_logger();
|
|
71862
|
+
init_model_discovery();
|
|
71714
71863
|
init_profile_config();
|
|
71715
71864
|
init_model_parser();
|
|
71716
71865
|
init_routing_rules();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.20.1",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"ai"
|
|
61
61
|
],
|
|
62
62
|
"optionalDependencies": {
|
|
63
|
-
"@claudish/magmux-darwin-arm64": "7.
|
|
64
|
-
"@claudish/magmux-darwin-x64": "7.
|
|
65
|
-
"@claudish/magmux-linux-arm64": "7.
|
|
66
|
-
"@claudish/magmux-linux-x64": "7.
|
|
63
|
+
"@claudish/magmux-darwin-arm64": "7.20.1",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.20.1",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.20.1",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.20.1"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|