claudish 9.5.0 → 9.6.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 +307 -60
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -715,7 +715,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
715
715
|
});
|
|
716
716
|
|
|
717
717
|
// src/version.ts
|
|
718
|
-
var VERSION = "9.
|
|
718
|
+
var VERSION = "9.6.0";
|
|
719
719
|
|
|
720
720
|
// src/logger.ts
|
|
721
721
|
import { appendFile, existsSync as existsSync2, mkdirSync, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -815,14 +815,17 @@ function redactLogLine(message, timestamp) {
|
|
|
815
815
|
return `[${timestamp}] ${message}
|
|
816
816
|
`;
|
|
817
817
|
}
|
|
818
|
+
function logFileStamp() {
|
|
819
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").split("T").join("_").slice(0, -5);
|
|
820
|
+
return `${timestamp}_${process.pid}`;
|
|
821
|
+
}
|
|
818
822
|
function initLogger(debugMode, level = "info", noLogs = false) {
|
|
819
823
|
if (!noLogs) {
|
|
820
824
|
const logsDir = join2(homedir2(), ".claudish", "logs");
|
|
821
825
|
if (!existsSync2(logsDir)) {
|
|
822
826
|
mkdirSync(logsDir, { recursive: true });
|
|
823
827
|
}
|
|
824
|
-
|
|
825
|
-
alwaysOnLogPath = join2(logsDir, `claudish_${timestamp}.log`);
|
|
828
|
+
alwaysOnLogPath = join2(logsDir, `claudish_${logFileStamp()}.log`);
|
|
826
829
|
writeFileSync2(alwaysOnLogPath, `Claudish Session Log - ${new Date().toISOString()}
|
|
827
830
|
Mode: structural (content redacted)
|
|
828
831
|
${"=".repeat(60)}
|
|
@@ -837,8 +840,7 @@ ${"=".repeat(60)}
|
|
|
837
840
|
if (!existsSync2(logsDir)) {
|
|
838
841
|
mkdirSync(logsDir, { recursive: true });
|
|
839
842
|
}
|
|
840
|
-
|
|
841
|
-
logFilePath = join2(logsDir, `claudish_${timestamp}.log`);
|
|
843
|
+
logFilePath = join2(logsDir, `claudish_${logFileStamp()}.log`);
|
|
842
844
|
writeFileSync2(logFilePath, `Claudish Debug Log - ${new Date().toISOString()}
|
|
843
845
|
Log Level: ${level}
|
|
844
846
|
${"=".repeat(80)}
|
|
@@ -18167,6 +18169,12 @@ var init_stdio2 = __esm(() => {
|
|
|
18167
18169
|
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
18168
18170
|
import { homedir as homedir7 } from "os";
|
|
18169
18171
|
import { dirname as dirname4, join as join7 } from "path";
|
|
18172
|
+
function reasoningStatusOf(entry) {
|
|
18173
|
+
if (entry.reasoningStatus === "known" || entry.reasoningStatus === "unknown") {
|
|
18174
|
+
return entry.reasoningStatus;
|
|
18175
|
+
}
|
|
18176
|
+
return entry.reasoning !== undefined ? "known" : "unknown";
|
|
18177
|
+
}
|
|
18170
18178
|
function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
18171
18179
|
if (!existsSync5(path))
|
|
18172
18180
|
return null;
|
|
@@ -18183,12 +18191,14 @@ function readAllModelsCache(path = ALL_MODELS_CACHE_PATH) {
|
|
|
18183
18191
|
const models = Array.isArray(data.models) ? data.models : [];
|
|
18184
18192
|
const entries = Array.isArray(data.entries) ? data.entries : [];
|
|
18185
18193
|
const plans = Array.isArray(data.plans) ? data.plans : undefined;
|
|
18194
|
+
const catalogRevision = typeof data.catalogRevision === "string" ? data.catalogRevision : undefined;
|
|
18186
18195
|
return {
|
|
18187
18196
|
version: 2,
|
|
18188
18197
|
lastUpdated,
|
|
18189
18198
|
entries,
|
|
18190
18199
|
models,
|
|
18191
|
-
...plans !== undefined ? { plans } : {}
|
|
18200
|
+
...plans !== undefined ? { plans } : {},
|
|
18201
|
+
...catalogRevision !== undefined ? { catalogRevision } : {}
|
|
18192
18202
|
};
|
|
18193
18203
|
}
|
|
18194
18204
|
function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
@@ -18198,7 +18208,8 @@ function writeAllModelsCache(data, path = ALL_MODELS_CACHE_PATH) {
|
|
|
18198
18208
|
lastUpdated: data.lastUpdated ?? new Date().toISOString(),
|
|
18199
18209
|
entries: data.entries ?? existing?.entries ?? [],
|
|
18200
18210
|
models: data.models ?? existing?.models ?? [],
|
|
18201
|
-
...data.plans !== undefined || existing?.plans !== undefined ? { plans: data.plans ?? existing?.plans ?? [] } : {}
|
|
18211
|
+
...data.plans !== undefined || existing?.plans !== undefined ? { plans: data.plans ?? existing?.plans ?? [] } : {},
|
|
18212
|
+
...data.catalogRevision !== undefined ? { catalogRevision: data.catalogRevision } : {}
|
|
18202
18213
|
};
|
|
18203
18214
|
mkdirSync5(dirname4(path), { recursive: true });
|
|
18204
18215
|
writeFileSync5(path, JSON.stringify(merged), "utf-8");
|
|
@@ -18285,6 +18296,10 @@ function lookupModel(modelId, cachePath) {
|
|
|
18285
18296
|
function lookupModelReasoning(modelId, cachePath) {
|
|
18286
18297
|
return findCacheEntry(modelId, cachePath)?.reasoning;
|
|
18287
18298
|
}
|
|
18299
|
+
function lookupModelReasoningStatus(modelId, cachePath) {
|
|
18300
|
+
const entry = findCacheEntry(modelId, cachePath);
|
|
18301
|
+
return entry ? reasoningStatusOf(entry) : undefined;
|
|
18302
|
+
}
|
|
18288
18303
|
function lookupModelTokenParam(modelId, cachePath) {
|
|
18289
18304
|
return findCacheEntry(modelId, cachePath)?.tokenParam;
|
|
18290
18305
|
}
|
|
@@ -18398,6 +18413,26 @@ function findCacheEntry(modelId, cachePath) {
|
|
|
18398
18413
|
return entry;
|
|
18399
18414
|
}
|
|
18400
18415
|
}
|
|
18416
|
+
const canonical = resolvePlanDescribedModelId(modelId, cache.plans);
|
|
18417
|
+
if (!canonical)
|
|
18418
|
+
return;
|
|
18419
|
+
const canonicalLower = canonical.toLowerCase();
|
|
18420
|
+
for (const entry of cache.entries) {
|
|
18421
|
+
if (entry.modelId.toLowerCase() === canonicalLower)
|
|
18422
|
+
return entry;
|
|
18423
|
+
if (entry.aliases?.some((a) => a.toLowerCase() === canonicalLower))
|
|
18424
|
+
return entry;
|
|
18425
|
+
}
|
|
18426
|
+
return;
|
|
18427
|
+
}
|
|
18428
|
+
function resolvePlanDescribedModelId(wireId, plans) {
|
|
18429
|
+
if (!plans)
|
|
18430
|
+
return;
|
|
18431
|
+
for (const plan of plans) {
|
|
18432
|
+
const described = plan.modelDescriptions?.[wireId];
|
|
18433
|
+
if (described?.status === "described" && described.modelId)
|
|
18434
|
+
return described.modelId;
|
|
18435
|
+
}
|
|
18401
18436
|
return;
|
|
18402
18437
|
}
|
|
18403
18438
|
function classifyCatalogHit(entry, q) {
|
|
@@ -19737,6 +19772,29 @@ function matchesModelFamily(modelId, family) {
|
|
|
19737
19772
|
function isEffortLevel(value) {
|
|
19738
19773
|
return typeof value === "string" && EFFORT_ORDER.includes(value);
|
|
19739
19774
|
}
|
|
19775
|
+
function outputCeilingOf(originalRequest, payload) {
|
|
19776
|
+
const candidates = [
|
|
19777
|
+
originalRequest?.max_tokens,
|
|
19778
|
+
payload?.max_tokens,
|
|
19779
|
+
payload?.max_completion_tokens,
|
|
19780
|
+
payload?.max_output_tokens
|
|
19781
|
+
];
|
|
19782
|
+
for (const value of candidates) {
|
|
19783
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0)
|
|
19784
|
+
return value;
|
|
19785
|
+
}
|
|
19786
|
+
return;
|
|
19787
|
+
}
|
|
19788
|
+
function clampThinkingBudget(budget, ceiling) {
|
|
19789
|
+
if (budget === undefined)
|
|
19790
|
+
return;
|
|
19791
|
+
if (ceiling === undefined)
|
|
19792
|
+
return budget;
|
|
19793
|
+
const allowed = ceiling - ANSWER_TOKEN_RESERVE;
|
|
19794
|
+
if (allowed < MIN_THINKING_BUDGET)
|
|
19795
|
+
return "no-room";
|
|
19796
|
+
return Math.min(budget, allowed);
|
|
19797
|
+
}
|
|
19740
19798
|
|
|
19741
19799
|
class BaseAPIFormat {
|
|
19742
19800
|
modelId;
|
|
@@ -19826,6 +19884,11 @@ class BaseAPIFormat {
|
|
|
19826
19884
|
}
|
|
19827
19885
|
}
|
|
19828
19886
|
applyAnthropicWireReasoning(request, originalRequest) {
|
|
19887
|
+
const status = this.lookupReasoningStatus();
|
|
19888
|
+
if (status !== "known") {
|
|
19889
|
+
log(`[${this.getName()}] ${this.modelId} reasoning control ${status === "unknown" ? "unknown" : "absent from the catalog"} -> no reasoning parameter emitted`);
|
|
19890
|
+
return request;
|
|
19891
|
+
}
|
|
19829
19892
|
const reasoning = this.lookupReasoningCapability();
|
|
19830
19893
|
if (reasoning?.supported === false) {
|
|
19831
19894
|
request.thinking = { type: "disabled" };
|
|
@@ -19836,36 +19899,63 @@ class BaseAPIFormat {
|
|
|
19836
19899
|
if (!effort)
|
|
19837
19900
|
return request;
|
|
19838
19901
|
if (effort === "none" || effort === "minimal") {
|
|
19902
|
+
if (reasoning?.mandatory) {
|
|
19903
|
+
return this.enableAnthropicEffort(request, effort, reasoning, "mandatory reasoning");
|
|
19904
|
+
}
|
|
19839
19905
|
request.thinking = { type: "disabled" };
|
|
19840
19906
|
log(`[${this.getName()}] effort ${effort} -> thinking.type: disabled for ${this.modelId}`);
|
|
19841
19907
|
return request;
|
|
19842
19908
|
}
|
|
19843
|
-
|
|
19844
|
-
|
|
19909
|
+
const control = reasoning?.control;
|
|
19910
|
+
const advertisesEfforts = (reasoning?.efforts?.length ?? 0) > 0;
|
|
19911
|
+
if (control === "effort" || control === undefined && advertisesEfforts) {
|
|
19912
|
+
return this.enableAnthropicEffort(request, effort, reasoning, "catalog: effort-controlled");
|
|
19845
19913
|
}
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
const level = this.clampToAdvertisedEffort(effort, advertised);
|
|
19849
|
-
request.thinking = { type: "enabled" };
|
|
19850
|
-
if (level) {
|
|
19851
|
-
request.output_config = { ...request.output_config ?? {}, effort: level };
|
|
19852
|
-
}
|
|
19853
|
-
log(`[${this.getName()}] effort ${effort} -> thinking: enabled, output_config.effort: ${level ?? "(none advertised)"} for ${this.modelId} (advertised: ${advertised.efforts?.join("/")})`);
|
|
19854
|
-
return request;
|
|
19914
|
+
if (control === "budget" || control === undefined && reasoning?.supportsBudgetTokens) {
|
|
19915
|
+
return this.enableAnthropicBudget(request, effort, originalRequest, reasoning);
|
|
19855
19916
|
}
|
|
19856
|
-
|
|
19857
|
-
|
|
19858
|
-
|
|
19859
|
-
|
|
19917
|
+
request.thinking = { type: "enabled" };
|
|
19918
|
+
this.stripAnthropicEffortField(request);
|
|
19919
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled (no depth knob; catalog control=${control ?? "unspecified"}) for ${this.modelId}`);
|
|
19920
|
+
return request;
|
|
19921
|
+
}
|
|
19922
|
+
enableAnthropicEffort(request, effort, reasoning, why) {
|
|
19923
|
+
const level = reasoning ? this.clampToAdvertisedEffort(effort, reasoning) : undefined;
|
|
19924
|
+
request.thinking = { type: "enabled" };
|
|
19925
|
+
if (level) {
|
|
19926
|
+
request.output_config = { ...request.output_config ?? {}, effort: level };
|
|
19860
19927
|
}
|
|
19861
|
-
|
|
19928
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled, output_config.effort: ${level ?? "(none advertised)"} for ${this.modelId} (${why}; advertised: ${reasoning?.efforts?.join("/") ?? "none"})`);
|
|
19929
|
+
return request;
|
|
19862
19930
|
}
|
|
19863
|
-
|
|
19864
|
-
const
|
|
19931
|
+
enableAnthropicBudget(request, effort, originalRequest, reasoning) {
|
|
19932
|
+
const requested = this.effortToThinkingTokenBudget(effort);
|
|
19933
|
+
const ceiling = outputCeilingOf(originalRequest, request);
|
|
19934
|
+
const budget = clampThinkingBudget(requested, ceiling);
|
|
19935
|
+
if (budget === "no-room") {
|
|
19936
|
+
if (reasoning?.mandatory) {
|
|
19937
|
+
request.thinking = { type: "enabled" };
|
|
19938
|
+
} else {
|
|
19939
|
+
request.thinking = { type: "disabled" };
|
|
19940
|
+
}
|
|
19941
|
+
this.stripAnthropicEffortField(request);
|
|
19942
|
+
log(`[${this.getName()}] effort ${effort} -> budget ${requested ?? "(model max)"} does not fit under max_tokens ${ceiling}; sent thinking.type: ${request.thinking.type} for ${this.modelId}`);
|
|
19943
|
+
return request;
|
|
19944
|
+
}
|
|
19865
19945
|
request.thinking = budget === undefined ? { type: "enabled" } : { type: "enabled", budget_tokens: budget };
|
|
19866
|
-
|
|
19946
|
+
this.stripAnthropicEffortField(request);
|
|
19947
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled, budget_tokens: ${budget ?? "(model max)"}${budget !== undefined && budget !== requested ? ` (clamped from ${requested} under max_tokens ${ceiling})` : ""} for ${this.modelId} (catalog: budget-controlled)`);
|
|
19867
19948
|
return request;
|
|
19868
19949
|
}
|
|
19950
|
+
stripAnthropicEffortField(request) {
|
|
19951
|
+
if (!request?.output_config || typeof request.output_config !== "object")
|
|
19952
|
+
return;
|
|
19953
|
+
if (request.output_config.effort === undefined)
|
|
19954
|
+
return;
|
|
19955
|
+
delete request.output_config.effort;
|
|
19956
|
+
if (Object.keys(request.output_config).length === 0)
|
|
19957
|
+
delete request.output_config;
|
|
19958
|
+
}
|
|
19869
19959
|
clampToAdvertisedEffort(requested, reasoning) {
|
|
19870
19960
|
if (this.pinnedEffort)
|
|
19871
19961
|
return this.pinnedEffort;
|
|
@@ -19894,6 +19984,13 @@ class BaseAPIFormat {
|
|
|
19894
19984
|
return;
|
|
19895
19985
|
}
|
|
19896
19986
|
}
|
|
19987
|
+
lookupReasoningStatus() {
|
|
19988
|
+
try {
|
|
19989
|
+
return lookupModelReasoningStatus(this.modelId);
|
|
19990
|
+
} catch {
|
|
19991
|
+
return;
|
|
19992
|
+
}
|
|
19993
|
+
}
|
|
19897
19994
|
effortToThinkingTokenBudget(effort) {
|
|
19898
19995
|
switch (effort) {
|
|
19899
19996
|
case "low":
|
|
@@ -20024,7 +20121,7 @@ class BaseAPIFormat {
|
|
|
20024
20121
|
}
|
|
20025
20122
|
}
|
|
20026
20123
|
}
|
|
20027
|
-
var OPTIONAL_SAMPLING_PARAMS, OPENAI_TOOL_NAME_LIMIT = 64, EFFORT_ORDER, EFFORT_LEVELS, NON_ANTHROPIC_REASONING_FIELDS, DefaultAPIFormat;
|
|
20124
|
+
var OPTIONAL_SAMPLING_PARAMS, OPENAI_TOOL_NAME_LIMIT = 64, EFFORT_ORDER, EFFORT_LEVELS, NON_ANTHROPIC_REASONING_FIELDS, MIN_THINKING_BUDGET = 1024, ANSWER_TOKEN_RESERVE = 1024, DefaultAPIFormat;
|
|
20028
20125
|
var init_base_api_format = __esm(() => {
|
|
20029
20126
|
init_remote_provider_types();
|
|
20030
20127
|
init_logger();
|
|
@@ -21589,6 +21686,31 @@ function formatRawSseLogPayload(dataStr) {
|
|
|
21589
21686
|
return dataStr;
|
|
21590
21687
|
return `${dataStr.substring(0, SSE_LOG_MAX_CHARS)} ${SSE_LOG_TRUNCATION_MARKER} original_chars=${dataStr.length}`;
|
|
21591
21688
|
}
|
|
21689
|
+
function describeInStreamError(chunk) {
|
|
21690
|
+
if (!chunk || typeof chunk !== "object")
|
|
21691
|
+
return;
|
|
21692
|
+
const error = chunk.error;
|
|
21693
|
+
if (!error)
|
|
21694
|
+
return;
|
|
21695
|
+
if (typeof error === "string")
|
|
21696
|
+
return error;
|
|
21697
|
+
if (typeof error !== "object")
|
|
21698
|
+
return String(error);
|
|
21699
|
+
const e = error;
|
|
21700
|
+
const metadata = e.metadata ?? {};
|
|
21701
|
+
const parts = [];
|
|
21702
|
+
const provider = chunk.provider;
|
|
21703
|
+
if (typeof provider === "string" && provider)
|
|
21704
|
+
parts.push(`[${provider}]`);
|
|
21705
|
+
const code = e.code ?? metadata.provider_code;
|
|
21706
|
+
const type = e.type ?? metadata.error_type;
|
|
21707
|
+
const label = [code, type].filter((v) => v !== undefined && v !== null && v !== "").join(" ");
|
|
21708
|
+
if (label)
|
|
21709
|
+
parts.push(label);
|
|
21710
|
+
const message = e.message ?? metadata.raw;
|
|
21711
|
+
parts.push(typeof message === "string" && message.trim() ? message : JSON.stringify(error).slice(0, 500));
|
|
21712
|
+
return parts.join(" ");
|
|
21713
|
+
}
|
|
21592
21714
|
function validateToolArguments(toolName, argsStr, toolSchemas, textContent) {
|
|
21593
21715
|
const result = validateAndRepairToolCall(toolName, argsStr, toolSchemas, textContent);
|
|
21594
21716
|
if (result.repaired) {
|
|
@@ -21865,6 +21987,12 @@ data: ${JSON.stringify(d)}
|
|
|
21865
21987
|
state.usage = chunk.usage;
|
|
21866
21988
|
log(`[Streaming] Usage data received: prompt=${chunk.usage.prompt_tokens}, completion=${chunk.usage.completion_tokens}, total=${chunk.usage.total_tokens}`);
|
|
21867
21989
|
}
|
|
21990
|
+
const inStreamError = describeInStreamError(chunk);
|
|
21991
|
+
if (inStreamError) {
|
|
21992
|
+
log(`[Streaming] Upstream error inside a 200 stream: ${inStreamError}`);
|
|
21993
|
+
await finalize("error", inStreamError);
|
|
21994
|
+
return;
|
|
21995
|
+
}
|
|
21868
21996
|
const delta = chunk.choices?.[0]?.delta;
|
|
21869
21997
|
const finishReason = chunk.choices?.[0]?.finish_reason;
|
|
21870
21998
|
if (finishReason)
|
|
@@ -23370,11 +23498,18 @@ var init_qwen_model_dialect = __esm(() => {
|
|
|
23370
23498
|
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: false for ${this.modelId}`);
|
|
23371
23499
|
} else {
|
|
23372
23500
|
request.enable_thinking = true;
|
|
23373
|
-
const
|
|
23374
|
-
|
|
23375
|
-
|
|
23501
|
+
const requested = this.effortToThinkingTokenBudget(effort);
|
|
23502
|
+
const ceiling = outputCeilingOf(originalRequest, request);
|
|
23503
|
+
const budget = clampThinkingBudget(requested, ceiling);
|
|
23504
|
+
if (budget === "no-room") {
|
|
23505
|
+
delete request.thinking_budget;
|
|
23506
|
+
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: true, no thinking_budget (${requested} does not fit under ceiling ${ceiling}) for ${this.modelId}`);
|
|
23507
|
+
} else {
|
|
23508
|
+
if (budget !== undefined) {
|
|
23509
|
+
request.thinking_budget = budget;
|
|
23510
|
+
}
|
|
23511
|
+
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: true, thinking_budget: ${budget ?? "(model max)"}${budget !== undefined && budget !== requested ? ` (clamped from ${requested} under ceiling ${ceiling})` : ""} for ${this.modelId}`);
|
|
23376
23512
|
}
|
|
23377
|
-
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: true, thinking_budget: ${budget ?? "(model max)"} for ${this.modelId}`);
|
|
23378
23513
|
}
|
|
23379
23514
|
if (originalRequest.thinking)
|
|
23380
23515
|
delete request.thinking;
|
|
@@ -37624,6 +37759,12 @@ var init_auto_route = __esm(() => {
|
|
|
37624
37759
|
});
|
|
37625
37760
|
|
|
37626
37761
|
// src/providers/catalog-client.ts
|
|
37762
|
+
function catalogUrl() {
|
|
37763
|
+
return process.env.CLAUDISH_CATALOG_URL ?? process.env.FIREBASE_CATALOG_URL ?? DEFAULT_CATALOG_URL;
|
|
37764
|
+
}
|
|
37765
|
+
function plansUrl() {
|
|
37766
|
+
return process.env.CLAUDISH_PLANS_URL ?? derivePlansUrl(catalogUrl());
|
|
37767
|
+
}
|
|
37627
37768
|
function derivePlansUrl(catalogUrl) {
|
|
37628
37769
|
try {
|
|
37629
37770
|
const url = new URL(catalogUrl);
|
|
@@ -37772,49 +37913,97 @@ function catalogWarmDisabledFor(value) {
|
|
|
37772
37913
|
function catalogWarmDisabled() {
|
|
37773
37914
|
return catalogWarmDisabledFor(process.env.CLAUDISH_DISABLE_CATALOG_WARM);
|
|
37774
37915
|
}
|
|
37775
|
-
|
|
37776
|
-
|
|
37777
|
-
|
|
37778
|
-
|
|
37779
|
-
|
|
37916
|
+
function buildCatalogPageUrl(baseUrl, offset, limit, revision) {
|
|
37917
|
+
const url = new URL(baseUrl);
|
|
37918
|
+
url.searchParams.set("offset", String(offset));
|
|
37919
|
+
url.searchParams.set("limit", String(limit));
|
|
37920
|
+
if (revision)
|
|
37921
|
+
url.searchParams.set("revision", revision);
|
|
37922
|
+
return url.toString();
|
|
37923
|
+
}
|
|
37924
|
+
async function fetchCatalogPage(url, timeoutMs) {
|
|
37780
37925
|
let response;
|
|
37781
37926
|
try {
|
|
37782
|
-
response = await fetch(
|
|
37927
|
+
response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
37783
37928
|
} catch (err) {
|
|
37784
37929
|
const name = err?.name;
|
|
37785
37930
|
const reason = name === "TimeoutError" || name === "AbortError" ? "timeout" : "network";
|
|
37786
|
-
return {
|
|
37931
|
+
return { ok: false, reason };
|
|
37787
37932
|
}
|
|
37788
37933
|
if (!response.ok)
|
|
37789
|
-
return {
|
|
37790
|
-
let
|
|
37934
|
+
return { ok: false, reason: "http_error" };
|
|
37935
|
+
let page;
|
|
37791
37936
|
try {
|
|
37792
|
-
|
|
37937
|
+
page = await response.json();
|
|
37793
37938
|
} catch {
|
|
37794
|
-
return {
|
|
37939
|
+
return { ok: false, reason: "network" };
|
|
37795
37940
|
}
|
|
37796
|
-
|
|
37797
|
-
|
|
37941
|
+
const revision = response.headers.get(CATALOG_REVISION_HEADER) ?? undefined;
|
|
37942
|
+
return { ok: true, page, revision };
|
|
37943
|
+
}
|
|
37944
|
+
async function refreshCatalog(timeoutMs, options = {}) {
|
|
37945
|
+
if (catalogWarmDisabled()) {
|
|
37946
|
+
return { kind: "fetch_failed", reason: "disabled" };
|
|
37947
|
+
}
|
|
37948
|
+
const entries = [];
|
|
37949
|
+
let revision;
|
|
37950
|
+
let pages = 0;
|
|
37951
|
+
let offset = 0;
|
|
37952
|
+
for (;; ) {
|
|
37953
|
+
const url = buildCatalogPageUrl(catalogUrl(), offset, CATALOG_PAGE_LIMIT, revision);
|
|
37954
|
+
const result = await fetchCatalogPage(url, timeoutMs);
|
|
37955
|
+
if (!result.ok) {
|
|
37956
|
+
return {
|
|
37957
|
+
kind: "fetch_failed",
|
|
37958
|
+
reason: pages === 0 ? result.reason : "incomplete"
|
|
37959
|
+
};
|
|
37960
|
+
}
|
|
37961
|
+
const { page } = result;
|
|
37962
|
+
if (!Array.isArray(page.models))
|
|
37963
|
+
return { kind: "fetch_failed", reason: "empty" };
|
|
37964
|
+
if (pages === 0) {
|
|
37965
|
+
revision = result.revision;
|
|
37966
|
+
if (page.models.length === 0)
|
|
37967
|
+
return { kind: "fetch_failed", reason: "empty" };
|
|
37968
|
+
} else if (revision && result.revision && result.revision !== revision) {
|
|
37969
|
+
return { kind: "fetch_failed", reason: "revision_mismatch" };
|
|
37970
|
+
}
|
|
37971
|
+
entries.push(...page.models);
|
|
37972
|
+
pages++;
|
|
37973
|
+
if (page.hasMore !== true)
|
|
37974
|
+
break;
|
|
37975
|
+
if (page.models.length === 0)
|
|
37976
|
+
return { kind: "fetch_failed", reason: "incomplete" };
|
|
37977
|
+
offset += page.models.length;
|
|
37978
|
+
if (pages >= MAX_CATALOG_PAGES) {
|
|
37979
|
+
return { kind: "fetch_failed", reason: "incomplete" };
|
|
37980
|
+
}
|
|
37798
37981
|
}
|
|
37982
|
+
if (entries.length === 0)
|
|
37983
|
+
return { kind: "fetch_failed", reason: "empty" };
|
|
37984
|
+
const plans = await fetchSubscriptionPlans(timeoutMs, revision);
|
|
37799
37985
|
const backwardCompatModels = [];
|
|
37800
|
-
for (const entry of
|
|
37986
|
+
for (const entry of entries) {
|
|
37801
37987
|
const id = externalIdFor(entry, "openrouter");
|
|
37802
37988
|
if (id)
|
|
37803
37989
|
backwardCompatModels.push({ id });
|
|
37804
37990
|
}
|
|
37805
|
-
_memCache =
|
|
37806
|
-
const plans = await plansPromise;
|
|
37991
|
+
_memCache = entries;
|
|
37807
37992
|
writeAllModelsCache({
|
|
37808
|
-
entries
|
|
37993
|
+
entries,
|
|
37809
37994
|
models: backwardCompatModels,
|
|
37810
|
-
...plans !== undefined ? { plans } : {}
|
|
37811
|
-
|
|
37995
|
+
...plans !== undefined ? { plans } : {},
|
|
37996
|
+
...revision !== undefined ? { catalogRevision: revision } : {}
|
|
37997
|
+
}, options.cachePath);
|
|
37812
37998
|
_warmPromise = Promise.resolve();
|
|
37813
|
-
return { kind: "refreshed", modelCount:
|
|
37999
|
+
return { kind: "refreshed", modelCount: entries.length, catalogRevision: revision, pages };
|
|
37814
38000
|
}
|
|
37815
|
-
async function fetchSubscriptionPlans(timeoutMs) {
|
|
38001
|
+
async function fetchSubscriptionPlans(timeoutMs, revision) {
|
|
37816
38002
|
try {
|
|
37817
|
-
const
|
|
38003
|
+
const url = new URL(plansUrl());
|
|
38004
|
+
if (revision)
|
|
38005
|
+
url.searchParams.set("revision", revision);
|
|
38006
|
+
const response = await fetch(url.toString(), {
|
|
37818
38007
|
signal: AbortSignal.timeout(timeoutMs)
|
|
37819
38008
|
});
|
|
37820
38009
|
if (!response.ok)
|
|
@@ -37846,11 +38035,9 @@ async function ensureCatalogReady(timeoutMs = 5000) {
|
|
|
37846
38035
|
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
37847
38036
|
]);
|
|
37848
38037
|
}
|
|
37849
|
-
var
|
|
38038
|
+
var DEFAULT_CATALOG_URL = "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=active&catalog=slim&limit=1000", _memCache = null, _catalogEntriesForTest, _warmPromise = null, CATALOG_REVISION_HEADER = "x-catalog-revision", MAX_CATALOG_PAGES = 40, CATALOG_PAGE_LIMIT = 1000;
|
|
37850
38039
|
var init_catalog_client = __esm(() => {
|
|
37851
38040
|
init_all_models_cache();
|
|
37852
|
-
FIREBASE_CATALOG_URL = process.env.CLAUDISH_CATALOG_URL ?? process.env.FIREBASE_CATALOG_URL ?? "https://us-central1-claudish-6da10.cloudfunctions.net/queryModels?status=active&catalog=slim&limit=1000";
|
|
37853
|
-
FIREBASE_PLANS_URL = process.env.CLAUDISH_PLANS_URL ?? derivePlansUrl(FIREBASE_CATALOG_URL);
|
|
37854
38041
|
});
|
|
37855
38042
|
|
|
37856
38043
|
// src/config-schema.ts
|
|
@@ -41049,6 +41236,18 @@ async function shutdownAllTeamRuns() {
|
|
|
41049
41236
|
return;
|
|
41050
41237
|
})));
|
|
41051
41238
|
}
|
|
41239
|
+
function snippetHeadAndTail(text) {
|
|
41240
|
+
if (text.length <= SNIPPET_LIMIT)
|
|
41241
|
+
return text;
|
|
41242
|
+
const head = text.slice(0, SNIPPET_HEAD);
|
|
41243
|
+
const tail = text.slice(-(SNIPPET_LIMIT - SNIPPET_HEAD));
|
|
41244
|
+
const omitted = text.length - head.length - tail.length;
|
|
41245
|
+
return `${head}
|
|
41246
|
+
|
|
41247
|
+
\u2026 [${omitted} bytes omitted] \u2026
|
|
41248
|
+
|
|
41249
|
+
${tail}`;
|
|
41250
|
+
}
|
|
41052
41251
|
function classifyRunOutput(opts) {
|
|
41053
41252
|
const {
|
|
41054
41253
|
outputSize,
|
|
@@ -41419,7 +41618,7 @@ async function startModels(sessionPath, opts = {}) {
|
|
|
41419
41618
|
reason,
|
|
41420
41619
|
detail,
|
|
41421
41620
|
stderrSnippet: stderr ? redactSecrets(stderr).slice(-2000) : undefined,
|
|
41422
|
-
stdoutSnippet: stdoutTail ? redactSecrets(stdoutTail)
|
|
41621
|
+
stdoutSnippet: stdoutTail ? snippetHeadAndTail(redactSecrets(stdoutTail)) : undefined,
|
|
41423
41622
|
errorLogPath,
|
|
41424
41623
|
upstreamErrorLogPath: existsSync20(upstreamErrorLogPath) ? upstreamErrorLogPath : undefined,
|
|
41425
41624
|
workDir: sessionPath
|
|
@@ -41696,7 +41895,7 @@ function formatVerdict(verdict, sessionPath) {
|
|
|
41696
41895
|
}
|
|
41697
41896
|
return output;
|
|
41698
41897
|
}
|
|
41699
|
-
var TEAM_CAPTURE_ENV_VAR = "CLAUDISH_TEAM_CAPTURE", liveTeamRuns, STDOUT_TAIL_LIMIT = 4000, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, BENIGN_STDERR_PATTERNS;
|
|
41898
|
+
var TEAM_CAPTURE_ENV_VAR = "CLAUDISH_TEAM_CAPTURE", liveTeamRuns, STDOUT_TAIL_LIMIT = 4000, SNIPPET_LIMIT = 2000, SNIPPET_HEAD = 600, API_ERROR_RE, BG_CEILING_RE, DEFAULT_MIN_OUTPUT_BYTES = 0, BENIGN_STDERR_PATTERNS;
|
|
41700
41899
|
var init_team_orchestrator = __esm(() => {
|
|
41701
41900
|
init_prehydrate();
|
|
41702
41901
|
init_stream_json_reducer();
|
|
@@ -67784,6 +67983,46 @@ function resolveAdvisorModelArg(config, cwd = process.cwd()) {
|
|
|
67784
67983
|
source: "claudish"
|
|
67785
67984
|
};
|
|
67786
67985
|
}
|
|
67986
|
+
function isSuppressibleChildStderrLine(line) {
|
|
67987
|
+
return CHILD_STDERR_NOISE.some((re) => re.test(line));
|
|
67988
|
+
}
|
|
67989
|
+
function relayChildStderr(stream) {
|
|
67990
|
+
let buffered = "";
|
|
67991
|
+
const emit = (line) => {
|
|
67992
|
+
if (isSuppressibleChildStderrLine(line)) {
|
|
67993
|
+
log(`[Suppressed] claude-code-stderr: ${line.trimEnd()}`);
|
|
67994
|
+
return;
|
|
67995
|
+
}
|
|
67996
|
+
process.stderr.write(`${line}
|
|
67997
|
+
`);
|
|
67998
|
+
};
|
|
67999
|
+
stream.setEncoding("utf8");
|
|
68000
|
+
stream.on("data", (chunk) => {
|
|
68001
|
+
buffered += chunk;
|
|
68002
|
+
const lines = buffered.split(`
|
|
68003
|
+
`);
|
|
68004
|
+
buffered = lines.pop() ?? "";
|
|
68005
|
+
for (const line of lines)
|
|
68006
|
+
emit(line);
|
|
68007
|
+
});
|
|
68008
|
+
const flush = () => {
|
|
68009
|
+
if (buffered.length === 0)
|
|
68010
|
+
return;
|
|
68011
|
+
const tail = buffered;
|
|
68012
|
+
buffered = "";
|
|
68013
|
+
if (isSuppressibleChildStderrLine(tail)) {
|
|
68014
|
+
log(`[Suppressed] claude-code-stderr: ${tail}`);
|
|
68015
|
+
} else {
|
|
68016
|
+
process.stderr.write(tail);
|
|
68017
|
+
}
|
|
68018
|
+
};
|
|
68019
|
+
stream.on("end", flush);
|
|
68020
|
+
stream.on("close", flush);
|
|
68021
|
+
stream.on("error", (err) => {
|
|
68022
|
+
flush();
|
|
68023
|
+
logStderr(`child stderr relay ended: ${err}`);
|
|
68024
|
+
});
|
|
68025
|
+
}
|
|
67787
68026
|
async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
|
|
67788
68027
|
const hasProfileMappings = config.modelOpus || config.modelSonnet || config.modelHaiku || config.modelSubagent;
|
|
67789
68028
|
const advisorNativeSession = isAdvisorNativeSession(config);
|
|
@@ -67858,6 +68097,9 @@ async function runClaudeWithProxy(config, proxyUrl, onCleanup) {
|
|
|
67858
68097
|
}
|
|
67859
68098
|
let hidAnthropicApiKey = false;
|
|
67860
68099
|
delete env.CLAUDECODE;
|
|
68100
|
+
if (!config.interactive && env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC === undefined) {
|
|
68101
|
+
env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
|
|
68102
|
+
}
|
|
67861
68103
|
if (config.monitor || advisorNativeSession) {
|
|
67862
68104
|
delete env.ANTHROPIC_API_KEY;
|
|
67863
68105
|
delete env.ANTHROPIC_AUTH_TOKEN;
|
|
@@ -67955,12 +68197,16 @@ Or set CLAUDE_PATH to your custom installation:`);
|
|
|
67955
68197
|
} else if (config.interactive && !process.stdout.isTTY && !process.stdin.isTTY) {
|
|
67956
68198
|
console.error("[claudish] An interactive session was requested but no terminal is attached (stdin and stdout are both non-TTY). Pass a prompt argument, or use --stdin / -p for non-interactive mode.");
|
|
67957
68199
|
}
|
|
67958
|
-
const
|
|
68200
|
+
const filterChildStderr = !config.interactive && ttyFd === undefined;
|
|
68201
|
+
const stdio = ttyFd !== undefined ? [0, ttyFd, ttyFd] : filterChildStderr ? ["inherit", "inherit", "pipe"] : "inherit";
|
|
67959
68202
|
const proc = spawn5(spawnCommand, claudeArgs, {
|
|
67960
68203
|
env,
|
|
67961
68204
|
stdio,
|
|
67962
68205
|
shell: needsShell
|
|
67963
68206
|
});
|
|
68207
|
+
if (filterChildStderr && proc.stderr) {
|
|
68208
|
+
relayChildStderr(proc.stderr);
|
|
68209
|
+
}
|
|
67964
68210
|
if (config.interactive) {
|
|
67965
68211
|
restoreTerminal = beginTerminalIsolation((entry) => {
|
|
67966
68212
|
logStderr(`[Suppressed] ${entry.source}: ${entry.text.trimEnd()}`);
|
|
@@ -68098,7 +68344,7 @@ var restoreTerminal = null, macosKeychainAnthropicResult, defaultKeychainAnthrop
|
|
|
68098
68344
|
macosKeychainAnthropicResult = false;
|
|
68099
68345
|
}
|
|
68100
68346
|
return macosKeychainAnthropicResult;
|
|
68101
|
-
}, CLAUDISH_PLACEHOLDER_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx", CLAUDISH_PLACEHOLDER_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth", STALE_TOKEN_FILE_MS, MAX_TOKEN_FILES_SCANNED = 4000, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, USER_STATUS_LINE_TIMEOUT_SECONDS = 3, MIN_AUTO_COMPACT_WINDOW = 200000, ADVISOR_TOOL_ENV_VAR = "CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL", CLAUDISH_CHILD_ADVISOR_MODEL = "sonnet", SIGNAL_EXIT_NUMBERS;
|
|
68347
|
+
}, CLAUDISH_PLACEHOLDER_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx", CLAUDISH_PLACEHOLDER_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth", STALE_TOKEN_FILE_MS, MAX_TOKEN_FILES_SCANNED = 4000, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, USER_STATUS_LINE_TIMEOUT_SECONDS = 3, MIN_AUTO_COMPACT_WINDOW = 200000, ADVISOR_TOOL_ENV_VAR = "CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL", CLAUDISH_CHILD_ADVISOR_MODEL = "sonnet", CHILD_STDERR_NOISE, SIGNAL_EXIT_NUMBERS;
|
|
68102
68348
|
var init_claude_runner = __esm(() => {
|
|
68103
68349
|
init_model_catalog();
|
|
68104
68350
|
init_config2();
|
|
@@ -68112,6 +68358,7 @@ var init_claude_runner = __esm(() => {
|
|
|
68112
68358
|
init_terminal_isolation();
|
|
68113
68359
|
init_theme_mode();
|
|
68114
68360
|
STALE_TOKEN_FILE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
68361
|
+
CHILD_STDERR_NOISE = [/^\[claude-code:unrecognized_model\]/];
|
|
68115
68362
|
SIGNAL_EXIT_NUMBERS = {
|
|
68116
68363
|
SIGHUP: 1,
|
|
68117
68364
|
SIGINT: 2,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.6.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": "9.
|
|
64
|
-
"@claudish/magmux-darwin-x64": "9.
|
|
65
|
-
"@claudish/magmux-linux-arm64": "9.
|
|
66
|
-
"@claudish/magmux-linux-x64": "9.
|
|
63
|
+
"@claudish/magmux-darwin-arm64": "9.6.0",
|
|
64
|
+
"@claudish/magmux-darwin-x64": "9.6.0",
|
|
65
|
+
"@claudish/magmux-linux-arm64": "9.6.0",
|
|
66
|
+
"@claudish/magmux-linux-x64": "9.6.0"
|
|
67
67
|
},
|
|
68
68
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
69
69
|
"license": "MIT",
|