claudish 7.57.0 → 7.59.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 +128 -7
- 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.59.0";
|
|
733
733
|
|
|
734
734
|
// src/logger.ts
|
|
735
735
|
var exports_logger = {};
|
|
@@ -41714,6 +41714,33 @@ var init_token_tracker = __esm(() => {
|
|
|
41714
41714
|
init_remote_provider_types();
|
|
41715
41715
|
});
|
|
41716
41716
|
|
|
41717
|
+
// src/handlers/shared/upstream-error-capture.ts
|
|
41718
|
+
import { appendFileSync as appendFileSync4 } from "fs";
|
|
41719
|
+
function captureUpstreamError(record4) {
|
|
41720
|
+
const path = process.env[UPSTREAM_ERROR_LOG_ENV];
|
|
41721
|
+
if (!path)
|
|
41722
|
+
return false;
|
|
41723
|
+
try {
|
|
41724
|
+
const raw = record4.body ?? "";
|
|
41725
|
+
const truncated = raw.length > MAX_CAPTURED_BODY_BYTES;
|
|
41726
|
+
const line = JSON.stringify({
|
|
41727
|
+
at: record4.at ?? new Date().toISOString(),
|
|
41728
|
+
provider: record4.provider,
|
|
41729
|
+
model: record4.model,
|
|
41730
|
+
status: record4.status,
|
|
41731
|
+
body: truncated ? raw.slice(0, MAX_CAPTURED_BODY_BYTES) : raw,
|
|
41732
|
+
...truncated ? { truncated: true, original_bytes: raw.length } : {}
|
|
41733
|
+
});
|
|
41734
|
+
appendFileSync4(path, `${line}
|
|
41735
|
+
`);
|
|
41736
|
+
return true;
|
|
41737
|
+
} catch {
|
|
41738
|
+
return false;
|
|
41739
|
+
}
|
|
41740
|
+
}
|
|
41741
|
+
var UPSTREAM_ERROR_LOG_ENV = "CLAUDISH_UPSTREAM_ERROR_LOG", MAX_CAPTURED_BODY_BYTES = 2048;
|
|
41742
|
+
var init_upstream_error_capture = () => {};
|
|
41743
|
+
|
|
41717
41744
|
// src/handlers/composed-handler.ts
|
|
41718
41745
|
function extractAuthHeaders(c) {
|
|
41719
41746
|
const headers = c.req.header();
|
|
@@ -42113,6 +42140,12 @@ class ComposedHandler {
|
|
|
42113
42140
|
} else {
|
|
42114
42141
|
const errorText = await response.text();
|
|
42115
42142
|
log(`[${this.provider.displayName}] Error: ${errorText}`);
|
|
42143
|
+
captureUpstreamError({
|
|
42144
|
+
provider: this.provider.displayName,
|
|
42145
|
+
model: this.bareModelName,
|
|
42146
|
+
status: response.status,
|
|
42147
|
+
body: errorText
|
|
42148
|
+
});
|
|
42116
42149
|
const transportTerminal = this.provider.classifyTerminalError?.(response.status, errorText);
|
|
42117
42150
|
const hint = getRecoveryHint(response.status, errorText, this.provider.displayName, transportTerminal);
|
|
42118
42151
|
let parsedErrorBody;
|
|
@@ -42615,6 +42648,7 @@ var init_composed_handler = __esm(() => {
|
|
|
42615
42648
|
init_openai_responses_sse();
|
|
42616
42649
|
init_openai_sse();
|
|
42617
42650
|
init_token_tracker();
|
|
42651
|
+
init_upstream_error_capture();
|
|
42618
42652
|
STREAM_RETRY_DELAYS_MS = [3000, 15000, 30000];
|
|
42619
42653
|
});
|
|
42620
42654
|
|
|
@@ -45015,6 +45049,36 @@ var init_default_routing_rules = __esm(() => {
|
|
|
45015
45049
|
validateDefaultRoutingRules();
|
|
45016
45050
|
});
|
|
45017
45051
|
|
|
45052
|
+
// src/providers/model-availability.ts
|
|
45053
|
+
function rosterHas(ids, wireId) {
|
|
45054
|
+
const needle = wireId.trim().toLowerCase();
|
|
45055
|
+
return ids.some((id) => id.trim().toLowerCase() === needle);
|
|
45056
|
+
}
|
|
45057
|
+
async function providerServesModel(provider, wireId) {
|
|
45058
|
+
const def = getProviderByName(provider);
|
|
45059
|
+
if (def?.modelDiscovery) {
|
|
45060
|
+
const models = await discoverProviderModels(provider);
|
|
45061
|
+
if (models.length > 0) {
|
|
45062
|
+
return rosterHas(models.map((m) => m.id), wireId) ? "serves" : "not-served";
|
|
45063
|
+
}
|
|
45064
|
+
getDiscoveryFailure(provider);
|
|
45065
|
+
return "unknown";
|
|
45066
|
+
}
|
|
45067
|
+
const entries = getCatalogEntries();
|
|
45068
|
+
if (!entries)
|
|
45069
|
+
return "unknown";
|
|
45070
|
+
const needle = wireId.trim().toLowerCase();
|
|
45071
|
+
const row = entries.find((e) => e.modelId.toLowerCase() === needle || e.aliases.some((a) => a.toLowerCase() === needle) || (e.aggregators ?? []).some((a) => a.externalId?.toLowerCase() === needle));
|
|
45072
|
+
if (!row)
|
|
45073
|
+
return "unknown";
|
|
45074
|
+
return (row.aggregators ?? []).some((a) => a.provider === provider) ? "serves" : "unknown";
|
|
45075
|
+
}
|
|
45076
|
+
var init_model_availability = __esm(() => {
|
|
45077
|
+
init_catalog_client();
|
|
45078
|
+
init_model_discovery();
|
|
45079
|
+
init_provider_definitions();
|
|
45080
|
+
});
|
|
45081
|
+
|
|
45018
45082
|
// src/providers/routing-rules.ts
|
|
45019
45083
|
function mergeRoutingRules(defaults, global_, local) {
|
|
45020
45084
|
return { ...defaults, ...global_, ...local };
|
|
@@ -45123,6 +45187,13 @@ async function routeExplicit(modelSpec, model, provider, cachePath) {
|
|
|
45123
45187
|
reason: `Could not build a route for "${modelSpec}".`
|
|
45124
45188
|
};
|
|
45125
45189
|
}
|
|
45190
|
+
if (await providerServesModel(built.provider, wireIdOf(built)) === "not-served") {
|
|
45191
|
+
return {
|
|
45192
|
+
kind: "no-route",
|
|
45193
|
+
reason: `${built.displayName} does not serve "${model}".`,
|
|
45194
|
+
hint: `Check the model id, or use a bare \`${model}\` to let claudish pick a provider ` + "that carries it."
|
|
45195
|
+
};
|
|
45196
|
+
}
|
|
45126
45197
|
return { kind: "ok", primary: built, fallbacks: [] };
|
|
45127
45198
|
}
|
|
45128
45199
|
async function routeBare(model, nativeProvider, rules, defaultProvider, cachePath) {
|
|
@@ -45164,9 +45235,37 @@ async function routeBare(model, nativeProvider, rules, defaultProvider, cachePat
|
|
|
45164
45235
|
hint: buildCredentialHint(model, skipped) ?? undefined
|
|
45165
45236
|
};
|
|
45166
45237
|
}
|
|
45167
|
-
const
|
|
45238
|
+
const availability = await Promise.all(credentialed.map((candidate) => providerServesModel(candidate.provider, wireIdOf(candidate))));
|
|
45239
|
+
const serving = [];
|
|
45240
|
+
const notServing = [];
|
|
45241
|
+
credentialed.forEach((candidate, i) => {
|
|
45242
|
+
if (availability[i] === "not-served") {
|
|
45243
|
+
notServing.push(candidate.provider);
|
|
45244
|
+
} else {
|
|
45245
|
+
serving.push(candidate);
|
|
45246
|
+
}
|
|
45247
|
+
});
|
|
45248
|
+
if (serving.length === 0) {
|
|
45249
|
+
return {
|
|
45250
|
+
kind: "no-route",
|
|
45251
|
+
reason: `No provider serves "${model}" (checked: ${notServing.join(", ")}).`,
|
|
45252
|
+
hint: buildCredentialHint(model, notServing) ?? undefined
|
|
45253
|
+
};
|
|
45254
|
+
}
|
|
45255
|
+
if (notServing.length > 0) {
|
|
45256
|
+
log(`[routing] ${model}: skipped ${notServing.join(", ")} \u2014 does not serve this model`);
|
|
45257
|
+
const droppedSubscription = notServing.filter((p) => isSubscriptionProvider(p));
|
|
45258
|
+
if (droppedSubscription.length > 0 && !isSubscriptionProvider(serving[0].provider)) {
|
|
45259
|
+
logStderr(`[claudish] ${droppedSubscription.join(", ")} does not serve ${model} \u2014 ` + `using ${serving[0].displayName}, which bills per token.`);
|
|
45260
|
+
}
|
|
45261
|
+
}
|
|
45262
|
+
const [primary, ...fallbacks] = serving;
|
|
45168
45263
|
return { kind: "ok", primary, fallbacks };
|
|
45169
45264
|
}
|
|
45265
|
+
function wireIdOf(route) {
|
|
45266
|
+
const at = route.modelSpec.indexOf("@");
|
|
45267
|
+
return at === -1 ? route.modelSpec : route.modelSpec.slice(at + 1);
|
|
45268
|
+
}
|
|
45170
45269
|
function normalizeGlmSlug(model) {
|
|
45171
45270
|
return model.replace(/^glm-(\d+)-(\d+)(-.*)?$/i, (_m, major, minor, suffix) => `glm-${major}.${minor}${suffix ?? ""}`);
|
|
45172
45271
|
}
|
|
@@ -45182,10 +45281,13 @@ async function route(modelSpec, rulesOverride, defaultProviderOverride, cachePat
|
|
|
45182
45281
|
var init_routing_rules = __esm(() => {
|
|
45183
45282
|
init_model_catalog();
|
|
45184
45283
|
init_authority();
|
|
45284
|
+
init_remote_provider_types();
|
|
45285
|
+
init_logger();
|
|
45185
45286
|
init_profile_config();
|
|
45186
45287
|
init_auto_route();
|
|
45187
45288
|
init_catalog_client();
|
|
45188
45289
|
init_default_routing_rules();
|
|
45290
|
+
init_model_availability();
|
|
45189
45291
|
init_model_parser();
|
|
45190
45292
|
init_model_parser();
|
|
45191
45293
|
init_routing_hints();
|
|
@@ -45611,7 +45713,7 @@ var init_prehydrate = __esm(() => {
|
|
|
45611
45713
|
});
|
|
45612
45714
|
|
|
45613
45715
|
// src/channel/diagnostics.ts
|
|
45614
|
-
import { appendFileSync as
|
|
45716
|
+
import { appendFileSync as appendFileSync5 } from "fs";
|
|
45615
45717
|
function traceEnabled() {
|
|
45616
45718
|
return process.env[TRACE_ENV] === "1";
|
|
45617
45719
|
}
|
|
@@ -45622,7 +45724,7 @@ function emit(line) {
|
|
|
45622
45724
|
const filePath = process.env[TRACE_FILE_ENV];
|
|
45623
45725
|
if (filePath) {
|
|
45624
45726
|
try {
|
|
45625
|
-
|
|
45727
|
+
appendFileSync5(filePath, formatted);
|
|
45626
45728
|
} catch {}
|
|
45627
45729
|
}
|
|
45628
45730
|
}
|
|
@@ -49175,7 +49277,7 @@ var init_fallback_handler = __esm(() => {
|
|
|
49175
49277
|
});
|
|
49176
49278
|
|
|
49177
49279
|
// src/handlers/native-handler-advisor.ts
|
|
49178
|
-
import { appendFileSync as
|
|
49280
|
+
import { appendFileSync as appendFileSync6 } from "fs";
|
|
49179
49281
|
function loadAdvisorSwapConfig(cliModels, cliCollector) {
|
|
49180
49282
|
return {
|
|
49181
49283
|
enabled: process.env.CLAUDISH_SWAP_ADVISOR === "1" || (cliModels?.length ?? 0) > 0,
|
|
@@ -49230,7 +49332,7 @@ function logAdvisorEvent(cfg, event) {
|
|
|
49230
49332
|
const line = `${JSON.stringify({ ts: new Date().toISOString(), ...event })}
|
|
49231
49333
|
`;
|
|
49232
49334
|
try {
|
|
49233
|
-
|
|
49335
|
+
appendFileSync6(cfg.logPath, line);
|
|
49234
49336
|
} catch {}
|
|
49235
49337
|
}
|
|
49236
49338
|
function recordAdvisorEventsFromChunk(cfg, chunkText) {
|
|
@@ -52031,11 +52133,30 @@ ${plan.hint}` : `[Route] ${plan.reason}`;
|
|
|
52031
52133
|
}));
|
|
52032
52134
|
app.get("/health", (c) => c.json({ status: "ok" }));
|
|
52033
52135
|
const servedSlotIds = options.servedSlotIds ?? [];
|
|
52136
|
+
const discoverableModelIds = (() => {
|
|
52137
|
+
const seen = new Set;
|
|
52138
|
+
try {
|
|
52139
|
+
const cfg = loadConfig();
|
|
52140
|
+
for (const name of Object.keys(cfg.routing ?? {})) {
|
|
52141
|
+
if (name === "*")
|
|
52142
|
+
continue;
|
|
52143
|
+
seen.add(name);
|
|
52144
|
+
}
|
|
52145
|
+
for (const ep of Object.values(cfg.customEndpoints ?? {})) {
|
|
52146
|
+
for (const m of ep.models ?? [])
|
|
52147
|
+
seen.add(m);
|
|
52148
|
+
}
|
|
52149
|
+
} catch (err) {
|
|
52150
|
+
log(`[Proxy] /v1/models discovery skipped: ${err instanceof Error ? err.message : err}`);
|
|
52151
|
+
}
|
|
52152
|
+
return [...seen];
|
|
52153
|
+
})();
|
|
52034
52154
|
app.get("/v1/models", (c) => {
|
|
52155
|
+
const ids = servedSlotIds.length > 0 ? servedSlotIds : discoverableModelIds;
|
|
52035
52156
|
return c.json({
|
|
52036
52157
|
object: "list",
|
|
52037
52158
|
has_more: false,
|
|
52038
|
-
data:
|
|
52159
|
+
data: ids.map((id) => ({
|
|
52039
52160
|
id,
|
|
52040
52161
|
object: "model",
|
|
52041
52162
|
type: "model",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.59.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.59.0",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "7.59.0",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "7.59.0",
|
|
66
|
+
"@claudish/magmux-linux-x64": "7.59.0"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|