claudish 5.1.1 → 5.2.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 +448 -112
- package/package.json +1 -1
- package/recommended-models.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33320,6 +33320,275 @@ var init_remote_provider_registry = __esm(() => {
|
|
|
33320
33320
|
init_model_parser();
|
|
33321
33321
|
});
|
|
33322
33322
|
|
|
33323
|
+
// src/auth/oauth-registry.ts
|
|
33324
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
|
|
33325
|
+
import { join as join8 } from "node:path";
|
|
33326
|
+
import { homedir as homedir7 } from "node:os";
|
|
33327
|
+
function hasValidOAuthCredentials(descriptor) {
|
|
33328
|
+
const credPath = join8(homedir7(), ".claudish", descriptor.credentialFile);
|
|
33329
|
+
if (!existsSync8(credPath))
|
|
33330
|
+
return false;
|
|
33331
|
+
if (descriptor.validationMode === "file-exists") {
|
|
33332
|
+
return true;
|
|
33333
|
+
}
|
|
33334
|
+
try {
|
|
33335
|
+
const data = JSON.parse(readFileSync7(credPath, "utf-8"));
|
|
33336
|
+
if (!data.access_token)
|
|
33337
|
+
return false;
|
|
33338
|
+
if (data.refresh_token)
|
|
33339
|
+
return true;
|
|
33340
|
+
if (descriptor.expiresAtField && data[descriptor.expiresAtField]) {
|
|
33341
|
+
const buffer = descriptor.expiryBufferMs ?? 0;
|
|
33342
|
+
return data[descriptor.expiresAtField] > Date.now() + buffer;
|
|
33343
|
+
}
|
|
33344
|
+
return true;
|
|
33345
|
+
} catch {
|
|
33346
|
+
return false;
|
|
33347
|
+
}
|
|
33348
|
+
}
|
|
33349
|
+
function hasOAuthCredentials(providerName) {
|
|
33350
|
+
const descriptor = OAUTH_PROVIDERS[providerName];
|
|
33351
|
+
if (!descriptor)
|
|
33352
|
+
return false;
|
|
33353
|
+
return hasValidOAuthCredentials(descriptor);
|
|
33354
|
+
}
|
|
33355
|
+
var OAUTH_PROVIDERS;
|
|
33356
|
+
var init_oauth_registry = __esm(() => {
|
|
33357
|
+
OAUTH_PROVIDERS = {
|
|
33358
|
+
"kimi-coding": {
|
|
33359
|
+
credentialFile: "kimi-oauth.json",
|
|
33360
|
+
validationMode: "check-expiry",
|
|
33361
|
+
expiresAtField: "expires_at",
|
|
33362
|
+
expiryBufferMs: 5 * 60 * 1000
|
|
33363
|
+
},
|
|
33364
|
+
kimi: {
|
|
33365
|
+
credentialFile: "kimi-oauth.json",
|
|
33366
|
+
validationMode: "check-expiry",
|
|
33367
|
+
expiresAtField: "expires_at",
|
|
33368
|
+
expiryBufferMs: 5 * 60 * 1000
|
|
33369
|
+
},
|
|
33370
|
+
google: {
|
|
33371
|
+
credentialFile: "gemini-oauth.json",
|
|
33372
|
+
validationMode: "check-expiry",
|
|
33373
|
+
expiresAtField: "expires_at",
|
|
33374
|
+
expiryBufferMs: 5 * 60 * 1000
|
|
33375
|
+
},
|
|
33376
|
+
"gemini-codeassist": {
|
|
33377
|
+
credentialFile: "gemini-oauth.json",
|
|
33378
|
+
validationMode: "check-expiry",
|
|
33379
|
+
expiresAtField: "expires_at",
|
|
33380
|
+
expiryBufferMs: 5 * 60 * 1000
|
|
33381
|
+
}
|
|
33382
|
+
};
|
|
33383
|
+
});
|
|
33384
|
+
|
|
33385
|
+
// src/providers/auto-route.ts
|
|
33386
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
|
|
33387
|
+
import { join as join9 } from "node:path";
|
|
33388
|
+
import { homedir as homedir8 } from "node:os";
|
|
33389
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
33390
|
+
function readLiteLLMCacheSync(baseUrl) {
|
|
33391
|
+
const hash2 = createHash3("sha256").update(baseUrl).digest("hex").substring(0, 16);
|
|
33392
|
+
const cachePath = join9(homedir8(), ".claudish", `litellm-models-${hash2}.json`);
|
|
33393
|
+
if (!existsSync9(cachePath))
|
|
33394
|
+
return null;
|
|
33395
|
+
try {
|
|
33396
|
+
const data = JSON.parse(readFileSync8(cachePath, "utf-8"));
|
|
33397
|
+
if (!Array.isArray(data.models))
|
|
33398
|
+
return null;
|
|
33399
|
+
return data.models;
|
|
33400
|
+
} catch {
|
|
33401
|
+
return null;
|
|
33402
|
+
}
|
|
33403
|
+
}
|
|
33404
|
+
function checkOAuthForProvider(nativeProvider, modelName) {
|
|
33405
|
+
if (!hasOAuthCredentials(nativeProvider))
|
|
33406
|
+
return null;
|
|
33407
|
+
return {
|
|
33408
|
+
provider: nativeProvider,
|
|
33409
|
+
resolvedModelId: modelName,
|
|
33410
|
+
modelName,
|
|
33411
|
+
reason: "oauth-credentials",
|
|
33412
|
+
displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (oauth)`
|
|
33413
|
+
};
|
|
33414
|
+
}
|
|
33415
|
+
function checkApiKeyForProvider(nativeProvider, modelName) {
|
|
33416
|
+
const keyInfo = API_KEY_ENV_VARS[nativeProvider];
|
|
33417
|
+
if (!keyInfo)
|
|
33418
|
+
return null;
|
|
33419
|
+
if (keyInfo.envVar && process.env[keyInfo.envVar]) {
|
|
33420
|
+
return {
|
|
33421
|
+
provider: nativeProvider,
|
|
33422
|
+
resolvedModelId: modelName,
|
|
33423
|
+
modelName,
|
|
33424
|
+
reason: "api-key",
|
|
33425
|
+
displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (api-key)`
|
|
33426
|
+
};
|
|
33427
|
+
}
|
|
33428
|
+
if (keyInfo.aliases) {
|
|
33429
|
+
for (const alias of keyInfo.aliases) {
|
|
33430
|
+
if (process.env[alias]) {
|
|
33431
|
+
return {
|
|
33432
|
+
provider: nativeProvider,
|
|
33433
|
+
resolvedModelId: modelName,
|
|
33434
|
+
modelName,
|
|
33435
|
+
reason: "api-key",
|
|
33436
|
+
displayMessage: `Auto-routed: ${modelName} -> ${nativeProvider} (api-key)`
|
|
33437
|
+
};
|
|
33438
|
+
}
|
|
33439
|
+
}
|
|
33440
|
+
}
|
|
33441
|
+
return null;
|
|
33442
|
+
}
|
|
33443
|
+
function formatForOpenRouter(modelName, nativeProvider) {
|
|
33444
|
+
if (modelName.includes("/")) {
|
|
33445
|
+
return modelName;
|
|
33446
|
+
}
|
|
33447
|
+
const vendor = OPENROUTER_VENDOR_MAP[nativeProvider];
|
|
33448
|
+
if (vendor) {
|
|
33449
|
+
return `${vendor}/${modelName}`;
|
|
33450
|
+
}
|
|
33451
|
+
return modelName;
|
|
33452
|
+
}
|
|
33453
|
+
function getAutoRouteHint(modelName, nativeProvider) {
|
|
33454
|
+
const hint = PROVIDER_HINT_MAP[nativeProvider];
|
|
33455
|
+
const lines = [
|
|
33456
|
+
`No credentials found for "${modelName}". Options:`
|
|
33457
|
+
];
|
|
33458
|
+
let hasOption = false;
|
|
33459
|
+
if (hint?.loginFlag) {
|
|
33460
|
+
lines.push(` Run: claudish ${hint.loginFlag} (authenticate via OAuth)`);
|
|
33461
|
+
hasOption = true;
|
|
33462
|
+
}
|
|
33463
|
+
if (hint?.apiKeyEnvVar) {
|
|
33464
|
+
lines.push(` Set: export ${hint.apiKeyEnvVar}=your-key`);
|
|
33465
|
+
hasOption = true;
|
|
33466
|
+
}
|
|
33467
|
+
if (hint?.openRouterModel) {
|
|
33468
|
+
lines.push(` Use: claudish --model or@${hint.openRouterModel} (route via OpenRouter)`);
|
|
33469
|
+
hasOption = true;
|
|
33470
|
+
}
|
|
33471
|
+
if (!hasOption) {
|
|
33472
|
+
return null;
|
|
33473
|
+
}
|
|
33474
|
+
lines.push(` Or set OPENROUTER_API_KEY for automatic OpenRouter fallback`);
|
|
33475
|
+
return lines.join(`
|
|
33476
|
+
`);
|
|
33477
|
+
}
|
|
33478
|
+
function autoRoute(modelName, nativeProvider) {
|
|
33479
|
+
const litellmBaseUrl = process.env.LITELLM_BASE_URL;
|
|
33480
|
+
if (litellmBaseUrl) {
|
|
33481
|
+
const models = readLiteLLMCacheSync(litellmBaseUrl);
|
|
33482
|
+
if (models !== null) {
|
|
33483
|
+
const match = models.find((m) => m.name === modelName || m.id === `litellm@${modelName}`);
|
|
33484
|
+
if (match) {
|
|
33485
|
+
return {
|
|
33486
|
+
provider: "litellm",
|
|
33487
|
+
resolvedModelId: `litellm@${modelName}`,
|
|
33488
|
+
modelName,
|
|
33489
|
+
reason: "litellm-cache",
|
|
33490
|
+
displayMessage: `Auto-routed: ${modelName} -> litellm`
|
|
33491
|
+
};
|
|
33492
|
+
}
|
|
33493
|
+
}
|
|
33494
|
+
}
|
|
33495
|
+
if (nativeProvider !== "unknown") {
|
|
33496
|
+
const oauthResult = checkOAuthForProvider(nativeProvider, modelName);
|
|
33497
|
+
if (oauthResult)
|
|
33498
|
+
return oauthResult;
|
|
33499
|
+
}
|
|
33500
|
+
if (nativeProvider !== "unknown") {
|
|
33501
|
+
const apiKeyResult = checkApiKeyForProvider(nativeProvider, modelName);
|
|
33502
|
+
if (apiKeyResult)
|
|
33503
|
+
return apiKeyResult;
|
|
33504
|
+
}
|
|
33505
|
+
if (process.env.OPENROUTER_API_KEY) {
|
|
33506
|
+
const orModelId = formatForOpenRouter(modelName, nativeProvider);
|
|
33507
|
+
return {
|
|
33508
|
+
provider: "openrouter",
|
|
33509
|
+
resolvedModelId: orModelId,
|
|
33510
|
+
modelName,
|
|
33511
|
+
reason: "openrouter-fallback",
|
|
33512
|
+
displayMessage: `Auto-routed: ${modelName} -> openrouter`
|
|
33513
|
+
};
|
|
33514
|
+
}
|
|
33515
|
+
return null;
|
|
33516
|
+
}
|
|
33517
|
+
var API_KEY_ENV_VARS, OPENROUTER_VENDOR_MAP, PROVIDER_HINT_MAP;
|
|
33518
|
+
var init_auto_route = __esm(() => {
|
|
33519
|
+
init_oauth_registry();
|
|
33520
|
+
API_KEY_ENV_VARS = {
|
|
33521
|
+
google: { envVar: "GEMINI_API_KEY" },
|
|
33522
|
+
"gemini-codeassist": { envVar: "GEMINI_API_KEY" },
|
|
33523
|
+
openai: { envVar: "OPENAI_API_KEY" },
|
|
33524
|
+
minimax: { envVar: "MINIMAX_API_KEY" },
|
|
33525
|
+
"minimax-coding": { envVar: "MINIMAX_CODING_API_KEY" },
|
|
33526
|
+
kimi: { envVar: "MOONSHOT_API_KEY", aliases: ["KIMI_API_KEY"] },
|
|
33527
|
+
"kimi-coding": { envVar: "KIMI_CODING_API_KEY" },
|
|
33528
|
+
glm: { envVar: "ZHIPU_API_KEY", aliases: ["GLM_API_KEY"] },
|
|
33529
|
+
"glm-coding": { envVar: "GLM_CODING_API_KEY", aliases: ["ZAI_CODING_API_KEY"] },
|
|
33530
|
+
zai: { envVar: "ZAI_API_KEY" },
|
|
33531
|
+
ollamacloud: { envVar: "OLLAMA_API_KEY" },
|
|
33532
|
+
litellm: { envVar: "LITELLM_API_KEY" },
|
|
33533
|
+
openrouter: { envVar: "OPENROUTER_API_KEY" },
|
|
33534
|
+
vertex: { envVar: "VERTEX_API_KEY", aliases: ["VERTEX_PROJECT"] },
|
|
33535
|
+
poe: { envVar: "POE_API_KEY" }
|
|
33536
|
+
};
|
|
33537
|
+
OPENROUTER_VENDOR_MAP = {
|
|
33538
|
+
google: "google",
|
|
33539
|
+
openai: "openai",
|
|
33540
|
+
kimi: "moonshot",
|
|
33541
|
+
"kimi-coding": "moonshot",
|
|
33542
|
+
glm: "zhipuai",
|
|
33543
|
+
"glm-coding": "zhipuai",
|
|
33544
|
+
minimax: "minimax",
|
|
33545
|
+
ollamacloud: "meta-llama"
|
|
33546
|
+
};
|
|
33547
|
+
PROVIDER_HINT_MAP = {
|
|
33548
|
+
"kimi-coding": {
|
|
33549
|
+
loginFlag: "--kimi-login",
|
|
33550
|
+
apiKeyEnvVar: "KIMI_CODING_API_KEY",
|
|
33551
|
+
openRouterModel: "moonshot/kimi-k2"
|
|
33552
|
+
},
|
|
33553
|
+
kimi: {
|
|
33554
|
+
loginFlag: "--kimi-login",
|
|
33555
|
+
apiKeyEnvVar: "MOONSHOT_API_KEY",
|
|
33556
|
+
openRouterModel: "moonshot/moonshot-v1-8k"
|
|
33557
|
+
},
|
|
33558
|
+
google: {
|
|
33559
|
+
loginFlag: "--gemini-login",
|
|
33560
|
+
apiKeyEnvVar: "GEMINI_API_KEY",
|
|
33561
|
+
openRouterModel: "google/gemini-2.0-flash"
|
|
33562
|
+
},
|
|
33563
|
+
"gemini-codeassist": {
|
|
33564
|
+
loginFlag: "--gemini-login",
|
|
33565
|
+
apiKeyEnvVar: "GEMINI_API_KEY",
|
|
33566
|
+
openRouterModel: "google/gemini-2.0-flash"
|
|
33567
|
+
},
|
|
33568
|
+
openai: {
|
|
33569
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
33570
|
+
openRouterModel: "openai/gpt-4o"
|
|
33571
|
+
},
|
|
33572
|
+
minimax: {
|
|
33573
|
+
apiKeyEnvVar: "MINIMAX_API_KEY",
|
|
33574
|
+
openRouterModel: "minimax/minimax-01"
|
|
33575
|
+
},
|
|
33576
|
+
"minimax-coding": {
|
|
33577
|
+
apiKeyEnvVar: "MINIMAX_CODING_API_KEY"
|
|
33578
|
+
},
|
|
33579
|
+
glm: {
|
|
33580
|
+
apiKeyEnvVar: "ZHIPU_API_KEY",
|
|
33581
|
+
openRouterModel: "zhipuai/glm-4"
|
|
33582
|
+
},
|
|
33583
|
+
"glm-coding": {
|
|
33584
|
+
apiKeyEnvVar: "GLM_CODING_API_KEY"
|
|
33585
|
+
},
|
|
33586
|
+
ollamacloud: {
|
|
33587
|
+
apiKeyEnvVar: "OLLAMA_API_KEY"
|
|
33588
|
+
}
|
|
33589
|
+
};
|
|
33590
|
+
});
|
|
33591
|
+
|
|
33323
33592
|
// src/providers/provider-resolver.ts
|
|
33324
33593
|
var exports_provider_resolver = {};
|
|
33325
33594
|
__export(exports_provider_resolver, {
|
|
@@ -33331,9 +33600,9 @@ __export(exports_provider_resolver, {
|
|
|
33331
33600
|
getMissingKeyResolutions: () => getMissingKeyResolutions,
|
|
33332
33601
|
getMissingKeyError: () => getMissingKeyError
|
|
33333
33602
|
});
|
|
33334
|
-
import { existsSync as
|
|
33335
|
-
import { join as
|
|
33336
|
-
import { homedir as
|
|
33603
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
33604
|
+
import { join as join10 } from "node:path";
|
|
33605
|
+
import { homedir as homedir9 } from "node:os";
|
|
33337
33606
|
function isApiKeyAvailable(info) {
|
|
33338
33607
|
if (!info.envVar) {
|
|
33339
33608
|
return true;
|
|
@@ -33350,8 +33619,8 @@ function isApiKeyAvailable(info) {
|
|
|
33350
33619
|
}
|
|
33351
33620
|
if (info.oauthFallback) {
|
|
33352
33621
|
try {
|
|
33353
|
-
const credPath =
|
|
33354
|
-
if (
|
|
33622
|
+
const credPath = join10(homedir9(), ".claudish", info.oauthFallback);
|
|
33623
|
+
if (existsSync10(credPath)) {
|
|
33355
33624
|
return true;
|
|
33356
33625
|
}
|
|
33357
33626
|
} catch {}
|
|
@@ -33442,6 +33711,43 @@ function resolveModelProvider(modelId) {
|
|
|
33442
33711
|
apiKeyUrl: info.url
|
|
33443
33712
|
});
|
|
33444
33713
|
}
|
|
33714
|
+
let pendingAutoRouteMessage;
|
|
33715
|
+
if (!parsed.isExplicitProvider && parsed.provider !== "native-anthropic") {
|
|
33716
|
+
const autoResult = autoRoute(parsed.model, parsed.provider);
|
|
33717
|
+
if (autoResult) {
|
|
33718
|
+
if (autoResult.provider === "litellm") {
|
|
33719
|
+
const info = API_KEY_INFO.litellm;
|
|
33720
|
+
return addCommonFields({
|
|
33721
|
+
category: "direct-api",
|
|
33722
|
+
providerName: "LiteLLM",
|
|
33723
|
+
modelName: autoResult.modelName,
|
|
33724
|
+
fullModelId: autoResult.resolvedModelId,
|
|
33725
|
+
requiredApiKeyEnvVar: info.envVar || null,
|
|
33726
|
+
apiKeyAvailable: isApiKeyAvailable(info),
|
|
33727
|
+
apiKeyDescription: info.description,
|
|
33728
|
+
apiKeyUrl: info.url,
|
|
33729
|
+
wasAutoRouted: true,
|
|
33730
|
+
autoRouteMessage: autoResult.displayMessage
|
|
33731
|
+
});
|
|
33732
|
+
}
|
|
33733
|
+
if (autoResult.provider === "openrouter") {
|
|
33734
|
+
const info = API_KEY_INFO.openrouter;
|
|
33735
|
+
return addCommonFields({
|
|
33736
|
+
category: "openrouter",
|
|
33737
|
+
providerName: "OpenRouter",
|
|
33738
|
+
modelName: autoResult.modelName,
|
|
33739
|
+
fullModelId: autoResult.resolvedModelId,
|
|
33740
|
+
requiredApiKeyEnvVar: info.envVar,
|
|
33741
|
+
apiKeyAvailable: isApiKeyAvailable(info),
|
|
33742
|
+
apiKeyDescription: info.description,
|
|
33743
|
+
apiKeyUrl: info.url,
|
|
33744
|
+
wasAutoRouted: true,
|
|
33745
|
+
autoRouteMessage: autoResult.displayMessage
|
|
33746
|
+
});
|
|
33747
|
+
}
|
|
33748
|
+
pendingAutoRouteMessage = autoResult.displayMessage;
|
|
33749
|
+
}
|
|
33750
|
+
}
|
|
33445
33751
|
const remoteResolved = resolveRemoteProvider(modelId);
|
|
33446
33752
|
if (remoteResolved) {
|
|
33447
33753
|
const provider = remoteResolved.provider;
|
|
@@ -33451,6 +33757,7 @@ function resolveModelProvider(modelId) {
|
|
|
33451
33757
|
url: ""
|
|
33452
33758
|
};
|
|
33453
33759
|
const providerDisplayName = PROVIDER_DISPLAY_NAMES[provider.name] || provider.name.charAt(0).toUpperCase() + provider.name.slice(1);
|
|
33760
|
+
const wasAutoRouted = !parsed.isExplicitProvider;
|
|
33454
33761
|
return addCommonFields({
|
|
33455
33762
|
category: "direct-api",
|
|
33456
33763
|
providerName: providerDisplayName,
|
|
@@ -33459,7 +33766,9 @@ function resolveModelProvider(modelId) {
|
|
|
33459
33766
|
requiredApiKeyEnvVar: info.envVar || null,
|
|
33460
33767
|
apiKeyAvailable: isApiKeyAvailable(info),
|
|
33461
33768
|
apiKeyDescription: info.envVar ? info.description : null,
|
|
33462
|
-
apiKeyUrl: info.envVar ? info.url : null
|
|
33769
|
+
apiKeyUrl: info.envVar ? info.url : null,
|
|
33770
|
+
wasAutoRouted,
|
|
33771
|
+
autoRouteMessage: wasAutoRouted ? pendingAutoRouteMessage ?? `Auto-routed: ${parsed.model} -> ${providerDisplayName}` : undefined
|
|
33463
33772
|
});
|
|
33464
33773
|
}
|
|
33465
33774
|
if (parsed.provider === "unknown") {
|
|
@@ -33522,6 +33831,16 @@ function getMissingKeyError(resolution) {
|
|
|
33522
33831
|
lines.push("");
|
|
33523
33832
|
lines.push(`Get your API key from: ${resolution.apiKeyUrl}`);
|
|
33524
33833
|
}
|
|
33834
|
+
{
|
|
33835
|
+
const parsed = resolution.parsed;
|
|
33836
|
+
if (parsed && !parsed.isExplicitProvider && parsed.provider !== "unknown" && parsed.provider !== "native-anthropic") {
|
|
33837
|
+
const hint = getAutoRouteHint(parsed.model, parsed.provider);
|
|
33838
|
+
if (hint) {
|
|
33839
|
+
lines.push("");
|
|
33840
|
+
lines.push(hint);
|
|
33841
|
+
}
|
|
33842
|
+
}
|
|
33843
|
+
}
|
|
33525
33844
|
if (resolution.category === "openrouter") {
|
|
33526
33845
|
const provider = resolution.fullModelId.split("/")[0];
|
|
33527
33846
|
lines.push("");
|
|
@@ -33582,6 +33901,7 @@ var API_KEY_INFO, PROVIDER_DISPLAY_NAMES;
|
|
|
33582
33901
|
var init_provider_resolver = __esm(() => {
|
|
33583
33902
|
init_provider_registry();
|
|
33584
33903
|
init_remote_provider_registry();
|
|
33904
|
+
init_auto_route();
|
|
33585
33905
|
init_model_parser();
|
|
33586
33906
|
API_KEY_INFO = {
|
|
33587
33907
|
openrouter: {
|
|
@@ -33697,16 +34017,16 @@ __export(exports_cli, {
|
|
|
33697
34017
|
getMissingKeyResolutions: () => getMissingKeyResolutions,
|
|
33698
34018
|
getMissingKeyError: () => getMissingKeyError
|
|
33699
34019
|
});
|
|
33700
|
-
import { readFileSync as
|
|
34020
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync6, copyFileSync, readdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
33701
34021
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
33702
|
-
import { dirname as dirname4, join as
|
|
33703
|
-
import { homedir as
|
|
34022
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
34023
|
+
import { homedir as homedir10 } from "node:os";
|
|
33704
34024
|
function getVersion() {
|
|
33705
34025
|
return VERSION;
|
|
33706
34026
|
}
|
|
33707
34027
|
function clearAllModelCaches() {
|
|
33708
|
-
const cacheDir =
|
|
33709
|
-
if (!
|
|
34028
|
+
const cacheDir = join11(homedir10(), ".claudish");
|
|
34029
|
+
if (!existsSync11(cacheDir))
|
|
33710
34030
|
return;
|
|
33711
34031
|
const cachePatterns = ["all-models.json", "pricing-cache.json"];
|
|
33712
34032
|
let cleared = 0;
|
|
@@ -33714,7 +34034,7 @@ function clearAllModelCaches() {
|
|
|
33714
34034
|
const files = readdirSync(cacheDir);
|
|
33715
34035
|
for (const file2 of files) {
|
|
33716
34036
|
if (cachePatterns.includes(file2) || file2.startsWith("litellm-models-")) {
|
|
33717
|
-
unlinkSync3(
|
|
34037
|
+
unlinkSync3(join11(cacheDir, file2));
|
|
33718
34038
|
cleared++;
|
|
33719
34039
|
}
|
|
33720
34040
|
}
|
|
@@ -33983,9 +34303,9 @@ async function fetchOllamaModels() {
|
|
|
33983
34303
|
}
|
|
33984
34304
|
async function searchAndPrintModels(query, forceUpdate) {
|
|
33985
34305
|
let models = [];
|
|
33986
|
-
if (!forceUpdate &&
|
|
34306
|
+
if (!forceUpdate && existsSync11(ALL_MODELS_JSON_PATH2)) {
|
|
33987
34307
|
try {
|
|
33988
|
-
const cacheData = JSON.parse(
|
|
34308
|
+
const cacheData = JSON.parse(readFileSync9(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
33989
34309
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
33990
34310
|
const now = new Date;
|
|
33991
34311
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -34153,9 +34473,9 @@ Found ${results.length} matching models:
|
|
|
34153
34473
|
async function printAllModels(jsonOutput, forceUpdate) {
|
|
34154
34474
|
let models = [];
|
|
34155
34475
|
const [ollamaModels, zenModels] = await Promise.all([fetchOllamaModels(), fetchZenModels()]);
|
|
34156
|
-
if (!forceUpdate &&
|
|
34476
|
+
if (!forceUpdate && existsSync11(ALL_MODELS_JSON_PATH2)) {
|
|
34157
34477
|
try {
|
|
34158
|
-
const cacheData = JSON.parse(
|
|
34478
|
+
const cacheData = JSON.parse(readFileSync9(ALL_MODELS_JSON_PATH2, "utf-8"));
|
|
34159
34479
|
const lastUpdated = new Date(cacheData.lastUpdated);
|
|
34160
34480
|
const now = new Date;
|
|
34161
34481
|
const ageInDays = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
|
|
@@ -34356,11 +34676,11 @@ async function printAllModels(jsonOutput, forceUpdate) {
|
|
|
34356
34676
|
console.log("Top models: claudish --top-models");
|
|
34357
34677
|
}
|
|
34358
34678
|
function isCacheStale() {
|
|
34359
|
-
if (!
|
|
34679
|
+
if (!existsSync11(MODELS_JSON_PATH)) {
|
|
34360
34680
|
return true;
|
|
34361
34681
|
}
|
|
34362
34682
|
try {
|
|
34363
|
-
const jsonContent =
|
|
34683
|
+
const jsonContent = readFileSync9(MODELS_JSON_PATH, "utf-8");
|
|
34364
34684
|
const data = JSON.parse(jsonContent);
|
|
34365
34685
|
if (!data.lastUpdated) {
|
|
34366
34686
|
return true;
|
|
@@ -34455,9 +34775,9 @@ async function updateModelsFromOpenRouter() {
|
|
|
34455
34775
|
providers.add(provider);
|
|
34456
34776
|
}
|
|
34457
34777
|
let version2 = "1.1.5";
|
|
34458
|
-
if (
|
|
34778
|
+
if (existsSync11(MODELS_JSON_PATH)) {
|
|
34459
34779
|
try {
|
|
34460
|
-
const existing = JSON.parse(
|
|
34780
|
+
const existing = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
|
|
34461
34781
|
version2 = existing.version || version2;
|
|
34462
34782
|
} catch {}
|
|
34463
34783
|
}
|
|
@@ -34485,7 +34805,7 @@ async function checkAndUpdateModelsCache(forceUpdate = false) {
|
|
|
34485
34805
|
await updateModelsFromOpenRouter();
|
|
34486
34806
|
} else {
|
|
34487
34807
|
try {
|
|
34488
|
-
const data = JSON.parse(
|
|
34808
|
+
const data = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
|
|
34489
34809
|
console.error(`✓ Using cached models (last updated: ${data.lastUpdated})`);
|
|
34490
34810
|
} catch {}
|
|
34491
34811
|
}
|
|
@@ -34789,8 +35109,8 @@ MORE INFO:
|
|
|
34789
35109
|
}
|
|
34790
35110
|
function printAIAgentGuide() {
|
|
34791
35111
|
try {
|
|
34792
|
-
const guidePath =
|
|
34793
|
-
const guideContent =
|
|
35112
|
+
const guidePath = join11(__dirname5, "../AI_AGENT_GUIDE.md");
|
|
35113
|
+
const guideContent = readFileSync9(guidePath, "utf-8");
|
|
34794
35114
|
console.log(guideContent);
|
|
34795
35115
|
} catch (error46) {
|
|
34796
35116
|
console.error("Error reading AI Agent Guide:");
|
|
@@ -34806,19 +35126,19 @@ async function initializeClaudishSkill() {
|
|
|
34806
35126
|
console.log(`\uD83D\uDD27 Initializing Claudish skill in current project...
|
|
34807
35127
|
`);
|
|
34808
35128
|
const cwd = process.cwd();
|
|
34809
|
-
const claudeDir =
|
|
34810
|
-
const skillsDir =
|
|
34811
|
-
const claudishSkillDir =
|
|
34812
|
-
const skillFile =
|
|
34813
|
-
if (
|
|
35129
|
+
const claudeDir = join11(cwd, ".claude");
|
|
35130
|
+
const skillsDir = join11(claudeDir, "skills");
|
|
35131
|
+
const claudishSkillDir = join11(skillsDir, "claudish-usage");
|
|
35132
|
+
const skillFile = join11(claudishSkillDir, "SKILL.md");
|
|
35133
|
+
if (existsSync11(skillFile)) {
|
|
34814
35134
|
console.log("✅ Claudish skill already installed at:");
|
|
34815
35135
|
console.log(` ${skillFile}
|
|
34816
35136
|
`);
|
|
34817
35137
|
console.log("\uD83D\uDCA1 To reinstall, delete the file and run 'claudish --init' again.");
|
|
34818
35138
|
return;
|
|
34819
35139
|
}
|
|
34820
|
-
const sourceSkillPath =
|
|
34821
|
-
if (!
|
|
35140
|
+
const sourceSkillPath = join11(__dirname5, "../skills/claudish-usage/SKILL.md");
|
|
35141
|
+
if (!existsSync11(sourceSkillPath)) {
|
|
34822
35142
|
console.error("❌ Error: Claudish skill file not found in installation.");
|
|
34823
35143
|
console.error(` Expected at: ${sourceSkillPath}`);
|
|
34824
35144
|
console.error(`
|
|
@@ -34827,15 +35147,15 @@ async function initializeClaudishSkill() {
|
|
|
34827
35147
|
process.exit(1);
|
|
34828
35148
|
}
|
|
34829
35149
|
try {
|
|
34830
|
-
if (!
|
|
35150
|
+
if (!existsSync11(claudeDir)) {
|
|
34831
35151
|
mkdirSync6(claudeDir, { recursive: true });
|
|
34832
35152
|
console.log("\uD83D\uDCC1 Created .claude/ directory");
|
|
34833
35153
|
}
|
|
34834
|
-
if (!
|
|
35154
|
+
if (!existsSync11(skillsDir)) {
|
|
34835
35155
|
mkdirSync6(skillsDir, { recursive: true });
|
|
34836
35156
|
console.log("\uD83D\uDCC1 Created .claude/skills/ directory");
|
|
34837
35157
|
}
|
|
34838
|
-
if (!
|
|
35158
|
+
if (!existsSync11(claudishSkillDir)) {
|
|
34839
35159
|
mkdirSync6(claudishSkillDir, { recursive: true });
|
|
34840
35160
|
console.log("\uD83D\uDCC1 Created .claude/skills/claudish-usage/ directory");
|
|
34841
35161
|
}
|
|
@@ -34878,8 +35198,8 @@ function printAvailableModels() {
|
|
|
34878
35198
|
let lastUpdated = "unknown";
|
|
34879
35199
|
let models = [];
|
|
34880
35200
|
try {
|
|
34881
|
-
if (
|
|
34882
|
-
const data = JSON.parse(
|
|
35201
|
+
if (existsSync11(MODELS_JSON_PATH)) {
|
|
35202
|
+
const data = JSON.parse(readFileSync9(MODELS_JSON_PATH, "utf-8"));
|
|
34883
35203
|
lastUpdated = data.lastUpdated || "unknown";
|
|
34884
35204
|
models = data.models || [];
|
|
34885
35205
|
}
|
|
@@ -34932,9 +35252,9 @@ Force update: claudish --list-models --force-update
|
|
|
34932
35252
|
`);
|
|
34933
35253
|
}
|
|
34934
35254
|
function printAvailableModelsJSON() {
|
|
34935
|
-
const jsonPath =
|
|
35255
|
+
const jsonPath = join11(__dirname5, "../recommended-models.json");
|
|
34936
35256
|
try {
|
|
34937
|
-
const jsonContent =
|
|
35257
|
+
const jsonContent = readFileSync9(jsonPath, "utf-8");
|
|
34938
35258
|
const data = JSON.parse(jsonContent);
|
|
34939
35259
|
const outputData = {
|
|
34940
35260
|
...data,
|
|
@@ -35026,7 +35346,7 @@ async function fetchGLMCodingModels2() {
|
|
|
35026
35346
|
return [];
|
|
35027
35347
|
}
|
|
35028
35348
|
}
|
|
35029
|
-
var __filename5, __dirname5, VERSION = "5.
|
|
35349
|
+
var __filename5, __dirname5, VERSION = "5.2.0", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, CLAUDISH_CACHE_DIR3, ALL_MODELS_JSON_PATH2;
|
|
35030
35350
|
var init_cli = __esm(() => {
|
|
35031
35351
|
init_config();
|
|
35032
35352
|
init_model_loader();
|
|
@@ -35035,12 +35355,12 @@ var init_cli = __esm(() => {
|
|
|
35035
35355
|
__filename5 = fileURLToPath4(import.meta.url);
|
|
35036
35356
|
__dirname5 = dirname4(__filename5);
|
|
35037
35357
|
try {
|
|
35038
|
-
const packageJson = JSON.parse(
|
|
35358
|
+
const packageJson = JSON.parse(readFileSync9(join11(__dirname5, "../package.json"), "utf-8"));
|
|
35039
35359
|
VERSION = packageJson.version;
|
|
35040
35360
|
} catch {}
|
|
35041
|
-
MODELS_JSON_PATH =
|
|
35042
|
-
CLAUDISH_CACHE_DIR3 =
|
|
35043
|
-
ALL_MODELS_JSON_PATH2 =
|
|
35361
|
+
MODELS_JSON_PATH = join11(__dirname5, "../recommended-models.json");
|
|
35362
|
+
CLAUDISH_CACHE_DIR3 = join11(homedir10(), ".claudish");
|
|
35363
|
+
ALL_MODELS_JSON_PATH2 = join11(CLAUDISH_CACHE_DIR3, "all-models.json");
|
|
35044
35364
|
});
|
|
35045
35365
|
|
|
35046
35366
|
// src/claude-runner.ts
|
|
@@ -35050,17 +35370,17 @@ __export(exports_claude_runner, {
|
|
|
35050
35370
|
checkClaudeInstalled: () => checkClaudeInstalled
|
|
35051
35371
|
});
|
|
35052
35372
|
import { spawn } from "node:child_process";
|
|
35053
|
-
import { writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7, existsSync as
|
|
35054
|
-
import { tmpdir, homedir as
|
|
35055
|
-
import { join as
|
|
35373
|
+
import { writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7, existsSync as existsSync12 } from "node:fs";
|
|
35374
|
+
import { tmpdir, homedir as homedir11 } from "node:os";
|
|
35375
|
+
import { join as join12 } from "node:path";
|
|
35056
35376
|
function isWindows() {
|
|
35057
35377
|
return process.platform === "win32";
|
|
35058
35378
|
}
|
|
35059
35379
|
function createStatusLineScript(tokenFilePath) {
|
|
35060
35380
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir();
|
|
35061
|
-
const claudishDir =
|
|
35381
|
+
const claudishDir = join12(homeDir, ".claudish");
|
|
35062
35382
|
const timestamp = Date.now();
|
|
35063
|
-
const scriptPath =
|
|
35383
|
+
const scriptPath = join12(claudishDir, `status-${timestamp}.js`);
|
|
35064
35384
|
const escapedTokenPath = tokenFilePath.replace(/\\/g, "\\\\");
|
|
35065
35385
|
const script = `
|
|
35066
35386
|
const fs = require('fs');
|
|
@@ -35145,13 +35465,13 @@ process.stdin.on('end', () => {
|
|
|
35145
35465
|
}
|
|
35146
35466
|
function createTempSettingsFile(modelDisplay, port) {
|
|
35147
35467
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir();
|
|
35148
|
-
const claudishDir =
|
|
35468
|
+
const claudishDir = join12(homeDir, ".claudish");
|
|
35149
35469
|
try {
|
|
35150
35470
|
mkdirSync7(claudishDir, { recursive: true });
|
|
35151
35471
|
} catch {}
|
|
35152
35472
|
const timestamp = Date.now();
|
|
35153
|
-
const tempPath =
|
|
35154
|
-
const tokenFilePath =
|
|
35473
|
+
const tempPath = join12(claudishDir, `settings-${timestamp}.json`);
|
|
35474
|
+
const tokenFilePath = join12(claudishDir, `tokens-${port}.json`);
|
|
35155
35475
|
let statusCommand;
|
|
35156
35476
|
if (isWindows()) {
|
|
35157
35477
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -35257,8 +35577,8 @@ async function runClaudeWithProxy(config3, proxyUrl) {
|
|
|
35257
35577
|
console.error("Install it from: https://claude.com/claude-code");
|
|
35258
35578
|
console.error(`
|
|
35259
35579
|
Or set CLAUDE_PATH to your custom installation:`);
|
|
35260
|
-
const home =
|
|
35261
|
-
const localPath = isWindows() ?
|
|
35580
|
+
const home = homedir11();
|
|
35581
|
+
const localPath = isWindows() ? join12(home, ".claude", "local", "claude.exe") : join12(home, ".claude", "local", "claude");
|
|
35262
35582
|
console.error(` export CLAUDE_PATH=${localPath}`);
|
|
35263
35583
|
process.exit(1);
|
|
35264
35584
|
}
|
|
@@ -35297,23 +35617,23 @@ function setupSignalHandlers(proc, tempSettingsPath, quiet) {
|
|
|
35297
35617
|
async function findClaudeBinary() {
|
|
35298
35618
|
const isWindows2 = process.platform === "win32";
|
|
35299
35619
|
if (process.env.CLAUDE_PATH) {
|
|
35300
|
-
if (
|
|
35620
|
+
if (existsSync12(process.env.CLAUDE_PATH)) {
|
|
35301
35621
|
return process.env.CLAUDE_PATH;
|
|
35302
35622
|
}
|
|
35303
35623
|
}
|
|
35304
|
-
const home =
|
|
35305
|
-
const localPath = isWindows2 ?
|
|
35306
|
-
if (
|
|
35624
|
+
const home = homedir11();
|
|
35625
|
+
const localPath = isWindows2 ? join12(home, ".claude", "local", "claude.exe") : join12(home, ".claude", "local", "claude");
|
|
35626
|
+
if (existsSync12(localPath)) {
|
|
35307
35627
|
return localPath;
|
|
35308
35628
|
}
|
|
35309
35629
|
if (isWindows2) {
|
|
35310
35630
|
const windowsPaths = [
|
|
35311
|
-
|
|
35312
|
-
|
|
35313
|
-
|
|
35631
|
+
join12(home, "AppData", "Roaming", "npm", "claude.cmd"),
|
|
35632
|
+
join12(home, ".npm-global", "claude.cmd"),
|
|
35633
|
+
join12(home, "node_modules", ".bin", "claude.cmd")
|
|
35314
35634
|
];
|
|
35315
35635
|
for (const path of windowsPaths) {
|
|
35316
|
-
if (
|
|
35636
|
+
if (existsSync12(path)) {
|
|
35317
35637
|
return path;
|
|
35318
35638
|
}
|
|
35319
35639
|
}
|
|
@@ -35321,14 +35641,14 @@ async function findClaudeBinary() {
|
|
|
35321
35641
|
const commonPaths = [
|
|
35322
35642
|
"/usr/local/bin/claude",
|
|
35323
35643
|
"/opt/homebrew/bin/claude",
|
|
35324
|
-
|
|
35325
|
-
|
|
35326
|
-
|
|
35644
|
+
join12(home, ".npm-global/bin/claude"),
|
|
35645
|
+
join12(home, ".local/bin/claude"),
|
|
35646
|
+
join12(home, "node_modules/.bin/claude"),
|
|
35327
35647
|
"/data/data/com.termux/files/usr/bin/claude",
|
|
35328
|
-
|
|
35648
|
+
join12(home, "../usr/bin/claude")
|
|
35329
35649
|
];
|
|
35330
35650
|
for (const path of commonPaths) {
|
|
35331
|
-
if (
|
|
35651
|
+
if (existsSync12(path)) {
|
|
35332
35652
|
return path;
|
|
35333
35653
|
}
|
|
35334
35654
|
}
|
|
@@ -61219,9 +61539,9 @@ var init_gemini_codeassist = __esm(() => {
|
|
|
61219
61539
|
// src/auth/vertex-auth.ts
|
|
61220
61540
|
import { exec as exec4 } from "node:child_process";
|
|
61221
61541
|
import { promisify as promisify3 } from "node:util";
|
|
61222
|
-
import { existsSync as
|
|
61223
|
-
import { homedir as
|
|
61224
|
-
import { join as
|
|
61542
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
61543
|
+
import { homedir as homedir12 } from "node:os";
|
|
61544
|
+
import { join as join13 } from "node:path";
|
|
61225
61545
|
|
|
61226
61546
|
class VertexAuthManager {
|
|
61227
61547
|
cachedToken = null;
|
|
@@ -61275,8 +61595,8 @@ class VertexAuthManager {
|
|
|
61275
61595
|
}
|
|
61276
61596
|
async tryADC() {
|
|
61277
61597
|
try {
|
|
61278
|
-
const adcPath =
|
|
61279
|
-
if (!
|
|
61598
|
+
const adcPath = join13(homedir12(), ".config/gcloud/application_default_credentials.json");
|
|
61599
|
+
if (!existsSync13(adcPath)) {
|
|
61280
61600
|
log("[VertexAuth] ADC credentials file not found");
|
|
61281
61601
|
return null;
|
|
61282
61602
|
}
|
|
@@ -61300,7 +61620,7 @@ class VertexAuthManager {
|
|
|
61300
61620
|
if (!credPath) {
|
|
61301
61621
|
return null;
|
|
61302
61622
|
}
|
|
61303
|
-
if (!
|
|
61623
|
+
if (!existsSync13(credPath)) {
|
|
61304
61624
|
throw new Error(`Service account file not found: ${credPath}
|
|
61305
61625
|
|
|
61306
61626
|
Check GOOGLE_APPLICATION_CREDENTIALS path.`);
|
|
@@ -61339,8 +61659,8 @@ function validateVertexOAuthConfig() {
|
|
|
61339
61659
|
` + ` export VERTEX_PROJECT='your-gcp-project-id'
|
|
61340
61660
|
` + " export VERTEX_LOCATION='us-central1' # optional";
|
|
61341
61661
|
}
|
|
61342
|
-
const adcPath =
|
|
61343
|
-
const hasADC =
|
|
61662
|
+
const adcPath = join13(homedir12(), ".config/gcloud/application_default_credentials.json");
|
|
61663
|
+
const hasADC = existsSync13(adcPath);
|
|
61344
61664
|
const hasServiceAccount = !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
61345
61665
|
if (!hasADC && !hasServiceAccount) {
|
|
61346
61666
|
return `No Vertex AI credentials found.
|
|
@@ -61736,8 +62056,8 @@ var init_middleware = __esm(() => {
|
|
|
61736
62056
|
|
|
61737
62057
|
// src/handlers/shared/token-tracker.ts
|
|
61738
62058
|
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
|
|
61739
|
-
import { homedir as
|
|
61740
|
-
import { join as
|
|
62059
|
+
import { homedir as homedir13 } from "node:os";
|
|
62060
|
+
import { join as join14 } from "node:path";
|
|
61741
62061
|
|
|
61742
62062
|
class TokenTracker {
|
|
61743
62063
|
port;
|
|
@@ -61851,9 +62171,9 @@ class TokenTracker {
|
|
|
61851
62171
|
is_free: isFreeModel,
|
|
61852
62172
|
is_estimated: isEstimate || false
|
|
61853
62173
|
};
|
|
61854
|
-
const claudishDir =
|
|
62174
|
+
const claudishDir = join14(homedir13(), ".claudish");
|
|
61855
62175
|
mkdirSync8(claudishDir, { recursive: true });
|
|
61856
|
-
writeFileSync8(
|
|
62176
|
+
writeFileSync8(join14(claudishDir, `tokens-${this.port}.json`), JSON.stringify(data), "utf-8");
|
|
61857
62177
|
} catch (e) {
|
|
61858
62178
|
log(`[TokenTracker] Error writing token file: ${e}`);
|
|
61859
62179
|
}
|
|
@@ -63048,10 +63368,10 @@ var init_litellm = __esm(() => {
|
|
|
63048
63368
|
});
|
|
63049
63369
|
|
|
63050
63370
|
// src/adapters/litellm-adapter.ts
|
|
63051
|
-
import { existsSync as
|
|
63052
|
-
import { createHash as
|
|
63053
|
-
import { homedir as
|
|
63054
|
-
import { join as
|
|
63371
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
|
|
63372
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
63373
|
+
import { homedir as homedir14 } from "node:os";
|
|
63374
|
+
import { join as join15 } from "node:path";
|
|
63055
63375
|
var INLINE_IMAGE_MODEL_PATTERNS, LiteLLMAdapter;
|
|
63056
63376
|
var init_litellm_adapter = __esm(() => {
|
|
63057
63377
|
init_base_adapter();
|
|
@@ -63146,11 +63466,11 @@ var init_litellm_adapter = __esm(() => {
|
|
|
63146
63466
|
}
|
|
63147
63467
|
checkVisionSupport() {
|
|
63148
63468
|
try {
|
|
63149
|
-
const hash2 =
|
|
63150
|
-
const cachePath =
|
|
63151
|
-
if (!
|
|
63469
|
+
const hash2 = createHash4("sha256").update(this.baseUrl).digest("hex").substring(0, 16);
|
|
63470
|
+
const cachePath = join15(homedir14(), ".claudish", `litellm-models-${hash2}.json`);
|
|
63471
|
+
if (!existsSync14(cachePath))
|
|
63152
63472
|
return true;
|
|
63153
|
-
const cacheData = JSON.parse(
|
|
63473
|
+
const cacheData = JSON.parse(readFileSync11(cachePath, "utf-8"));
|
|
63154
63474
|
const model = cacheData.models?.find((m) => m.name === this.modelId);
|
|
63155
63475
|
if (model && model.supportsVision === false) {
|
|
63156
63476
|
log(`[LiteLLMAdapter] Model ${this.modelId} does not support vision`);
|
|
@@ -63268,12 +63588,12 @@ class AnthropicCompatProvider {
|
|
|
63268
63588
|
}
|
|
63269
63589
|
if (this.provider.name === "kimi-coding" && !this.apiKey) {
|
|
63270
63590
|
try {
|
|
63271
|
-
const { existsSync:
|
|
63272
|
-
const { join:
|
|
63273
|
-
const { homedir:
|
|
63274
|
-
const credPath =
|
|
63275
|
-
if (
|
|
63276
|
-
const data = JSON.parse(
|
|
63591
|
+
const { existsSync: existsSync15, readFileSync: readFileSync12 } = await import("node:fs");
|
|
63592
|
+
const { join: join16 } = await import("node:path");
|
|
63593
|
+
const { homedir: homedir15 } = await import("node:os");
|
|
63594
|
+
const credPath = join16(homedir15(), ".claudish", "kimi-oauth.json");
|
|
63595
|
+
if (existsSync15(credPath)) {
|
|
63596
|
+
const data = JSON.parse(readFileSync12(credPath, "utf-8"));
|
|
63277
63597
|
if (data.access_token && data.refresh_token) {
|
|
63278
63598
|
const { KimiOAuth: KimiOAuth2 } = await Promise.resolve().then(() => (init_kimi_oauth(), exports_kimi_oauth));
|
|
63279
63599
|
const oauth = KimiOAuth2.getInstance();
|
|
@@ -63495,9 +63815,9 @@ var init_ollamacloud_adapter = __esm(() => {
|
|
|
63495
63815
|
});
|
|
63496
63816
|
|
|
63497
63817
|
// src/services/pricing-cache.ts
|
|
63498
|
-
import { readFileSync as
|
|
63499
|
-
import { homedir as
|
|
63500
|
-
import { join as
|
|
63818
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync9, statSync } from "node:fs";
|
|
63819
|
+
import { homedir as homedir15 } from "node:os";
|
|
63820
|
+
import { join as join16 } from "node:path";
|
|
63501
63821
|
function getDynamicPricingSync(provider, modelName) {
|
|
63502
63822
|
if (provider === "openrouter") {
|
|
63503
63823
|
const direct = pricingMap.get(modelName);
|
|
@@ -63562,12 +63882,12 @@ async function warmPricingCache() {
|
|
|
63562
63882
|
}
|
|
63563
63883
|
function loadDiskCache() {
|
|
63564
63884
|
try {
|
|
63565
|
-
if (!
|
|
63885
|
+
if (!existsSync15(CACHE_FILE))
|
|
63566
63886
|
return false;
|
|
63567
63887
|
const stat = statSync(CACHE_FILE);
|
|
63568
63888
|
const age = Date.now() - stat.mtimeMs;
|
|
63569
63889
|
const isFresh = age < CACHE_TTL_MS;
|
|
63570
|
-
const raw2 =
|
|
63890
|
+
const raw2 = readFileSync12(CACHE_FILE, "utf-8");
|
|
63571
63891
|
const data = JSON.parse(raw2);
|
|
63572
63892
|
for (const [key, pricing] of Object.entries(data)) {
|
|
63573
63893
|
pricingMap.set(key, pricing);
|
|
@@ -63614,8 +63934,8 @@ var init_pricing_cache = __esm(() => {
|
|
|
63614
63934
|
init_model_loader();
|
|
63615
63935
|
init_remote_provider_types();
|
|
63616
63936
|
pricingMap = new Map;
|
|
63617
|
-
CACHE_DIR =
|
|
63618
|
-
CACHE_FILE =
|
|
63937
|
+
CACHE_DIR = join16(homedir15(), ".claudish");
|
|
63938
|
+
CACHE_FILE = join16(CACHE_DIR, "pricing-cache.json");
|
|
63619
63939
|
CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
63620
63940
|
PROVIDER_TO_OR_PREFIX = {
|
|
63621
63941
|
openai: ["openai/"],
|
|
@@ -63710,11 +64030,18 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
63710
64030
|
return remoteProviderHandlers.get(targetModel);
|
|
63711
64031
|
}
|
|
63712
64032
|
const resolution = resolveModelProvider(targetModel);
|
|
64033
|
+
if (resolution.wasAutoRouted && resolution.autoRouteMessage) {
|
|
64034
|
+
console.error(`[Auto-route] ${resolution.autoRouteMessage}`);
|
|
64035
|
+
}
|
|
63713
64036
|
if (resolution.category === "openrouter") {
|
|
64037
|
+
if (resolution.wasAutoRouted && resolution.fullModelId) {
|
|
64038
|
+
return getOpenRouterHandler(resolution.fullModelId);
|
|
64039
|
+
}
|
|
63714
64040
|
return null;
|
|
63715
64041
|
}
|
|
64042
|
+
const resolveTarget = resolution.wasAutoRouted && resolution.fullModelId ? resolution.fullModelId : targetModel;
|
|
63716
64043
|
if (resolution.category === "direct-api" && resolution.apiKeyAvailable) {
|
|
63717
|
-
const resolved = resolveRemoteProvider(
|
|
64044
|
+
const resolved = resolveRemoteProvider(resolveTarget);
|
|
63718
64045
|
if (!resolved)
|
|
63719
64046
|
return null;
|
|
63720
64047
|
if (resolved.provider.name === "openrouter") {
|
|
@@ -63838,11 +64165,19 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
63838
64165
|
} else {
|
|
63839
64166
|
return null;
|
|
63840
64167
|
}
|
|
63841
|
-
remoteProviderHandlers.set(
|
|
64168
|
+
remoteProviderHandlers.set(resolveTarget, handler);
|
|
64169
|
+
if (resolveTarget !== targetModel) {
|
|
64170
|
+
remoteProviderHandlers.set(targetModel, handler);
|
|
64171
|
+
}
|
|
63842
64172
|
return handler;
|
|
63843
64173
|
}
|
|
63844
64174
|
return null;
|
|
63845
64175
|
};
|
|
64176
|
+
if (process.env.LITELLM_BASE_URL && process.env.LITELLM_API_KEY) {
|
|
64177
|
+
fetchLiteLLMModels(process.env.LITELLM_BASE_URL, process.env.LITELLM_API_KEY).then(() => {
|
|
64178
|
+
log("[Proxy] LiteLLM model cache pre-warmed for auto-routing");
|
|
64179
|
+
}).catch(() => {});
|
|
64180
|
+
}
|
|
63846
64181
|
const getHandlerForRequest = (requestedModel) => {
|
|
63847
64182
|
if (monitorMode)
|
|
63848
64183
|
return nativeHandler;
|
|
@@ -63965,6 +64300,7 @@ var init_proxy_server = __esm(() => {
|
|
|
63965
64300
|
init_vertex_auth();
|
|
63966
64301
|
init_provider_resolver();
|
|
63967
64302
|
init_pricing_cache();
|
|
64303
|
+
init_model_loader();
|
|
63968
64304
|
});
|
|
63969
64305
|
|
|
63970
64306
|
// src/update-checker.ts
|
|
@@ -63976,9 +64312,9 @@ __export(exports_update_checker, {
|
|
|
63976
64312
|
checkForUpdates: () => checkForUpdates
|
|
63977
64313
|
});
|
|
63978
64314
|
import { execSync } from "node:child_process";
|
|
63979
|
-
import { existsSync as
|
|
63980
|
-
import { homedir as
|
|
63981
|
-
import { join as
|
|
64315
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "node:fs";
|
|
64316
|
+
import { homedir as homedir16, platform as platform2, tmpdir as tmpdir2 } from "node:os";
|
|
64317
|
+
import { join as join17 } from "node:path";
|
|
63982
64318
|
import { createInterface as createInterface2 } from "node:readline";
|
|
63983
64319
|
function getUpdateCommand() {
|
|
63984
64320
|
const scriptPath = process.argv[1] || "";
|
|
@@ -63990,27 +64326,27 @@ function getUpdateCommand() {
|
|
|
63990
64326
|
function getCacheFilePath() {
|
|
63991
64327
|
let cacheDir;
|
|
63992
64328
|
if (isWindows2) {
|
|
63993
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
63994
|
-
cacheDir =
|
|
64329
|
+
const localAppData = process.env.LOCALAPPDATA || join17(homedir16(), "AppData", "Local");
|
|
64330
|
+
cacheDir = join17(localAppData, "claudish");
|
|
63995
64331
|
} else {
|
|
63996
|
-
cacheDir =
|
|
64332
|
+
cacheDir = join17(homedir16(), ".cache", "claudish");
|
|
63997
64333
|
}
|
|
63998
64334
|
try {
|
|
63999
|
-
if (!
|
|
64335
|
+
if (!existsSync16(cacheDir)) {
|
|
64000
64336
|
mkdirSync10(cacheDir, { recursive: true });
|
|
64001
64337
|
}
|
|
64002
|
-
return
|
|
64338
|
+
return join17(cacheDir, "update-check.json");
|
|
64003
64339
|
} catch {
|
|
64004
|
-
return
|
|
64340
|
+
return join17(tmpdir2(), "claudish-update-check.json");
|
|
64005
64341
|
}
|
|
64006
64342
|
}
|
|
64007
64343
|
function readCache() {
|
|
64008
64344
|
try {
|
|
64009
64345
|
const cachePath = getCacheFilePath();
|
|
64010
|
-
if (!
|
|
64346
|
+
if (!existsSync16(cachePath)) {
|
|
64011
64347
|
return null;
|
|
64012
64348
|
}
|
|
64013
|
-
const data = JSON.parse(
|
|
64349
|
+
const data = JSON.parse(readFileSync13(cachePath, "utf-8"));
|
|
64014
64350
|
return data;
|
|
64015
64351
|
} catch {
|
|
64016
64352
|
return null;
|
|
@@ -64033,7 +64369,7 @@ function isCacheValid(cache) {
|
|
|
64033
64369
|
function clearCache() {
|
|
64034
64370
|
try {
|
|
64035
64371
|
const cachePath = getCacheFilePath();
|
|
64036
|
-
if (
|
|
64372
|
+
if (existsSync16(cachePath)) {
|
|
64037
64373
|
unlinkSync5(cachePath);
|
|
64038
64374
|
}
|
|
64039
64375
|
} catch {}
|
package/package.json
CHANGED