claudish 7.62.0 → 7.64.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 +209 -92
- 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.64.0";
|
|
733
733
|
|
|
734
734
|
// src/logger.ts
|
|
735
735
|
var exports_logger = {};
|
|
@@ -35087,7 +35087,7 @@ class OpenAIProviderTransport {
|
|
|
35087
35087
|
}
|
|
35088
35088
|
async getHeaders() {
|
|
35089
35089
|
const headers = {};
|
|
35090
|
-
if (this.apiKey) {
|
|
35090
|
+
if (this.provider.authScheme !== "none" && this.apiKey) {
|
|
35091
35091
|
if (this.provider.authScheme === "x-api-key") {
|
|
35092
35092
|
headers["x-api-key"] = this.apiKey;
|
|
35093
35093
|
} else {
|
|
@@ -36505,6 +36505,17 @@ function wrapAnthropicError(status, message, errorType, upstreamStatus) {
|
|
|
36505
36505
|
error46.upstream_status = upstreamStatus;
|
|
36506
36506
|
return { type: "error", error: error46 };
|
|
36507
36507
|
}
|
|
36508
|
+
function extractUpstreamStatus(body) {
|
|
36509
|
+
if (!body)
|
|
36510
|
+
return;
|
|
36511
|
+
try {
|
|
36512
|
+
const parsed = JSON.parse(body);
|
|
36513
|
+
const status = parsed?.error?.upstream_status;
|
|
36514
|
+
return typeof status === "number" ? status : undefined;
|
|
36515
|
+
} catch {
|
|
36516
|
+
return;
|
|
36517
|
+
}
|
|
36518
|
+
}
|
|
36508
36519
|
function extractProviderMessage(body) {
|
|
36509
36520
|
if (body == null)
|
|
36510
36521
|
return "";
|
|
@@ -40894,6 +40905,8 @@ class ApiKeyCredentialProvider {
|
|
|
40894
40905
|
}
|
|
40895
40906
|
}
|
|
40896
40907
|
async isAvailable(opts) {
|
|
40908
|
+
if (this.authScheme === "none")
|
|
40909
|
+
return true;
|
|
40897
40910
|
if (this.publicKeyFallback)
|
|
40898
40911
|
return true;
|
|
40899
40912
|
if (this.resolveFromEnvConfig())
|
|
@@ -40908,6 +40921,9 @@ class ApiKeyCredentialProvider {
|
|
|
40908
40921
|
this.resolving = undefined;
|
|
40909
40922
|
}
|
|
40910
40923
|
async getRequestAuth(ctx) {
|
|
40924
|
+
if (this.authScheme === "none") {
|
|
40925
|
+
return { headers: { ...this.staticHeaders } };
|
|
40926
|
+
}
|
|
40911
40927
|
const key = await this.resolveKey({ allowOpPrompt: ctx.allowOpPrompt }) || this.publicKeyFallback || "";
|
|
40912
40928
|
let headers;
|
|
40913
40929
|
if (this.authScheme === "x-api-key") {
|
|
@@ -42077,6 +42093,13 @@ __export(exports_authority, {
|
|
|
42077
42093
|
credentials: () => credentials,
|
|
42078
42094
|
CredentialAuthority: () => CredentialAuthority
|
|
42079
42095
|
});
|
|
42096
|
+
function normalizeAuthScheme(scheme) {
|
|
42097
|
+
if (scheme === "x-api-key")
|
|
42098
|
+
return "x-api-key";
|
|
42099
|
+
if (scheme === "none")
|
|
42100
|
+
return "none";
|
|
42101
|
+
return "bearer";
|
|
42102
|
+
}
|
|
42080
42103
|
|
|
42081
42104
|
class CredentialAuthority {
|
|
42082
42105
|
registry = new Map;
|
|
@@ -42093,7 +42116,7 @@ class CredentialAuthority {
|
|
|
42093
42116
|
catalogName: descriptor.name,
|
|
42094
42117
|
envVar: descriptor.envVar,
|
|
42095
42118
|
aliases: descriptor.aliases,
|
|
42096
|
-
authScheme: descriptor.authScheme
|
|
42119
|
+
authScheme: normalizeAuthScheme(descriptor.authScheme),
|
|
42097
42120
|
declaredKey: descriptor.declaredKey
|
|
42098
42121
|
}), [descriptor.name]);
|
|
42099
42122
|
}
|
|
@@ -42166,7 +42189,7 @@ class CredentialAuthority {
|
|
|
42166
42189
|
catalogName: def.name,
|
|
42167
42190
|
envVar: def.apiKeyEnvVar,
|
|
42168
42191
|
aliases: def.apiKeyAliases,
|
|
42169
|
-
authScheme: def.authScheme
|
|
42192
|
+
authScheme: normalizeAuthScheme(def.authScheme),
|
|
42170
42193
|
publicKeyFallback: def.publicKeyFallback,
|
|
42171
42194
|
oauthFallback: def.oauthFallback
|
|
42172
42195
|
}), [def.name, ...RUNTIME_NAME_ALIASES[def.name] ?? []]);
|
|
@@ -43333,7 +43356,7 @@ class AnthropicProviderTransport {
|
|
|
43333
43356
|
const headers = {
|
|
43334
43357
|
"anthropic-version": "2023-06-01"
|
|
43335
43358
|
};
|
|
43336
|
-
if (this.provider.authScheme === "bearer") {
|
|
43359
|
+
if (this.provider.authScheme === "none") {} else if (this.provider.authScheme === "bearer") {
|
|
43337
43360
|
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
43338
43361
|
} else {
|
|
43339
43362
|
headers["x-api-key"] = this.apiKey;
|
|
@@ -45239,7 +45262,27 @@ var init_catalog_client = __esm(() => {
|
|
|
45239
45262
|
});
|
|
45240
45263
|
|
|
45241
45264
|
// src/config-schema.ts
|
|
45242
|
-
|
|
45265
|
+
function requireKeyUnlessNoAuth(ep, ctx) {
|
|
45266
|
+
const declared = ep.apiKey?.trim() ?? "";
|
|
45267
|
+
if (ep.authScheme === "none") {
|
|
45268
|
+
if (declared !== "") {
|
|
45269
|
+
ctx.addIssue({
|
|
45270
|
+
code: "custom",
|
|
45271
|
+
path: ["apiKey"],
|
|
45272
|
+
message: 'authScheme "none" sends no auth header, so apiKey must be omitted. ' + "Remove apiKey, or drop authScheme to send it as a bearer token."
|
|
45273
|
+
});
|
|
45274
|
+
}
|
|
45275
|
+
return;
|
|
45276
|
+
}
|
|
45277
|
+
if (declared === "") {
|
|
45278
|
+
ctx.addIssue({
|
|
45279
|
+
code: "custom",
|
|
45280
|
+
path: ["apiKey"],
|
|
45281
|
+
message: "apiKey is required. If this endpoint needs no credential, set " + '"authScheme": "none" and omit apiKey entirely.'
|
|
45282
|
+
});
|
|
45283
|
+
}
|
|
45284
|
+
}
|
|
45285
|
+
var BuiltinDefaultProviderSchema, CustomEndpointAuthSchemeSchema, CustomEndpointSimpleSchema, CustomEndpointComplexSchema, CustomEndpointSchema, PredefinedEndpointsConfigSchema, DefaultProviderSchema;
|
|
45243
45286
|
var init_config_schema = __esm(() => {
|
|
45244
45287
|
init_zod();
|
|
45245
45288
|
BuiltinDefaultProviderSchema = exports_external.enum([
|
|
@@ -45249,27 +45292,29 @@ var init_config_schema = __esm(() => {
|
|
|
45249
45292
|
"anthropic",
|
|
45250
45293
|
"google"
|
|
45251
45294
|
]);
|
|
45295
|
+
CustomEndpointAuthSchemeSchema = exports_external.enum(["bearer", "x-api-key", "none"]);
|
|
45252
45296
|
CustomEndpointSimpleSchema = exports_external.object({
|
|
45253
45297
|
kind: exports_external.literal("simple"),
|
|
45254
45298
|
url: exports_external.url(),
|
|
45255
45299
|
format: exports_external.enum(["openai", "anthropic"]),
|
|
45256
|
-
apiKey: exports_external.string().
|
|
45300
|
+
apiKey: exports_external.string().optional(),
|
|
45301
|
+
authScheme: CustomEndpointAuthSchemeSchema.optional(),
|
|
45257
45302
|
modelPrefix: exports_external.string().optional(),
|
|
45258
45303
|
models: exports_external.array(exports_external.string()).optional()
|
|
45259
|
-
});
|
|
45304
|
+
}).superRefine(requireKeyUnlessNoAuth);
|
|
45260
45305
|
CustomEndpointComplexSchema = exports_external.object({
|
|
45261
45306
|
kind: exports_external.literal("complex"),
|
|
45262
45307
|
displayName: exports_external.string(),
|
|
45263
45308
|
transport: exports_external.enum(["openai", "anthropic", "gemini", "ollamacloud", "litellm"]),
|
|
45264
45309
|
baseUrl: exports_external.url(),
|
|
45265
45310
|
apiPath: exports_external.string().optional(),
|
|
45266
|
-
apiKey: exports_external.string().
|
|
45267
|
-
authScheme:
|
|
45311
|
+
apiKey: exports_external.string().optional(),
|
|
45312
|
+
authScheme: CustomEndpointAuthSchemeSchema.optional(),
|
|
45268
45313
|
headers: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
45269
45314
|
streamFormat: exports_external.enum(["openai-sse", "openai-responses-sse", "gemini-sse", "anthropic-sse", "ollama-jsonl"]).optional(),
|
|
45270
45315
|
modelPrefix: exports_external.string().optional(),
|
|
45271
45316
|
models: exports_external.array(exports_external.string()).optional()
|
|
45272
|
-
});
|
|
45317
|
+
}).superRefine(requireKeyUnlessNoAuth);
|
|
45273
45318
|
CustomEndpointSchema = exports_external.discriminatedUnion("kind", [
|
|
45274
45319
|
CustomEndpointSimpleSchema,
|
|
45275
45320
|
CustomEndpointComplexSchema
|
|
@@ -45297,6 +45342,40 @@ var init_endpoint_diagnostics = __esm(() => {
|
|
|
45297
45342
|
reasons = new Map;
|
|
45298
45343
|
});
|
|
45299
45344
|
|
|
45345
|
+
// src/providers/picker-alias-extra.ts
|
|
45346
|
+
var PROVIDER_FILTER_ALIAS_EXTRA;
|
|
45347
|
+
var init_picker_alias_extra = __esm(() => {
|
|
45348
|
+
PROVIDER_FILTER_ALIAS_EXTRA = {
|
|
45349
|
+
gem: "google",
|
|
45350
|
+
zen: "opencode-zen"
|
|
45351
|
+
};
|
|
45352
|
+
});
|
|
45353
|
+
|
|
45354
|
+
// src/providers/reserved-namespace.ts
|
|
45355
|
+
function reservedNamespace() {
|
|
45356
|
+
const reserved = new Map;
|
|
45357
|
+
for (const def of BUILTIN_PROVIDERS) {
|
|
45358
|
+
reserved.set(def.name.toLowerCase(), def.name);
|
|
45359
|
+
for (const shortcut of def.shortcuts) {
|
|
45360
|
+
reserved.set(shortcut.toLowerCase(), def.name);
|
|
45361
|
+
}
|
|
45362
|
+
for (const legacy of def.legacyPrefixes) {
|
|
45363
|
+
reserved.set(legacy.prefix.replace(/[/:]+$/, "").toLowerCase(), def.name);
|
|
45364
|
+
}
|
|
45365
|
+
}
|
|
45366
|
+
for (const [alias, owner] of Object.entries(PROVIDER_FILTER_ALIAS_EXTRA)) {
|
|
45367
|
+
reserved.set(alias.toLowerCase(), owner);
|
|
45368
|
+
}
|
|
45369
|
+
return reserved;
|
|
45370
|
+
}
|
|
45371
|
+
function reservedNamespaceOwner(name) {
|
|
45372
|
+
return reservedNamespace().get(name.toLowerCase());
|
|
45373
|
+
}
|
|
45374
|
+
var init_reserved_namespace = __esm(() => {
|
|
45375
|
+
init_picker_alias_extra();
|
|
45376
|
+
init_provider_definitions();
|
|
45377
|
+
});
|
|
45378
|
+
|
|
45300
45379
|
// src/providers/custom-endpoints-loader.ts
|
|
45301
45380
|
function registerEndpoint(name, entry, ovr) {
|
|
45302
45381
|
const validated = CustomEndpointSchema.parse(entry);
|
|
@@ -45308,17 +45387,24 @@ function registerEndpoint(name, entry, ovr) {
|
|
|
45308
45387
|
name: def.name,
|
|
45309
45388
|
envVar: def.apiKeyEnvVar,
|
|
45310
45389
|
aliases: def.apiKeyAliases,
|
|
45311
|
-
authScheme: def.authScheme
|
|
45390
|
+
authScheme: def.authScheme,
|
|
45312
45391
|
declaredKey: () => resolveDeclaredEndpointKey(validated)
|
|
45313
45392
|
});
|
|
45314
45393
|
clearEndpointUnavailable(name);
|
|
45315
45394
|
}
|
|
45316
45395
|
function loadCustomEndpoints(config2) {
|
|
45317
|
-
const result = { registered: 0, errors: [] };
|
|
45396
|
+
const result = { registered: 0, errors: [], refused: [] };
|
|
45318
45397
|
const raw = config2.customEndpoints;
|
|
45319
45398
|
if (!raw || typeof raw !== "object")
|
|
45320
45399
|
return result;
|
|
45321
45400
|
for (const [name, entry] of Object.entries(raw)) {
|
|
45401
|
+
const owner = reservedNamespaceOwner(name);
|
|
45402
|
+
if (owner) {
|
|
45403
|
+
const reason = `'${name}' is already claimed by builtin provider '${owner}' ` + "(as its name, a shortcut, or a legacy prefix)";
|
|
45404
|
+
result.refused.push({ name, reason });
|
|
45405
|
+
recordEndpointUnavailable(name, `custom endpoint was skipped because ${reason}`);
|
|
45406
|
+
continue;
|
|
45407
|
+
}
|
|
45322
45408
|
try {
|
|
45323
45409
|
registerEndpoint(name, entry);
|
|
45324
45410
|
result.registered++;
|
|
@@ -45352,7 +45438,7 @@ function buildProviderDefinition(name, ep, ovr) {
|
|
|
45352
45438
|
isDirectApi: true,
|
|
45353
45439
|
shortestPrefix: name,
|
|
45354
45440
|
description: ovr?.description ?? `Custom endpoint: ${name}`,
|
|
45355
|
-
authScheme: "bearer"
|
|
45441
|
+
authScheme: ep.authScheme ?? "bearer"
|
|
45356
45442
|
};
|
|
45357
45443
|
}
|
|
45358
45444
|
return {
|
|
@@ -45514,7 +45600,7 @@ function buildComplexHandler(ep, ctx, apiKey, baseUrl) {
|
|
|
45514
45600
|
}
|
|
45515
45601
|
}
|
|
45516
45602
|
function resolveCustomEndpointApiKey(ep) {
|
|
45517
|
-
const literal3 = ep.apiKey;
|
|
45603
|
+
const literal3 = ep.apiKey ?? "";
|
|
45518
45604
|
const match = literal3.match(/^\$\{([A-Z_][A-Z0-9_]*)\}$/i);
|
|
45519
45605
|
if (match) {
|
|
45520
45606
|
return process.env[match[1]] ?? "";
|
|
@@ -45549,21 +45635,13 @@ var init_custom_endpoints_loader = __esm(() => {
|
|
|
45549
45635
|
init_composed_handler();
|
|
45550
45636
|
init_endpoint_diagnostics();
|
|
45551
45637
|
init_provider_definitions();
|
|
45638
|
+
init_reserved_namespace();
|
|
45552
45639
|
init_runtime_providers();
|
|
45553
45640
|
init_anthropic_compat();
|
|
45554
45641
|
init_litellm();
|
|
45555
45642
|
init_openai();
|
|
45556
45643
|
});
|
|
45557
45644
|
|
|
45558
|
-
// src/providers/picker-alias-extra.ts
|
|
45559
|
-
var PROVIDER_FILTER_ALIAS_EXTRA;
|
|
45560
|
-
var init_picker_alias_extra = __esm(() => {
|
|
45561
|
-
PROVIDER_FILTER_ALIAS_EXTRA = {
|
|
45562
|
-
gem: "google",
|
|
45563
|
-
zen: "opencode-zen"
|
|
45564
|
-
};
|
|
45565
|
-
});
|
|
45566
|
-
|
|
45567
45645
|
// src/providers/predefined-catalog.ts
|
|
45568
45646
|
var PREDEFINED_ENDPOINTS;
|
|
45569
45647
|
var init_predefined_catalog = __esm(() => {
|
|
@@ -45872,22 +45950,6 @@ function warnOnce2(message) {
|
|
|
45872
45950
|
function activeCatalog() {
|
|
45873
45951
|
return catalogOverride ?? PREDEFINED_ENDPOINTS;
|
|
45874
45952
|
}
|
|
45875
|
-
function reservedNamespace() {
|
|
45876
|
-
const reserved = new Map;
|
|
45877
|
-
for (const def of BUILTIN_PROVIDERS) {
|
|
45878
|
-
reserved.set(def.name.toLowerCase(), def.name);
|
|
45879
|
-
for (const shortcut of def.shortcuts) {
|
|
45880
|
-
reserved.set(shortcut.toLowerCase(), def.name);
|
|
45881
|
-
}
|
|
45882
|
-
for (const legacy of def.legacyPrefixes) {
|
|
45883
|
-
reserved.set(legacy.prefix.replace(/[/:]+$/, "").toLowerCase(), def.name);
|
|
45884
|
-
}
|
|
45885
|
-
}
|
|
45886
|
-
for (const [alias, owner] of Object.entries(PROVIDER_FILTER_ALIAS_EXTRA)) {
|
|
45887
|
-
reserved.set(alias.toLowerCase(), owner);
|
|
45888
|
-
}
|
|
45889
|
-
return reserved;
|
|
45890
|
-
}
|
|
45891
45953
|
function readOptOut(config2) {
|
|
45892
45954
|
const off = { disabled: true, disable: new Set, enable: new Set };
|
|
45893
45955
|
if (process.env[KILL_SWITCH_ENV] === "1")
|
|
@@ -46026,9 +46088,8 @@ var init_predefined_endpoints = __esm(() => {
|
|
|
46026
46088
|
init_config_schema();
|
|
46027
46089
|
init_custom_endpoints_loader();
|
|
46028
46090
|
init_endpoint_diagnostics();
|
|
46029
|
-
init_picker_alias_extra();
|
|
46030
46091
|
init_predefined_catalog();
|
|
46031
|
-
|
|
46092
|
+
init_reserved_namespace();
|
|
46032
46093
|
init_runtime_providers();
|
|
46033
46094
|
warnedMessages2 = new Set;
|
|
46034
46095
|
ownRegistrations = new Set;
|
|
@@ -46038,23 +46099,67 @@ var init_predefined_endpoints = __esm(() => {
|
|
|
46038
46099
|
var exports_endpoint_registration = {};
|
|
46039
46100
|
__export(exports_endpoint_registration, {
|
|
46040
46101
|
invalidateEndpointRegistration: () => invalidateEndpointRegistration,
|
|
46102
|
+
getCustomEndpointResult: () => getCustomEndpointResult,
|
|
46041
46103
|
ensureEndpointsRegistered: () => ensureEndpointsRegistered
|
|
46042
46104
|
});
|
|
46105
|
+
function getCustomEndpointResult() {
|
|
46106
|
+
return lastCustomResult;
|
|
46107
|
+
}
|
|
46043
46108
|
function ensureEndpointsRegistered(opts = {}) {
|
|
46044
46109
|
if (registered && !opts.force)
|
|
46045
46110
|
return;
|
|
46111
|
+
let config2;
|
|
46112
|
+
try {
|
|
46113
|
+
config2 = opts.config ?? loadConfig();
|
|
46114
|
+
} catch {
|
|
46115
|
+
return;
|
|
46116
|
+
}
|
|
46046
46117
|
registered = true;
|
|
46047
46118
|
try {
|
|
46048
|
-
loadPredefinedEndpoints(
|
|
46119
|
+
loadPredefinedEndpoints(config2);
|
|
46120
|
+
} catch {}
|
|
46121
|
+
try {
|
|
46122
|
+
lastCustomResult = loadCustomEndpoints(config2);
|
|
46123
|
+
reportCustomEndpoints(lastCustomResult);
|
|
46124
|
+
} catch {}
|
|
46125
|
+
try {
|
|
46126
|
+
warnOnProjectScopedEndpoints();
|
|
46127
|
+
} catch {}
|
|
46128
|
+
}
|
|
46129
|
+
function reportCustomEndpoints(result) {
|
|
46130
|
+
for (const { name, message } of result.errors) {
|
|
46131
|
+
logStderr(`customEndpoints['${name}'] failed validation: ${message}`);
|
|
46132
|
+
}
|
|
46133
|
+
for (const { name, reason } of result.refused) {
|
|
46134
|
+
warnOnce3(`customEndpoints['${name}'] skipped: ${reason}. The builtin wins. ` + `Rename your entry (e.g. '${name}-custom') to use it.`);
|
|
46135
|
+
}
|
|
46136
|
+
}
|
|
46137
|
+
function warnOnProjectScopedEndpoints() {
|
|
46138
|
+
try {
|
|
46139
|
+
const local = loadLocalConfig();
|
|
46140
|
+
const names = Object.keys(local?.customEndpoints ?? {});
|
|
46141
|
+
if (names.length === 0)
|
|
46142
|
+
return;
|
|
46143
|
+
warnOnce3(`.claudish.json declares customEndpoints (${names.join(", ")}) but they are ` + "read from the GLOBAL config only, so they are being ignored. Move them to " + "~/.claudish/config.json.");
|
|
46049
46144
|
} catch {}
|
|
46050
46145
|
}
|
|
46146
|
+
function warnOnce3(message) {
|
|
46147
|
+
if (warnedMessages3.has(message))
|
|
46148
|
+
return;
|
|
46149
|
+
warnedMessages3.add(message);
|
|
46150
|
+
logStderr(message);
|
|
46151
|
+
}
|
|
46051
46152
|
function invalidateEndpointRegistration() {
|
|
46052
46153
|
registered = false;
|
|
46053
46154
|
}
|
|
46054
|
-
var registered = false;
|
|
46155
|
+
var registered = false, lastCustomResult, warnedMessages3;
|
|
46055
46156
|
var init_endpoint_registration = __esm(() => {
|
|
46157
|
+
init_logger();
|
|
46056
46158
|
init_profile_config();
|
|
46159
|
+
init_custom_endpoints_loader();
|
|
46057
46160
|
init_predefined_endpoints();
|
|
46161
|
+
lastCustomResult = { registered: 0, errors: [], refused: [] };
|
|
46162
|
+
warnedMessages3 = new Set;
|
|
46058
46163
|
});
|
|
46059
46164
|
|
|
46060
46165
|
// src/providers/provider-registry.ts
|
|
@@ -46911,7 +47016,6 @@ async function prepareParentRoutingContext() {
|
|
|
46911
47016
|
try {
|
|
46912
47017
|
const config2 = loadConfig();
|
|
46913
47018
|
ensureEndpointsRegistered({ config: config2 });
|
|
46914
|
-
loadCustomEndpoints(config2);
|
|
46915
47019
|
} catch {}
|
|
46916
47020
|
}
|
|
46917
47021
|
try {
|
|
@@ -46960,7 +47064,6 @@ var init_prehydrate = __esm(() => {
|
|
|
46960
47064
|
init_profile_config();
|
|
46961
47065
|
init_auto_route();
|
|
46962
47066
|
init_catalog_client();
|
|
46963
|
-
init_custom_endpoints_loader();
|
|
46964
47067
|
init_endpoint_registration();
|
|
46965
47068
|
init_model_parser();
|
|
46966
47069
|
init_onepassword();
|
|
@@ -48113,17 +48216,6 @@ async function safeReadBody(response) {
|
|
|
48113
48216
|
return "";
|
|
48114
48217
|
}
|
|
48115
48218
|
}
|
|
48116
|
-
function extractUpstreamStatus(body) {
|
|
48117
|
-
if (!body)
|
|
48118
|
-
return;
|
|
48119
|
-
try {
|
|
48120
|
-
const parsed = JSON.parse(body);
|
|
48121
|
-
const status = parsed?.error?.upstream_status;
|
|
48122
|
-
return typeof status === "number" ? status : undefined;
|
|
48123
|
-
} catch {
|
|
48124
|
-
return;
|
|
48125
|
-
}
|
|
48126
|
-
}
|
|
48127
48219
|
function extractErrorType(body) {
|
|
48128
48220
|
if (!body)
|
|
48129
48221
|
return;
|
|
@@ -48447,6 +48539,7 @@ function isFailureState(state) {
|
|
|
48447
48539
|
}
|
|
48448
48540
|
var STREAM_MS_FLOOR = 50, OAUTH_PROVIDERS2, PROBE_PROMPT = "Count from one to twenty in words, one per line.", PROBE_MAX_TOKENS = 512, MINIMAL_EFFORT_UNSUPPORTED;
|
|
48449
48541
|
var init_probe_live = __esm(() => {
|
|
48542
|
+
init_anthropic_error();
|
|
48450
48543
|
init_model_unsupported();
|
|
48451
48544
|
OAUTH_PROVIDERS2 = new Set(["vertex", "antigravity", "devin"]);
|
|
48452
48545
|
MINIMAL_EFFORT_UNSUPPORTED = new Set(["native-anthropic", "anthropic"]);
|
|
@@ -50491,6 +50584,10 @@ ${summary}`);
|
|
|
50491
50584
|
function isRetryableError(status, errorBody, provider) {
|
|
50492
50585
|
if (hasQuotaExhaustionWording(errorBody))
|
|
50493
50586
|
return true;
|
|
50587
|
+
const upstream = status === 400 ? extractUpstreamStatus(errorBody) : undefined;
|
|
50588
|
+
if (upstream === 401 || upstream === 403 || upstream === 402 || upstream === 429) {
|
|
50589
|
+
return true;
|
|
50590
|
+
}
|
|
50494
50591
|
if (status === 401 || status === 403)
|
|
50495
50592
|
return true;
|
|
50496
50593
|
if (status === 402)
|
|
@@ -50526,8 +50623,15 @@ function isRetryableError(status, errorBody, provider) {
|
|
|
50526
50623
|
function exhaustedChainStatus(errors3) {
|
|
50527
50624
|
if (errors3.length === 0)
|
|
50528
50625
|
return 400;
|
|
50529
|
-
const
|
|
50530
|
-
|
|
50626
|
+
const isTransient = (e) => {
|
|
50627
|
+
if (e.status === 429 || e.status === 503)
|
|
50628
|
+
return true;
|
|
50629
|
+
if (hasQuotaExhaustionWording(e.message))
|
|
50630
|
+
return true;
|
|
50631
|
+
const upstream = e.status === 400 ? extractUpstreamStatus(e.message) : undefined;
|
|
50632
|
+
return upstream === 429 || upstream === 503;
|
|
50633
|
+
};
|
|
50634
|
+
return errors3.every(isTransient) ? 503 : 400;
|
|
50531
50635
|
}
|
|
50532
50636
|
function isProvider(provider, needle) {
|
|
50533
50637
|
if (!provider)
|
|
@@ -50552,6 +50656,7 @@ function truncate(s, max) {
|
|
|
50552
50656
|
var init_fallback_handler = __esm(() => {
|
|
50553
50657
|
init_logger();
|
|
50554
50658
|
init_composed_handler();
|
|
50659
|
+
init_anthropic_error();
|
|
50555
50660
|
init_quota_exhaustion();
|
|
50556
50661
|
});
|
|
50557
50662
|
|
|
@@ -52034,14 +52139,11 @@ function maybeCaptureClassifierRequest(c, body) {
|
|
|
52034
52139
|
async function createProxyServer(port, _openrouterApiKey, model, monitorMode = false, anthropicApiKey, modelMap, options = {}) {
|
|
52035
52140
|
try {
|
|
52036
52141
|
const config2 = loadConfig();
|
|
52037
|
-
ensureEndpointsRegistered({ config: config2 });
|
|
52038
|
-
const customEpResult =
|
|
52142
|
+
ensureEndpointsRegistered({ config: config2, force: true });
|
|
52143
|
+
const customEpResult = getCustomEndpointResult();
|
|
52039
52144
|
if (customEpResult.registered > 0) {
|
|
52040
52145
|
log(`[Proxy] Registered ${customEpResult.registered} custom endpoint(s) from config`);
|
|
52041
52146
|
}
|
|
52042
|
-
for (const err of customEpResult.errors) {
|
|
52043
|
-
logStderr(`customEndpoints['${err.name}'] failed validation: ${err.message}`);
|
|
52044
|
-
}
|
|
52045
52147
|
} catch (err) {
|
|
52046
52148
|
log(`[Proxy] customEndpoints load skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
52047
52149
|
}
|
|
@@ -52155,7 +52257,8 @@ async function createProxyServer(port, _openrouterApiKey, model, monitorMode = f
|
|
|
52155
52257
|
return null;
|
|
52156
52258
|
}
|
|
52157
52259
|
let apiKey = "";
|
|
52158
|
-
|
|
52260
|
+
const needsNoAuth = resolved.provider.authScheme === "none";
|
|
52261
|
+
if (resolved.provider.apiKeyEnvVar && !needsNoAuth) {
|
|
52159
52262
|
if (!credentials.get(resolved.provider.name)) {
|
|
52160
52263
|
logStderr(`[Proxy] No credential provider registered for "${resolved.provider.name}" \u2014 treating as missing credential (authority registration gap)`);
|
|
52161
52264
|
log(`[Proxy] Credential authority has no provider registered under "${resolved.provider.name}"`);
|
|
@@ -52511,7 +52614,6 @@ var init_proxy_server = __esm(() => {
|
|
|
52511
52614
|
init_profile_config();
|
|
52512
52615
|
init_auto_route();
|
|
52513
52616
|
init_catalog_client();
|
|
52514
|
-
init_custom_endpoints_loader();
|
|
52515
52617
|
init_endpoint_diagnostics();
|
|
52516
52618
|
init_endpoint_registration();
|
|
52517
52619
|
init_model_parser();
|
|
@@ -54106,6 +54208,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
54106
54208
|
const doProbe = args.probe !== false;
|
|
54107
54209
|
const timeoutMs = typeof args.timeout_ms === "number" ? args.timeout_ms : 20000;
|
|
54108
54210
|
const proxy = doProbe ? await getProxy() : null;
|
|
54211
|
+
ensureEndpointsRegistered();
|
|
54109
54212
|
const rows = [];
|
|
54110
54213
|
const readyModels = [];
|
|
54111
54214
|
const failedModels = [];
|
|
@@ -54775,6 +54878,7 @@ var init_mcp_server = __esm(() => {
|
|
|
54775
54878
|
init_progress_heartbeat();
|
|
54776
54879
|
init_model_loader();
|
|
54777
54880
|
init_port_manager();
|
|
54881
|
+
init_endpoint_registration();
|
|
54778
54882
|
init_model_parser();
|
|
54779
54883
|
init_onepassword();
|
|
54780
54884
|
init_probe_live();
|
|
@@ -55806,7 +55910,7 @@ __export(exports_providers, {
|
|
|
55806
55910
|
providerAuthSource: () => providerAuthSource,
|
|
55807
55911
|
providerAuthCapabilities: () => providerAuthCapabilities,
|
|
55808
55912
|
maskKey: () => maskKey2,
|
|
55809
|
-
|
|
55913
|
+
getProviderDefs: () => getProviderDefs
|
|
55810
55914
|
});
|
|
55811
55915
|
function toProviderDef(def) {
|
|
55812
55916
|
return {
|
|
@@ -55846,6 +55950,9 @@ function providerAuthCapabilities(p, config3) {
|
|
|
55846
55950
|
oauth: { supported: oauthSupported, set: oauthSet }
|
|
55847
55951
|
};
|
|
55848
55952
|
}
|
|
55953
|
+
function getProviderDefs() {
|
|
55954
|
+
return getAllProviders().filter((d) => !SKIP.has(d.name)).map(toProviderDef);
|
|
55955
|
+
}
|
|
55849
55956
|
function maskKey2(key) {
|
|
55850
55957
|
if (!key)
|
|
55851
55958
|
return "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
|
|
@@ -55853,7 +55960,7 @@ function maskKey2(key) {
|
|
|
55853
55960
|
return "**** ";
|
|
55854
55961
|
return `${key.slice(0, 3)}\u2022\u2022${key.slice(-3)}`;
|
|
55855
55962
|
}
|
|
55856
|
-
var SKIP
|
|
55963
|
+
var SKIP;
|
|
55857
55964
|
var init_providers = __esm(() => {
|
|
55858
55965
|
init_antigravity_token();
|
|
55859
55966
|
init_source();
|
|
@@ -55861,7 +55968,6 @@ var init_providers = __esm(() => {
|
|
|
55861
55968
|
init_devin_credentials();
|
|
55862
55969
|
init_provider_definitions();
|
|
55863
55970
|
SKIP = new Set(["qwen", "native-anthropic"]);
|
|
55864
|
-
PROVIDERS = getAllProviders().filter((d) => !SKIP.has(d.name)).map(toProviderDef);
|
|
55865
55971
|
});
|
|
55866
55972
|
|
|
55867
55973
|
// src/providers-command.ts
|
|
@@ -55871,7 +55977,8 @@ __export(exports_providers_command, {
|
|
|
55871
55977
|
collectProviderStatuses: () => collectProviderStatuses
|
|
55872
55978
|
});
|
|
55873
55979
|
async function collectProviderStatuses(config3 = loadConfig()) {
|
|
55874
|
-
|
|
55980
|
+
ensureEndpointsRegistered();
|
|
55981
|
+
return Promise.all(getProviderDefs().map(async (p) => {
|
|
55875
55982
|
const authSource = await describeSource(p, config3);
|
|
55876
55983
|
return {
|
|
55877
55984
|
slug: p.catalogName,
|
|
@@ -55895,6 +56002,7 @@ async function providersCommand(opts) {
|
|
|
55895
56002
|
var init_providers_command = __esm(() => {
|
|
55896
56003
|
init_source();
|
|
55897
56004
|
init_profile_config();
|
|
56005
|
+
init_endpoint_registration();
|
|
55898
56006
|
init_providers();
|
|
55899
56007
|
});
|
|
55900
56008
|
|
|
@@ -75055,7 +75163,17 @@ var init_probe_catalog = __esm(() => {
|
|
|
75055
75163
|
});
|
|
75056
75164
|
|
|
75057
75165
|
// src/tui/constants.ts
|
|
75058
|
-
|
|
75166
|
+
function getProviderPrefixes() {
|
|
75167
|
+
return getProviderDefs().map((p) => ({
|
|
75168
|
+
prefix: p.aliases?.[0] ? `${p.aliases[0]}@` : `${p.name}@`,
|
|
75169
|
+
displayName: p.displayName,
|
|
75170
|
+
name: p.name
|
|
75171
|
+
}));
|
|
75172
|
+
}
|
|
75173
|
+
function getChainProviders() {
|
|
75174
|
+
return getProviderDefs();
|
|
75175
|
+
}
|
|
75176
|
+
var COMMON_MODELS, HEADER_H = 2, TABS_H = 3, FOOTER_H = 1, DETAIL_H = 7;
|
|
75059
75177
|
var init_constants3 = __esm(() => {
|
|
75060
75178
|
init_providers();
|
|
75061
75179
|
COMMON_MODELS = [
|
|
@@ -75077,12 +75195,6 @@ var init_constants3 = __esm(() => {
|
|
|
75077
75195
|
"or@x-ai/grok-code-fast-1",
|
|
75078
75196
|
"or@deepseek/deepseek-r1"
|
|
75079
75197
|
];
|
|
75080
|
-
PROVIDER_PREFIXES = PROVIDERS.map((p) => ({
|
|
75081
|
-
prefix: p.aliases?.[0] ? `${p.aliases[0]}@` : `${p.name}@`,
|
|
75082
|
-
displayName: p.displayName,
|
|
75083
|
-
name: p.name
|
|
75084
|
-
}));
|
|
75085
|
-
CHAIN_PROVIDERS = PROVIDERS;
|
|
75086
75198
|
});
|
|
75087
75199
|
|
|
75088
75200
|
// src/tui/components/Footer.tsx
|
|
@@ -76863,8 +76975,9 @@ function ProfilesContent({
|
|
|
76863
76975
|
{ name: "global ~/.claudish/config.json", description: "", value: "global" },
|
|
76864
76976
|
{ name: "project ./.claudish.json", description: "", value: "project" }
|
|
76865
76977
|
];
|
|
76866
|
-
const
|
|
76867
|
-
const
|
|
76978
|
+
const prefixes = getProviderPrefixes();
|
|
76979
|
+
const prefixColW = prefixes.reduce((max, p) => Math.max(max, p.prefix.length), 0) + 2;
|
|
76980
|
+
const prefixOptions = prefixes.map((p) => ({
|
|
76868
76981
|
name: `${p.prefix.padEnd(prefixColW)}${p.displayName}`,
|
|
76869
76982
|
description: "",
|
|
76870
76983
|
value: p.prefix
|
|
@@ -78750,7 +78863,7 @@ function RoutingContent({
|
|
|
78750
78863
|
scrollY: true,
|
|
78751
78864
|
focused: false,
|
|
78752
78865
|
style: { flexGrow: 1 },
|
|
78753
|
-
children:
|
|
78866
|
+
children: getChainProviders().map((prov, idx) => {
|
|
78754
78867
|
const isCursor = idx === chainCursor;
|
|
78755
78868
|
const isOn = chainSelected.has(prov.name);
|
|
78756
78869
|
const pos = isOn ? chainOrder.indexOf(prov.name) + 1 : 0;
|
|
@@ -79192,10 +79305,10 @@ function useProfileWizard(args) {
|
|
|
79192
79305
|
setProviderPickerIndex((i) => Math.max(0, i - 1));
|
|
79193
79306
|
}, []);
|
|
79194
79307
|
const prefixPickerDown = useCallback(() => {
|
|
79195
|
-
setProviderPickerIndex((i) => Math.min(
|
|
79308
|
+
setProviderPickerIndex((i) => Math.min(getProviderPrefixes().length - 1, i + 1));
|
|
79196
79309
|
}, []);
|
|
79197
79310
|
const prefixPickerSubmit = useCallback(() => {
|
|
79198
|
-
const prefix =
|
|
79311
|
+
const prefix = getProviderPrefixes()[providerPickerIndex]?.prefix ?? "";
|
|
79199
79312
|
setEditProfileValue(prefix);
|
|
79200
79313
|
setSuggestions(computeSuggestions(prefix));
|
|
79201
79314
|
setSuggestionIndex(-1);
|
|
@@ -79505,7 +79618,7 @@ function useRouteProbe(config3) {
|
|
|
79505
79618
|
}
|
|
79506
79619
|
for (let i = 0;i < chain.length; i++) {
|
|
79507
79620
|
const link = chain[i];
|
|
79508
|
-
const provDef =
|
|
79621
|
+
const provDef = getProviderDefs().find((p) => p.catalogName === link.provider);
|
|
79509
79622
|
const ready = provDef ? providerIsReady(provDef, config3) : true;
|
|
79510
79623
|
if (!ready) {
|
|
79511
79624
|
setProbeResults((prev) => prev.map((e, idx) => idx === i ? { ...e, status: "no_key" } : e));
|
|
@@ -79609,7 +79722,7 @@ function App({ requestLogin } = {}) {
|
|
|
79609
79722
|
if (activeTab !== "providers")
|
|
79610
79723
|
return;
|
|
79611
79724
|
let cancelled = false;
|
|
79612
|
-
const localNames =
|
|
79725
|
+
const localNames = getProviderDefs().filter((p) => p.isLocal).map((p) => p.catalogName);
|
|
79613
79726
|
if (localNames.length === 0)
|
|
79614
79727
|
return;
|
|
79615
79728
|
const sweep = async () => {
|
|
@@ -79653,11 +79766,12 @@ function App({ requestLogin } = {}) {
|
|
|
79653
79766
|
const opPickerResolver = useRef4(null);
|
|
79654
79767
|
const quit = useCallback3(() => renderer.destroy(), [renderer]);
|
|
79655
79768
|
const displayProviders = useMemo2(() => {
|
|
79656
|
-
|
|
79769
|
+
const roster = getProviderDefs();
|
|
79770
|
+
return [...roster].sort((a, b) => {
|
|
79657
79771
|
const aReady = providerIsReadyForDisplay(a, config3, localLiveness);
|
|
79658
79772
|
const bReady = providerIsReadyForDisplay(b, config3, localLiveness);
|
|
79659
79773
|
if (aReady === bReady)
|
|
79660
|
-
return
|
|
79774
|
+
return roster.indexOf(a) - roster.indexOf(b);
|
|
79661
79775
|
return aReady ? -1 : 1;
|
|
79662
79776
|
});
|
|
79663
79777
|
}, [config3, localLiveness]);
|
|
@@ -80269,9 +80383,9 @@ function App({ requestLogin } = {}) {
|
|
|
80269
80383
|
if (key.name === "up" || key.name === "k") {
|
|
80270
80384
|
setChainCursor((i) => Math.max(0, i - 1));
|
|
80271
80385
|
} else if (key.name === "down" || key.name === "j") {
|
|
80272
|
-
setChainCursor((i) => Math.min(
|
|
80386
|
+
setChainCursor((i) => Math.min(getChainProviders().length - 1, i + 1));
|
|
80273
80387
|
} else if (key.name === "space" || key.raw === " ") {
|
|
80274
|
-
const prov =
|
|
80388
|
+
const prov = getChainProviders()[chainCursor];
|
|
80275
80389
|
if (prov.isLocal && !providerIsReady(prov, config3)) {
|
|
80276
80390
|
setStatusMsg(`${prov.displayName} is disabled. Enable it in Providers first.`);
|
|
80277
80391
|
return;
|
|
@@ -80289,7 +80403,7 @@ function App({ requestLogin } = {}) {
|
|
|
80289
80403
|
return next;
|
|
80290
80404
|
});
|
|
80291
80405
|
} else if (key.raw && key.raw >= "1" && key.raw <= "9") {
|
|
80292
|
-
const prov =
|
|
80406
|
+
const prov = getChainProviders()[chainCursor];
|
|
80293
80407
|
if (prov.isLocal && !providerIsReady(prov, config3)) {
|
|
80294
80408
|
setStatusMsg(`${prov.displayName} is disabled. Enable it in Providers first.`);
|
|
80295
80409
|
return;
|
|
@@ -80745,7 +80859,7 @@ function App({ requestLogin } = {}) {
|
|
|
80745
80859
|
}
|
|
80746
80860
|
} else if (key.raw === "T") {
|
|
80747
80861
|
const fired = [];
|
|
80748
|
-
for (const prov of
|
|
80862
|
+
for (const prov of getProviderDefs()) {
|
|
80749
80863
|
const localRunning = prov.isLocal && localLiveness[prov.catalogName] === "running";
|
|
80750
80864
|
if (!providerIsReady(prov, config3) && !localRunning)
|
|
80751
80865
|
continue;
|
|
@@ -85530,8 +85644,11 @@ if (isMcpMode) {
|
|
|
85530
85644
|
} else if (isConfigCommand) {
|
|
85531
85645
|
traceSpan("startup:tui-import", () => Promise.resolve().then(() => (init_tui(), exports_tui))).then(async (m) => {
|
|
85532
85646
|
const { credentials: credentials2 } = await Promise.resolve().then(() => (init_authority(), exports_authority));
|
|
85533
|
-
const {
|
|
85534
|
-
|
|
85647
|
+
const { ensureEndpointsRegistered: ensureEndpointsRegistered2 } = await Promise.resolve().then(() => (init_endpoint_registration(), exports_endpoint_registration));
|
|
85648
|
+
ensureEndpointsRegistered2();
|
|
85649
|
+
const { getProviderDefs: getProviderDefs2 } = await Promise.resolve().then(() => (init_providers(), exports_providers));
|
|
85650
|
+
const tuiProviders = getProviderDefs2();
|
|
85651
|
+
await traceSpan("startup:credential-resolution", () => Promise.all(tuiProviders.map((p) => credentials2.isAvailable(p.catalogName, { allowOpPrompt: true }))), { providers: tuiProviders.length });
|
|
85535
85652
|
finalizeStartupTrace("config");
|
|
85536
85653
|
suppressStartupTraceTerminalOutput();
|
|
85537
85654
|
return m.startConfigTui().catch(handlePromptExit);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.64.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.64.0",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.64.0",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.64.0",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.64.0"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|