claudish 7.43.0 → 7.45.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 +729 -319
- 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.45.0";
|
|
733
733
|
|
|
734
734
|
// src/logger.ts
|
|
735
735
|
var exports_logger = {};
|
|
@@ -28338,6 +28338,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28338
28338
|
{ prefix: "ollama:", stripPrefix: true }
|
|
28339
28339
|
],
|
|
28340
28340
|
isLocal: true,
|
|
28341
|
+
modelDiscovery: { path: "/api/tags", format: "ollama-tags" },
|
|
28341
28342
|
description: "Local Ollama (ollama@)"
|
|
28342
28343
|
},
|
|
28343
28344
|
{
|
|
@@ -28359,6 +28360,7 @@ var init_provider_definitions = __esm(() => {
|
|
|
28359
28360
|
{ prefix: "mlstudio:", stripPrefix: true }
|
|
28360
28361
|
],
|
|
28361
28362
|
isLocal: true,
|
|
28363
|
+
modelDiscovery: { path: "/v1/models", format: "openai-models-list" },
|
|
28362
28364
|
description: "Local LM Studio (lms@)"
|
|
28363
28365
|
},
|
|
28364
28366
|
{
|
|
@@ -28553,6 +28555,217 @@ var init_auto_route = __esm(() => {
|
|
|
28553
28555
|
})();
|
|
28554
28556
|
});
|
|
28555
28557
|
|
|
28558
|
+
// src/providers/all-models-cache.ts
|
|
28559
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
28560
|
+
import { homedir as homedir8 } from "os";
|
|
28561
|
+
import { dirname as dirname5, join as join8 } from "path";
|
|
28562
|
+
function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
28563
|
+
if (!existsSync6(path))
|
|
28564
|
+
return null;
|
|
28565
|
+
let raw;
|
|
28566
|
+
try {
|
|
28567
|
+
raw = JSON.parse(readFileSync6(path, "utf-8"));
|
|
28568
|
+
} catch {
|
|
28569
|
+
return null;
|
|
28570
|
+
}
|
|
28571
|
+
if (!raw || typeof raw !== "object")
|
|
28572
|
+
return null;
|
|
28573
|
+
const data = raw;
|
|
28574
|
+
const lastUpdated = typeof data.lastUpdated === "string" ? data.lastUpdated : new Date(0).toISOString();
|
|
28575
|
+
const models = Array.isArray(data.models) ? data.models : [];
|
|
28576
|
+
const entries = Array.isArray(data.entries) ? data.entries : [];
|
|
28577
|
+
return {
|
|
28578
|
+
version: 2,
|
|
28579
|
+
lastUpdated,
|
|
28580
|
+
entries,
|
|
28581
|
+
models
|
|
28582
|
+
};
|
|
28583
|
+
}
|
|
28584
|
+
function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
28585
|
+
const existing = readAllModelsCache(path);
|
|
28586
|
+
const merged = {
|
|
28587
|
+
version: 2,
|
|
28588
|
+
lastUpdated: data.lastUpdated ?? new Date().toISOString(),
|
|
28589
|
+
entries: data.entries ?? existing?.entries ?? [],
|
|
28590
|
+
models: data.models ?? existing?.models ?? []
|
|
28591
|
+
};
|
|
28592
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
28593
|
+
writeFileSync6(path, JSON.stringify(merged), "utf-8");
|
|
28594
|
+
}
|
|
28595
|
+
var ALL_MODELS_CACHE_PATH;
|
|
28596
|
+
var init_all_models_cache = __esm(() => {
|
|
28597
|
+
ALL_MODELS_CACHE_PATH = join8(homedir8(), ".claudish", "all-models.json");
|
|
28598
|
+
});
|
|
28599
|
+
|
|
28600
|
+
// src/providers/catalog-client.ts
|
|
28601
|
+
function getCatalogEntries() {
|
|
28602
|
+
if (_memCache)
|
|
28603
|
+
return _memCache;
|
|
28604
|
+
const cache = readAllModelsCache();
|
|
28605
|
+
if (!cache)
|
|
28606
|
+
return null;
|
|
28607
|
+
if (cache.entries.length > 0) {
|
|
28608
|
+
_memCache = cache.entries;
|
|
28609
|
+
return _memCache;
|
|
28610
|
+
}
|
|
28611
|
+
if (cache.models.length > 0) {
|
|
28612
|
+
_memCache = cache.models.map((m) => ({
|
|
28613
|
+
modelId: m.id.includes("/") ? m.id.split("/").slice(1).join("/") : m.id,
|
|
28614
|
+
aliases: [],
|
|
28615
|
+
sources: { "openrouter-api": { externalId: m.id } }
|
|
28616
|
+
}));
|
|
28617
|
+
return _memCache;
|
|
28618
|
+
}
|
|
28619
|
+
return null;
|
|
28620
|
+
}
|
|
28621
|
+
function isCatalogWarm() {
|
|
28622
|
+
return _memCache !== null && _memCache.length > 0;
|
|
28623
|
+
}
|
|
28624
|
+
function externalIdFor(entry, provider) {
|
|
28625
|
+
const agg = entry.aggregators?.find((a) => a.provider === provider);
|
|
28626
|
+
if (agg?.externalId)
|
|
28627
|
+
return agg.externalId;
|
|
28628
|
+
if (provider !== "openrouter")
|
|
28629
|
+
return null;
|
|
28630
|
+
const orSource = entry.sources["openrouter-api"];
|
|
28631
|
+
if (orSource?.externalId)
|
|
28632
|
+
return orSource.externalId;
|
|
28633
|
+
for (const src of Object.values(entry.sources)) {
|
|
28634
|
+
if (src.externalId.includes("/"))
|
|
28635
|
+
return src.externalId;
|
|
28636
|
+
}
|
|
28637
|
+
return null;
|
|
28638
|
+
}
|
|
28639
|
+
function resolveExternalId(userInput, provider) {
|
|
28640
|
+
const entries = getCatalogEntries();
|
|
28641
|
+
if (userInput.includes("/")) {
|
|
28642
|
+
if (entries) {
|
|
28643
|
+
for (const entry of entries) {
|
|
28644
|
+
for (const src of Object.values(entry.sources)) {
|
|
28645
|
+
if (src.externalId === userInput)
|
|
28646
|
+
return userInput;
|
|
28647
|
+
}
|
|
28648
|
+
}
|
|
28649
|
+
}
|
|
28650
|
+
return userInput;
|
|
28651
|
+
}
|
|
28652
|
+
if (!entries)
|
|
28653
|
+
return null;
|
|
28654
|
+
const byModelId = entries.find((e) => e.modelId === userInput);
|
|
28655
|
+
if (byModelId)
|
|
28656
|
+
return externalIdFor(byModelId, provider);
|
|
28657
|
+
const byAlias = entries.find((e) => e.aliases.includes(userInput));
|
|
28658
|
+
if (byAlias) {
|
|
28659
|
+
const id = externalIdFor(byAlias, provider);
|
|
28660
|
+
if (id)
|
|
28661
|
+
return id;
|
|
28662
|
+
}
|
|
28663
|
+
for (const entry of entries) {
|
|
28664
|
+
for (const src of Object.values(entry.sources)) {
|
|
28665
|
+
if (src.externalId === userInput) {
|
|
28666
|
+
const id = externalIdFor(entry, provider);
|
|
28667
|
+
if (id)
|
|
28668
|
+
return id;
|
|
28669
|
+
}
|
|
28670
|
+
}
|
|
28671
|
+
}
|
|
28672
|
+
const suffix = `/${userInput}`;
|
|
28673
|
+
for (const entry of entries) {
|
|
28674
|
+
const id = externalIdFor(entry, provider);
|
|
28675
|
+
if (id?.endsWith(suffix))
|
|
28676
|
+
return id;
|
|
28677
|
+
}
|
|
28678
|
+
const lowerSuffix = `/${userInput.toLowerCase()}`;
|
|
28679
|
+
for (const entry of entries) {
|
|
28680
|
+
const id = externalIdFor(entry, provider);
|
|
28681
|
+
if (id?.toLowerCase().endsWith(lowerSuffix))
|
|
28682
|
+
return id;
|
|
28683
|
+
}
|
|
28684
|
+
return null;
|
|
28685
|
+
}
|
|
28686
|
+
function resolveModelNameSync(userInput, targetProvider) {
|
|
28687
|
+
if (targetProvider !== "openrouter" && userInput.includes("/")) {
|
|
28688
|
+
return { resolvedId: userInput, wasResolved: false, sourceLabel: "passthrough" };
|
|
28689
|
+
}
|
|
28690
|
+
const resolved = resolveExternalId(userInput, targetProvider);
|
|
28691
|
+
if (!resolved || resolved === userInput) {
|
|
28692
|
+
return { resolvedId: userInput, wasResolved: false, sourceLabel: "passthrough" };
|
|
28693
|
+
}
|
|
28694
|
+
return { resolvedId: resolved, wasResolved: true, sourceLabel: `${targetProvider} catalog` };
|
|
28695
|
+
}
|
|
28696
|
+
function resolveTargetForCatalog(target, isExplicitProvider, model, provider, resolve = resolveModelNameSync) {
|
|
28697
|
+
if (!isExplicitProvider)
|
|
28698
|
+
return { target, resolution: null };
|
|
28699
|
+
const resolution = resolve(model, provider);
|
|
28700
|
+
return {
|
|
28701
|
+
target: resolution.wasResolved ? `${provider}@${resolution.resolvedId}` : target,
|
|
28702
|
+
resolution
|
|
28703
|
+
};
|
|
28704
|
+
}
|
|
28705
|
+
function logResolution(userInput, result, quiet = false) {
|
|
28706
|
+
if (result.wasResolved && !quiet) {
|
|
28707
|
+
process.stderr.write(`[Model] Resolved "${userInput}" \u2192 "${result.resolvedId}" (${result.sourceLabel})
|
|
28708
|
+
`);
|
|
28709
|
+
}
|
|
28710
|
+
}
|
|
28711
|
+
async function refreshCatalog(timeoutMs) {
|
|
28712
|
+
let response;
|
|
28713
|
+
try {
|
|
28714
|
+
response = await fetch(FIREBASE_CATALOG_URL, { signal: AbortSignal.timeout(timeoutMs) });
|
|
28715
|
+
} catch (err) {
|
|
28716
|
+
const name = err?.name;
|
|
28717
|
+
const reason = name === "TimeoutError" || name === "AbortError" ? "timeout" : "network";
|
|
28718
|
+
return { kind: "fetch_failed", reason };
|
|
28719
|
+
}
|
|
28720
|
+
if (!response.ok)
|
|
28721
|
+
return { kind: "fetch_failed", reason: "http_error" };
|
|
28722
|
+
let data;
|
|
28723
|
+
try {
|
|
28724
|
+
data = await response.json();
|
|
28725
|
+
} catch {
|
|
28726
|
+
return { kind: "fetch_failed", reason: "network" };
|
|
28727
|
+
}
|
|
28728
|
+
if (!Array.isArray(data.models) || data.models.length === 0) {
|
|
28729
|
+
return { kind: "fetch_failed", reason: "empty" };
|
|
28730
|
+
}
|
|
28731
|
+
const backwardCompatModels = [];
|
|
28732
|
+
for (const entry of data.models) {
|
|
28733
|
+
const id = externalIdFor(entry, "openrouter");
|
|
28734
|
+
if (id)
|
|
28735
|
+
backwardCompatModels.push({ id });
|
|
28736
|
+
}
|
|
28737
|
+
_memCache = data.models;
|
|
28738
|
+
writeAllModelsCache({ entries: data.models, models: backwardCompatModels });
|
|
28739
|
+
_warmPromise = Promise.resolve();
|
|
28740
|
+
return { kind: "refreshed", modelCount: data.models.length };
|
|
28741
|
+
}
|
|
28742
|
+
async function warmCatalog() {
|
|
28743
|
+
if (!_warmPromise) {
|
|
28744
|
+
_warmPromise = refreshCatalog(8000).then(() => {
|
|
28745
|
+
return;
|
|
28746
|
+
});
|
|
28747
|
+
}
|
|
28748
|
+
await _warmPromise;
|
|
28749
|
+
}
|
|
28750
|
+
async function ensureCatalogReady(timeoutMs = 5000) {
|
|
28751
|
+
if (isCatalogWarm())
|
|
28752
|
+
return;
|
|
28753
|
+
if (!_warmPromise) {
|
|
28754
|
+
_warmPromise = refreshCatalog(8000).then(() => {
|
|
28755
|
+
return;
|
|
28756
|
+
});
|
|
28757
|
+
}
|
|
28758
|
+
await Promise.race([
|
|
28759
|
+
_warmPromise,
|
|
28760
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
28761
|
+
]);
|
|
28762
|
+
}
|
|
28763
|
+
var FIREBASE_CATALOG_URL, _memCache = null, _warmPromise = null;
|
|
28764
|
+
var init_catalog_client = __esm(() => {
|
|
28765
|
+
init_all_models_cache();
|
|
28766
|
+
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";
|
|
28767
|
+
});
|
|
28768
|
+
|
|
28556
28769
|
// ../../node_modules/.bun/zod@4.1.13/node_modules/zod/index.js
|
|
28557
28770
|
var init_zod = __esm(() => {
|
|
28558
28771
|
init_external2();
|
|
@@ -28612,48 +28825,6 @@ var init_remote_provider_types = __esm(() => {
|
|
|
28612
28825
|
};
|
|
28613
28826
|
});
|
|
28614
28827
|
|
|
28615
|
-
// src/providers/all-models-cache.ts
|
|
28616
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
28617
|
-
import { homedir as homedir8 } from "os";
|
|
28618
|
-
import { dirname as dirname5, join as join8 } from "path";
|
|
28619
|
-
function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
28620
|
-
if (!existsSync6(path))
|
|
28621
|
-
return null;
|
|
28622
|
-
let raw;
|
|
28623
|
-
try {
|
|
28624
|
-
raw = JSON.parse(readFileSync6(path, "utf-8"));
|
|
28625
|
-
} catch {
|
|
28626
|
-
return null;
|
|
28627
|
-
}
|
|
28628
|
-
if (!raw || typeof raw !== "object")
|
|
28629
|
-
return null;
|
|
28630
|
-
const data = raw;
|
|
28631
|
-
const lastUpdated = typeof data.lastUpdated === "string" ? data.lastUpdated : new Date(0).toISOString();
|
|
28632
|
-
const models = Array.isArray(data.models) ? data.models : [];
|
|
28633
|
-
const entries = Array.isArray(data.entries) ? data.entries : [];
|
|
28634
|
-
return {
|
|
28635
|
-
version: 2,
|
|
28636
|
-
lastUpdated,
|
|
28637
|
-
entries,
|
|
28638
|
-
models
|
|
28639
|
-
};
|
|
28640
|
-
}
|
|
28641
|
-
function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
28642
|
-
const existing = readAllModelsCache(path);
|
|
28643
|
-
const merged = {
|
|
28644
|
-
version: 2,
|
|
28645
|
-
lastUpdated: data.lastUpdated ?? new Date().toISOString(),
|
|
28646
|
-
entries: data.entries ?? existing?.entries ?? [],
|
|
28647
|
-
models: data.models ?? existing?.models ?? []
|
|
28648
|
-
};
|
|
28649
|
-
mkdirSync6(dirname5(path), { recursive: true });
|
|
28650
|
-
writeFileSync6(path, JSON.stringify(merged), "utf-8");
|
|
28651
|
-
}
|
|
28652
|
-
var ALL_MODELS_CACHE_PATH;
|
|
28653
|
-
var init_all_models_cache = __esm(() => {
|
|
28654
|
-
ALL_MODELS_CACHE_PATH = join8(homedir8(), ".claudish", "all-models.json");
|
|
28655
|
-
});
|
|
28656
|
-
|
|
28657
28828
|
// src/adapters/model-catalog.ts
|
|
28658
28829
|
function lookupModel(modelId, cachePath) {
|
|
28659
28830
|
const entry = findCacheEntry(modelId, cachePath);
|
|
@@ -30447,10 +30618,10 @@ ${lines.join(`
|
|
|
30447
30618
|
}
|
|
30448
30619
|
var ANTIGRAVITY_BASE = "https://cloudcode-pa.googleapis.com", ANTIGRAVITY_ENDPOINT, MAX_RETRY_ATTEMPTS = 3, DEFAULT_RATE_LIMIT_DELAY_MS = 1e4, REASONING_TIER_RANK;
|
|
30449
30620
|
var init_antigravity = __esm(() => {
|
|
30621
|
+
init_model_catalog();
|
|
30450
30622
|
init_antigravity_token();
|
|
30451
|
-
init_authority();
|
|
30452
30623
|
init_antigravity_user();
|
|
30453
|
-
|
|
30624
|
+
init_authority();
|
|
30454
30625
|
init_gemini_queue();
|
|
30455
30626
|
init_logger();
|
|
30456
30627
|
ANTIGRAVITY_ENDPOINT = `${ANTIGRAVITY_BASE}/v1internal:streamGenerateContent?alt=sse`;
|
|
@@ -34927,6 +35098,11 @@ var init_digest = __esm(() => {
|
|
|
34927
35098
|
});
|
|
34928
35099
|
|
|
34929
35100
|
// src/providers/ollama-discovery.ts
|
|
35101
|
+
var exports_ollama_discovery = {};
|
|
35102
|
+
__export(exports_ollama_discovery, {
|
|
35103
|
+
ollamaBaseUrl: () => ollamaBaseUrl,
|
|
35104
|
+
fetchOllamaModels: () => fetchOllamaModels
|
|
35105
|
+
});
|
|
34930
35106
|
function ollamaBaseUrl() {
|
|
34931
35107
|
return process.env.OLLAMA_HOST || process.env.OLLAMA_BASE_URL || "http://localhost:11434";
|
|
34932
35108
|
}
|
|
@@ -36495,6 +36671,10 @@ function warnGoAliasDeprecatedOnce() {
|
|
|
36495
36671
|
process.stderr.write(`[claudish] go@ is deprecated \u2014 use ag@<model> (Antigravity). Routing there.
|
|
36496
36672
|
`);
|
|
36497
36673
|
}
|
|
36674
|
+
function parseModelChain(modelSpec) {
|
|
36675
|
+
const parts = modelSpec.split(MODEL_CHAIN_SEPARATOR).map((s) => s.trim()).filter(Boolean);
|
|
36676
|
+
return parts.length > 0 ? parts : [modelSpec];
|
|
36677
|
+
}
|
|
36498
36678
|
function parseModelSpec(modelSpec) {
|
|
36499
36679
|
const original = modelSpec;
|
|
36500
36680
|
if (modelSpec.startsWith("http://") || modelSpec.startsWith("https://")) {
|
|
@@ -36594,7 +36774,7 @@ function getLegacySyntaxWarning(parsed) {
|
|
|
36594
36774
|
return `Deprecation warning: "${parsed.original}" uses legacy prefix syntax.
|
|
36595
36775
|
` + ` Consider using: ${newSyntax}`;
|
|
36596
36776
|
}
|
|
36597
|
-
var PROVIDER_SHORTCUTS, _goDeprecationWarned = false, LOCAL_PROVIDERS, NATIVE_MODEL_PATTERNS, LEGACY_PREFIX_PATTERNS;
|
|
36777
|
+
var PROVIDER_SHORTCUTS, _goDeprecationWarned = false, LOCAL_PROVIDERS, NATIVE_MODEL_PATTERNS, LEGACY_PREFIX_PATTERNS, MODEL_CHAIN_SEPARATOR = "+";
|
|
36598
36778
|
var init_model_parser = __esm(() => {
|
|
36599
36779
|
init_provider_definitions();
|
|
36600
36780
|
PROVIDER_SHORTCUTS = getShortcuts();
|
|
@@ -40501,6 +40681,13 @@ class ComposedHandler {
|
|
|
40501
40681
|
response = next;
|
|
40502
40682
|
}
|
|
40503
40683
|
}
|
|
40684
|
+
describeComposition() {
|
|
40685
|
+
return {
|
|
40686
|
+
transport: this.provider.name,
|
|
40687
|
+
streamFormat: this.resolveStreamFormat(),
|
|
40688
|
+
endpoint: this.provider.getEndpoint(this.bareModelName)
|
|
40689
|
+
};
|
|
40690
|
+
}
|
|
40504
40691
|
resolveStreamFormat() {
|
|
40505
40692
|
return this.provider.overrideStreamFormat?.() ?? this.explicitAdapter?.getStreamFormat() ?? this.modelAdapter?.getStreamFormat() ?? this.getAdapter().getStreamFormat();
|
|
40506
40693
|
}
|
|
@@ -40796,6 +40983,7 @@ __export(exports_devin_models, {
|
|
|
40796
40983
|
getServedDevinModels: () => getServedDevinModels,
|
|
40797
40984
|
fetchDevinModelConfigs: () => fetchDevinModelConfigs,
|
|
40798
40985
|
fetchDevinAllowedUids: () => fetchDevinAllowedUids,
|
|
40986
|
+
decodeModelConfigs: () => decodeModelConfigs,
|
|
40799
40987
|
_resetDevinModelCache: () => _resetDevinModelCache
|
|
40800
40988
|
});
|
|
40801
40989
|
function unaryMetadata(apiKey) {
|
|
@@ -40835,11 +41023,59 @@ function decodeModelDetails(payload) {
|
|
|
40835
41023
|
}
|
|
40836
41024
|
return { maxOutput, family };
|
|
40837
41025
|
}
|
|
41026
|
+
function decodeFamilyMetadata(payload) {
|
|
41027
|
+
let groupLabel;
|
|
41028
|
+
const axes = [];
|
|
41029
|
+
for (const sub of parseTLV(payload)) {
|
|
41030
|
+
if (sub.no === 1 && sub.wire === 2) {
|
|
41031
|
+
groupLabel = readString(sub) || undefined;
|
|
41032
|
+
continue;
|
|
41033
|
+
}
|
|
41034
|
+
if (sub.no !== 2 || sub.wire !== 2)
|
|
41035
|
+
continue;
|
|
41036
|
+
const axis = { key: "", enabled: false };
|
|
41037
|
+
for (const entry of parseTLV(sub.payload)) {
|
|
41038
|
+
if (entry.no === 1 && entry.wire === 2)
|
|
41039
|
+
axis.key = readString(entry);
|
|
41040
|
+
else if (entry.no === 2 && entry.wire === 2) {
|
|
41041
|
+
for (const value of parseTLV(entry.payload)) {
|
|
41042
|
+
if (value.no === 1 && value.wire === 0)
|
|
41043
|
+
axis.enabled = readVarintValue(value) === 1;
|
|
41044
|
+
else if (value.no === 2 && value.wire === 2)
|
|
41045
|
+
axis.label = readString(value) || undefined;
|
|
41046
|
+
}
|
|
41047
|
+
}
|
|
41048
|
+
}
|
|
41049
|
+
if (axis.key)
|
|
41050
|
+
axes.push(axis);
|
|
41051
|
+
}
|
|
41052
|
+
return { groupLabel, axes };
|
|
41053
|
+
}
|
|
41054
|
+
function decodePromo(payload) {
|
|
41055
|
+
for (const sub of parseTLV(payload)) {
|
|
41056
|
+
if (sub.wire !== 2)
|
|
41057
|
+
continue;
|
|
41058
|
+
for (const inner of parseTLV(sub.payload)) {
|
|
41059
|
+
if (inner.no === 1 && inner.wire === 0) {
|
|
41060
|
+
const expiresAt = readVarintValue(inner);
|
|
41061
|
+
if (expiresAt > 0)
|
|
41062
|
+
return { expiresAt };
|
|
41063
|
+
}
|
|
41064
|
+
}
|
|
41065
|
+
}
|
|
41066
|
+
return;
|
|
41067
|
+
}
|
|
40838
41068
|
function decodeModelConfig(payload) {
|
|
40839
41069
|
let uid = "";
|
|
40840
41070
|
let displayName = "";
|
|
40841
41071
|
let contextWindow = 0;
|
|
40842
41072
|
let details = { maxOutput: 0, family: "" };
|
|
41073
|
+
let family = { axes: [] };
|
|
41074
|
+
let creditMultiplier;
|
|
41075
|
+
let costTier;
|
|
41076
|
+
let isFamilyDefault = false;
|
|
41077
|
+
let isRecommended = false;
|
|
41078
|
+
let promo;
|
|
40843
41079
|
for (const field of parseTLV(payload)) {
|
|
40844
41080
|
if (field.no === 22 && field.wire === 2)
|
|
40845
41081
|
uid = readString(field);
|
|
@@ -40849,10 +41085,34 @@ function decodeModelConfig(payload) {
|
|
|
40849
41085
|
contextWindow = readVarintValue(field);
|
|
40850
41086
|
else if (field.no === 23 && field.wire === 2)
|
|
40851
41087
|
details = decodeModelDetails(field.payload);
|
|
41088
|
+
else if (field.no === 30 && field.wire === 2)
|
|
41089
|
+
family = decodeFamilyMetadata(field.payload);
|
|
41090
|
+
else if (field.no === 3 && field.wire === 5)
|
|
41091
|
+
creditMultiplier = readFloat32LE(field);
|
|
41092
|
+
else if (field.no === 24 && field.wire === 0)
|
|
41093
|
+
costTier = readVarintValue(field);
|
|
41094
|
+
else if (field.no === 31 && field.wire === 0)
|
|
41095
|
+
isFamilyDefault = readVarintValue(field) === 1;
|
|
41096
|
+
else if (field.no === 11 && field.wire === 0)
|
|
41097
|
+
isRecommended = readVarintValue(field) === 1;
|
|
41098
|
+
else if (field.no === 19 && field.wire === 2)
|
|
41099
|
+
promo = decodePromo(field.payload);
|
|
40852
41100
|
}
|
|
40853
41101
|
if (!uid)
|
|
40854
41102
|
return null;
|
|
40855
|
-
return {
|
|
41103
|
+
return {
|
|
41104
|
+
uid,
|
|
41105
|
+
displayName: displayName || uid,
|
|
41106
|
+
contextWindow,
|
|
41107
|
+
...details,
|
|
41108
|
+
groupLabel: family.groupLabel,
|
|
41109
|
+
axes: family.axes,
|
|
41110
|
+
creditMultiplier,
|
|
41111
|
+
costTier,
|
|
41112
|
+
isFamilyDefault,
|
|
41113
|
+
isRecommended,
|
|
41114
|
+
promo
|
|
41115
|
+
};
|
|
40856
41116
|
}
|
|
40857
41117
|
function topLevelDelimited(body, fieldNumber) {
|
|
40858
41118
|
return parseTLV(body).filter((field) => field.no === fieldNumber && field.wire === 2);
|
|
@@ -40861,13 +41121,17 @@ async function fetchDevinModelConfigs(apiKey) {
|
|
|
40861
41121
|
const body = await postUnary(MODEL_CONFIGS_PATH, apiKey);
|
|
40862
41122
|
if (!body)
|
|
40863
41123
|
return [];
|
|
41124
|
+
const configs = decodeModelConfigs(body);
|
|
41125
|
+
log(`[Devin] GetCliModelConfigs: ${configs.length} configs`);
|
|
41126
|
+
return configs;
|
|
41127
|
+
}
|
|
41128
|
+
function decodeModelConfigs(body) {
|
|
40864
41129
|
const configs = [];
|
|
40865
41130
|
for (const field of topLevelDelimited(body, 1)) {
|
|
40866
41131
|
const config2 = decodeModelConfig(field.payload);
|
|
40867
41132
|
if (config2)
|
|
40868
41133
|
configs.push(config2);
|
|
40869
41134
|
}
|
|
40870
|
-
log(`[Devin] GetCliModelConfigs: ${configs.length} configs`);
|
|
40871
41135
|
return configs;
|
|
40872
41136
|
}
|
|
40873
41137
|
async function fetchDevinAllowedUids(apiKey) {
|
|
@@ -40923,7 +41187,246 @@ var init_devin_models = __esm(() => {
|
|
|
40923
41187
|
ROSTER_TTL_MS = 5 * 60 * 1000;
|
|
40924
41188
|
});
|
|
40925
41189
|
|
|
41190
|
+
// src/providers/model-resolvers/types.ts
|
|
41191
|
+
function nonEmpty(value) {
|
|
41192
|
+
const trimmed2 = value?.trim();
|
|
41193
|
+
return trimmed2 ? trimmed2 : undefined;
|
|
41194
|
+
}
|
|
41195
|
+
function groupKeyOf(entry) {
|
|
41196
|
+
return nonEmpty(entry.groupLabel) ?? nonEmpty(entry.family) ?? entry.wireId;
|
|
41197
|
+
}
|
|
41198
|
+
function offerIsLive(offer, now = Date.now()) {
|
|
41199
|
+
if (!offer)
|
|
41200
|
+
return false;
|
|
41201
|
+
if (offer.expiresAt === undefined)
|
|
41202
|
+
return true;
|
|
41203
|
+
return offer.expiresAt * 1000 > now;
|
|
41204
|
+
}
|
|
41205
|
+
|
|
41206
|
+
// src/providers/model-resolvers/devin.ts
|
|
41207
|
+
var exports_devin = {};
|
|
41208
|
+
__export(exports_devin, {
|
|
41209
|
+
devinRosterEntry: () => devinRosterEntry,
|
|
41210
|
+
devinHasSpeedPremium: () => devinHasSpeedPremium,
|
|
41211
|
+
devinEffortOf: () => devinEffortOf,
|
|
41212
|
+
DevinModelResolver: () => DevinModelResolver
|
|
41213
|
+
});
|
|
41214
|
+
function toEffortLevel(label) {
|
|
41215
|
+
const normalised = label?.toLowerCase().replace(/[^a-z]/g, "");
|
|
41216
|
+
if (!normalised)
|
|
41217
|
+
return;
|
|
41218
|
+
if (normalised === "nothinking")
|
|
41219
|
+
return "none";
|
|
41220
|
+
return isEffortLevel(normalised) ? normalised : undefined;
|
|
41221
|
+
}
|
|
41222
|
+
function effortFromUid(uid) {
|
|
41223
|
+
for (const part of uid.toLowerCase().split("-").reverse()) {
|
|
41224
|
+
if (isEffortLevel(part))
|
|
41225
|
+
return part;
|
|
41226
|
+
if (!SPEED_SUFFIXES.includes(part) && part !== "1m")
|
|
41227
|
+
break;
|
|
41228
|
+
}
|
|
41229
|
+
return;
|
|
41230
|
+
}
|
|
41231
|
+
function devinEffortOf(config2) {
|
|
41232
|
+
const axis = config2.axes.find((a) => EFFORT_AXIS_KEYS.includes(a.key.toLowerCase()));
|
|
41233
|
+
return toEffortLevel(axis?.label) ?? effortFromUid(config2.uid);
|
|
41234
|
+
}
|
|
41235
|
+
function devinHasSpeedPremium(config2) {
|
|
41236
|
+
const axis = config2.axes.find((a) => a.key.toLowerCase() === SPEED_AXIS_KEY);
|
|
41237
|
+
if (axis)
|
|
41238
|
+
return axis.enabled;
|
|
41239
|
+
return SPEED_SUFFIXES.some((suffix) => config2.uid.toLowerCase().endsWith(`-${suffix}`));
|
|
41240
|
+
}
|
|
41241
|
+
function namesEffortTier(id) {
|
|
41242
|
+
return id.toLowerCase().split("-").some((part) => isEffortLevel(part));
|
|
41243
|
+
}
|
|
41244
|
+
function modifiersOf(config2) {
|
|
41245
|
+
const parts = config2.uid.toLowerCase().split("-");
|
|
41246
|
+
const named = SPEED_SUFFIXES.filter((suffix) => parts.includes(suffix));
|
|
41247
|
+
if (named.length > 0)
|
|
41248
|
+
return named;
|
|
41249
|
+
return devinHasSpeedPremium(config2) ? ["premium"] : [];
|
|
41250
|
+
}
|
|
41251
|
+
function devinRosterEntry(config2) {
|
|
41252
|
+
return {
|
|
41253
|
+
wireId: config2.uid,
|
|
41254
|
+
displayName: config2.displayName,
|
|
41255
|
+
contextWindow: config2.contextWindow,
|
|
41256
|
+
groupLabel: config2.groupLabel,
|
|
41257
|
+
family: config2.family,
|
|
41258
|
+
costFactor: config2.creditMultiplier,
|
|
41259
|
+
costTier: config2.costTier,
|
|
41260
|
+
isFamilyDefault: config2.isFamilyDefault,
|
|
41261
|
+
isRecommended: config2.isRecommended,
|
|
41262
|
+
axes: config2.axes,
|
|
41263
|
+
offer: config2.promo ? { kind: "promo", expiresAt: config2.promo.expiresAt } : undefined
|
|
41264
|
+
};
|
|
41265
|
+
}
|
|
41266
|
+
function asConfig(entry) {
|
|
41267
|
+
return {
|
|
41268
|
+
uid: entry.wireId,
|
|
41269
|
+
displayName: entry.displayName ?? entry.wireId,
|
|
41270
|
+
contextWindow: entry.contextWindow ?? 0,
|
|
41271
|
+
maxOutput: 0,
|
|
41272
|
+
family: entry.family ?? "",
|
|
41273
|
+
groupLabel: entry.groupLabel,
|
|
41274
|
+
axes: entry.axes ?? [],
|
|
41275
|
+
creditMultiplier: entry.costFactor,
|
|
41276
|
+
costTier: entry.costTier,
|
|
41277
|
+
isFamilyDefault: entry.isFamilyDefault ?? false,
|
|
41278
|
+
isRecommended: entry.isRecommended ?? false
|
|
41279
|
+
};
|
|
41280
|
+
}
|
|
41281
|
+
function byCost(a, b) {
|
|
41282
|
+
const tier = (a.costTier ?? Number.MAX_SAFE_INTEGER) - (b.costTier ?? Number.MAX_SAFE_INTEGER);
|
|
41283
|
+
if (tier !== 0)
|
|
41284
|
+
return tier;
|
|
41285
|
+
const cost = (a.costFactor ?? Number.MAX_SAFE_INTEGER) - (b.costFactor ?? Number.MAX_SAFE_INTEGER);
|
|
41286
|
+
if (cost !== 0)
|
|
41287
|
+
return cost;
|
|
41288
|
+
const length = a.wireId.length - b.wireId.length;
|
|
41289
|
+
return length !== 0 ? length : a.wireId.localeCompare(b.wireId);
|
|
41290
|
+
}
|
|
41291
|
+
function defaultOf(group) {
|
|
41292
|
+
const declared = group.find((entry) => entry.isFamilyDefault);
|
|
41293
|
+
if (declared)
|
|
41294
|
+
return declared;
|
|
41295
|
+
const plain = group.filter((entry) => !devinHasSpeedPremium(asConfig(entry)));
|
|
41296
|
+
const pool = plain.length > 0 ? plain : group;
|
|
41297
|
+
const tierless = pool.filter((entry) => !namesEffortTier(entry.wireId));
|
|
41298
|
+
return [...tierless.length > 0 ? tierless : pool].sort(byCost)[0];
|
|
41299
|
+
}
|
|
41300
|
+
function keyOf(entry) {
|
|
41301
|
+
return `${groupKeyOf(entry)}\x00${entry.contextWindow ?? 0}`;
|
|
41302
|
+
}
|
|
41303
|
+
function formatWindow(tokens) {
|
|
41304
|
+
return tokens >= 1e6 ? `${Math.round(tokens / 1e5) / 10}M`.replace(".0M", "M") : `${Math.round(tokens / 1000)}K`;
|
|
41305
|
+
}
|
|
41306
|
+
|
|
41307
|
+
class DevinModelResolver {
|
|
41308
|
+
provider = "devin";
|
|
41309
|
+
collapse(roster) {
|
|
41310
|
+
const groups = new Map;
|
|
41311
|
+
for (const entry of roster) {
|
|
41312
|
+
const key = keyOf(entry);
|
|
41313
|
+
const bucket = groups.get(key);
|
|
41314
|
+
if (bucket)
|
|
41315
|
+
bucket.push(entry);
|
|
41316
|
+
else
|
|
41317
|
+
groups.set(key, [entry]);
|
|
41318
|
+
}
|
|
41319
|
+
const windowsPerLabel = new Map;
|
|
41320
|
+
for (const entry of roster) {
|
|
41321
|
+
const label = groupKeyOf(entry);
|
|
41322
|
+
const seen = windowsPerLabel.get(label) ?? new Set;
|
|
41323
|
+
seen.add(entry.contextWindow ?? 0);
|
|
41324
|
+
windowsPerLabel.set(label, seen);
|
|
41325
|
+
}
|
|
41326
|
+
const choices = [];
|
|
41327
|
+
for (const group of groups.values()) {
|
|
41328
|
+
const chosen = defaultOf(group);
|
|
41329
|
+
const label = groupKeyOf(chosen);
|
|
41330
|
+
const ambiguous = (windowsPerLabel.get(label)?.size ?? 1) > 1;
|
|
41331
|
+
const window2 = chosen.contextWindow ?? 0;
|
|
41332
|
+
const variants = group.map((entry) => {
|
|
41333
|
+
const config2 = asConfig(entry);
|
|
41334
|
+
return {
|
|
41335
|
+
wireId: entry.wireId,
|
|
41336
|
+
effort: devinEffortOf(config2),
|
|
41337
|
+
modifiers: modifiersOf(config2),
|
|
41338
|
+
costFactor: entry.costFactor
|
|
41339
|
+
};
|
|
41340
|
+
});
|
|
41341
|
+
choices.push({
|
|
41342
|
+
id: chosen.wireId,
|
|
41343
|
+
displayName: ambiguous && window2 > 0 ? `${label} (${formatWindow(window2)})` : label,
|
|
41344
|
+
contextWindow: chosen.contextWindow,
|
|
41345
|
+
variants,
|
|
41346
|
+
costFactor: chosen.costFactor,
|
|
41347
|
+
offer: chosen.offer,
|
|
41348
|
+
isRecommended: chosen.isRecommended
|
|
41349
|
+
});
|
|
41350
|
+
}
|
|
41351
|
+
return choices;
|
|
41352
|
+
}
|
|
41353
|
+
expand(selection, roster, ctx) {
|
|
41354
|
+
const requested = selection.trim();
|
|
41355
|
+
if (!requested || roster.length === 0)
|
|
41356
|
+
return requested || selection;
|
|
41357
|
+
const groups = new Map;
|
|
41358
|
+
for (const entry of roster) {
|
|
41359
|
+
const key = keyOf(entry);
|
|
41360
|
+
const bucket = groups.get(key);
|
|
41361
|
+
if (bucket)
|
|
41362
|
+
bucket.push(entry);
|
|
41363
|
+
else
|
|
41364
|
+
groups.set(key, [entry]);
|
|
41365
|
+
}
|
|
41366
|
+
const lower = requested.toLowerCase();
|
|
41367
|
+
const exact = roster.find((entry) => entry.wireId.toLowerCase() === lower);
|
|
41368
|
+
if (exact) {
|
|
41369
|
+
if (!ctx.effort)
|
|
41370
|
+
return exact.wireId;
|
|
41371
|
+
const group = groups.get(keyOf(exact));
|
|
41372
|
+
if (exact.wireId === defaultOf(group).wireId)
|
|
41373
|
+
return pickForEffort(group, ctx.effort).wireId;
|
|
41374
|
+
if (namesEffortTier(exact.wireId))
|
|
41375
|
+
return exact.wireId;
|
|
41376
|
+
return pickForEffort(group, ctx.effort).wireId;
|
|
41377
|
+
}
|
|
41378
|
+
const named = roster.filter((entry) => {
|
|
41379
|
+
const label = nonEmpty(entry.groupLabel)?.toLowerCase();
|
|
41380
|
+
const family = nonEmpty(entry.family)?.toLowerCase();
|
|
41381
|
+
return label === lower || family === lower;
|
|
41382
|
+
});
|
|
41383
|
+
const pool = named.length > 0 ? named : roster.filter((entry) => entry.wireId.toLowerCase().startsWith(`${lower}-`));
|
|
41384
|
+
if (pool.length === 0)
|
|
41385
|
+
return requested;
|
|
41386
|
+
if (named.length === 0 && new Set(pool.map(keyOf)).size > 1)
|
|
41387
|
+
return requested;
|
|
41388
|
+
const chosen = pool.filter((entry) => entry.isFamilyDefault).sort(byCost)[0] ?? pool.slice().sort(byCost)[0];
|
|
41389
|
+
return pickForEffort(groups.get(keyOf(chosen)), ctx.effort).wireId;
|
|
41390
|
+
}
|
|
41391
|
+
}
|
|
41392
|
+
function pickForEffort(group, effort) {
|
|
41393
|
+
if (!effort)
|
|
41394
|
+
return defaultOf(group);
|
|
41395
|
+
const plain = group.filter((entry) => !devinHasSpeedPremium(asConfig(entry)));
|
|
41396
|
+
const pool = plain.length > 0 ? plain : group;
|
|
41397
|
+
const tiered = pool.map((entry) => ({ entry, effort: devinEffortOf(asConfig(entry)) })).filter((row) => row.effort !== undefined);
|
|
41398
|
+
if (tiered.length === 0)
|
|
41399
|
+
return defaultOf(group);
|
|
41400
|
+
const target = EFFORT_LEVELS.indexOf(effort);
|
|
41401
|
+
const ranked = tiered.slice().sort((a, b) => {
|
|
41402
|
+
const distanceA = Math.abs(EFFORT_LEVELS.indexOf(a.effort) - target);
|
|
41403
|
+
const distanceB = Math.abs(EFFORT_LEVELS.indexOf(b.effort) - target);
|
|
41404
|
+
if (distanceA !== distanceB)
|
|
41405
|
+
return distanceA - distanceB;
|
|
41406
|
+
const levelA = EFFORT_LEVELS.indexOf(a.effort);
|
|
41407
|
+
const levelB = EFFORT_LEVELS.indexOf(b.effort);
|
|
41408
|
+
if (levelA !== levelB)
|
|
41409
|
+
return levelB - levelA;
|
|
41410
|
+
const defaultA = a.entry.isFamilyDefault ? 0 : 1;
|
|
41411
|
+
const defaultB = b.entry.isFamilyDefault ? 0 : 1;
|
|
41412
|
+
if (defaultA !== defaultB)
|
|
41413
|
+
return defaultA - defaultB;
|
|
41414
|
+
return byCost(a.entry, b.entry);
|
|
41415
|
+
});
|
|
41416
|
+
return ranked[0].entry;
|
|
41417
|
+
}
|
|
41418
|
+
var EFFORT_AXIS_KEYS, SPEED_AXIS_KEY = "fast mode", SPEED_SUFFIXES;
|
|
41419
|
+
var init_devin = __esm(() => {
|
|
41420
|
+
init_base_api_format();
|
|
41421
|
+
EFFORT_AXIS_KEYS = ["effort", "reasoning effort"];
|
|
41422
|
+
SPEED_SUFFIXES = ["fast", "priority"];
|
|
41423
|
+
});
|
|
41424
|
+
|
|
40926
41425
|
// src/providers/model-discovery.ts
|
|
41426
|
+
function toRosterEntry(model) {
|
|
41427
|
+
const { id, ...rest } = model;
|
|
41428
|
+
return { wireId: id, ...rest };
|
|
41429
|
+
}
|
|
40927
41430
|
function resolveBaseUrl(catalogName) {
|
|
40928
41431
|
const def = getProviderByName(catalogName);
|
|
40929
41432
|
if (!def)
|
|
@@ -40990,26 +41493,46 @@ async function discoverProviderModels(providerName) {
|
|
|
40990
41493
|
log(`[model-discovery:${providerName}] no models for this subscription`);
|
|
40991
41494
|
return [];
|
|
40992
41495
|
}
|
|
40993
|
-
const
|
|
40994
|
-
|
|
40995
|
-
|
|
40996
|
-
|
|
40997
|
-
})
|
|
41496
|
+
const { devinRosterEntry: devinRosterEntry2 } = await Promise.resolve().then(() => (init_devin(), exports_devin));
|
|
41497
|
+
const models2 = served.map((model) => {
|
|
41498
|
+
const { wireId, ...rest } = devinRosterEntry2(model);
|
|
41499
|
+
return { id: wireId, ...rest };
|
|
41500
|
+
});
|
|
40998
41501
|
log(`[model-discovery:${providerName}] discovered ${models2.length} models`);
|
|
40999
41502
|
_cache.set(providerName, { models: models2, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
41000
41503
|
return models2;
|
|
41001
41504
|
}
|
|
41505
|
+
if (descriptor.format === "ollama-tags") {
|
|
41506
|
+
const { fetchOllamaModels: fetchOllamaModels2 } = await Promise.resolve().then(() => exports_ollama_discovery);
|
|
41507
|
+
const installed = await fetchOllamaModels2({ enrichCapabilities: false });
|
|
41508
|
+
if (installed.length === 0)
|
|
41509
|
+
return [];
|
|
41510
|
+
const models2 = installed.map((model) => ({
|
|
41511
|
+
id: model.name,
|
|
41512
|
+
displayName: model.name,
|
|
41513
|
+
supportsTools: model.supportsTools
|
|
41514
|
+
}));
|
|
41515
|
+
log(`[model-discovery:${providerName}] discovered ${models2.length} local models`);
|
|
41516
|
+
_cache.set(providerName, { models: models2, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
41517
|
+
return models2;
|
|
41518
|
+
}
|
|
41002
41519
|
const baseUrl = resolveBaseUrl(providerName);
|
|
41003
41520
|
if (!baseUrl)
|
|
41004
41521
|
return [];
|
|
41005
41522
|
const endpoint = `${baseUrl}${descriptor.path}`;
|
|
41006
41523
|
let headers = {};
|
|
41007
|
-
|
|
41008
|
-
const
|
|
41009
|
-
|
|
41010
|
-
|
|
41011
|
-
|
|
41012
|
-
|
|
41524
|
+
if (def.isLocal) {
|
|
41525
|
+
const key = def.apiKeyEnvVar ? process.env[def.apiKeyEnvVar] : undefined;
|
|
41526
|
+
if (key)
|
|
41527
|
+
headers = { Authorization: `Bearer ${key}` };
|
|
41528
|
+
} else {
|
|
41529
|
+
try {
|
|
41530
|
+
const auth = await credentials.getRequestAuth(providerName, { model: "" });
|
|
41531
|
+
headers = { ...auth.headers };
|
|
41532
|
+
} catch (e) {
|
|
41533
|
+
log(`[model-discovery:${providerName}] no credentials, skipping: ${e?.message}`);
|
|
41534
|
+
return [];
|
|
41535
|
+
}
|
|
41013
41536
|
}
|
|
41014
41537
|
let response;
|
|
41015
41538
|
try {
|
|
@@ -41789,166 +42312,6 @@ var init_custom_endpoints_loader = __esm(() => {
|
|
|
41789
42312
|
init_openai();
|
|
41790
42313
|
});
|
|
41791
42314
|
|
|
41792
|
-
// src/providers/catalog-client.ts
|
|
41793
|
-
function getCatalogEntries() {
|
|
41794
|
-
if (_memCache)
|
|
41795
|
-
return _memCache;
|
|
41796
|
-
const cache2 = readAllModelsCache();
|
|
41797
|
-
if (!cache2)
|
|
41798
|
-
return null;
|
|
41799
|
-
if (cache2.entries.length > 0) {
|
|
41800
|
-
_memCache = cache2.entries;
|
|
41801
|
-
return _memCache;
|
|
41802
|
-
}
|
|
41803
|
-
if (cache2.models.length > 0) {
|
|
41804
|
-
_memCache = cache2.models.map((m) => ({
|
|
41805
|
-
modelId: m.id.includes("/") ? m.id.split("/").slice(1).join("/") : m.id,
|
|
41806
|
-
aliases: [],
|
|
41807
|
-
sources: { "openrouter-api": { externalId: m.id } }
|
|
41808
|
-
}));
|
|
41809
|
-
return _memCache;
|
|
41810
|
-
}
|
|
41811
|
-
return null;
|
|
41812
|
-
}
|
|
41813
|
-
function isCatalogWarm() {
|
|
41814
|
-
return _memCache !== null && _memCache.length > 0;
|
|
41815
|
-
}
|
|
41816
|
-
function externalIdFor(entry, provider) {
|
|
41817
|
-
const agg = entry.aggregators?.find((a) => a.provider === provider);
|
|
41818
|
-
if (agg?.externalId)
|
|
41819
|
-
return agg.externalId;
|
|
41820
|
-
if (provider !== "openrouter")
|
|
41821
|
-
return null;
|
|
41822
|
-
const orSource = entry.sources["openrouter-api"];
|
|
41823
|
-
if (orSource?.externalId)
|
|
41824
|
-
return orSource.externalId;
|
|
41825
|
-
for (const src of Object.values(entry.sources)) {
|
|
41826
|
-
if (src.externalId.includes("/"))
|
|
41827
|
-
return src.externalId;
|
|
41828
|
-
}
|
|
41829
|
-
return null;
|
|
41830
|
-
}
|
|
41831
|
-
function resolveExternalId(userInput, provider) {
|
|
41832
|
-
const entries = getCatalogEntries();
|
|
41833
|
-
if (userInput.includes("/")) {
|
|
41834
|
-
if (entries) {
|
|
41835
|
-
for (const entry of entries) {
|
|
41836
|
-
for (const src of Object.values(entry.sources)) {
|
|
41837
|
-
if (src.externalId === userInput)
|
|
41838
|
-
return userInput;
|
|
41839
|
-
}
|
|
41840
|
-
}
|
|
41841
|
-
}
|
|
41842
|
-
return userInput;
|
|
41843
|
-
}
|
|
41844
|
-
if (!entries)
|
|
41845
|
-
return null;
|
|
41846
|
-
const byModelId = entries.find((e) => e.modelId === userInput);
|
|
41847
|
-
if (byModelId)
|
|
41848
|
-
return externalIdFor(byModelId, provider);
|
|
41849
|
-
const byAlias = entries.find((e) => e.aliases.includes(userInput));
|
|
41850
|
-
if (byAlias) {
|
|
41851
|
-
const id = externalIdFor(byAlias, provider);
|
|
41852
|
-
if (id)
|
|
41853
|
-
return id;
|
|
41854
|
-
}
|
|
41855
|
-
for (const entry of entries) {
|
|
41856
|
-
for (const src of Object.values(entry.sources)) {
|
|
41857
|
-
if (src.externalId === userInput) {
|
|
41858
|
-
const id = externalIdFor(entry, provider);
|
|
41859
|
-
if (id)
|
|
41860
|
-
return id;
|
|
41861
|
-
}
|
|
41862
|
-
}
|
|
41863
|
-
}
|
|
41864
|
-
const suffix = `/${userInput}`;
|
|
41865
|
-
for (const entry of entries) {
|
|
41866
|
-
const id = externalIdFor(entry, provider);
|
|
41867
|
-
if (id?.endsWith(suffix))
|
|
41868
|
-
return id;
|
|
41869
|
-
}
|
|
41870
|
-
const lowerSuffix = `/${userInput.toLowerCase()}`;
|
|
41871
|
-
for (const entry of entries) {
|
|
41872
|
-
const id = externalIdFor(entry, provider);
|
|
41873
|
-
if (id?.toLowerCase().endsWith(lowerSuffix))
|
|
41874
|
-
return id;
|
|
41875
|
-
}
|
|
41876
|
-
return null;
|
|
41877
|
-
}
|
|
41878
|
-
function resolveModelNameSync(userInput, targetProvider) {
|
|
41879
|
-
if (targetProvider !== "openrouter" && userInput.includes("/")) {
|
|
41880
|
-
return { resolvedId: userInput, wasResolved: false, sourceLabel: "passthrough" };
|
|
41881
|
-
}
|
|
41882
|
-
const resolved = resolveExternalId(userInput, targetProvider);
|
|
41883
|
-
if (!resolved || resolved === userInput) {
|
|
41884
|
-
return { resolvedId: userInput, wasResolved: false, sourceLabel: "passthrough" };
|
|
41885
|
-
}
|
|
41886
|
-
return { resolvedId: resolved, wasResolved: true, sourceLabel: `${targetProvider} catalog` };
|
|
41887
|
-
}
|
|
41888
|
-
function logResolution(userInput, result, quiet = false) {
|
|
41889
|
-
if (result.wasResolved && !quiet) {
|
|
41890
|
-
process.stderr.write(`[Model] Resolved "${userInput}" \u2192 "${result.resolvedId}" (${result.sourceLabel})
|
|
41891
|
-
`);
|
|
41892
|
-
}
|
|
41893
|
-
}
|
|
41894
|
-
async function refreshCatalog(timeoutMs) {
|
|
41895
|
-
let response;
|
|
41896
|
-
try {
|
|
41897
|
-
response = await fetch(FIREBASE_CATALOG_URL, { signal: AbortSignal.timeout(timeoutMs) });
|
|
41898
|
-
} catch (err) {
|
|
41899
|
-
const name = err?.name;
|
|
41900
|
-
const reason = name === "TimeoutError" || name === "AbortError" ? "timeout" : "network";
|
|
41901
|
-
return { kind: "fetch_failed", reason };
|
|
41902
|
-
}
|
|
41903
|
-
if (!response.ok)
|
|
41904
|
-
return { kind: "fetch_failed", reason: "http_error" };
|
|
41905
|
-
let data;
|
|
41906
|
-
try {
|
|
41907
|
-
data = await response.json();
|
|
41908
|
-
} catch {
|
|
41909
|
-
return { kind: "fetch_failed", reason: "network" };
|
|
41910
|
-
}
|
|
41911
|
-
if (!Array.isArray(data.models) || data.models.length === 0) {
|
|
41912
|
-
return { kind: "fetch_failed", reason: "empty" };
|
|
41913
|
-
}
|
|
41914
|
-
const backwardCompatModels = [];
|
|
41915
|
-
for (const entry of data.models) {
|
|
41916
|
-
const id = externalIdFor(entry, "openrouter");
|
|
41917
|
-
if (id)
|
|
41918
|
-
backwardCompatModels.push({ id });
|
|
41919
|
-
}
|
|
41920
|
-
_memCache = data.models;
|
|
41921
|
-
writeAllModelsCache({ entries: data.models, models: backwardCompatModels });
|
|
41922
|
-
_warmPromise = Promise.resolve();
|
|
41923
|
-
return { kind: "refreshed", modelCount: data.models.length };
|
|
41924
|
-
}
|
|
41925
|
-
async function warmCatalog() {
|
|
41926
|
-
if (!_warmPromise) {
|
|
41927
|
-
_warmPromise = refreshCatalog(8000).then(() => {
|
|
41928
|
-
return;
|
|
41929
|
-
});
|
|
41930
|
-
}
|
|
41931
|
-
await _warmPromise;
|
|
41932
|
-
}
|
|
41933
|
-
async function ensureCatalogReady(timeoutMs = 5000) {
|
|
41934
|
-
if (isCatalogWarm())
|
|
41935
|
-
return;
|
|
41936
|
-
if (!_warmPromise) {
|
|
41937
|
-
_warmPromise = refreshCatalog(8000).then(() => {
|
|
41938
|
-
return;
|
|
41939
|
-
});
|
|
41940
|
-
}
|
|
41941
|
-
await Promise.race([
|
|
41942
|
-
_warmPromise,
|
|
41943
|
-
new Promise((resolve2) => setTimeout(resolve2, timeoutMs))
|
|
41944
|
-
]);
|
|
41945
|
-
}
|
|
41946
|
-
var FIREBASE_CATALOG_URL, _memCache = null, _warmPromise = null;
|
|
41947
|
-
var init_catalog_client = __esm(() => {
|
|
41948
|
-
init_all_models_cache();
|
|
41949
|
-
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";
|
|
41950
|
-
});
|
|
41951
|
-
|
|
41952
42315
|
// src/providers/provider-registry.ts
|
|
41953
42316
|
function resolveBaseUrl2(envVar, fallbackEnvVars, staticDefault) {
|
|
41954
42317
|
for (const v of [envVar, ...fallbackEnvVars]) {
|
|
@@ -42447,8 +42810,8 @@ var init_routing_rules = __esm(() => {
|
|
|
42447
42810
|
init_authority();
|
|
42448
42811
|
init_profile_config();
|
|
42449
42812
|
init_auto_route();
|
|
42450
|
-
init_default_routing_rules();
|
|
42451
42813
|
init_catalog_client();
|
|
42814
|
+
init_default_routing_rules();
|
|
42452
42815
|
init_model_parser();
|
|
42453
42816
|
init_model_parser();
|
|
42454
42817
|
init_routing_hints();
|
|
@@ -42827,11 +43190,15 @@ async function pinSpecFor(model, router = route) {
|
|
|
42827
43190
|
const plan = await router(model);
|
|
42828
43191
|
if (plan.kind !== "ok")
|
|
42829
43192
|
return null;
|
|
42830
|
-
return
|
|
43193
|
+
return joinPinnedChain([plan.primary, ...plan.fallbacks]);
|
|
42831
43194
|
} catch {
|
|
42832
43195
|
return null;
|
|
42833
43196
|
}
|
|
42834
43197
|
}
|
|
43198
|
+
function joinPinnedChain(routes) {
|
|
43199
|
+
const specs = routes.map(normalizePinnedSpec).filter((s) => !!s);
|
|
43200
|
+
return specs.length > 0 ? specs.join(MODEL_CHAIN_SEPARATOR) : null;
|
|
43201
|
+
}
|
|
42835
43202
|
function normalizePinnedSpec(r) {
|
|
42836
43203
|
const spec = r.modelSpec?.trim();
|
|
42837
43204
|
if (!spec)
|
|
@@ -42857,8 +43224,8 @@ var CATALOG_WARM_TIMEOUT_MS = 5000, parentRoutingContextReady = false;
|
|
|
42857
43224
|
var init_prehydrate = __esm(() => {
|
|
42858
43225
|
init_profile_config();
|
|
42859
43226
|
init_auto_route();
|
|
42860
|
-
init_custom_endpoints_loader();
|
|
42861
43227
|
init_catalog_client();
|
|
43228
|
+
init_custom_endpoints_loader();
|
|
42862
43229
|
init_model_parser();
|
|
42863
43230
|
init_onepassword();
|
|
42864
43231
|
init_provider_resolver();
|
|
@@ -43115,6 +43482,18 @@ var init_signal_watcher = __esm(() => {
|
|
|
43115
43482
|
QUESTION_PATTERNS = [/\?\s*$/m, /\bchoose\b.*:/im, /\bselect\b.*:/im, /\benter\b.*:/im];
|
|
43116
43483
|
});
|
|
43117
43484
|
|
|
43485
|
+
// src/spawn-claudish.ts
|
|
43486
|
+
function resolveClaudishSpawn(env = process.env) {
|
|
43487
|
+
const bin = env[CLAUDISH_BIN_ENV]?.trim();
|
|
43488
|
+
if (!bin)
|
|
43489
|
+
return { command: "claudish", prefixArgs: [] };
|
|
43490
|
+
if (/\.(ts|tsx|js|mjs|cjs)$/.test(bin)) {
|
|
43491
|
+
return { command: process.execPath, prefixArgs: ["run", bin] };
|
|
43492
|
+
}
|
|
43493
|
+
return { command: bin, prefixArgs: [] };
|
|
43494
|
+
}
|
|
43495
|
+
var CLAUDISH_BIN_ENV = "CLAUDISH_BIN";
|
|
43496
|
+
|
|
43118
43497
|
// src/channel/session-manager.ts
|
|
43119
43498
|
import { spawn } from "child_process";
|
|
43120
43499
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
@@ -43155,7 +43534,8 @@ class SessionManager {
|
|
|
43155
43534
|
"--quiet",
|
|
43156
43535
|
...opts.claudishFlags ?? []
|
|
43157
43536
|
];
|
|
43158
|
-
const
|
|
43537
|
+
const spawnTarget = resolveClaudishSpawn();
|
|
43538
|
+
const proc = spawn(spawnTarget.command, [...spawnTarget.prefixArgs, ...args], {
|
|
43159
43539
|
cwd: opts.cwd ?? process.cwd(),
|
|
43160
43540
|
stdio: ["pipe", "pipe", "pipe"],
|
|
43161
43541
|
shell: false
|
|
@@ -45806,7 +46186,7 @@ ${summary}`);
|
|
|
45806
46186
|
error: truncate(parseErrorMessage(e.message), 200)
|
|
45807
46187
|
}))
|
|
45808
46188
|
}
|
|
45809
|
-
},
|
|
46189
|
+
}, exhaustedChainStatus(errors3));
|
|
45810
46190
|
}
|
|
45811
46191
|
async shutdown() {
|
|
45812
46192
|
for (const { handler } of this.candidates) {
|
|
@@ -45840,6 +46220,9 @@ function isRetryableError(status, errorBody, provider) {
|
|
|
45840
46220
|
if (provider?.toLowerCase().includes("antigravity") && lower.includes("invalid argument")) {
|
|
45841
46221
|
return true;
|
|
45842
46222
|
}
|
|
46223
|
+
if (isProvider(provider, "opencodezen") && (lower.includes("upstream request failed") || lower.includes("error from provider ("))) {
|
|
46224
|
+
return true;
|
|
46225
|
+
}
|
|
45843
46226
|
}
|
|
45844
46227
|
if (status === 500) {
|
|
45845
46228
|
if (lower.includes("insufficient balance") || lower.includes("insufficient credit") || lower.includes("quota exceeded") || lower.includes("billing")) {
|
|
@@ -45848,6 +46231,17 @@ function isRetryableError(status, errorBody, provider) {
|
|
|
45848
46231
|
}
|
|
45849
46232
|
return false;
|
|
45850
46233
|
}
|
|
46234
|
+
function exhaustedChainStatus(errors3) {
|
|
46235
|
+
if (errors3.length === 0)
|
|
46236
|
+
return 400;
|
|
46237
|
+
const allTransient = errors3.every((e) => e.status === 429 || e.status === 503 || hasQuotaExhaustionWording(e.message));
|
|
46238
|
+
return allTransient ? 503 : 400;
|
|
46239
|
+
}
|
|
46240
|
+
function isProvider(provider, needle) {
|
|
46241
|
+
if (!provider)
|
|
46242
|
+
return false;
|
|
46243
|
+
return provider.toLowerCase().replace(/[^a-z0-9]/g, "").includes(needle);
|
|
46244
|
+
}
|
|
45851
46245
|
function parseErrorMessage(body) {
|
|
45852
46246
|
try {
|
|
45853
46247
|
const parsed = JSON.parse(body);
|
|
@@ -46237,8 +46631,8 @@ Be direct. Limit your response to 300-500 words.`, COLLECTOR_SYSTEM_PROMPT = `Yo
|
|
|
46237
46631
|
Be concise. Do not attribute advice to specific models.`;
|
|
46238
46632
|
var init_native_handler_advisor = __esm(() => {
|
|
46239
46633
|
init_logger();
|
|
46240
|
-
init_catalog_query();
|
|
46241
46634
|
init_catalog_client();
|
|
46635
|
+
init_catalog_query();
|
|
46242
46636
|
init_model_parser();
|
|
46243
46637
|
advisorToolUseIds = new Set;
|
|
46244
46638
|
});
|
|
@@ -46989,56 +47383,44 @@ var init_api_key_provenance = __esm(() => {
|
|
|
46989
47383
|
import_dotenv = __toESM(require_main(), 1);
|
|
46990
47384
|
});
|
|
46991
47385
|
|
|
46992
|
-
// src/providers/
|
|
46993
|
-
function
|
|
46994
|
-
|
|
46995
|
-
let fast = false;
|
|
46996
|
-
if (base.toLowerCase().endsWith(FAST_SUFFIX)) {
|
|
46997
|
-
fast = true;
|
|
46998
|
-
base = base.slice(0, -FAST_SUFFIX.length);
|
|
46999
|
-
}
|
|
47000
|
-
const match2 = base.match(TIER_SUFFIX_RE);
|
|
47001
|
-
const candidate = match2?.[1]?.toLowerCase();
|
|
47002
|
-
return { tier: isEffortLevel(candidate) ? candidate : null, fast };
|
|
47386
|
+
// src/providers/model-resolvers/registry.ts
|
|
47387
|
+
function getModelResolver(provider) {
|
|
47388
|
+
return BY_PROVIDER.get(provider);
|
|
47003
47389
|
}
|
|
47004
|
-
function
|
|
47005
|
-
|
|
47390
|
+
function collapseRoster(provider, roster) {
|
|
47391
|
+
const resolver = getModelResolver(provider);
|
|
47392
|
+
if (resolver)
|
|
47393
|
+
return resolver.collapse(roster);
|
|
47394
|
+
return roster.map((entry) => ({
|
|
47395
|
+
id: entry.wireId,
|
|
47396
|
+
displayName: entry.displayName ?? entry.wireId,
|
|
47397
|
+
contextWindow: entry.contextWindow,
|
|
47398
|
+
variants: [{ wireId: entry.wireId, modifiers: [] }],
|
|
47399
|
+
costFactor: entry.costFactor,
|
|
47400
|
+
offer: entry.offer,
|
|
47401
|
+
isRecommended: entry.isRecommended
|
|
47402
|
+
}));
|
|
47006
47403
|
}
|
|
47404
|
+
function expandSelection(provider, selection, roster, ctx = {}) {
|
|
47405
|
+
return getModelResolver(provider)?.expand(selection, roster, ctx) ?? selection;
|
|
47406
|
+
}
|
|
47407
|
+
var RESOLVERS, BY_PROVIDER;
|
|
47408
|
+
var init_registry2 = __esm(() => {
|
|
47409
|
+
init_devin();
|
|
47410
|
+
RESOLVERS = [new DevinModelResolver];
|
|
47411
|
+
BY_PROVIDER = new Map(RESOLVERS.map((resolver) => [resolver.provider, resolver]));
|
|
47412
|
+
});
|
|
47413
|
+
|
|
47414
|
+
// src/providers/devin/model-id-resolver.ts
|
|
47007
47415
|
function resolveDevinModelUid(requested, effort, served) {
|
|
47008
|
-
const
|
|
47009
|
-
if (!
|
|
47010
|
-
return
|
|
47011
|
-
|
|
47012
|
-
const exact = served.find((model) => model.uid.toLowerCase() === lower);
|
|
47013
|
-
if (exact)
|
|
47014
|
-
return exact.uid;
|
|
47015
|
-
const prefix = `${lower}-`;
|
|
47016
|
-
const candidates = served.filter((model) => model.family.toLowerCase() === lower || model.uid.toLowerCase().startsWith(prefix));
|
|
47017
|
-
if (candidates.length === 0)
|
|
47018
|
-
return req;
|
|
47019
|
-
const nonFast = candidates.filter((model) => !parseDevinUidTier(model.uid).fast);
|
|
47020
|
-
const pool = nonFast.length > 0 ? nonFast : candidates;
|
|
47021
|
-
if (pool.length === 1)
|
|
47022
|
-
return pool[0].uid;
|
|
47023
|
-
const tiered = pool.map((model) => ({ model, tier: parseDevinUidTier(model.uid).tier })).filter((entry) => entry.tier !== null);
|
|
47024
|
-
if (tiered.length === 0)
|
|
47025
|
-
return pool[0].uid;
|
|
47026
|
-
const target = effort ? effortIndex(effort) : EFFORT_LEVELS.length - 1;
|
|
47027
|
-
let best = tiered[0];
|
|
47028
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
47029
|
-
for (const entry of tiered) {
|
|
47030
|
-
const distance = Math.abs(effortIndex(entry.tier) - target);
|
|
47031
|
-
if (distance < bestDistance || distance === bestDistance && effortIndex(entry.tier) > effortIndex(best.tier)) {
|
|
47032
|
-
best = entry;
|
|
47033
|
-
bestDistance = distance;
|
|
47034
|
-
}
|
|
47035
|
-
}
|
|
47036
|
-
return best.model.uid;
|
|
47416
|
+
const trimmed2 = requested.trim();
|
|
47417
|
+
if (!trimmed2 || served.length === 0)
|
|
47418
|
+
return trimmed2 || requested;
|
|
47419
|
+
return expandSelection("devin", trimmed2, served.map(devinRosterEntry), { effort });
|
|
47037
47420
|
}
|
|
47038
|
-
var FAST_SUFFIX = "-fast", TIER_SUFFIX_RE;
|
|
47039
47421
|
var init_model_id_resolver = __esm(() => {
|
|
47040
|
-
|
|
47041
|
-
|
|
47422
|
+
init_devin();
|
|
47423
|
+
init_registry2();
|
|
47042
47424
|
});
|
|
47043
47425
|
|
|
47044
47426
|
// src/providers/transport/devin.ts
|
|
@@ -47134,7 +47516,7 @@ class DevinProviderTransport {
|
|
|
47134
47516
|
}
|
|
47135
47517
|
}
|
|
47136
47518
|
var CHAT_PATH = "/exa.api_server_pb.ApiServerService/GetChatMessage", CHAT_CONTENT_TYPE = "application/connect+proto";
|
|
47137
|
-
var
|
|
47519
|
+
var init_devin2 = __esm(() => {
|
|
47138
47520
|
init_authority();
|
|
47139
47521
|
init_devin_credential();
|
|
47140
47522
|
init_logger();
|
|
@@ -47352,7 +47734,7 @@ var init_provider_profiles = __esm(() => {
|
|
|
47352
47734
|
init_runtime_providers();
|
|
47353
47735
|
init_anthropic_compat();
|
|
47354
47736
|
init_antigravity();
|
|
47355
|
-
|
|
47737
|
+
init_devin2();
|
|
47356
47738
|
init_gemini_apikey();
|
|
47357
47739
|
init_litellm();
|
|
47358
47740
|
init_ollamacloud();
|
|
@@ -47464,17 +47846,6 @@ var init_provider_profiles = __esm(() => {
|
|
|
47464
47846
|
createHandler(ctx) {
|
|
47465
47847
|
const zenApiKey = ctx.apiKey;
|
|
47466
47848
|
const isGoProvider = ctx.provider.name === "opencode-zen-go";
|
|
47467
|
-
if (ctx.modelName.toLowerCase().includes("minimax")) {
|
|
47468
|
-
const bearerProvider = { ...ctx.provider, authScheme: "bearer" };
|
|
47469
|
-
const transport2 = new AnthropicProviderTransport(bearerProvider, zenApiKey);
|
|
47470
|
-
const adapter2 = new AnthropicAPIFormat(ctx.modelName, ctx.provider.name);
|
|
47471
|
-
const handler2 = new ComposedHandler(transport2, ctx.targetModel, ctx.modelName, ctx.port, {
|
|
47472
|
-
adapter: adapter2,
|
|
47473
|
-
...ctx.sharedOpts
|
|
47474
|
-
});
|
|
47475
|
-
log(`[Proxy] Created OpenCode Zen${isGoProvider ? " Go" : ""} (Anthropic composed): ${ctx.modelName}`);
|
|
47476
|
-
return handler2;
|
|
47477
|
-
}
|
|
47478
47849
|
if (ctx.modelName.toLowerCase().startsWith("gpt-")) {
|
|
47479
47850
|
const responsesProvider = { ...ctx.provider, apiPath: "/v1/responses" };
|
|
47480
47851
|
const transport2 = new OpenAIProviderTransport(responsesProvider, ctx.modelName, zenApiKey);
|
|
@@ -48589,13 +48960,38 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
|
|
|
48589
48960
|
target = model;
|
|
48590
48961
|
}
|
|
48591
48962
|
const invocationMode = detectInvocationMode(target, wasFromModelMap);
|
|
48963
|
+
if (options.modelChain && options.modelChain.length > 1 && target === options.modelChain[0]) {
|
|
48964
|
+
const cacheKey = `chain:${options.modelChain.join("+")}`;
|
|
48965
|
+
const cached2 = fallbackHandlerCache.get(cacheKey);
|
|
48966
|
+
if (cached2)
|
|
48967
|
+
return cached2;
|
|
48968
|
+
await ensureCatalogReady(5000);
|
|
48969
|
+
const candidates = [];
|
|
48970
|
+
for (const spec of options.modelChain) {
|
|
48971
|
+
const parsed = parseModelSpec(spec);
|
|
48972
|
+
const resolvedSpec = resolveTargetForCatalog(spec, parsed.isExplicitProvider, parsed.model, parsed.provider).target;
|
|
48973
|
+
const handler = parsed.provider === "openrouter" ? getOpenRouterHandler(resolvedSpec, invocationMode) : await getRemoteProviderHandler(resolvedSpec, invocationMode) ?? getLocalProviderHandler(resolvedSpec, invocationMode);
|
|
48974
|
+
if (handler) {
|
|
48975
|
+
candidates.push({ name: DISPLAY_NAMES[parsed.provider] ?? parsed.provider, handler });
|
|
48976
|
+
}
|
|
48977
|
+
}
|
|
48978
|
+
if (candidates.length > 0) {
|
|
48979
|
+
const resultHandler = candidates.length > 1 ? new FallbackHandler(candidates) : candidates[0].handler;
|
|
48980
|
+
fallbackHandlerCache.set(cacheKey, resultHandler);
|
|
48981
|
+
if (!options.quiet && candidates.length > 1) {
|
|
48982
|
+
logStderr(`[Route] ${candidates.length} pinned providers for ${target}: ${candidates.map((c) => c.name).join(" \u2192 ")}`);
|
|
48983
|
+
}
|
|
48984
|
+
return resultHandler;
|
|
48985
|
+
}
|
|
48986
|
+
}
|
|
48592
48987
|
{
|
|
48593
48988
|
const parsedTarget = parseModelSpec(target);
|
|
48594
|
-
|
|
48595
|
-
|
|
48596
|
-
|
|
48597
|
-
|
|
48598
|
-
|
|
48989
|
+
if (parsedTarget.isExplicitProvider) {
|
|
48990
|
+
await ensureCatalogReady(5000);
|
|
48991
|
+
const outcome = resolveTargetForCatalog(target, parsedTarget.isExplicitProvider, parsedTarget.model, parsedTarget.provider);
|
|
48992
|
+
if (outcome.resolution)
|
|
48993
|
+
logResolution(parsedTarget.model, outcome.resolution, options.quiet);
|
|
48994
|
+
target = outcome.target;
|
|
48599
48995
|
}
|
|
48600
48996
|
}
|
|
48601
48997
|
{
|
|
@@ -48812,8 +49208,9 @@ var init_proxy_server = __esm(() => {
|
|
|
48812
49208
|
init_model_loader();
|
|
48813
49209
|
init_profile_config();
|
|
48814
49210
|
init_api_key_map();
|
|
48815
|
-
|
|
49211
|
+
init_auto_route();
|
|
48816
49212
|
init_catalog_client();
|
|
49213
|
+
init_custom_endpoints_loader();
|
|
48817
49214
|
init_model_parser();
|
|
48818
49215
|
init_provider_profiles();
|
|
48819
49216
|
init_provider_registry();
|
|
@@ -49206,7 +49603,8 @@ async function runModels(sessionPath, opts = {}) {
|
|
|
49206
49603
|
state: "RUNNING",
|
|
49207
49604
|
startedAt: new Date().toISOString()
|
|
49208
49605
|
});
|
|
49209
|
-
const
|
|
49606
|
+
const teamSpawnTarget = resolveClaudishSpawn();
|
|
49607
|
+
const proc = spawn2(teamSpawnTarget.command, [...teamSpawnTarget.prefixArgs, ...args], {
|
|
49210
49608
|
stdio: ["pipe", "pipe", "pipe"],
|
|
49211
49609
|
shell: false,
|
|
49212
49610
|
env: {
|
|
@@ -64574,28 +64972,52 @@ async function pickModelFromList(provider, displayName, tierName, models) {
|
|
|
64574
64972
|
});
|
|
64575
64973
|
return selected === CUSTOM_VALUE ? null : selected;
|
|
64576
64974
|
}
|
|
64975
|
+
function describeOffer(offer) {
|
|
64976
|
+
if (!offerIsLive(offer) || offer?.kind !== "promo")
|
|
64977
|
+
return;
|
|
64978
|
+
if (offer.expiresAt === undefined)
|
|
64979
|
+
return "FREE";
|
|
64980
|
+
const until = new Date(offer.expiresAt * 1000).toLocaleDateString("en-US", {
|
|
64981
|
+
month: "short",
|
|
64982
|
+
day: "numeric"
|
|
64983
|
+
});
|
|
64984
|
+
return `FREE until ${until}`;
|
|
64985
|
+
}
|
|
64577
64986
|
async function buildDiscoveredModelRows(provider, displayName, catalog) {
|
|
64578
64987
|
const discovered = rankDiscoveredModels(await discoverProviderModels(provider)).filter((m) => isChatCapable(m.id));
|
|
64579
64988
|
if (discovered.length === 0)
|
|
64580
64989
|
return [];
|
|
64581
64990
|
const subscription = isSubscriptionProvider(provider);
|
|
64582
|
-
const
|
|
64991
|
+
const local = getProviderByName(provider)?.isLocal === true;
|
|
64992
|
+
const flatRate = subscription || local;
|
|
64993
|
+
const pricingById = flatRate ? new Map : new Map((await loadModelsForPickerProvider(provider, catalog)).map((m) => [
|
|
64583
64994
|
m.id.toLowerCase(),
|
|
64584
64995
|
m.pricing
|
|
64585
64996
|
]));
|
|
64586
|
-
const
|
|
64587
|
-
|
|
64997
|
+
const choices = collapseRoster(provider, discovered.map(toRosterEntry));
|
|
64998
|
+
const discoveredById = new Map(discovered.map((m) => [m.id, m]));
|
|
64999
|
+
const rows = choices.map((c) => {
|
|
65000
|
+
const source = discoveredById.get(c.id);
|
|
65001
|
+
const contextLength = source ? resolveDiscoveredContextLength(source) : c.contextWindow ?? 0;
|
|
65002
|
+
const parts = [c.displayName];
|
|
65003
|
+
if (contextLength)
|
|
65004
|
+
parts.push(`${Math.round(contextLength / 1024)}K context`);
|
|
65005
|
+
if (subscription && c.costFactor !== undefined)
|
|
65006
|
+
parts.push(`\xD7${c.costFactor}`);
|
|
65007
|
+
const promo = describeOffer(c.offer);
|
|
65008
|
+
if (promo)
|
|
65009
|
+
parts.push(promo);
|
|
64588
65010
|
return {
|
|
64589
|
-
id:
|
|
64590
|
-
name:
|
|
64591
|
-
description:
|
|
65011
|
+
id: c.id,
|
|
65012
|
+
name: c.displayName,
|
|
65013
|
+
description: parts.join(" \xB7 "),
|
|
64592
65014
|
provider: displayName,
|
|
64593
|
-
releaseDate: resolveDiscoveredReleaseDate(
|
|
64594
|
-
pricing: subscription ? SUBSCRIPTION_PRICING : pricingById.get(
|
|
65015
|
+
releaseDate: source ? resolveDiscoveredReleaseDate(source) : undefined,
|
|
65016
|
+
pricing: subscription ? SUBSCRIPTION_PRICING : pricingById.get(c.id.toLowerCase()),
|
|
64595
65017
|
context: formatContextLength(contextLength),
|
|
64596
65018
|
contextLength,
|
|
64597
|
-
supportsTools: lookupModelCapabilities(
|
|
64598
|
-
isFree:
|
|
65019
|
+
supportsTools: lookupModelCapabilities(c.id)?.supportsTools ?? source?.supportsTools ?? true,
|
|
65020
|
+
isFree: flatRate,
|
|
64599
65021
|
source: displayName
|
|
64600
65022
|
};
|
|
64601
65023
|
});
|
|
@@ -64613,23 +65035,6 @@ async function selectModelFromProvider(provider, tierName, recommendedModels, _f
|
|
|
64613
65035
|
return picked;
|
|
64614
65036
|
}
|
|
64615
65037
|
}
|
|
64616
|
-
if (provider === "ollama") {
|
|
64617
|
-
const ollamaModels = await fetchOllamaModels({ enrichCapabilities: false });
|
|
64618
|
-
const chatModels = sortModelsNewestFirst(ollamaModels.map((m) => ({
|
|
64619
|
-
id: m.name,
|
|
64620
|
-
name: m.name,
|
|
64621
|
-
description: m.description,
|
|
64622
|
-
provider: displayName,
|
|
64623
|
-
supportsTools: m.supportsTools,
|
|
64624
|
-
isFree: true,
|
|
64625
|
-
source: displayName
|
|
64626
|
-
})));
|
|
64627
|
-
if (chatModels.length > 0) {
|
|
64628
|
-
const picked = await pickModelFromList(provider, displayName, tierName, chatModels);
|
|
64629
|
-
if (picked)
|
|
64630
|
-
return picked;
|
|
64631
|
-
}
|
|
64632
|
-
}
|
|
64633
65038
|
if (isUserDeployedProvider(provider)) {
|
|
64634
65039
|
const modelName = await dist_default5({
|
|
64635
65040
|
message: tierName === "interactive session" ? `Enter ${displayName} model name:` : `Enter ${displayName} model name for ${tierName}:`,
|
|
@@ -64793,6 +65198,7 @@ var init_model_selector = __esm(() => {
|
|
|
64793
65198
|
init_model_loader();
|
|
64794
65199
|
init_model_catalog2();
|
|
64795
65200
|
init_model_discovery();
|
|
65201
|
+
init_registry2();
|
|
64796
65202
|
init_provider_definitions();
|
|
64797
65203
|
init_probe_discovery();
|
|
64798
65204
|
pickerProviderToFirebaseSlug = {
|
|
@@ -67773,7 +68179,10 @@ async function parseArgs(args) {
|
|
|
67773
68179
|
printAvailableModels();
|
|
67774
68180
|
process.exit(1);
|
|
67775
68181
|
}
|
|
67776
|
-
|
|
68182
|
+
const chain = parseModelChain(modelArg);
|
|
68183
|
+
config3.model = chain[0];
|
|
68184
|
+
if (chain.length > 1)
|
|
68185
|
+
config3.modelChain = chain;
|
|
67777
68186
|
} else if (arg === "--model-opus") {
|
|
67778
68187
|
const val = args[++i];
|
|
67779
68188
|
if (val)
|
|
@@ -78362,7 +78771,8 @@ Team Status`);
|
|
|
78362
78771
|
quiet: cliConfig.quiet,
|
|
78363
78772
|
isInteractive: cliConfig.interactive,
|
|
78364
78773
|
advisorModels: cliConfig.advisorModels,
|
|
78365
|
-
advisorCollector: cliConfig.advisorCollector
|
|
78774
|
+
advisorCollector: cliConfig.advisorCollector,
|
|
78775
|
+
modelChain: cliConfig.monitor ? undefined : cliConfig.modelChain
|
|
78366
78776
|
}));
|
|
78367
78777
|
const diag = createDiagOutput2({
|
|
78368
78778
|
interactive: cliConfig.interactive,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.45.0",
|
|
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.45.0",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.45.0",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.45.0",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.45.0"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|