claudish 3.9.0 → 3.11.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 +599 -105
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53247,6 +53247,157 @@ var init_undici = __esm(() => {
|
|
|
53247
53247
|
({ EventSource } = require_eventsource());
|
|
53248
53248
|
});
|
|
53249
53249
|
|
|
53250
|
+
// ../core/dist/handlers/shared/local-queue.js
|
|
53251
|
+
class LocalModelQueue {
|
|
53252
|
+
static instance = null;
|
|
53253
|
+
queue = [];
|
|
53254
|
+
activeRequests = 0;
|
|
53255
|
+
maxParallel;
|
|
53256
|
+
maxQueueSize = 100;
|
|
53257
|
+
requestDelay = 100;
|
|
53258
|
+
totalProcessed = 0;
|
|
53259
|
+
totalErrors = 0;
|
|
53260
|
+
totalOOMErrors = 0;
|
|
53261
|
+
constructor() {
|
|
53262
|
+
this.maxParallel = this.getMaxParallelFromEnv();
|
|
53263
|
+
if (getLogLevel() === "debug") {
|
|
53264
|
+
log(`[LocalQueue] Queue initialized with maxParallel=${this.maxParallel}, maxQueueSize=${this.maxQueueSize}`);
|
|
53265
|
+
}
|
|
53266
|
+
}
|
|
53267
|
+
static getInstance() {
|
|
53268
|
+
if (!LocalModelQueue.instance) {
|
|
53269
|
+
LocalModelQueue.instance = new LocalModelQueue;
|
|
53270
|
+
}
|
|
53271
|
+
return LocalModelQueue.instance;
|
|
53272
|
+
}
|
|
53273
|
+
static isEnabled() {
|
|
53274
|
+
const enabled = process.env.CLAUDISH_LOCAL_QUEUE_ENABLED;
|
|
53275
|
+
if (enabled === undefined || enabled === "")
|
|
53276
|
+
return true;
|
|
53277
|
+
return enabled !== "false" && enabled !== "0";
|
|
53278
|
+
}
|
|
53279
|
+
async enqueue(fetchFn, providerId) {
|
|
53280
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
53281
|
+
if (getLogLevel() === "debug") {
|
|
53282
|
+
log(`[LocalQueue] Queue full (${this.queue.length}/${this.maxQueueSize}), rejecting request`);
|
|
53283
|
+
}
|
|
53284
|
+
throw new Error(`Local model queue full (${this.queue.length}/${this.maxQueueSize}). GPU is overloaded. Please wait for current requests to complete.`);
|
|
53285
|
+
}
|
|
53286
|
+
return new Promise((resolve, reject) => {
|
|
53287
|
+
const queuedRequest = {
|
|
53288
|
+
fetchFn,
|
|
53289
|
+
resolve,
|
|
53290
|
+
reject,
|
|
53291
|
+
providerId
|
|
53292
|
+
};
|
|
53293
|
+
this.queue.push(queuedRequest);
|
|
53294
|
+
if (getLogLevel() === "debug") {
|
|
53295
|
+
log(`[LocalQueue] Request enqueued for ${providerId} (queue length: ${this.queue.length}, active: ${this.activeRequests}/${this.maxParallel})`);
|
|
53296
|
+
}
|
|
53297
|
+
this.processQueue();
|
|
53298
|
+
});
|
|
53299
|
+
}
|
|
53300
|
+
async processQueue() {
|
|
53301
|
+
while (this.queue.length > 0 && this.activeRequests < this.maxParallel) {
|
|
53302
|
+
const request = this.queue.shift();
|
|
53303
|
+
if (!request)
|
|
53304
|
+
break;
|
|
53305
|
+
if (getLogLevel() === "debug") {
|
|
53306
|
+
log(`[LocalQueue] Processing request for ${request.providerId} (${this.queue.length} remaining in queue, ${this.activeRequests + 1}/${this.maxParallel} active)`);
|
|
53307
|
+
}
|
|
53308
|
+
this.executeRequest(request).catch((err) => {
|
|
53309
|
+
if (getLogLevel() === "debug") {
|
|
53310
|
+
log(`[LocalQueue] Request execution failed: ${err}`);
|
|
53311
|
+
}
|
|
53312
|
+
});
|
|
53313
|
+
await this.delay(this.requestDelay);
|
|
53314
|
+
}
|
|
53315
|
+
}
|
|
53316
|
+
async executeRequest(request) {
|
|
53317
|
+
this.activeRequests++;
|
|
53318
|
+
try {
|
|
53319
|
+
const response = await request.fetchFn();
|
|
53320
|
+
if (response.status === 500) {
|
|
53321
|
+
const errorBody = await response.clone().text();
|
|
53322
|
+
if (this.isOOMError(errorBody)) {
|
|
53323
|
+
this.totalOOMErrors++;
|
|
53324
|
+
if (getLogLevel() === "debug") {
|
|
53325
|
+
log(`[LocalQueue] GPU out-of-memory detected for ${request.providerId}. Consider reducing CLAUDISH_LOCAL_MAX_PARALLEL (current: ${this.maxParallel})`);
|
|
53326
|
+
}
|
|
53327
|
+
await this.delay(2000);
|
|
53328
|
+
const retryResponse = await request.fetchFn();
|
|
53329
|
+
if (retryResponse.status === 500) {
|
|
53330
|
+
const retryErrorBody = await retryResponse.clone().text();
|
|
53331
|
+
if (this.isOOMError(retryErrorBody)) {
|
|
53332
|
+
throw new Error(`GPU out-of-memory error persisted after retry. Try setting CLAUDISH_LOCAL_MAX_PARALLEL=1 for sequential processing.`);
|
|
53333
|
+
}
|
|
53334
|
+
}
|
|
53335
|
+
this.totalProcessed++;
|
|
53336
|
+
request.resolve(retryResponse);
|
|
53337
|
+
return;
|
|
53338
|
+
}
|
|
53339
|
+
}
|
|
53340
|
+
this.totalProcessed++;
|
|
53341
|
+
request.resolve(response);
|
|
53342
|
+
} catch (error46) {
|
|
53343
|
+
this.totalErrors++;
|
|
53344
|
+
if (getLogLevel() === "debug") {
|
|
53345
|
+
log(`[LocalQueue] Request failed for ${request.providerId}: ${error46}`);
|
|
53346
|
+
}
|
|
53347
|
+
request.reject(error46 instanceof Error ? error46 : new Error(String(error46)));
|
|
53348
|
+
} finally {
|
|
53349
|
+
this.activeRequests--;
|
|
53350
|
+
if (this.queue.length > 0) {
|
|
53351
|
+
this.processQueue();
|
|
53352
|
+
}
|
|
53353
|
+
}
|
|
53354
|
+
}
|
|
53355
|
+
isOOMError(errorBody) {
|
|
53356
|
+
const oomPatterns = [
|
|
53357
|
+
"failed to allocate memory",
|
|
53358
|
+
"CUDA out of memory",
|
|
53359
|
+
"OOM",
|
|
53360
|
+
"out of memory",
|
|
53361
|
+
"memory allocation failed",
|
|
53362
|
+
"insufficient memory",
|
|
53363
|
+
"GPU memory"
|
|
53364
|
+
];
|
|
53365
|
+
const bodyLower = errorBody.toLowerCase();
|
|
53366
|
+
return oomPatterns.some((pattern) => bodyLower.includes(pattern.toLowerCase()));
|
|
53367
|
+
}
|
|
53368
|
+
getMaxParallelFromEnv() {
|
|
53369
|
+
const envValue = process.env.CLAUDISH_LOCAL_MAX_PARALLEL;
|
|
53370
|
+
if (!envValue)
|
|
53371
|
+
return 1;
|
|
53372
|
+
const parsed = Number.parseInt(envValue, 10);
|
|
53373
|
+
if (Number.isNaN(parsed) || parsed < 1) {
|
|
53374
|
+
log(`[LocalQueue] Invalid CLAUDISH_LOCAL_MAX_PARALLEL: ${envValue}, using default: 1`);
|
|
53375
|
+
return 1;
|
|
53376
|
+
}
|
|
53377
|
+
if (parsed > 8) {
|
|
53378
|
+
log(`[LocalQueue] CLAUDISH_LOCAL_MAX_PARALLEL too high: ${parsed}, capping at 8`);
|
|
53379
|
+
return 8;
|
|
53380
|
+
}
|
|
53381
|
+
return parsed;
|
|
53382
|
+
}
|
|
53383
|
+
delay(ms) {
|
|
53384
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
53385
|
+
}
|
|
53386
|
+
getStats() {
|
|
53387
|
+
return {
|
|
53388
|
+
queueLength: this.queue.length,
|
|
53389
|
+
activeRequests: this.activeRequests,
|
|
53390
|
+
maxParallel: this.maxParallel,
|
|
53391
|
+
totalProcessed: this.totalProcessed,
|
|
53392
|
+
totalErrors: this.totalErrors,
|
|
53393
|
+
totalOOMErrors: this.totalOOMErrors
|
|
53394
|
+
};
|
|
53395
|
+
}
|
|
53396
|
+
}
|
|
53397
|
+
var init_local_queue = __esm(() => {
|
|
53398
|
+
init_logger();
|
|
53399
|
+
});
|
|
53400
|
+
|
|
53250
53401
|
// ../core/dist/handlers/local-provider-handler.js
|
|
53251
53402
|
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "node:fs";
|
|
53252
53403
|
import { homedir as homedir2 } from "node:os";
|
|
@@ -53620,7 +53771,7 @@ If you cannot use structured tool_calls, format as JSON:
|
|
|
53620
53771
|
log(`[LocalProvider:${this.provider.name}] Request timeout (10 min) - aborting`);
|
|
53621
53772
|
controller.abort();
|
|
53622
53773
|
}, 600000);
|
|
53623
|
-
const
|
|
53774
|
+
const doFetch = () => fetch(apiUrl, {
|
|
53624
53775
|
method: "POST",
|
|
53625
53776
|
headers: {
|
|
53626
53777
|
"Content-Type": "application/json"
|
|
@@ -53629,6 +53780,7 @@ If you cannot use structured tool_calls, format as JSON:
|
|
|
53629
53780
|
signal: controller.signal,
|
|
53630
53781
|
dispatcher: localProviderAgent
|
|
53631
53782
|
});
|
|
53783
|
+
const response = LocalModelQueue.isEnabled() ? await LocalModelQueue.getInstance().enqueue(doFetch, this.provider.name) : await doFetch();
|
|
53632
53784
|
clearTimeout(timeoutId);
|
|
53633
53785
|
log(`[LocalProvider:${this.provider.name}] Response status: ${response.status}`);
|
|
53634
53786
|
if (!response.ok) {
|
|
@@ -53706,6 +53858,7 @@ var init_local_provider_handler = __esm(() => {
|
|
|
53706
53858
|
init_logger();
|
|
53707
53859
|
init_undici();
|
|
53708
53860
|
init_openai_compat();
|
|
53861
|
+
init_local_queue();
|
|
53709
53862
|
localProviderAgent = new $Agent({
|
|
53710
53863
|
headersTimeout: 600000,
|
|
53711
53864
|
bodyTimeout: 600000,
|
|
@@ -58545,7 +58698,21 @@ var getRemoteProviders = () => [
|
|
|
58545
58698
|
supportsVision: true,
|
|
58546
58699
|
supportsStreaming: true,
|
|
58547
58700
|
supportsJsonMode: true,
|
|
58548
|
-
supportsReasoning:
|
|
58701
|
+
supportsReasoning: true
|
|
58702
|
+
}
|
|
58703
|
+
},
|
|
58704
|
+
{
|
|
58705
|
+
name: "zai",
|
|
58706
|
+
baseUrl: process.env.ZAI_BASE_URL || "https://api.z.ai",
|
|
58707
|
+
apiPath: "/api/anthropic/v1/messages",
|
|
58708
|
+
apiKeyEnvVar: "ZAI_API_KEY",
|
|
58709
|
+
prefixes: ["zai/"],
|
|
58710
|
+
capabilities: {
|
|
58711
|
+
supportsTools: true,
|
|
58712
|
+
supportsVision: true,
|
|
58713
|
+
supportsStreaming: true,
|
|
58714
|
+
supportsJsonMode: true,
|
|
58715
|
+
supportsReasoning: true
|
|
58549
58716
|
}
|
|
58550
58717
|
},
|
|
58551
58718
|
{
|
|
@@ -58578,6 +58745,323 @@ var getRemoteProviders = () => [
|
|
|
58578
58745
|
}
|
|
58579
58746
|
];
|
|
58580
58747
|
|
|
58748
|
+
// ../core/dist/providers/provider-resolver.js
|
|
58749
|
+
function isApiKeyAvailable(info) {
|
|
58750
|
+
if (!info.envVar) {
|
|
58751
|
+
return true;
|
|
58752
|
+
}
|
|
58753
|
+
if (process.env[info.envVar]) {
|
|
58754
|
+
return true;
|
|
58755
|
+
}
|
|
58756
|
+
if (info.aliases) {
|
|
58757
|
+
for (const alias of info.aliases) {
|
|
58758
|
+
if (process.env[alias]) {
|
|
58759
|
+
return true;
|
|
58760
|
+
}
|
|
58761
|
+
}
|
|
58762
|
+
}
|
|
58763
|
+
return false;
|
|
58764
|
+
}
|
|
58765
|
+
function resolveModelProvider(modelId) {
|
|
58766
|
+
if (!modelId) {
|
|
58767
|
+
const info2 = API_KEY_INFO.openrouter;
|
|
58768
|
+
return {
|
|
58769
|
+
category: "openrouter",
|
|
58770
|
+
providerName: "OpenRouter",
|
|
58771
|
+
modelName: "",
|
|
58772
|
+
fullModelId: "",
|
|
58773
|
+
requiredApiKeyEnvVar: info2.envVar,
|
|
58774
|
+
apiKeyAvailable: isApiKeyAvailable(info2),
|
|
58775
|
+
apiKeyDescription: info2.description,
|
|
58776
|
+
apiKeyUrl: info2.url
|
|
58777
|
+
};
|
|
58778
|
+
}
|
|
58779
|
+
const lowerModelId = modelId.toLowerCase();
|
|
58780
|
+
if (LOCAL_PREFIXES.some((prefix) => lowerModelId.startsWith(prefix))) {
|
|
58781
|
+
const resolved = resolveProvider(modelId);
|
|
58782
|
+
const urlParsed = parseUrlModel(modelId);
|
|
58783
|
+
let providerName = "Local";
|
|
58784
|
+
let modelName = modelId;
|
|
58785
|
+
if (resolved) {
|
|
58786
|
+
providerName = resolved.provider.name.charAt(0).toUpperCase() + resolved.provider.name.slice(1);
|
|
58787
|
+
modelName = resolved.modelName;
|
|
58788
|
+
} else if (urlParsed) {
|
|
58789
|
+
providerName = "Custom URL";
|
|
58790
|
+
modelName = urlParsed.modelName;
|
|
58791
|
+
}
|
|
58792
|
+
return {
|
|
58793
|
+
category: "local",
|
|
58794
|
+
providerName,
|
|
58795
|
+
modelName,
|
|
58796
|
+
fullModelId: modelId,
|
|
58797
|
+
requiredApiKeyEnvVar: null,
|
|
58798
|
+
apiKeyAvailable: true,
|
|
58799
|
+
apiKeyDescription: null,
|
|
58800
|
+
apiKeyUrl: null
|
|
58801
|
+
};
|
|
58802
|
+
}
|
|
58803
|
+
const remoteResolved = resolveRemoteProvider(modelId);
|
|
58804
|
+
if (remoteResolved) {
|
|
58805
|
+
const provider = remoteResolved.provider;
|
|
58806
|
+
if (provider.name === "openrouter") {
|
|
58807
|
+
const info3 = API_KEY_INFO.openrouter;
|
|
58808
|
+
return {
|
|
58809
|
+
category: "openrouter",
|
|
58810
|
+
providerName: "OpenRouter",
|
|
58811
|
+
modelName: remoteResolved.modelName,
|
|
58812
|
+
fullModelId: modelId,
|
|
58813
|
+
requiredApiKeyEnvVar: info3.envVar,
|
|
58814
|
+
apiKeyAvailable: isApiKeyAvailable(info3),
|
|
58815
|
+
apiKeyDescription: info3.description,
|
|
58816
|
+
apiKeyUrl: info3.url
|
|
58817
|
+
};
|
|
58818
|
+
}
|
|
58819
|
+
const info2 = API_KEY_INFO[provider.name] || {
|
|
58820
|
+
envVar: provider.apiKeyEnvVar,
|
|
58821
|
+
description: `${provider.name} API Key`,
|
|
58822
|
+
url: ""
|
|
58823
|
+
};
|
|
58824
|
+
if (isApiKeyAvailable(info2)) {
|
|
58825
|
+
const providerDisplayName2 = PROVIDER_DISPLAY_NAMES[provider.name] || provider.name.charAt(0).toUpperCase() + provider.name.slice(1);
|
|
58826
|
+
return {
|
|
58827
|
+
category: "direct-api",
|
|
58828
|
+
providerName: providerDisplayName2,
|
|
58829
|
+
modelName: remoteResolved.modelName,
|
|
58830
|
+
fullModelId: modelId,
|
|
58831
|
+
requiredApiKeyEnvVar: info2.envVar || null,
|
|
58832
|
+
apiKeyAvailable: isApiKeyAvailable(info2),
|
|
58833
|
+
apiKeyDescription: info2.envVar ? info2.description : null,
|
|
58834
|
+
apiKeyUrl: info2.envVar ? info2.url : null
|
|
58835
|
+
};
|
|
58836
|
+
}
|
|
58837
|
+
if (isApiKeyAvailable(API_KEY_INFO.openrouter)) {
|
|
58838
|
+
const orInfo = API_KEY_INFO.openrouter;
|
|
58839
|
+
return {
|
|
58840
|
+
category: "openrouter",
|
|
58841
|
+
providerName: "OpenRouter (fallback)",
|
|
58842
|
+
modelName: modelId,
|
|
58843
|
+
fullModelId: modelId,
|
|
58844
|
+
requiredApiKeyEnvVar: orInfo.envVar,
|
|
58845
|
+
apiKeyAvailable: true,
|
|
58846
|
+
apiKeyDescription: orInfo.description,
|
|
58847
|
+
apiKeyUrl: orInfo.url
|
|
58848
|
+
};
|
|
58849
|
+
}
|
|
58850
|
+
if (isApiKeyAvailable(API_KEY_INFO.vertex)) {
|
|
58851
|
+
const vertexInfo = API_KEY_INFO.vertex;
|
|
58852
|
+
return {
|
|
58853
|
+
category: "direct-api",
|
|
58854
|
+
providerName: "Vertex AI (fallback)",
|
|
58855
|
+
modelName: modelId,
|
|
58856
|
+
fullModelId: modelId,
|
|
58857
|
+
requiredApiKeyEnvVar: vertexInfo.envVar,
|
|
58858
|
+
apiKeyAvailable: true,
|
|
58859
|
+
apiKeyDescription: vertexInfo.description,
|
|
58860
|
+
apiKeyUrl: vertexInfo.url
|
|
58861
|
+
};
|
|
58862
|
+
}
|
|
58863
|
+
const providerDisplayName = PROVIDER_DISPLAY_NAMES[provider.name] || provider.name.charAt(0).toUpperCase() + provider.name.slice(1);
|
|
58864
|
+
return {
|
|
58865
|
+
category: "direct-api",
|
|
58866
|
+
providerName: providerDisplayName,
|
|
58867
|
+
modelName: remoteResolved.modelName,
|
|
58868
|
+
fullModelId: modelId,
|
|
58869
|
+
requiredApiKeyEnvVar: info2.envVar || null,
|
|
58870
|
+
apiKeyAvailable: false,
|
|
58871
|
+
apiKeyDescription: info2.envVar ? info2.description : null,
|
|
58872
|
+
apiKeyUrl: info2.envVar ? info2.url : null
|
|
58873
|
+
};
|
|
58874
|
+
}
|
|
58875
|
+
if (!modelId.includes("/")) {
|
|
58876
|
+
return {
|
|
58877
|
+
category: "native-anthropic",
|
|
58878
|
+
providerName: "Anthropic (Native)",
|
|
58879
|
+
modelName: modelId,
|
|
58880
|
+
fullModelId: modelId,
|
|
58881
|
+
requiredApiKeyEnvVar: null,
|
|
58882
|
+
apiKeyAvailable: true,
|
|
58883
|
+
apiKeyDescription: null,
|
|
58884
|
+
apiKeyUrl: null
|
|
58885
|
+
};
|
|
58886
|
+
}
|
|
58887
|
+
const info = API_KEY_INFO.openrouter;
|
|
58888
|
+
return {
|
|
58889
|
+
category: "openrouter",
|
|
58890
|
+
providerName: "OpenRouter",
|
|
58891
|
+
modelName: modelId,
|
|
58892
|
+
fullModelId: modelId,
|
|
58893
|
+
requiredApiKeyEnvVar: info.envVar,
|
|
58894
|
+
apiKeyAvailable: isApiKeyAvailable(info),
|
|
58895
|
+
apiKeyDescription: info.description,
|
|
58896
|
+
apiKeyUrl: info.url
|
|
58897
|
+
};
|
|
58898
|
+
}
|
|
58899
|
+
function validateApiKeysForModels(models) {
|
|
58900
|
+
return models.filter((m) => m !== undefined).map((m) => resolveModelProvider(m));
|
|
58901
|
+
}
|
|
58902
|
+
function getMissingKeyResolutions(resolutions) {
|
|
58903
|
+
return resolutions.filter((r) => r.requiredApiKeyEnvVar && !r.apiKeyAvailable);
|
|
58904
|
+
}
|
|
58905
|
+
function getMissingKeyError(resolution) {
|
|
58906
|
+
if (!resolution.requiredApiKeyEnvVar || resolution.apiKeyAvailable) {
|
|
58907
|
+
return "";
|
|
58908
|
+
}
|
|
58909
|
+
const lines = [];
|
|
58910
|
+
lines.push(`Error: ${resolution.apiKeyDescription} is required for model "${resolution.fullModelId}"`);
|
|
58911
|
+
lines.push("");
|
|
58912
|
+
lines.push("Set it with:");
|
|
58913
|
+
lines.push(` export ${resolution.requiredApiKeyEnvVar}='your-key-here'`);
|
|
58914
|
+
if (resolution.apiKeyUrl) {
|
|
58915
|
+
lines.push("");
|
|
58916
|
+
lines.push(`Get your API key from: ${resolution.apiKeyUrl}`);
|
|
58917
|
+
}
|
|
58918
|
+
if (resolution.category === "openrouter") {
|
|
58919
|
+
const provider = resolution.fullModelId.split("/")[0];
|
|
58920
|
+
lines.push("");
|
|
58921
|
+
lines.push(`Tip: "${resolution.fullModelId}" is an OpenRouter model.`);
|
|
58922
|
+
lines.push(` OpenRouter routes to ${provider}'s API through their unified interface.`);
|
|
58923
|
+
if (provider === "google") {
|
|
58924
|
+
lines.push("");
|
|
58925
|
+
lines.push(" For direct Gemini API (no OpenRouter), use prefix 'g/' or 'gemini/':");
|
|
58926
|
+
lines.push(' claudish --model g/gemini-2.0-flash "task"');
|
|
58927
|
+
} else if (provider === "openai") {
|
|
58928
|
+
lines.push("");
|
|
58929
|
+
lines.push(" For direct OpenAI API (no OpenRouter), use prefix 'oai/':");
|
|
58930
|
+
lines.push(' claudish --model oai/gpt-4o "task"');
|
|
58931
|
+
}
|
|
58932
|
+
}
|
|
58933
|
+
return lines.join(`
|
|
58934
|
+
`);
|
|
58935
|
+
}
|
|
58936
|
+
function getMissingKeysError(resolutions) {
|
|
58937
|
+
const missing = getMissingKeyResolutions(resolutions);
|
|
58938
|
+
if (missing.length === 0) {
|
|
58939
|
+
return "";
|
|
58940
|
+
}
|
|
58941
|
+
if (missing.length === 1) {
|
|
58942
|
+
return getMissingKeyError(missing[0]);
|
|
58943
|
+
}
|
|
58944
|
+
const lines = [];
|
|
58945
|
+
lines.push("Error: Multiple API keys are required for the configured models:");
|
|
58946
|
+
lines.push("");
|
|
58947
|
+
const byEnvVar = new Map;
|
|
58948
|
+
for (const r of missing) {
|
|
58949
|
+
if (r.requiredApiKeyEnvVar && !byEnvVar.has(r.requiredApiKeyEnvVar)) {
|
|
58950
|
+
byEnvVar.set(r.requiredApiKeyEnvVar, r);
|
|
58951
|
+
}
|
|
58952
|
+
}
|
|
58953
|
+
for (const [envVar, resolution] of byEnvVar) {
|
|
58954
|
+
lines.push(` ${resolution.apiKeyDescription}:`);
|
|
58955
|
+
lines.push(` export ${envVar}='your-key-here'`);
|
|
58956
|
+
if (resolution.apiKeyUrl) {
|
|
58957
|
+
lines.push(` Get from: ${resolution.apiKeyUrl}`);
|
|
58958
|
+
}
|
|
58959
|
+
lines.push("");
|
|
58960
|
+
}
|
|
58961
|
+
return lines.join(`
|
|
58962
|
+
`);
|
|
58963
|
+
}
|
|
58964
|
+
function requiresOpenRouterKey(modelId) {
|
|
58965
|
+
const resolution = resolveModelProvider(modelId);
|
|
58966
|
+
return resolution.category === "openrouter";
|
|
58967
|
+
}
|
|
58968
|
+
function isLocalModel(modelId) {
|
|
58969
|
+
if (!modelId)
|
|
58970
|
+
return false;
|
|
58971
|
+
const resolution = resolveModelProvider(modelId);
|
|
58972
|
+
return resolution.category === "local";
|
|
58973
|
+
}
|
|
58974
|
+
var API_KEY_INFO, LOCAL_PREFIXES, PROVIDER_DISPLAY_NAMES;
|
|
58975
|
+
var init_provider_resolver = __esm(() => {
|
|
58976
|
+
API_KEY_INFO = {
|
|
58977
|
+
openrouter: {
|
|
58978
|
+
envVar: "OPENROUTER_API_KEY",
|
|
58979
|
+
description: "OpenRouter API Key",
|
|
58980
|
+
url: "https://openrouter.ai/keys"
|
|
58981
|
+
},
|
|
58982
|
+
gemini: {
|
|
58983
|
+
envVar: "GEMINI_API_KEY",
|
|
58984
|
+
description: "Google Gemini API Key",
|
|
58985
|
+
url: "https://aistudio.google.com/app/apikey"
|
|
58986
|
+
},
|
|
58987
|
+
"gemini-codeassist": {
|
|
58988
|
+
envVar: "",
|
|
58989
|
+
description: "Gemini Code Assist (OAuth)",
|
|
58990
|
+
url: "https://cloud.google.com/code-assist"
|
|
58991
|
+
},
|
|
58992
|
+
vertex: {
|
|
58993
|
+
envVar: "VERTEX_API_KEY",
|
|
58994
|
+
description: "Vertex AI API Key",
|
|
58995
|
+
url: "https://console.cloud.google.com/vertex-ai",
|
|
58996
|
+
aliases: ["VERTEX_PROJECT"]
|
|
58997
|
+
},
|
|
58998
|
+
openai: {
|
|
58999
|
+
envVar: "OPENAI_API_KEY",
|
|
59000
|
+
description: "OpenAI API Key",
|
|
59001
|
+
url: "https://platform.openai.com/api-keys"
|
|
59002
|
+
},
|
|
59003
|
+
minimax: {
|
|
59004
|
+
envVar: "MINIMAX_API_KEY",
|
|
59005
|
+
description: "MiniMax API Key",
|
|
59006
|
+
url: "https://www.minimaxi.com/"
|
|
59007
|
+
},
|
|
59008
|
+
kimi: {
|
|
59009
|
+
envVar: "MOONSHOT_API_KEY",
|
|
59010
|
+
description: "Kimi/Moonshot API Key",
|
|
59011
|
+
url: "https://platform.moonshot.cn/",
|
|
59012
|
+
aliases: ["KIMI_API_KEY"]
|
|
59013
|
+
},
|
|
59014
|
+
glm: {
|
|
59015
|
+
envVar: "ZHIPU_API_KEY",
|
|
59016
|
+
description: "GLM/Zhipu API Key",
|
|
59017
|
+
url: "https://open.bigmodel.cn/",
|
|
59018
|
+
aliases: ["GLM_API_KEY"]
|
|
59019
|
+
},
|
|
59020
|
+
ollamacloud: {
|
|
59021
|
+
envVar: "OLLAMA_API_KEY",
|
|
59022
|
+
description: "OllamaCloud API Key",
|
|
59023
|
+
url: "https://ollama.com/account"
|
|
59024
|
+
},
|
|
59025
|
+
"opencode-zen": {
|
|
59026
|
+
envVar: "",
|
|
59027
|
+
description: "OpenCode Zen (Free)",
|
|
59028
|
+
url: "https://opencode.ai/"
|
|
59029
|
+
},
|
|
59030
|
+
zai: {
|
|
59031
|
+
envVar: "ZAI_API_KEY",
|
|
59032
|
+
description: "Z.AI API Key",
|
|
59033
|
+
url: "https://z.ai/"
|
|
59034
|
+
}
|
|
59035
|
+
};
|
|
59036
|
+
LOCAL_PREFIXES = [
|
|
59037
|
+
"ollama/",
|
|
59038
|
+
"ollama:",
|
|
59039
|
+
"lmstudio/",
|
|
59040
|
+
"lmstudio:",
|
|
59041
|
+
"mlstudio/",
|
|
59042
|
+
"mlstudio:",
|
|
59043
|
+
"vllm/",
|
|
59044
|
+
"vllm:",
|
|
59045
|
+
"mlx/",
|
|
59046
|
+
"mlx:",
|
|
59047
|
+
"http://",
|
|
59048
|
+
"https://localhost"
|
|
59049
|
+
];
|
|
59050
|
+
PROVIDER_DISPLAY_NAMES = {
|
|
59051
|
+
gemini: "Gemini",
|
|
59052
|
+
"gemini-codeassist": "Gemini Code Assist",
|
|
59053
|
+
vertex: "Vertex AI",
|
|
59054
|
+
openai: "OpenAI",
|
|
59055
|
+
openrouter: "OpenRouter",
|
|
59056
|
+
minimax: "MiniMax",
|
|
59057
|
+
kimi: "Kimi",
|
|
59058
|
+
glm: "GLM",
|
|
59059
|
+
zai: "Z.AI",
|
|
59060
|
+
ollamacloud: "OllamaCloud",
|
|
59061
|
+
"opencode-zen": "OpenCode Zen"
|
|
59062
|
+
};
|
|
59063
|
+
});
|
|
59064
|
+
|
|
58581
59065
|
// ../core/dist/proxy-server.js
|
|
58582
59066
|
async function createProxyServer(port, openrouterApiKey, model, monitorMode = false, anthropicApiKey, modelMap, options = {}) {
|
|
58583
59067
|
const nativeHandler = new NativeHandler(anthropicApiKey);
|
|
@@ -58633,68 +59117,70 @@ async function createProxyServer(port, openrouterApiKey, model, monitorMode = fa
|
|
|
58633
59117
|
if (remoteProviderHandlers.has(targetModel)) {
|
|
58634
59118
|
return remoteProviderHandlers.get(targetModel);
|
|
58635
59119
|
}
|
|
58636
|
-
const
|
|
58637
|
-
if (
|
|
59120
|
+
const resolution = resolveModelProvider(targetModel);
|
|
59121
|
+
if (resolution.category === "openrouter") {
|
|
58638
59122
|
return null;
|
|
58639
59123
|
}
|
|
58640
|
-
if (
|
|
58641
|
-
|
|
58642
|
-
|
|
58643
|
-
|
|
58644
|
-
|
|
58645
|
-
|
|
58646
|
-
|
|
58647
|
-
|
|
58648
|
-
|
|
58649
|
-
|
|
58650
|
-
|
|
58651
|
-
|
|
58652
|
-
|
|
58653
|
-
|
|
58654
|
-
|
|
58655
|
-
|
|
58656
|
-
|
|
58657
|
-
|
|
58658
|
-
|
|
58659
|
-
handler = new AnthropicCompatHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
58660
|
-
log(`[Proxy] Created ${resolved.provider.name} handler: ${resolved.modelName}`);
|
|
58661
|
-
} else if (resolved.provider.name === "glm") {
|
|
58662
|
-
handler = new OpenAIHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
58663
|
-
log(`[Proxy] Created ${resolved.provider.name} handler: ${resolved.modelName}`);
|
|
58664
|
-
} else if (resolved.provider.name === "opencode-zen") {
|
|
58665
|
-
if (resolved.modelName.toLowerCase().includes("minimax")) {
|
|
59124
|
+
if (resolution.category === "direct-api" && resolution.apiKeyAvailable) {
|
|
59125
|
+
const resolved = resolveRemoteProvider(targetModel);
|
|
59126
|
+
if (!resolved)
|
|
59127
|
+
return null;
|
|
59128
|
+
if (resolved.provider.name === "openrouter") {
|
|
59129
|
+
return null;
|
|
59130
|
+
}
|
|
59131
|
+
const apiKey = resolved.provider.apiKeyEnvVar ? process.env[resolved.provider.apiKeyEnvVar] || "" : "";
|
|
59132
|
+
let handler;
|
|
59133
|
+
if (resolved.provider.name === "gemini") {
|
|
59134
|
+
handler = new GeminiHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59135
|
+
log(`[Proxy] Created Gemini handler: ${resolved.modelName}`);
|
|
59136
|
+
} else if (resolved.provider.name === "gemini-codeassist") {
|
|
59137
|
+
handler = new GeminiCodeAssistHandler(resolved.modelName, port);
|
|
59138
|
+
log(`[Proxy] Created Gemini Code Assist handler: ${resolved.modelName}`);
|
|
59139
|
+
} else if (resolved.provider.name === "openai") {
|
|
59140
|
+
handler = new OpenAIHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59141
|
+
log(`[Proxy] Created OpenAI handler: ${resolved.modelName}`);
|
|
59142
|
+
} else if (resolved.provider.name === "minimax" || resolved.provider.name === "kimi" || resolved.provider.name === "zai") {
|
|
58666
59143
|
handler = new AnthropicCompatHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
58667
|
-
log(`[Proxy] Created
|
|
58668
|
-
} else {
|
|
59144
|
+
log(`[Proxy] Created ${resolved.provider.name} handler: ${resolved.modelName}`);
|
|
59145
|
+
} else if (resolved.provider.name === "glm") {
|
|
58669
59146
|
handler = new OpenAIHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
58670
|
-
log(`[Proxy] Created
|
|
58671
|
-
}
|
|
58672
|
-
|
|
58673
|
-
|
|
58674
|
-
|
|
58675
|
-
|
|
58676
|
-
|
|
58677
|
-
|
|
58678
|
-
|
|
58679
|
-
|
|
58680
|
-
|
|
58681
|
-
|
|
58682
|
-
|
|
58683
|
-
|
|
58684
|
-
|
|
59147
|
+
log(`[Proxy] Created ${resolved.provider.name} handler: ${resolved.modelName}`);
|
|
59148
|
+
} else if (resolved.provider.name === "opencode-zen") {
|
|
59149
|
+
if (resolved.modelName.toLowerCase().includes("minimax")) {
|
|
59150
|
+
handler = new AnthropicCompatHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59151
|
+
log(`[Proxy] Created OpenCode Zen (Anthropic) handler: ${resolved.modelName}`);
|
|
59152
|
+
} else {
|
|
59153
|
+
handler = new OpenAIHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59154
|
+
log(`[Proxy] Created OpenCode Zen (OpenAI) handler: ${resolved.modelName}`);
|
|
59155
|
+
}
|
|
59156
|
+
} else if (resolved.provider.name === "ollamacloud") {
|
|
59157
|
+
handler = new OllamaCloudHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59158
|
+
log(`[Proxy] Created OllamaCloud handler: ${resolved.modelName}`);
|
|
59159
|
+
} else if (resolved.provider.name === "vertex") {
|
|
59160
|
+
const hasApiKey = !!process.env.VERTEX_API_KEY;
|
|
59161
|
+
const vertexConfig = getVertexConfig();
|
|
59162
|
+
if (hasApiKey) {
|
|
59163
|
+
handler = new GeminiHandler(resolved.provider, resolved.modelName, apiKey, port);
|
|
59164
|
+
log(`[Proxy] Created Vertex AI Express handler: ${resolved.modelName}`);
|
|
59165
|
+
} else if (vertexConfig) {
|
|
59166
|
+
const oauthError = validateVertexOAuthConfig();
|
|
59167
|
+
if (oauthError) {
|
|
59168
|
+
log(`[Proxy] Vertex OAuth config error: ${oauthError}`);
|
|
59169
|
+
return null;
|
|
59170
|
+
}
|
|
59171
|
+
handler = new VertexOAuthHandler(resolved.modelName, port);
|
|
59172
|
+
log(`[Proxy] Created Vertex AI OAuth handler: ${resolved.modelName} (project: ${vertexConfig.projectId})`);
|
|
59173
|
+
} else {
|
|
59174
|
+
log(`[Proxy] Vertex AI requires either VERTEX_API_KEY or VERTEX_PROJECT`);
|
|
58685
59175
|
return null;
|
|
58686
59176
|
}
|
|
58687
|
-
handler = new VertexOAuthHandler(resolved.modelName, port);
|
|
58688
|
-
log(`[Proxy] Created Vertex AI OAuth handler: ${resolved.modelName} (project: ${vertexConfig.projectId})`);
|
|
58689
59177
|
} else {
|
|
58690
|
-
log(`[Proxy] Vertex AI requires either VERTEX_API_KEY or VERTEX_PROJECT`);
|
|
58691
59178
|
return null;
|
|
58692
59179
|
}
|
|
58693
|
-
|
|
58694
|
-
return
|
|
59180
|
+
remoteProviderHandlers.set(targetModel, handler);
|
|
59181
|
+
return handler;
|
|
58695
59182
|
}
|
|
58696
|
-
|
|
58697
|
-
return handler;
|
|
59183
|
+
return null;
|
|
58698
59184
|
};
|
|
58699
59185
|
const getHandlerForRequest = (requestedModel) => {
|
|
58700
59186
|
if (monitorMode)
|
|
@@ -58799,18 +59285,22 @@ var init_proxy_server = __esm(() => {
|
|
|
58799
59285
|
init_poe_handler();
|
|
58800
59286
|
init_ollamacloud_handler();
|
|
58801
59287
|
init_vertex_auth();
|
|
59288
|
+
init_provider_resolver();
|
|
58802
59289
|
});
|
|
58803
59290
|
|
|
58804
59291
|
// ../core/dist/index.js
|
|
58805
59292
|
var exports_dist = {};
|
|
58806
59293
|
__export(exports_dist, {
|
|
58807
59294
|
validateRemoteProviderApiKey: () => validateRemoteProviderApiKey,
|
|
59295
|
+
validateApiKeysForModels: () => validateApiKeysForModels,
|
|
58808
59296
|
transformOpenAIToClaude: () => transformOpenAIToClaude,
|
|
58809
59297
|
transformMessages: () => transformMessages,
|
|
58810
59298
|
setupGeminiUser: () => setupGeminiUser,
|
|
58811
59299
|
sanitizeRoot: () => sanitizeRoot,
|
|
58812
59300
|
resolveRemoteProvider: () => resolveRemoteProvider,
|
|
58813
59301
|
resolveProvider: () => resolveProvider,
|
|
59302
|
+
resolveModelProvider: () => resolveModelProvider,
|
|
59303
|
+
requiresOpenRouterKey: () => requiresOpenRouterKey,
|
|
58814
59304
|
removeUriFormat: () => removeUriFormat,
|
|
58815
59305
|
parseUrlModel: () => parseUrlModel,
|
|
58816
59306
|
mapTools: () => mapTools,
|
|
@@ -58819,10 +59309,14 @@ __export(exports_dist, {
|
|
|
58819
59309
|
log: () => log,
|
|
58820
59310
|
isLoggingEnabled: () => isLoggingEnabled,
|
|
58821
59311
|
isLocalProvider: () => isLocalProvider,
|
|
59312
|
+
isLocalModel: () => isLocalModel,
|
|
58822
59313
|
initLogger: () => initLogger,
|
|
58823
59314
|
getValidAccessToken: () => getValidAccessToken,
|
|
58824
59315
|
getRegisteredRemoteProviders: () => getRegisteredRemoteProviders,
|
|
58825
59316
|
getRegisteredProviders: () => getRegisteredProviders,
|
|
59317
|
+
getMissingKeysError: () => getMissingKeysError,
|
|
59318
|
+
getMissingKeyResolutions: () => getMissingKeyResolutions,
|
|
59319
|
+
getMissingKeyError: () => getMissingKeyError,
|
|
58826
59320
|
getLogFilePath: () => getLogFilePath,
|
|
58827
59321
|
createUrlProvider: () => createUrlProvider,
|
|
58828
59322
|
createProxyServer: () => createProxyServer,
|
|
@@ -58851,6 +59345,7 @@ var init_dist3 = __esm(() => {
|
|
|
58851
59345
|
init_poe_handler();
|
|
58852
59346
|
init_gemini_codeassist_handler();
|
|
58853
59347
|
init_gemini_oauth();
|
|
59348
|
+
init_provider_resolver();
|
|
58854
59349
|
init_transform();
|
|
58855
59350
|
init_manager();
|
|
58856
59351
|
init_gemini_thought_signature();
|
|
@@ -61983,9 +62478,15 @@ function fuzzyScore2(text, query) {
|
|
|
61983
62478
|
// src/cli.ts
|
|
61984
62479
|
var exports_cli = {};
|
|
61985
62480
|
__export(exports_cli, {
|
|
62481
|
+
validateApiKeysForModels: () => validateApiKeysForModels,
|
|
62482
|
+
resolveModelProvider: () => resolveModelProvider,
|
|
62483
|
+
requiresOpenRouterKey: () => requiresOpenRouterKey,
|
|
61986
62484
|
parseArgs: () => parseArgs,
|
|
61987
62485
|
isLocalModel: () => isLocalModel,
|
|
61988
|
-
getVersion: () => getVersion
|
|
62486
|
+
getVersion: () => getVersion,
|
|
62487
|
+
getMissingKeysError: () => getMissingKeysError,
|
|
62488
|
+
getMissingKeyResolutions: () => getMissingKeyResolutions,
|
|
62489
|
+
getMissingKeyError: () => getMissingKeyError
|
|
61989
62490
|
});
|
|
61990
62491
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync13, existsSync as existsSync9, mkdirSync as mkdirSync11, copyFileSync } from "node:fs";
|
|
61991
62492
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
@@ -61993,20 +62494,6 @@ import { dirname as dirname5, join as join17 } from "node:path";
|
|
|
61993
62494
|
function getVersion() {
|
|
61994
62495
|
return VERSION;
|
|
61995
62496
|
}
|
|
61996
|
-
function isLocalModel(modelId) {
|
|
61997
|
-
if (!modelId)
|
|
61998
|
-
return false;
|
|
61999
|
-
const localPrefixes = [
|
|
62000
|
-
"ollama/",
|
|
62001
|
-
"ollama:",
|
|
62002
|
-
"lmstudio/",
|
|
62003
|
-
"vllm/",
|
|
62004
|
-
"mlx/",
|
|
62005
|
-
"http://",
|
|
62006
|
-
"https://localhost"
|
|
62007
|
-
];
|
|
62008
|
-
return localPrefixes.some((prefix) => modelId.toLowerCase().startsWith(prefix));
|
|
62009
|
-
}
|
|
62010
62497
|
async function parseArgs(args) {
|
|
62011
62498
|
const config3 = {
|
|
62012
62499
|
model: undefined,
|
|
@@ -62186,35 +62673,9 @@ async function parseArgs(args) {
|
|
|
62186
62673
|
console.log("[claudish] API key will be extracted from Claude Code's requests");
|
|
62187
62674
|
console.log("[claudish] Ensure you are logged in to Claude Code (claude auth login)");
|
|
62188
62675
|
}
|
|
62189
|
-
} else {
|
|
62190
|
-
const allModels = [
|
|
62191
|
-
config3.model,
|
|
62192
|
-
config3.modelOpus,
|
|
62193
|
-
config3.modelSonnet,
|
|
62194
|
-
config3.modelHaiku,
|
|
62195
|
-
config3.modelSubagent
|
|
62196
|
-
];
|
|
62197
|
-
const hasNonLocalModel = allModels.some((m) => m && !isLocalModel(m));
|
|
62198
|
-
if (hasNonLocalModel) {
|
|
62199
|
-
const apiKey = process.env[ENV.OPENROUTER_API_KEY];
|
|
62200
|
-
if (!apiKey) {
|
|
62201
|
-
if (!config3.interactive) {
|
|
62202
|
-
console.error("Error: OPENROUTER_API_KEY environment variable is required");
|
|
62203
|
-
console.error("Get your API key from: https://openrouter.ai/keys");
|
|
62204
|
-
console.error("");
|
|
62205
|
-
console.error("Set it now:");
|
|
62206
|
-
console.error(" export OPENROUTER_API_KEY='sk-or-v1-...'");
|
|
62207
|
-
process.exit(1);
|
|
62208
|
-
}
|
|
62209
|
-
config3.openrouterApiKey = undefined;
|
|
62210
|
-
} else {
|
|
62211
|
-
config3.openrouterApiKey = apiKey;
|
|
62212
|
-
}
|
|
62213
|
-
} else {
|
|
62214
|
-
config3.openrouterApiKey = process.env[ENV.OPENROUTER_API_KEY];
|
|
62215
|
-
}
|
|
62216
|
-
config3.anthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
62217
62676
|
}
|
|
62677
|
+
config3.openrouterApiKey = process.env[ENV.OPENROUTER_API_KEY];
|
|
62678
|
+
config3.anthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
62218
62679
|
if (config3.quiet === undefined) {
|
|
62219
62680
|
config3.quiet = !config3.interactive;
|
|
62220
62681
|
}
|
|
@@ -62691,7 +63152,7 @@ function printVersion() {
|
|
|
62691
63152
|
}
|
|
62692
63153
|
function printHelp() {
|
|
62693
63154
|
console.log(`
|
|
62694
|
-
claudish - Run Claude Code with any AI model (OpenRouter, Gemini, OpenAI, MiniMax, Kimi, GLM, Local)
|
|
63155
|
+
claudish - Run Claude Code with any AI model (OpenRouter, Gemini, OpenAI, MiniMax, Kimi, GLM, Z.AI, Local)
|
|
62695
63156
|
|
|
62696
63157
|
USAGE:
|
|
62697
63158
|
claudish # Interactive mode (default, shows model selector)
|
|
@@ -62705,6 +63166,7 @@ MODEL ROUTING (prefix-based):
|
|
|
62705
63166
|
mmax/, mm/ MiniMax Direct API claudish --model mmax/MiniMax-M2.1 "task"
|
|
62706
63167
|
kimi/, moonshot/ Kimi Direct API claudish --model kimi/kimi-k2-thinking-turbo "task"
|
|
62707
63168
|
glm/, zhipu/ GLM Direct API claudish --model glm/glm-4.7 "task"
|
|
63169
|
+
zai/ Z.AI Direct API claudish --model zai/glm-4.7 "task"
|
|
62708
63170
|
oc/ OllamaCloud claudish --model oc/gpt-oss:20b "task"
|
|
62709
63171
|
zen/ OpenCode Zen (free) claudish --model zen/grok-code "task"
|
|
62710
63172
|
ollama/ Ollama (local) claudish --model ollama/llama3.2 "task"
|
|
@@ -63139,11 +63601,12 @@ async function fetchZenModels2() {
|
|
|
63139
63601
|
return [];
|
|
63140
63602
|
}
|
|
63141
63603
|
}
|
|
63142
|
-
var __filename6, __dirname6, VERSION = "3.
|
|
63604
|
+
var __filename6, __dirname6, VERSION = "3.11.0", CACHE_MAX_AGE_DAYS3 = 2, MODELS_JSON_PATH, ALL_MODELS_JSON_PATH2;
|
|
63143
63605
|
var init_cli = __esm(() => {
|
|
63144
63606
|
init_dist3();
|
|
63145
63607
|
init_model_loader2();
|
|
63146
63608
|
init_profile_config();
|
|
63609
|
+
init_dist3();
|
|
63147
63610
|
__filename6 = fileURLToPath5(import.meta.url);
|
|
63148
63611
|
__dirname6 = dirname5(__filename6);
|
|
63149
63612
|
try {
|
|
@@ -63842,6 +64305,12 @@ async function runCli() {
|
|
|
63842
64305
|
const { parseArgs: parseArgs2, getVersion: getVersion2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
|
|
63843
64306
|
const { DEFAULT_PORT_RANGE: DEFAULT_PORT_RANGE2 } = await Promise.resolve().then(() => (init_dist3(), exports_dist));
|
|
63844
64307
|
const { selectModel: selectModel2, promptForApiKey: promptForApiKey2 } = await Promise.resolve().then(() => (init_model_selector(), exports_model_selector));
|
|
64308
|
+
const {
|
|
64309
|
+
resolveModelProvider: resolveModelProvider2,
|
|
64310
|
+
validateApiKeysForModels: validateApiKeysForModels2,
|
|
64311
|
+
getMissingKeyResolutions: getMissingKeyResolutions2,
|
|
64312
|
+
getMissingKeysError: getMissingKeysError2
|
|
64313
|
+
} = await Promise.resolve().then(() => (init_dist3(), exports_dist));
|
|
63845
64314
|
const { initLogger: initLogger2, getLogFilePath: getLogFilePath2 } = await Promise.resolve().then(() => (init_dist3(), exports_dist));
|
|
63846
64315
|
const { findAvailablePort: findAvailablePort2 } = await Promise.resolve().then(() => (init_port_manager(), exports_port_manager));
|
|
63847
64316
|
const { createProxyServer: createProxyServer2 } = await Promise.resolve().then(() => (init_dist3(), exports_dist));
|
|
@@ -63879,12 +64348,6 @@ async function runCli() {
|
|
|
63879
64348
|
console.error(" export CLAUDE_PATH=~/.claude/local/claude");
|
|
63880
64349
|
process.exit(1);
|
|
63881
64350
|
}
|
|
63882
|
-
const { isLocalModel: isLocalModel2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
|
|
63883
|
-
const usingLocalModel = isLocalModel2(cliConfig.model);
|
|
63884
|
-
if (cliConfig.interactive && !cliConfig.monitor && !cliConfig.openrouterApiKey && !usingLocalModel) {
|
|
63885
|
-
cliConfig.openrouterApiKey = await promptForApiKey2();
|
|
63886
|
-
console.log("");
|
|
63887
|
-
}
|
|
63888
64351
|
if (cliConfig.interactive && !cliConfig.monitor && !cliConfig.model) {
|
|
63889
64352
|
cliConfig.model = await selectModel2({ freeOnly: cliConfig.freeOnly });
|
|
63890
64353
|
console.log("");
|
|
@@ -63895,6 +64358,37 @@ async function runCli() {
|
|
|
63895
64358
|
console.error("Try: claudish --list-models");
|
|
63896
64359
|
process.exit(1);
|
|
63897
64360
|
}
|
|
64361
|
+
if (!cliConfig.monitor) {
|
|
64362
|
+
const hasExplicitModel = typeof cliConfig.model === "string";
|
|
64363
|
+
const modelsToValidate = hasExplicitModel ? [cliConfig.model] : [
|
|
64364
|
+
cliConfig.model,
|
|
64365
|
+
cliConfig.modelOpus,
|
|
64366
|
+
cliConfig.modelSonnet,
|
|
64367
|
+
cliConfig.modelHaiku,
|
|
64368
|
+
cliConfig.modelSubagent
|
|
64369
|
+
];
|
|
64370
|
+
const resolutions = validateApiKeysForModels2(modelsToValidate);
|
|
64371
|
+
const missingKeys = getMissingKeyResolutions2(resolutions);
|
|
64372
|
+
if (missingKeys.length > 0) {
|
|
64373
|
+
if (cliConfig.interactive) {
|
|
64374
|
+
const needsOpenRouter = missingKeys.some((r) => r.category === "openrouter");
|
|
64375
|
+
if (needsOpenRouter && !cliConfig.openrouterApiKey) {
|
|
64376
|
+
cliConfig.openrouterApiKey = await promptForApiKey2();
|
|
64377
|
+
console.log("");
|
|
64378
|
+
process.env.OPENROUTER_API_KEY = cliConfig.openrouterApiKey;
|
|
64379
|
+
}
|
|
64380
|
+
const stillMissing = getMissingKeyResolutions2(validateApiKeysForModels2(modelsToValidate));
|
|
64381
|
+
const nonOpenRouterMissing = stillMissing.filter((r) => r.category !== "openrouter");
|
|
64382
|
+
if (nonOpenRouterMissing.length > 0) {
|
|
64383
|
+
console.error(getMissingKeysError2(nonOpenRouterMissing));
|
|
64384
|
+
process.exit(1);
|
|
64385
|
+
}
|
|
64386
|
+
} else {
|
|
64387
|
+
console.error(getMissingKeysError2(missingKeys));
|
|
64388
|
+
process.exit(1);
|
|
64389
|
+
}
|
|
64390
|
+
}
|
|
64391
|
+
}
|
|
63898
64392
|
if (cliConfig.model && typeof cliConfig.model === "string" && cliConfig.model.startsWith("go/")) {
|
|
63899
64393
|
const { GeminiOAuth: GeminiOAuth2 } = await Promise.resolve().then(() => (init_dist3(), exports_dist));
|
|
63900
64394
|
const oauth = GeminiOAuth2.getInstance();
|