claudish 7.30.0 → 7.32.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 +1300 -492
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
651
651
|
});
|
|
652
652
|
|
|
653
653
|
// src/version.ts
|
|
654
|
-
var VERSION = "7.
|
|
654
|
+
var VERSION = "7.32.0";
|
|
655
655
|
|
|
656
656
|
// src/logger.ts
|
|
657
657
|
var exports_logger = {};
|
|
@@ -28218,6 +28218,25 @@ var init_provider_definitions = __esm(() => {
|
|
|
28218
28218
|
isDirectApi: true,
|
|
28219
28219
|
description: "Sakana Fugu Subscription (sc@)"
|
|
28220
28220
|
},
|
|
28221
|
+
{
|
|
28222
|
+
name: "qwen-cloud",
|
|
28223
|
+
displayName: "Qwen Plan",
|
|
28224
|
+
transport: "anthropic",
|
|
28225
|
+
baseUrl: "https://token-plan.ap-southeast-1.maas.aliyuncs.com",
|
|
28226
|
+
baseUrlEnvVars: ["QWEN_CLOUD_PLAN_BASE_URL"],
|
|
28227
|
+
apiPath: "/apps/anthropic/v1/messages",
|
|
28228
|
+
apiKeyEnvVar: "QWEN_CLOUD_PLAN_API_KEY",
|
|
28229
|
+
apiKeyDescription: "Qwen Plan API Key",
|
|
28230
|
+
apiKeyUrl: "https://www.alibabacloud.com/help/en/model-studio/claude-code",
|
|
28231
|
+
authScheme: "bearer",
|
|
28232
|
+
shortcuts: ["qc"],
|
|
28233
|
+
shortestPrefix: "qc",
|
|
28234
|
+
legacyPrefixes: [{ prefix: "qc/", stripPrefix: true }],
|
|
28235
|
+
nativeModelPatterns: [{ pattern: /^qwen3\.\d/i }],
|
|
28236
|
+
modelDiscovery: { path: "/compatible-mode/v1/models", format: "openai-models-list" },
|
|
28237
|
+
isDirectApi: true,
|
|
28238
|
+
description: "Qwen Plan (qc@)"
|
|
28239
|
+
},
|
|
28221
28240
|
{
|
|
28222
28241
|
name: "qwen",
|
|
28223
28242
|
displayName: "Qwen",
|
|
@@ -31500,6 +31519,7 @@ var init_routing_hints = __esm(() => {
|
|
|
31500
31519
|
deepseek: { apiKeyEnvVar: "DEEPSEEK_API_KEY" },
|
|
31501
31520
|
sakana: { apiKeyEnvVar: "SAKANA_API_KEY" },
|
|
31502
31521
|
"sakana-subscription": { apiKeyEnvVar: "SAKANA_SUBSCRIPTION_API_KEY" },
|
|
31522
|
+
"qwen-cloud": { apiKeyEnvVar: "QWEN_CLOUD_PLAN_API_KEY" },
|
|
31503
31523
|
ollamacloud: { apiKeyEnvVar: "OLLAMA_API_KEY" },
|
|
31504
31524
|
"native-anthropic": { apiKeyEnvVar: "ANTHROPIC_API_KEY" },
|
|
31505
31525
|
openrouter: { apiKeyEnvVar: "OPENROUTER_API_KEY" },
|
|
@@ -31559,9 +31579,13 @@ function lookupModel(modelId, cachePath) {
|
|
|
31559
31579
|
return {
|
|
31560
31580
|
modelId: entry.modelId,
|
|
31561
31581
|
contextWindow: entry.contextWindow,
|
|
31562
|
-
supportsVision: entry.supportsVision
|
|
31582
|
+
supportsVision: entry.supportsVision,
|
|
31583
|
+
releaseDate: entry.releaseDate
|
|
31563
31584
|
};
|
|
31564
31585
|
}
|
|
31586
|
+
function lookupModelReasoning(modelId, cachePath) {
|
|
31587
|
+
return findCacheEntry(modelId, cachePath)?.reasoning;
|
|
31588
|
+
}
|
|
31565
31589
|
function lookupModelForProvider(modelId, provider, cachePath) {
|
|
31566
31590
|
const entry = findCacheEntry(modelId, cachePath);
|
|
31567
31591
|
if (!entry)
|
|
@@ -31668,6 +31692,7 @@ var init_default_routing_rules = __esm(() => {
|
|
|
31668
31692
|
"k3*": ["kimi-coding", "kimi", "openrouter"],
|
|
31669
31693
|
"minimax-*": ["minimax-coding", "minimax", "openrouter"],
|
|
31670
31694
|
"glm-*": ["glm-coding", "glm", "openrouter"],
|
|
31695
|
+
"qwen3.*": ["qwen-cloud", "openrouter"],
|
|
31671
31696
|
"z-ai-*": ["z-ai", "openrouter"],
|
|
31672
31697
|
"deepseek-*": ["deepseek", "openrouter"],
|
|
31673
31698
|
fugu: ["sakana-subscription", "sakana"],
|
|
@@ -32917,18 +32942,80 @@ var init_cache_ttl = __esm(() => {
|
|
|
32917
32942
|
FIREBASE_CACHE_TTL_MS = FIREBASE_CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
32918
32943
|
});
|
|
32919
32944
|
|
|
32945
|
+
// src/providers/model-ordering.ts
|
|
32946
|
+
function extractVersionParts(modelId) {
|
|
32947
|
+
const tokens = modelId.toLowerCase().split(/[\/_-]+/);
|
|
32948
|
+
let started = false;
|
|
32949
|
+
const parts = [];
|
|
32950
|
+
for (const token of tokens) {
|
|
32951
|
+
const match = token.match(/\d+(?:\.\d+)*/);
|
|
32952
|
+
if (!match) {
|
|
32953
|
+
if (started)
|
|
32954
|
+
break;
|
|
32955
|
+
continue;
|
|
32956
|
+
}
|
|
32957
|
+
if (!started) {
|
|
32958
|
+
started = true;
|
|
32959
|
+
for (const part of match[0].split(".")) {
|
|
32960
|
+
parts.push(Number.parseInt(part, 10));
|
|
32961
|
+
}
|
|
32962
|
+
if (!/^\d+(?:\.\d+)*$/.test(token)) {
|
|
32963
|
+
break;
|
|
32964
|
+
}
|
|
32965
|
+
continue;
|
|
32966
|
+
}
|
|
32967
|
+
if (!/^\d{1,2}(?:\.\d+)?$/.test(token)) {
|
|
32968
|
+
break;
|
|
32969
|
+
}
|
|
32970
|
+
for (const part of token.split(".")) {
|
|
32971
|
+
parts.push(Number.parseInt(part, 10));
|
|
32972
|
+
}
|
|
32973
|
+
}
|
|
32974
|
+
return parts;
|
|
32975
|
+
}
|
|
32976
|
+
function compareVersionPartsDesc(a, b) {
|
|
32977
|
+
const maxLength = Math.max(a.length, b.length);
|
|
32978
|
+
for (let i = 0;i < maxLength; i++) {
|
|
32979
|
+
const aPart = a[i] ?? -1;
|
|
32980
|
+
const bPart = b[i] ?? -1;
|
|
32981
|
+
if (aPart !== bPart) {
|
|
32982
|
+
return bPart - aPart;
|
|
32983
|
+
}
|
|
32984
|
+
}
|
|
32985
|
+
return 0;
|
|
32986
|
+
}
|
|
32987
|
+
function compareByReleaseDateDesc(a, b) {
|
|
32988
|
+
const aReleaseRaw = a.releaseDate ? Date.parse(a.releaseDate) : 0;
|
|
32989
|
+
const bReleaseRaw = b.releaseDate ? Date.parse(b.releaseDate) : 0;
|
|
32990
|
+
const aRelease = Number.isNaN(aReleaseRaw) ? 0 : aReleaseRaw;
|
|
32991
|
+
const bRelease = Number.isNaN(bReleaseRaw) ? 0 : bReleaseRaw;
|
|
32992
|
+
if (aRelease !== bRelease) {
|
|
32993
|
+
return bRelease - aRelease;
|
|
32994
|
+
}
|
|
32995
|
+
const aId = a.id ?? a.modelId ?? "";
|
|
32996
|
+
const bId = b.id ?? b.modelId ?? "";
|
|
32997
|
+
const versionCompare = compareVersionPartsDesc(extractVersionParts(aId), extractVersionParts(bId));
|
|
32998
|
+
if (versionCompare !== 0) {
|
|
32999
|
+
return versionCompare;
|
|
33000
|
+
}
|
|
33001
|
+
return aId.localeCompare(bId);
|
|
33002
|
+
}
|
|
33003
|
+
|
|
32920
33004
|
// src/model-loader.ts
|
|
32921
33005
|
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
32922
33006
|
import { homedir as homedir17 } from "os";
|
|
32923
33007
|
import { join as join17 } from "path";
|
|
32924
33008
|
function groupRecommendedModels(entries) {
|
|
32925
33009
|
const byId = new Map;
|
|
33010
|
+
const categoryOrder = new Map;
|
|
32926
33011
|
for (const entry of entries) {
|
|
32927
33012
|
const list = byId.get(entry.id);
|
|
32928
33013
|
if (list)
|
|
32929
33014
|
list.push(entry);
|
|
32930
33015
|
else
|
|
32931
33016
|
byId.set(entry.id, [entry]);
|
|
33017
|
+
if (!categoryOrder.has(entry.category))
|
|
33018
|
+
categoryOrder.set(entry.category, categoryOrder.size);
|
|
32932
33019
|
}
|
|
32933
33020
|
const flagship = [];
|
|
32934
33021
|
const fast = [];
|
|
@@ -32942,6 +33029,17 @@ function groupRecommendedModels(entries) {
|
|
|
32942
33029
|
else
|
|
32943
33030
|
fast.push(group);
|
|
32944
33031
|
}
|
|
33032
|
+
const byCuratedPriorityThenFreshness = (a, b) => {
|
|
33033
|
+
const aCat = categoryOrder.get(a.primary.category) ?? Number.MAX_SAFE_INTEGER;
|
|
33034
|
+
const bCat = categoryOrder.get(b.primary.category) ?? Number.MAX_SAFE_INTEGER;
|
|
33035
|
+
if (aCat !== bCat)
|
|
33036
|
+
return aCat - bCat;
|
|
33037
|
+
if (a.primary.priority !== b.primary.priority)
|
|
33038
|
+
return a.primary.priority - b.primary.priority;
|
|
33039
|
+
return compareByReleaseDateDesc(a.primary, b.primary);
|
|
33040
|
+
};
|
|
33041
|
+
flagship.sort(byCuratedPriorityThenFreshness);
|
|
33042
|
+
fast.sort(byCuratedPriorityThenFreshness);
|
|
32945
33043
|
return { flagship, fast };
|
|
32946
33044
|
}
|
|
32947
33045
|
function collectRoutingPrefixes(group, getNativePrefix) {
|
|
@@ -34932,6 +35030,9 @@ var cors = (options) => {
|
|
|
34932
35030
|
var init_cors = () => {};
|
|
34933
35031
|
|
|
34934
35032
|
// src/handlers/shared/remote-provider-types.ts
|
|
35033
|
+
function isSubscriptionProvider(provider) {
|
|
35034
|
+
return SUBSCRIPTION_PROVIDERS.has(provider.toLowerCase());
|
|
35035
|
+
}
|
|
34935
35036
|
function registerDynamicPricingLookup(fn) {
|
|
34936
35037
|
_dynamicLookup = fn;
|
|
34937
35038
|
}
|
|
@@ -34940,7 +35041,7 @@ function getModelPricing(provider, modelName) {
|
|
|
34940
35041
|
if (FREE_PROVIDERS.has(p)) {
|
|
34941
35042
|
return { inputCostPer1M: 0, outputCostPer1M: 0, isFree: true };
|
|
34942
35043
|
}
|
|
34943
|
-
if (
|
|
35044
|
+
if (isSubscriptionProvider(p)) {
|
|
34944
35045
|
return { inputCostPer1M: 0, outputCostPer1M: 0, isSubscription: true };
|
|
34945
35046
|
}
|
|
34946
35047
|
if (_dynamicLookup) {
|
|
@@ -34962,7 +35063,12 @@ var init_remote_provider_types = __esm(() => {
|
|
|
34962
35063
|
ollamacloud: { inputCostPer1M: 1, outputCostPer1M: 4, isEstimate: true }
|
|
34963
35064
|
};
|
|
34964
35065
|
FREE_PROVIDERS = new Set(["opencode-zen", "zen"]);
|
|
34965
|
-
SUBSCRIPTION_PROVIDERS = new Set([
|
|
35066
|
+
SUBSCRIPTION_PROVIDERS = new Set([
|
|
35067
|
+
"minimax-coding",
|
|
35068
|
+
"kimi-coding",
|
|
35069
|
+
"glm-coding",
|
|
35070
|
+
"qwen-cloud"
|
|
35071
|
+
]);
|
|
34966
35072
|
PROVIDER_ALIAS = {
|
|
34967
35073
|
google: "gemini",
|
|
34968
35074
|
oai: "openai",
|
|
@@ -35326,16 +35432,24 @@ function matchesModelFamily(modelId, family) {
|
|
|
35326
35432
|
const fam = family.toLowerCase();
|
|
35327
35433
|
return lower.startsWith(fam) || lower.includes(`/${fam}`);
|
|
35328
35434
|
}
|
|
35435
|
+
function isEffortLevel(value) {
|
|
35436
|
+
return typeof value === "string" && EFFORT_ORDER.includes(value);
|
|
35437
|
+
}
|
|
35329
35438
|
|
|
35330
35439
|
class BaseAPIFormat {
|
|
35331
35440
|
modelId;
|
|
35441
|
+
wireFormat;
|
|
35332
35442
|
toolNameMap = new Map;
|
|
35333
|
-
constructor(modelId) {
|
|
35443
|
+
constructor(modelId, wireFormat) {
|
|
35334
35444
|
this.modelId = modelId;
|
|
35445
|
+
this.wireFormat = wireFormat;
|
|
35335
35446
|
}
|
|
35336
35447
|
getModelId() {
|
|
35337
35448
|
return this.modelId;
|
|
35338
35449
|
}
|
|
35450
|
+
getWireFormat() {
|
|
35451
|
+
return this.wireFormat;
|
|
35452
|
+
}
|
|
35339
35453
|
getToolNameLimit() {
|
|
35340
35454
|
return null;
|
|
35341
35455
|
}
|
|
@@ -35348,9 +35462,114 @@ class BaseAPIFormat {
|
|
|
35348
35462
|
restoreToolName(name) {
|
|
35349
35463
|
return this.toolNameMap.get(name) || name;
|
|
35350
35464
|
}
|
|
35351
|
-
prepareRequest(request,
|
|
35465
|
+
prepareRequest(request, originalRequest) {
|
|
35466
|
+
const prepared = this.prepareRequestCommon(request, originalRequest) ?? request;
|
|
35467
|
+
if (!this.isAnthropicWire()) {
|
|
35468
|
+
return this.applyNativeReasoning(prepared, originalRequest) ?? prepared;
|
|
35469
|
+
}
|
|
35470
|
+
this.stripNonAnthropicReasoningFields(prepared);
|
|
35471
|
+
return this.applyAnthropicWireReasoning(prepared, originalRequest) ?? prepared;
|
|
35472
|
+
}
|
|
35473
|
+
prepareRequestCommon(request, _originalRequest) {
|
|
35474
|
+
return request;
|
|
35475
|
+
}
|
|
35476
|
+
applyNativeReasoning(request, _originalRequest) {
|
|
35477
|
+
return request;
|
|
35478
|
+
}
|
|
35479
|
+
isAnthropicWire() {
|
|
35480
|
+
return this.wireFormat === "anthropic-sse";
|
|
35481
|
+
}
|
|
35482
|
+
stripNonAnthropicReasoningFields(request) {
|
|
35483
|
+
if (!request)
|
|
35484
|
+
return;
|
|
35485
|
+
for (const field of NON_ANTHROPIC_REASONING_FIELDS) {
|
|
35486
|
+
if (request[field] !== undefined)
|
|
35487
|
+
delete request[field];
|
|
35488
|
+
}
|
|
35489
|
+
}
|
|
35490
|
+
applyAnthropicWireReasoning(request, originalRequest) {
|
|
35491
|
+
const reasoning = this.lookupReasoningCapability();
|
|
35492
|
+
if (reasoning?.supported === false) {
|
|
35493
|
+
request.thinking = { type: "disabled" };
|
|
35494
|
+
log(`[${this.getName()}] ${this.modelId} reports no reasoning support -> thinking: disabled`);
|
|
35495
|
+
return request;
|
|
35496
|
+
}
|
|
35497
|
+
const effort = this.resolveEffortLevel(originalRequest);
|
|
35498
|
+
if (!effort)
|
|
35499
|
+
return request;
|
|
35500
|
+
if (effort === "none" || effort === "minimal") {
|
|
35501
|
+
request.thinking = { type: "disabled" };
|
|
35502
|
+
log(`[${this.getName()}] effort ${effort} -> thinking.type: disabled for ${this.modelId}`);
|
|
35503
|
+
return request;
|
|
35504
|
+
}
|
|
35505
|
+
if (reasoning && (reasoning.control === "budget" || reasoning.supportsBudgetTokens)) {
|
|
35506
|
+
return this.enableAnthropicThinkingWithBudget(request, effort, "catalog: budget-controlled");
|
|
35507
|
+
}
|
|
35508
|
+
const advertised = reasoning?.efforts?.length ? reasoning : undefined;
|
|
35509
|
+
if (advertised) {
|
|
35510
|
+
const level = this.clampToAdvertisedEffort(effort, advertised);
|
|
35511
|
+
request.thinking = { type: "enabled" };
|
|
35512
|
+
if (level) {
|
|
35513
|
+
request.output_config = { ...request.output_config ?? {}, effort: level };
|
|
35514
|
+
}
|
|
35515
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled, output_config.effort: ${level ?? "(none advertised)"} for ${this.modelId} (advertised: ${advertised.efforts?.join("/")})`);
|
|
35516
|
+
return request;
|
|
35517
|
+
}
|
|
35518
|
+
if (reasoning) {
|
|
35519
|
+
request.thinking = { type: "enabled" };
|
|
35520
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled (no depth knob; catalog control=${reasoning.control ?? "unknown"}) for ${this.modelId}`);
|
|
35521
|
+
return request;
|
|
35522
|
+
}
|
|
35523
|
+
return this.enableAnthropicThinkingWithBudget(request, effort, "no catalog entry");
|
|
35524
|
+
}
|
|
35525
|
+
enableAnthropicThinkingWithBudget(request, effort, why) {
|
|
35526
|
+
const budget = this.effortToThinkingTokenBudget(effort);
|
|
35527
|
+
request.thinking = budget === undefined ? { type: "enabled" } : { type: "enabled", budget_tokens: budget };
|
|
35528
|
+
log(`[${this.getName()}] effort ${effort} -> thinking: enabled, budget_tokens: ${budget ?? "(model max)"} for ${this.modelId} (${why})`);
|
|
35352
35529
|
return request;
|
|
35353
35530
|
}
|
|
35531
|
+
clampToAdvertisedEffort(requested, reasoning) {
|
|
35532
|
+
const advertised = (reasoning.efforts ?? []).filter(isEffortLevel);
|
|
35533
|
+
if (advertised.length === 0) {
|
|
35534
|
+
return isEffortLevel(reasoning.defaultEffort) ? reasoning.defaultEffort : undefined;
|
|
35535
|
+
}
|
|
35536
|
+
if (advertised.includes(requested))
|
|
35537
|
+
return requested;
|
|
35538
|
+
const target = EFFORT_ORDER.indexOf(requested);
|
|
35539
|
+
let best = advertised[0];
|
|
35540
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
35541
|
+
for (const candidate of advertised) {
|
|
35542
|
+
const distance = Math.abs(EFFORT_ORDER.indexOf(candidate) - target);
|
|
35543
|
+
if (distance < bestDistance || distance === bestDistance && EFFORT_ORDER.indexOf(candidate) > EFFORT_ORDER.indexOf(best)) {
|
|
35544
|
+
best = candidate;
|
|
35545
|
+
bestDistance = distance;
|
|
35546
|
+
}
|
|
35547
|
+
}
|
|
35548
|
+
return best;
|
|
35549
|
+
}
|
|
35550
|
+
lookupReasoningCapability() {
|
|
35551
|
+
try {
|
|
35552
|
+
return lookupModelReasoning(this.modelId);
|
|
35553
|
+
} catch {
|
|
35554
|
+
return;
|
|
35555
|
+
}
|
|
35556
|
+
}
|
|
35557
|
+
effortToThinkingTokenBudget(effort) {
|
|
35558
|
+
switch (effort) {
|
|
35559
|
+
case "low":
|
|
35560
|
+
return 2048;
|
|
35561
|
+
case "medium":
|
|
35562
|
+
return 8192;
|
|
35563
|
+
case "high":
|
|
35564
|
+
return 24576;
|
|
35565
|
+
case "xhigh":
|
|
35566
|
+
return 38912;
|
|
35567
|
+
case "max":
|
|
35568
|
+
return;
|
|
35569
|
+
default:
|
|
35570
|
+
return 8192;
|
|
35571
|
+
}
|
|
35572
|
+
}
|
|
35354
35573
|
resolveEffortLevel(originalRequest) {
|
|
35355
35574
|
const lvl = originalRequest?.output_config?.effort;
|
|
35356
35575
|
if (typeof lvl === "string") {
|
|
@@ -35412,7 +35631,7 @@ class BaseAPIFormat {
|
|
|
35412
35631
|
return true;
|
|
35413
35632
|
}
|
|
35414
35633
|
shouldFilterThinking() {
|
|
35415
|
-
return
|
|
35634
|
+
return this.isAnthropicWire();
|
|
35416
35635
|
}
|
|
35417
35636
|
truncateToolNames(request) {
|
|
35418
35637
|
const limit = this.getToolNameLimit();
|
|
@@ -35451,13 +35670,19 @@ class BaseAPIFormat {
|
|
|
35451
35670
|
}
|
|
35452
35671
|
}
|
|
35453
35672
|
}
|
|
35454
|
-
var EFFORT_ORDER, DefaultAPIFormat;
|
|
35673
|
+
var EFFORT_ORDER, NON_ANTHROPIC_REASONING_FIELDS, DefaultAPIFormat;
|
|
35455
35674
|
var init_base_api_format = __esm(() => {
|
|
35456
35675
|
init_remote_provider_types();
|
|
35676
|
+
init_logger();
|
|
35457
35677
|
init_model_catalog();
|
|
35458
35678
|
init_tool_name_utils();
|
|
35459
35679
|
init_openai_tools();
|
|
35460
35680
|
EFFORT_ORDER = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
35681
|
+
NON_ANTHROPIC_REASONING_FIELDS = [
|
|
35682
|
+
"reasoning_effort",
|
|
35683
|
+
"enable_thinking",
|
|
35684
|
+
"thinking_budget"
|
|
35685
|
+
];
|
|
35461
35686
|
DefaultAPIFormat = class DefaultAPIFormat extends BaseAPIFormat {
|
|
35462
35687
|
processTextContent(textContent, _accumulatedText) {
|
|
35463
35688
|
return {
|
|
@@ -35707,7 +35932,7 @@ var init_deepseek_model_dialect = __esm(() => {
|
|
|
35707
35932
|
wasTransformed: false
|
|
35708
35933
|
};
|
|
35709
35934
|
}
|
|
35710
|
-
|
|
35935
|
+
applyNativeReasoning(request, originalRequest) {
|
|
35711
35936
|
const effort = this.resolveEffortLevel(originalRequest);
|
|
35712
35937
|
if (effort && this.isV4Model()) {
|
|
35713
35938
|
if (effort === "none" || effort === "minimal") {
|
|
@@ -36426,6 +36651,7 @@ data: ${JSON.stringify(d)}
|
|
|
36426
36651
|
output_tokens: state.usage?.completion_tokens || 0
|
|
36427
36652
|
}
|
|
36428
36653
|
});
|
|
36654
|
+
behavior?.onTurnEnd?.();
|
|
36429
36655
|
send("message_stop", { type: "message_stop" });
|
|
36430
36656
|
}
|
|
36431
36657
|
if (onTokenUpdate) {
|
|
@@ -36492,6 +36718,7 @@ data: ${JSON.stringify(d)}
|
|
|
36492
36718
|
});
|
|
36493
36719
|
}
|
|
36494
36720
|
if (delta.reasoning_content) {
|
|
36721
|
+
behavior?.onAssistantText?.(delta.reasoning_content, "reasoning");
|
|
36495
36722
|
state.lastActivity = Date.now();
|
|
36496
36723
|
if (!state.reasoningStarted) {
|
|
36497
36724
|
state.reasoningIdx = state.curIdx++;
|
|
@@ -36509,6 +36736,8 @@ data: ${JSON.stringify(d)}
|
|
|
36509
36736
|
});
|
|
36510
36737
|
}
|
|
36511
36738
|
const txt = delta.content || "";
|
|
36739
|
+
if (txt)
|
|
36740
|
+
behavior?.onAssistantText?.(txt, "text");
|
|
36512
36741
|
log(`[Streaming] Text chunk: "${txt.substring(0, 30).replace(/\n/g, "\\n")}" (${txt.length} chars)`);
|
|
36513
36742
|
if (txt) {
|
|
36514
36743
|
state.lastActivity = Date.now();
|
|
@@ -37136,7 +37365,7 @@ var init_glm_model_dialect = __esm(() => {
|
|
|
37136
37365
|
wasTransformed: false
|
|
37137
37366
|
};
|
|
37138
37367
|
}
|
|
37139
|
-
|
|
37368
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37140
37369
|
const effort = this.resolveEffortLevel(originalRequest);
|
|
37141
37370
|
if (effort && this.isHybridThinkingModel()) {
|
|
37142
37371
|
const type = effort === "none" || effort === "minimal" ? "disabled" : "enabled";
|
|
@@ -37218,7 +37447,7 @@ var init_grok_model_dialect = __esm(() => {
|
|
|
37218
37447
|
wasTransformed: true
|
|
37219
37448
|
};
|
|
37220
37449
|
}
|
|
37221
|
-
|
|
37450
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37222
37451
|
const effort = this.resolveEffortLevel(originalRequest);
|
|
37223
37452
|
if (effort) {
|
|
37224
37453
|
const value = this.effortToReasoningEffort(effort);
|
|
@@ -37310,7 +37539,7 @@ var init_minimax_model_dialect = __esm(() => {
|
|
|
37310
37539
|
wasTransformed: false
|
|
37311
37540
|
};
|
|
37312
37541
|
}
|
|
37313
|
-
|
|
37542
|
+
prepareRequestCommon(request, _originalRequest) {
|
|
37314
37543
|
if (request.temperature !== undefined) {
|
|
37315
37544
|
if (request.temperature < TEMPERATURE_RANGE.min) {
|
|
37316
37545
|
log(`[MiniMaxModelDialect] Clamping temperature ${request.temperature} \u2192 ${TEMPERATURE_RANGE.min} (MiniMax requires >= ${TEMPERATURE_RANGE.min})`);
|
|
@@ -37320,6 +37549,9 @@ var init_minimax_model_dialect = __esm(() => {
|
|
|
37320
37549
|
request.temperature = TEMPERATURE_RANGE.max;
|
|
37321
37550
|
}
|
|
37322
37551
|
}
|
|
37552
|
+
return request;
|
|
37553
|
+
}
|
|
37554
|
+
applyMiniMaxThinking(request, originalRequest) {
|
|
37323
37555
|
const effort = this.resolveEffortLevel(originalRequest);
|
|
37324
37556
|
if (effort) {
|
|
37325
37557
|
const type = effort === "none" ? "disabled" : "adaptive";
|
|
@@ -37328,6 +37560,12 @@ var init_minimax_model_dialect = __esm(() => {
|
|
|
37328
37560
|
}
|
|
37329
37561
|
return request;
|
|
37330
37562
|
}
|
|
37563
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37564
|
+
return this.applyMiniMaxThinking(request, originalRequest);
|
|
37565
|
+
}
|
|
37566
|
+
applyAnthropicWireReasoning(request, originalRequest) {
|
|
37567
|
+
return this.applyMiniMaxThinking(request, originalRequest);
|
|
37568
|
+
}
|
|
37331
37569
|
getContextWindow() {
|
|
37332
37570
|
return lookupModel(this.modelId)?.contextWindow ?? 0;
|
|
37333
37571
|
}
|
|
@@ -37365,7 +37603,14 @@ var init_openai_api_format = __esm(() => {
|
|
|
37365
37603
|
getMaxToolCount() {
|
|
37366
37604
|
return 128;
|
|
37367
37605
|
}
|
|
37368
|
-
|
|
37606
|
+
prepareRequestCommon(request, _originalRequest) {
|
|
37607
|
+
this.truncateToolNames(request);
|
|
37608
|
+
if (request.messages) {
|
|
37609
|
+
this.truncateToolNamesInMessages(request.messages);
|
|
37610
|
+
}
|
|
37611
|
+
return request;
|
|
37612
|
+
}
|
|
37613
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37369
37614
|
if (this.supportsReasoningEffort() && request.reasoning_effort === undefined) {
|
|
37370
37615
|
const effort = this.resolveReasoningEffort(originalRequest);
|
|
37371
37616
|
if (effort) {
|
|
@@ -37375,10 +37620,6 @@ var init_openai_api_format = __esm(() => {
|
|
|
37375
37620
|
}
|
|
37376
37621
|
if (request.thinking)
|
|
37377
37622
|
delete request.thinking;
|
|
37378
|
-
this.truncateToolNames(request);
|
|
37379
|
-
if (request.messages) {
|
|
37380
|
-
this.truncateToolNamesInMessages(request.messages);
|
|
37381
|
-
}
|
|
37382
37623
|
return request;
|
|
37383
37624
|
}
|
|
37384
37625
|
shouldHandle(modelId) {
|
|
@@ -37536,41 +37777,25 @@ var init_qwen_model_dialect = __esm(() => {
|
|
|
37536
37777
|
wasTransformed
|
|
37537
37778
|
};
|
|
37538
37779
|
}
|
|
37539
|
-
|
|
37780
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37540
37781
|
const effort = this.resolveEffortLevel(originalRequest);
|
|
37541
|
-
if (effort)
|
|
37542
|
-
|
|
37543
|
-
|
|
37544
|
-
|
|
37545
|
-
}
|
|
37546
|
-
|
|
37547
|
-
|
|
37548
|
-
|
|
37549
|
-
|
|
37550
|
-
|
|
37551
|
-
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: true, thinking_budget: ${budget ?? "(model max)"} for ${this.modelId}`);
|
|
37782
|
+
if (!effort)
|
|
37783
|
+
return request;
|
|
37784
|
+
if (effort === "none" || effort === "minimal") {
|
|
37785
|
+
request.enable_thinking = false;
|
|
37786
|
+
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: false for ${this.modelId}`);
|
|
37787
|
+
} else {
|
|
37788
|
+
request.enable_thinking = true;
|
|
37789
|
+
const budget = this.effortToThinkingTokenBudget(effort);
|
|
37790
|
+
if (budget !== undefined) {
|
|
37791
|
+
request.thinking_budget = budget;
|
|
37552
37792
|
}
|
|
37553
|
-
|
|
37554
|
-
delete request.thinking;
|
|
37793
|
+
log(`[QwenModelDialect] effort ${effort} -> enable_thinking: true, thinking_budget: ${budget ?? "(model max)"} for ${this.modelId}`);
|
|
37555
37794
|
}
|
|
37795
|
+
if (originalRequest.thinking)
|
|
37796
|
+
delete request.thinking;
|
|
37556
37797
|
return request;
|
|
37557
37798
|
}
|
|
37558
|
-
effortToThinkingBudget(effort) {
|
|
37559
|
-
switch (effort) {
|
|
37560
|
-
case "low":
|
|
37561
|
-
return 2048;
|
|
37562
|
-
case "medium":
|
|
37563
|
-
return 8192;
|
|
37564
|
-
case "high":
|
|
37565
|
-
return 24576;
|
|
37566
|
-
case "xhigh":
|
|
37567
|
-
return 38912;
|
|
37568
|
-
case "max":
|
|
37569
|
-
return;
|
|
37570
|
-
default:
|
|
37571
|
-
return 8192;
|
|
37572
|
-
}
|
|
37573
|
-
}
|
|
37574
37799
|
shouldHandle(modelId) {
|
|
37575
37800
|
return matchesModelFamily(modelId, "qwen") || matchesModelFamily(modelId, "alibaba");
|
|
37576
37801
|
}
|
|
@@ -37596,17 +37821,20 @@ var init_xiaomi_model_dialect = __esm(() => {
|
|
|
37596
37821
|
getToolNameLimit() {
|
|
37597
37822
|
return 64;
|
|
37598
37823
|
}
|
|
37599
|
-
|
|
37600
|
-
if (originalRequest.thinking) {
|
|
37601
|
-
log("[XiaomiModelDialect] Stripping thinking object (not supported by Xiaomi API)");
|
|
37602
|
-
delete request.thinking;
|
|
37603
|
-
}
|
|
37824
|
+
prepareRequestCommon(request, _originalRequest) {
|
|
37604
37825
|
this.truncateToolNames(request);
|
|
37605
37826
|
if (request.messages) {
|
|
37606
37827
|
this.truncateToolNamesInMessages(request.messages);
|
|
37607
37828
|
}
|
|
37608
37829
|
return request;
|
|
37609
37830
|
}
|
|
37831
|
+
applyNativeReasoning(request, originalRequest) {
|
|
37832
|
+
if (originalRequest.thinking) {
|
|
37833
|
+
log("[XiaomiModelDialect] Stripping thinking object (not supported by Xiaomi API)");
|
|
37834
|
+
delete request.thinking;
|
|
37835
|
+
}
|
|
37836
|
+
return request;
|
|
37837
|
+
}
|
|
37610
37838
|
shouldHandle(modelId) {
|
|
37611
37839
|
return matchesModelFamily(modelId, "xiaomi") || matchesModelFamily(modelId, "mimo");
|
|
37612
37840
|
}
|
|
@@ -37626,19 +37854,19 @@ __export(exports_dialect_manager, {
|
|
|
37626
37854
|
class DialectManager {
|
|
37627
37855
|
adapters;
|
|
37628
37856
|
defaultAdapter;
|
|
37629
|
-
constructor(modelId) {
|
|
37857
|
+
constructor(modelId, wireFormat) {
|
|
37630
37858
|
this.adapters = [
|
|
37631
|
-
new GrokModelDialect(modelId),
|
|
37632
|
-
new GeminiAPIFormat(modelId),
|
|
37633
|
-
new CodexAPIFormat(modelId),
|
|
37634
|
-
new OpenAIAPIFormat(modelId),
|
|
37635
|
-
new QwenModelDialect(modelId),
|
|
37636
|
-
new MiniMaxModelDialect(modelId),
|
|
37637
|
-
new DeepSeekModelDialect(modelId),
|
|
37638
|
-
new GLMModelDialect(modelId),
|
|
37639
|
-
new XiaomiModelDialect(modelId)
|
|
37859
|
+
new GrokModelDialect(modelId, wireFormat),
|
|
37860
|
+
new GeminiAPIFormat(modelId, wireFormat),
|
|
37861
|
+
new CodexAPIFormat(modelId, wireFormat),
|
|
37862
|
+
new OpenAIAPIFormat(modelId, wireFormat),
|
|
37863
|
+
new QwenModelDialect(modelId, wireFormat),
|
|
37864
|
+
new MiniMaxModelDialect(modelId, wireFormat),
|
|
37865
|
+
new DeepSeekModelDialect(modelId, wireFormat),
|
|
37866
|
+
new GLMModelDialect(modelId, wireFormat),
|
|
37867
|
+
new XiaomiModelDialect(modelId, wireFormat)
|
|
37640
37868
|
];
|
|
37641
|
-
this.defaultAdapter = new DefaultAPIFormat(modelId);
|
|
37869
|
+
this.defaultAdapter = new DefaultAPIFormat(modelId, wireFormat);
|
|
37642
37870
|
}
|
|
37643
37871
|
getAdapter() {
|
|
37644
37872
|
for (const adapter of this.adapters) {
|
|
@@ -37745,7 +37973,7 @@ ${messages[0].content}`;
|
|
|
37745
37973
|
}
|
|
37746
37974
|
return payload;
|
|
37747
37975
|
}
|
|
37748
|
-
|
|
37976
|
+
prepareRequestCommon(request, originalRequest) {
|
|
37749
37977
|
this.innerAdapter.prepareRequest(request, originalRequest);
|
|
37750
37978
|
for (const [k, v] of this.innerAdapter.getToolNameMap()) {
|
|
37751
37979
|
this.toolNameMap.set(k, v);
|
|
@@ -37931,7 +38159,7 @@ ${text}`;
|
|
|
37931
38159
|
}
|
|
37932
38160
|
return payload;
|
|
37933
38161
|
}
|
|
37934
|
-
|
|
38162
|
+
prepareRequestCommon(request, originalRequest) {
|
|
37935
38163
|
return this.innerAdapter.prepareRequest(request, originalRequest);
|
|
37936
38164
|
}
|
|
37937
38165
|
getToolNameMap() {
|
|
@@ -37967,24 +38195,44 @@ function parseBehaviorConfig(raw2) {
|
|
|
37967
38195
|
}
|
|
37968
38196
|
return result.data;
|
|
37969
38197
|
}
|
|
37970
|
-
function resolveSeverity(ruleId, defaultSeverity, config2) {
|
|
38198
|
+
function resolveSeverity(ruleId, defaultSeverity, config2, modelId) {
|
|
37971
38199
|
const rules = config2.rules;
|
|
37972
38200
|
if (!rules)
|
|
37973
38201
|
return defaultSeverity;
|
|
37974
|
-
|
|
37975
|
-
|
|
37976
|
-
|
|
38202
|
+
if (modelId) {
|
|
38203
|
+
const scoped = bestMatch(rules, ruleId, modelId);
|
|
38204
|
+
if (scoped)
|
|
38205
|
+
return scoped;
|
|
38206
|
+
}
|
|
38207
|
+
return bestMatch(rules, ruleId, undefined) ?? defaultSeverity;
|
|
38208
|
+
}
|
|
38209
|
+
function bestMatch(rules, ruleId, modelId) {
|
|
37977
38210
|
let best = null;
|
|
37978
|
-
for (const [
|
|
37979
|
-
|
|
38211
|
+
for (const [key, severity] of Object.entries(rules)) {
|
|
38212
|
+
const { model: keyModel, rule: keyRule } = parseRuleKey(key);
|
|
38213
|
+
if (!scopeMatches(keyModel, modelId))
|
|
37980
38214
|
continue;
|
|
37981
|
-
if (!globMatches(
|
|
38215
|
+
if (!globMatches(keyRule, ruleId))
|
|
37982
38216
|
continue;
|
|
37983
|
-
const
|
|
37984
|
-
if (!best ||
|
|
37985
|
-
best = {
|
|
38217
|
+
const score = specificity(keyRule);
|
|
38218
|
+
if (!best || score > best.score)
|
|
38219
|
+
best = { score, severity };
|
|
37986
38220
|
}
|
|
37987
|
-
return best ? best.severity :
|
|
38221
|
+
return best ? best.severity : null;
|
|
38222
|
+
}
|
|
38223
|
+
function parseRuleKey(key) {
|
|
38224
|
+
const sep = key.indexOf(":");
|
|
38225
|
+
if (sep <= 0 || key.startsWith("hook:"))
|
|
38226
|
+
return { rule: key };
|
|
38227
|
+
return { model: key.slice(0, sep), rule: key.slice(sep + 1) };
|
|
38228
|
+
}
|
|
38229
|
+
function scopeMatches(keyModel, modelId) {
|
|
38230
|
+
if (modelId === undefined)
|
|
38231
|
+
return keyModel === undefined;
|
|
38232
|
+
return keyModel !== undefined && globMatches(keyModel, modelId);
|
|
38233
|
+
}
|
|
38234
|
+
function specificity(pattern) {
|
|
38235
|
+
return pattern.includes("*") ? pattern.replace(/\*/g, "").length : Number.MAX_SAFE_INTEGER;
|
|
37988
38236
|
}
|
|
37989
38237
|
function globMatches(pattern, value) {
|
|
37990
38238
|
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
@@ -38011,6 +38259,41 @@ var init_config = __esm(() => {
|
|
|
38011
38259
|
});
|
|
38012
38260
|
|
|
38013
38261
|
// src/behavior/harness.ts
|
|
38262
|
+
function extractAvailableSkills(systemText) {
|
|
38263
|
+
if (!systemText)
|
|
38264
|
+
return [];
|
|
38265
|
+
const start = SKILL_SECTION.exec(systemText);
|
|
38266
|
+
if (!start)
|
|
38267
|
+
return [];
|
|
38268
|
+
const out = [];
|
|
38269
|
+
const body = systemText.slice(start.index + start[0].length);
|
|
38270
|
+
for (const line of body.split(`
|
|
38271
|
+
`)) {
|
|
38272
|
+
const trimmed = line.trim();
|
|
38273
|
+
if (!trimmed)
|
|
38274
|
+
continue;
|
|
38275
|
+
const m = SKILL_LINE.exec(trimmed);
|
|
38276
|
+
if (!m) {
|
|
38277
|
+
if (out.length > 0)
|
|
38278
|
+
break;
|
|
38279
|
+
continue;
|
|
38280
|
+
}
|
|
38281
|
+
out.push({ name: m[1], description: m[2].trim() });
|
|
38282
|
+
}
|
|
38283
|
+
return out;
|
|
38284
|
+
}
|
|
38285
|
+
function extractSessionId(claudeRequest) {
|
|
38286
|
+
const raw2 = claudeRequest?.metadata?.user_id;
|
|
38287
|
+
if (typeof raw2 !== "string")
|
|
38288
|
+
return;
|
|
38289
|
+
try {
|
|
38290
|
+
const parsed = JSON.parse(raw2);
|
|
38291
|
+
const id = parsed?.session_id;
|
|
38292
|
+
return typeof id === "string" && id.length > 0 ? id : undefined;
|
|
38293
|
+
} catch {
|
|
38294
|
+
return;
|
|
38295
|
+
}
|
|
38296
|
+
}
|
|
38014
38297
|
function textOf(value) {
|
|
38015
38298
|
if (!value)
|
|
38016
38299
|
return "";
|
|
@@ -38062,7 +38345,7 @@ function detectHarnessFacts(claudeRequest) {
|
|
|
38062
38345
|
}
|
|
38063
38346
|
return facts;
|
|
38064
38347
|
}
|
|
38065
|
-
var PLAN_PATH_PATTERNS, PLAN_MODE_HINT;
|
|
38348
|
+
var PLAN_PATH_PATTERNS, PLAN_MODE_HINT, SKILL_SECTION, SKILL_LINE;
|
|
38066
38349
|
var init_harness = __esm(() => {
|
|
38067
38350
|
PLAN_PATH_PATTERNS = [
|
|
38068
38351
|
/You should create your plan at\s+(\S+?\.md)/,
|
|
@@ -38070,10 +38353,12 @@ var init_harness = __esm(() => {
|
|
|
38070
38353
|
/Read-only except plan file\s*\(([^)]+\.md)\)/
|
|
38071
38354
|
];
|
|
38072
38355
|
PLAN_MODE_HINT = /plan file|create your plan at|Plan mode is active|Plan mode still active/i;
|
|
38356
|
+
SKILL_SECTION = /The following skills are available[^\n]*\n/;
|
|
38357
|
+
SKILL_LINE = /^-\s+([a-z0-9][a-z0-9:_-]*):\s*(.+)$/i;
|
|
38073
38358
|
});
|
|
38074
38359
|
|
|
38075
38360
|
// src/behavior/journal.ts
|
|
38076
|
-
import { appendFile as appendFile2, mkdir, stat } from "fs/promises";
|
|
38361
|
+
import { appendFile as appendFile2, mkdir, readFile, rename, stat, writeFile } from "fs/promises";
|
|
38077
38362
|
import { homedir as homedir18 } from "os";
|
|
38078
38363
|
import { dirname as dirname6, join as join18 } from "path";
|
|
38079
38364
|
function classifyPath(observed, expected) {
|
|
@@ -38089,28 +38374,46 @@ function classifyPath(observed, expected) {
|
|
|
38089
38374
|
function journalPath() {
|
|
38090
38375
|
return join18(homedir18(), ".claudish", "behavior-journal.jsonl");
|
|
38091
38376
|
}
|
|
38377
|
+
async function prune(path) {
|
|
38378
|
+
const content = await readFile(path, "utf8");
|
|
38379
|
+
const lines = content.split(`
|
|
38380
|
+
`).filter(Boolean);
|
|
38381
|
+
let kept = 0;
|
|
38382
|
+
let firstKept = lines.length;
|
|
38383
|
+
for (let i = lines.length - 1;i >= 0; i--) {
|
|
38384
|
+
const cost = Buffer.byteLength(lines[i]) + 1;
|
|
38385
|
+
if (kept + cost > PRUNE_TO_BYTES)
|
|
38386
|
+
break;
|
|
38387
|
+
kept += cost;
|
|
38388
|
+
firstKept = i;
|
|
38389
|
+
}
|
|
38390
|
+
const survivors = lines.slice(firstKept);
|
|
38391
|
+
const tmp = `${path}.pruning`;
|
|
38392
|
+
await writeFile(tmp, survivors.length ? `${survivors.join(`
|
|
38393
|
+
`)}
|
|
38394
|
+
` : "");
|
|
38395
|
+
await rename(tmp, path);
|
|
38396
|
+
log(`[behavior:journal] pruned ${lines.length - survivors.length} of ${lines.length} entries ` + `to stay under ${Math.round(MAX_JOURNAL_BYTES / 1e6)}MB`);
|
|
38397
|
+
}
|
|
38092
38398
|
async function recordDecision(entry, path = journalPath()) {
|
|
38093
38399
|
try {
|
|
38094
38400
|
const size = await stat(path).then((s) => s.size, () => 0);
|
|
38095
|
-
if (size > MAX_JOURNAL_BYTES) {
|
|
38096
|
-
if (!capWarned) {
|
|
38097
|
-
capWarned = true;
|
|
38098
|
-
log(`[behavior:journal] ${path} exceeded ${Math.round(MAX_JOURNAL_BYTES / 1e6)}MB \u2014 ` + "no longer recording. Archive or delete it to resume.");
|
|
38099
|
-
}
|
|
38100
|
-
return;
|
|
38101
|
-
}
|
|
38102
38401
|
if (size === 0)
|
|
38103
38402
|
await mkdir(dirname6(path), { recursive: true }).catch(() => {});
|
|
38403
|
+
if (size > MAX_JOURNAL_BYTES) {
|
|
38404
|
+
await prune(path).catch((err) => log(`[behavior:journal] prune failed: ${err}`));
|
|
38405
|
+
}
|
|
38104
38406
|
await appendFile2(path, `${JSON.stringify(entry)}
|
|
38105
38407
|
`);
|
|
38106
38408
|
} catch (err) {
|
|
38107
38409
|
log(`[behavior:journal] could not record: ${err}`);
|
|
38108
38410
|
}
|
|
38109
38411
|
}
|
|
38110
|
-
var MAX_JOURNAL_BYTES,
|
|
38412
|
+
var MAX_JOURNAL_BYTES, PRUNE_TO_BYTES;
|
|
38111
38413
|
var init_journal = __esm(() => {
|
|
38112
38414
|
init_logger();
|
|
38113
38415
|
MAX_JOURNAL_BYTES = 32 * 1024 * 1024;
|
|
38416
|
+
PRUNE_TO_BYTES = Math.floor(MAX_JOURNAL_BYTES * 0.6);
|
|
38114
38417
|
});
|
|
38115
38418
|
|
|
38116
38419
|
// src/behavior/observer/digest.ts
|
|
@@ -38327,13 +38630,23 @@ class BehaviorSession {
|
|
|
38327
38630
|
modelId;
|
|
38328
38631
|
providerName;
|
|
38329
38632
|
config;
|
|
38633
|
+
engine;
|
|
38330
38634
|
facts = { planModeActive: false };
|
|
38331
38635
|
bufferedTools = new Set;
|
|
38332
|
-
|
|
38636
|
+
textBuf = "";
|
|
38637
|
+
reasoningBuf = "";
|
|
38638
|
+
toolsCalled = [];
|
|
38639
|
+
sessionId;
|
|
38640
|
+
systemText = "";
|
|
38641
|
+
get watchesOutput() {
|
|
38642
|
+
return this.active.some((a) => typeof a.rule.onModelOutput === "function");
|
|
38643
|
+
}
|
|
38644
|
+
constructor(active, modelId, providerName, config2 = {}, engine = { queueCorrection() {}, drainCorrections: () => [] }) {
|
|
38333
38645
|
this.active = active;
|
|
38334
38646
|
this.modelId = modelId;
|
|
38335
38647
|
this.providerName = providerName;
|
|
38336
38648
|
this.config = config2;
|
|
38649
|
+
this.engine = engine;
|
|
38337
38650
|
}
|
|
38338
38651
|
get observerOn() {
|
|
38339
38652
|
return this.config.observer?.enabled === true && (this.config.observer.mode ?? "suggest") !== "off";
|
|
@@ -38367,7 +38680,26 @@ class BehaviorSession {
|
|
|
38367
38680
|
if (this.active.length === 0)
|
|
38368
38681
|
return;
|
|
38369
38682
|
this.facts = detectHarnessFacts(claudeRequest);
|
|
38683
|
+
this.sessionId = extractSessionId(claudeRequest);
|
|
38684
|
+
this.systemText = typeof claudeRequest?.system === "string" ? claudeRequest.system : String(claudeRequest?.system ?? "");
|
|
38685
|
+
this.facts.sessionId = this.sessionId;
|
|
38686
|
+
this.facts.skills = extractAvailableSkills(this.systemText);
|
|
38370
38687
|
this.armBuffering();
|
|
38688
|
+
if (this.sessionId) {
|
|
38689
|
+
for (const text of this.engine.drainCorrections(this.sessionId)) {
|
|
38690
|
+
this.applyAction("behavior/pending-correction", "fix", { type: "injectSystemNote", text }, {
|
|
38691
|
+
modelId: this.modelId,
|
|
38692
|
+
providerName: this.providerName,
|
|
38693
|
+
isNativeAnthropic: false,
|
|
38694
|
+
claudeRequest,
|
|
38695
|
+
claudeTools,
|
|
38696
|
+
tools,
|
|
38697
|
+
messages,
|
|
38698
|
+
systemText: this.systemText,
|
|
38699
|
+
harness: this.facts
|
|
38700
|
+
});
|
|
38701
|
+
}
|
|
38702
|
+
}
|
|
38371
38703
|
const ctx = {
|
|
38372
38704
|
modelId: this.modelId,
|
|
38373
38705
|
providerName: this.providerName,
|
|
@@ -38376,6 +38708,7 @@ class BehaviorSession {
|
|
|
38376
38708
|
claudeTools,
|
|
38377
38709
|
tools,
|
|
38378
38710
|
messages,
|
|
38711
|
+
systemText: this.systemText,
|
|
38379
38712
|
harness: this.facts
|
|
38380
38713
|
};
|
|
38381
38714
|
for (const { rule, severity } of this.active) {
|
|
@@ -38395,6 +38728,66 @@ class BehaviorSession {
|
|
|
38395
38728
|
interceptsTool(toolName) {
|
|
38396
38729
|
return this.bufferedTools.has(toolName);
|
|
38397
38730
|
}
|
|
38731
|
+
observeText(text, kind = "text") {
|
|
38732
|
+
if (!this.watchesOutput || !text)
|
|
38733
|
+
return;
|
|
38734
|
+
const buf = kind === "reasoning" ? this.reasoningBuf : this.textBuf;
|
|
38735
|
+
if (buf.length >= MAX_OBSERVED_CHARS)
|
|
38736
|
+
return;
|
|
38737
|
+
if (kind === "reasoning")
|
|
38738
|
+
this.reasoningBuf += text;
|
|
38739
|
+
else
|
|
38740
|
+
this.textBuf += text;
|
|
38741
|
+
}
|
|
38742
|
+
observeToolCall(toolName) {
|
|
38743
|
+
if (!this.watchesOutput)
|
|
38744
|
+
return;
|
|
38745
|
+
if (this.toolsCalled.length < MAX_OBSERVED_TOOLS)
|
|
38746
|
+
this.toolsCalled.push(toolName);
|
|
38747
|
+
}
|
|
38748
|
+
finishTurn() {
|
|
38749
|
+
if (!this.watchesOutput)
|
|
38750
|
+
return;
|
|
38751
|
+
const ctx = {
|
|
38752
|
+
modelId: this.modelId,
|
|
38753
|
+
providerName: this.providerName,
|
|
38754
|
+
text: this.textBuf,
|
|
38755
|
+
reasoning: this.reasoningBuf,
|
|
38756
|
+
toolsCalled: this.toolsCalled,
|
|
38757
|
+
harness: this.facts
|
|
38758
|
+
};
|
|
38759
|
+
for (const { rule, severity } of this.active) {
|
|
38760
|
+
if (!rule.onModelOutput)
|
|
38761
|
+
continue;
|
|
38762
|
+
let actions = [];
|
|
38763
|
+
try {
|
|
38764
|
+
actions = rule.onModelOutput(ctx) ?? [];
|
|
38765
|
+
} catch (err) {
|
|
38766
|
+
log(`[behavior] rule ${rule.id} onModelOutput threw: ${err}`);
|
|
38767
|
+
continue;
|
|
38768
|
+
}
|
|
38769
|
+
for (const action of actions) {
|
|
38770
|
+
if (action.type === "warn") {
|
|
38771
|
+
log(`[behavior] ${rule.id} (output): ${action.message}`);
|
|
38772
|
+
this.journal("model_output", "warned", { ruleId: rule.id, note: action.message });
|
|
38773
|
+
continue;
|
|
38774
|
+
}
|
|
38775
|
+
if (action.type !== "injectSystemNote")
|
|
38776
|
+
continue;
|
|
38777
|
+
if (severity !== "fix") {
|
|
38778
|
+
this.journal("model_output", "warned", { ruleId: rule.id, note: "correction withheld" });
|
|
38779
|
+
continue;
|
|
38780
|
+
}
|
|
38781
|
+
if (this.sessionId)
|
|
38782
|
+
this.engine.queueCorrection(this.sessionId, action.text);
|
|
38783
|
+
this.journal("model_output", "matched", { ruleId: rule.id, note: "correction queued" });
|
|
38784
|
+
log(`[behavior] ${rule.id} queued a correction for the next request`);
|
|
38785
|
+
}
|
|
38786
|
+
}
|
|
38787
|
+
this.textBuf = "";
|
|
38788
|
+
this.reasoningBuf = "";
|
|
38789
|
+
this.toolsCalled = [];
|
|
38790
|
+
}
|
|
38398
38791
|
repairToolCall(toolName, rawArgs) {
|
|
38399
38792
|
if (!this.bufferedTools.has(toolName))
|
|
38400
38793
|
return null;
|
|
@@ -38562,15 +38955,32 @@ ${action.text}`;
|
|
|
38562
38955
|
class BehaviorEngine {
|
|
38563
38956
|
config;
|
|
38564
38957
|
rules;
|
|
38958
|
+
corrections = new Map;
|
|
38565
38959
|
constructor(config2, rules) {
|
|
38566
38960
|
this.config = config2;
|
|
38567
38961
|
this.rules = rules;
|
|
38568
38962
|
}
|
|
38963
|
+
queueCorrection(key, text) {
|
|
38964
|
+
const list = this.corrections.get(key) ?? [];
|
|
38965
|
+
list.push(text);
|
|
38966
|
+
this.corrections.set(key, list);
|
|
38967
|
+
while (this.corrections.size > MAX_TRACKED_CONVERSATIONS) {
|
|
38968
|
+
const oldest = this.corrections.keys().next().value;
|
|
38969
|
+
if (oldest === undefined)
|
|
38970
|
+
break;
|
|
38971
|
+
this.corrections.delete(oldest);
|
|
38972
|
+
}
|
|
38973
|
+
}
|
|
38974
|
+
drainCorrections(key) {
|
|
38975
|
+
const list = this.corrections.get(key) ?? [];
|
|
38976
|
+
this.corrections.delete(key);
|
|
38977
|
+
return list;
|
|
38978
|
+
}
|
|
38569
38979
|
startSession(params) {
|
|
38570
38980
|
const active = [];
|
|
38571
38981
|
if (!params.isNativeAnthropic) {
|
|
38572
38982
|
for (const rule of this.rules) {
|
|
38573
|
-
const severity = resolveSeverity(rule.id, rule.defaultSeverity, this.config);
|
|
38983
|
+
const severity = resolveSeverity(rule.id, rule.defaultSeverity, this.config, params.modelId);
|
|
38574
38984
|
if (severity === "off")
|
|
38575
38985
|
continue;
|
|
38576
38986
|
let applies = false;
|
|
@@ -38587,14 +38997,16 @@ class BehaviorEngine {
|
|
|
38587
38997
|
if (active.length > 0) {
|
|
38588
38998
|
log(`[behavior] ${active.length} rule(s) active for ${params.modelId}: ` + active.map((a) => `${a.rule.id}=${a.severity}`).join(", "));
|
|
38589
38999
|
}
|
|
38590
|
-
return new BehaviorSession(active, params.modelId, params.providerName, this.config);
|
|
39000
|
+
return new BehaviorSession(active, params.modelId, params.providerName, this.config, this);
|
|
38591
39001
|
}
|
|
38592
39002
|
}
|
|
39003
|
+
var MAX_OBSERVED_CHARS, MAX_OBSERVED_TOOLS = 200, MAX_TRACKED_CONVERSATIONS = 64;
|
|
38593
39004
|
var init_engine = __esm(() => {
|
|
38594
39005
|
init_logger();
|
|
38595
39006
|
init_config();
|
|
38596
39007
|
init_harness();
|
|
38597
39008
|
init_journal();
|
|
39009
|
+
MAX_OBSERVED_CHARS = 64 * 1024;
|
|
38598
39010
|
});
|
|
38599
39011
|
|
|
38600
39012
|
// src/behavior/rules/plan-mode.ts
|
|
@@ -40104,7 +40516,8 @@ var init_telemetry = __esm(() => {
|
|
|
40104
40516
|
"x-ai",
|
|
40105
40517
|
"minimax-coding",
|
|
40106
40518
|
"kimi-coding",
|
|
40107
|
-
"glm-coding"
|
|
40519
|
+
"glm-coding",
|
|
40520
|
+
"qwen-cloud"
|
|
40108
40521
|
]);
|
|
40109
40522
|
});
|
|
40110
40523
|
|
|
@@ -40602,6 +41015,60 @@ var init_connection_error = __esm(() => {
|
|
|
40602
41015
|
BUN_CONNECT_MESSAGE = /unable to connect\. is the computer able to access the url\?/i;
|
|
40603
41016
|
});
|
|
40604
41017
|
|
|
41018
|
+
// src/handlers/shared/context-window-fallback.ts
|
|
41019
|
+
function isDisabled() {
|
|
41020
|
+
if (process.env.CLAUDISH_NO_CATALOG_FALLBACK)
|
|
41021
|
+
return true;
|
|
41022
|
+
return false;
|
|
41023
|
+
}
|
|
41024
|
+
function resolveCatalogContextWindow(modelId) {
|
|
41025
|
+
if (!modelId || isDisabled())
|
|
41026
|
+
return Promise.resolve(null);
|
|
41027
|
+
const cached2 = results.get(modelId);
|
|
41028
|
+
if (cached2 !== undefined)
|
|
41029
|
+
return Promise.resolve(cached2);
|
|
41030
|
+
const pending = inFlight2.get(modelId);
|
|
41031
|
+
if (pending)
|
|
41032
|
+
return pending;
|
|
41033
|
+
const promise3 = fetcher(modelId).then((cw) => {
|
|
41034
|
+
const value = typeof cw === "number" && cw > 0 ? cw : null;
|
|
41035
|
+
results.set(modelId, value);
|
|
41036
|
+
return value;
|
|
41037
|
+
}).catch((err) => {
|
|
41038
|
+
results.set(modelId, null);
|
|
41039
|
+
log(`[ContextWindow] Catalog lookup failed for ${modelId}: ${err}`);
|
|
41040
|
+
return null;
|
|
41041
|
+
}).finally(() => {
|
|
41042
|
+
inFlight2.delete(modelId);
|
|
41043
|
+
});
|
|
41044
|
+
inFlight2.set(modelId, promise3);
|
|
41045
|
+
return promise3;
|
|
41046
|
+
}
|
|
41047
|
+
function requestCatalogContextWindow(modelId, apply) {
|
|
41048
|
+
resolveCatalogContextWindow(modelId).then((cw) => {
|
|
41049
|
+
if (cw === null)
|
|
41050
|
+
return;
|
|
41051
|
+
try {
|
|
41052
|
+
apply(cw);
|
|
41053
|
+
log(`[ContextWindow] Resolved ${modelId} = ${cw} tokens from the cloud catalog`);
|
|
41054
|
+
} catch (err) {
|
|
41055
|
+
log(`[ContextWindow] Failed to apply catalog window for ${modelId}: ${err}`);
|
|
41056
|
+
}
|
|
41057
|
+
});
|
|
41058
|
+
}
|
|
41059
|
+
var defaultFetcher = async (modelId) => {
|
|
41060
|
+
const doc2 = await getModelByIdFromFirebase(modelId);
|
|
41061
|
+
const cw = doc2?.contextWindow;
|
|
41062
|
+
return typeof cw === "number" && cw > 0 ? cw : null;
|
|
41063
|
+
}, fetcher, results, inFlight2;
|
|
41064
|
+
var init_context_window_fallback = __esm(() => {
|
|
41065
|
+
init_logger();
|
|
41066
|
+
init_model_loader();
|
|
41067
|
+
fetcher = defaultFetcher;
|
|
41068
|
+
results = new Map;
|
|
41069
|
+
inFlight2 = new Map;
|
|
41070
|
+
});
|
|
41071
|
+
|
|
40605
41072
|
// src/handlers/shared/stream-head-sniffer.ts
|
|
40606
41073
|
function isRetryableStreamError(code, type, message) {
|
|
40607
41074
|
if (RETRYABLE_ERROR_CODES.has(code))
|
|
@@ -40737,6 +41204,12 @@ var init_stream_head_sniffer = __esm(() => {
|
|
|
40737
41204
|
});
|
|
40738
41205
|
|
|
40739
41206
|
// src/handlers/shared/stream-parsers/anthropic-sse.ts
|
|
41207
|
+
function sseDataPayload(line) {
|
|
41208
|
+
if (!line.startsWith("data:"))
|
|
41209
|
+
return null;
|
|
41210
|
+
const rest = line.slice(5);
|
|
41211
|
+
return rest.startsWith(" ") ? rest.slice(1) : rest;
|
|
41212
|
+
}
|
|
40740
41213
|
function createToolRepairInterceptor(opts) {
|
|
40741
41214
|
const heldTools = new Map;
|
|
40742
41215
|
const flush = (index, stopFrame) => {
|
|
@@ -40809,12 +41282,24 @@ function createAnthropicPassthroughStream(c, response, opts) {
|
|
|
40809
41282
|
let pingInterval = null;
|
|
40810
41283
|
const filterThinking = opts.adapter?.shouldFilterThinking() ?? false;
|
|
40811
41284
|
const interceptToolFrame = createToolRepairInterceptor(opts);
|
|
41285
|
+
let pendingEventLine = null;
|
|
41286
|
+
const flushPendingEvent = (controller) => {
|
|
41287
|
+
if (pendingEventLine !== null && !isClosed) {
|
|
41288
|
+
controller.enqueue(encoder.encode(`${pendingEventLine}
|
|
41289
|
+
`));
|
|
41290
|
+
}
|
|
41291
|
+
pendingEventLine = null;
|
|
41292
|
+
};
|
|
40812
41293
|
const enqueueData = (controller, data, line) => {
|
|
40813
41294
|
if (isClosed)
|
|
40814
41295
|
return;
|
|
40815
41296
|
const out = interceptToolFrame(data, line);
|
|
40816
|
-
if (out
|
|
40817
|
-
|
|
41297
|
+
if (out === null) {
|
|
41298
|
+
pendingEventLine = null;
|
|
41299
|
+
return;
|
|
41300
|
+
}
|
|
41301
|
+
flushPendingEvent(controller);
|
|
41302
|
+
controller.enqueue(encoder.encode(out));
|
|
40818
41303
|
};
|
|
40819
41304
|
return c.body(new ReadableStream({
|
|
40820
41305
|
async start(controller) {
|
|
@@ -40843,6 +41328,7 @@ data: {"type":"ping"}
|
|
|
40843
41328
|
let stopReason = null;
|
|
40844
41329
|
let insideThinkingBlock = false;
|
|
40845
41330
|
let thinkingBlocksSuppressed = 0;
|
|
41331
|
+
let suppressedFrame = false;
|
|
40846
41332
|
while (true) {
|
|
40847
41333
|
const { done, value } = await reader.read();
|
|
40848
41334
|
if (done)
|
|
@@ -40854,9 +41340,10 @@ data: {"type":"ping"}
|
|
|
40854
41340
|
buffer = lines.pop() || "";
|
|
40855
41341
|
for (const line of lines) {
|
|
40856
41342
|
totalLines++;
|
|
40857
|
-
|
|
41343
|
+
const payload = sseDataPayload(line);
|
|
41344
|
+
if (filterThinking && payload !== null) {
|
|
40858
41345
|
try {
|
|
40859
|
-
const data = JSON.parse(
|
|
41346
|
+
const data = JSON.parse(payload);
|
|
40860
41347
|
if (data.error) {
|
|
40861
41348
|
const errMsg = data.error.message || JSON.stringify(data.error);
|
|
40862
41349
|
log(`[AnthropicSSE] In-stream error detected: ${errMsg}`);
|
|
@@ -40881,19 +41368,26 @@ data: ${JSON.stringify({
|
|
|
40881
41368
|
insideThinkingBlock = true;
|
|
40882
41369
|
thinkingBlocksSuppressed++;
|
|
40883
41370
|
log(`[AnthropicSSE] Filtering thinking block at index ${data.index}`);
|
|
41371
|
+
pendingEventLine = null;
|
|
41372
|
+
suppressedFrame = true;
|
|
40884
41373
|
continue;
|
|
40885
41374
|
}
|
|
40886
41375
|
if (insideThinkingBlock && data.type === "content_block_stop") {
|
|
40887
41376
|
insideThinkingBlock = false;
|
|
41377
|
+
pendingEventLine = null;
|
|
41378
|
+
suppressedFrame = true;
|
|
40888
41379
|
continue;
|
|
40889
41380
|
}
|
|
40890
41381
|
if (insideThinkingBlock) {
|
|
41382
|
+
pendingEventLine = null;
|
|
41383
|
+
suppressedFrame = true;
|
|
40891
41384
|
continue;
|
|
40892
41385
|
}
|
|
40893
41386
|
if (typeof data.index === "number" && thinkingBlocksSuppressed > 0) {
|
|
40894
41387
|
const reindexed = data.index - thinkingBlocksSuppressed;
|
|
40895
41388
|
const modifiedLine = `data: ${JSON.stringify({ ...data, index: reindexed })}`;
|
|
40896
41389
|
if (!isClosed) {
|
|
41390
|
+
flushPendingEvent(controller);
|
|
40897
41391
|
controller.enqueue(encoder.encode(`${modifiedLine}
|
|
40898
41392
|
`));
|
|
40899
41393
|
}
|
|
@@ -40902,14 +41396,15 @@ data: ${JSON.stringify({
|
|
|
40902
41396
|
}
|
|
40903
41397
|
} catch {
|
|
40904
41398
|
if (!isClosed) {
|
|
41399
|
+
flushPendingEvent(controller);
|
|
40905
41400
|
controller.enqueue(encoder.encode(`${line}
|
|
40906
41401
|
`));
|
|
40907
41402
|
}
|
|
40908
41403
|
}
|
|
40909
41404
|
} else {
|
|
40910
|
-
if (!filterThinking &&
|
|
41405
|
+
if (!filterThinking && payload !== null) {
|
|
40911
41406
|
try {
|
|
40912
|
-
const data = JSON.parse(
|
|
41407
|
+
const data = JSON.parse(payload);
|
|
40913
41408
|
if (data.error) {
|
|
40914
41409
|
const errMsg = data.error.message || JSON.stringify(data.error);
|
|
40915
41410
|
log(`[AnthropicSSE] In-stream error detected: ${errMsg}`);
|
|
@@ -40941,11 +41436,13 @@ data: ${JSON.stringify({
|
|
|
40941
41436
|
}
|
|
40942
41437
|
if (data.type === "content_block_delta" && data.delta?.type === "text_delta") {
|
|
40943
41438
|
const txt = data.delta.text || "";
|
|
41439
|
+
opts.onAssistantText?.(txt, "text");
|
|
40944
41440
|
textChunks++;
|
|
40945
41441
|
log(`[AnthropicSSE] Text chunk: "${txt.substring(0, 30).replace(/\n/g, "\\n")}" (${txt.length} chars)`);
|
|
40946
41442
|
}
|
|
40947
41443
|
if (data.type === "content_block_start" && data.content_block?.type === "tool_use") {
|
|
40948
41444
|
toolUseBlocks++;
|
|
41445
|
+
opts.onToolCallObserved?.(data.content_block.name);
|
|
40949
41446
|
log(`[AnthropicSSE] Tool use: ${data.content_block.name}`);
|
|
40950
41447
|
}
|
|
40951
41448
|
if (data.type === "message_delta" && data.delta?.stop_reason) {
|
|
@@ -40957,6 +41454,15 @@ data: ${JSON.stringify({
|
|
|
40957
41454
|
`));
|
|
40958
41455
|
}
|
|
40959
41456
|
}
|
|
41457
|
+
} else if (filterThinking) {
|
|
41458
|
+
if (line.startsWith("event:")) {
|
|
41459
|
+
pendingEventLine = line;
|
|
41460
|
+
} else if (line.trim() === "" && suppressedFrame) {
|
|
41461
|
+
suppressedFrame = false;
|
|
41462
|
+
} else if (!isClosed) {
|
|
41463
|
+
controller.enqueue(encoder.encode(`${line}
|
|
41464
|
+
`));
|
|
41465
|
+
}
|
|
40960
41466
|
} else {
|
|
40961
41467
|
if (!isClosed) {
|
|
40962
41468
|
controller.enqueue(encoder.encode(`${line}
|
|
@@ -40964,9 +41470,9 @@ data: ${JSON.stringify({
|
|
|
40964
41470
|
}
|
|
40965
41471
|
}
|
|
40966
41472
|
}
|
|
40967
|
-
if (filterThinking &&
|
|
41473
|
+
if (filterThinking && payload !== null) {
|
|
40968
41474
|
try {
|
|
40969
|
-
const data = JSON.parse(
|
|
41475
|
+
const data = JSON.parse(payload);
|
|
40970
41476
|
if (data.message?.usage) {
|
|
40971
41477
|
inputTokens = data.message.usage.input_tokens || inputTokens;
|
|
40972
41478
|
outputTokens = data.message.usage.output_tokens || outputTokens;
|
|
@@ -40976,10 +41482,12 @@ data: ${JSON.stringify({
|
|
|
40976
41482
|
outputTokens = data.usage.output_tokens || outputTokens;
|
|
40977
41483
|
}
|
|
40978
41484
|
if (data.type === "content_block_delta" && data.delta?.type === "text_delta") {
|
|
41485
|
+
opts.onAssistantText?.(data.delta.text || "", "text");
|
|
40979
41486
|
textChunks++;
|
|
40980
41487
|
}
|
|
40981
41488
|
if (data.type === "content_block_start" && data.content_block?.type === "tool_use") {
|
|
40982
41489
|
toolUseBlocks++;
|
|
41490
|
+
opts.onToolCallObserved?.(data.content_block.name);
|
|
40983
41491
|
log(`[AnthropicSSE] Tool use: ${data.content_block.name}`);
|
|
40984
41492
|
}
|
|
40985
41493
|
if (data.type === "message_delta" && data.delta?.stop_reason) {
|
|
@@ -40990,6 +41498,7 @@ data: ${JSON.stringify({
|
|
|
40990
41498
|
}
|
|
40991
41499
|
}
|
|
40992
41500
|
log(`[AnthropicSSE] Stream complete for ${opts.modelName}: ${totalLines} lines, ${textChunks} text chunks, ${toolUseBlocks} tool_use blocks, stop_reason=${stopReason}${filterThinking ? `, filtered ${thinkingBlocksSuppressed} thinking blocks` : ""}`);
|
|
41501
|
+
opts.onTurnEnd?.();
|
|
40993
41502
|
if (opts.onTokenUpdate) {
|
|
40994
41503
|
opts.onTokenUpdate(inputTokens, outputTokens);
|
|
40995
41504
|
}
|
|
@@ -41118,6 +41627,7 @@ data: ${JSON.stringify(data)}
|
|
|
41118
41627
|
output_tokens: outputTokens
|
|
41119
41628
|
}
|
|
41120
41629
|
});
|
|
41630
|
+
opts.onTurnEnd?.();
|
|
41121
41631
|
send("message_stop", { type: "message_stop" });
|
|
41122
41632
|
}
|
|
41123
41633
|
if (!isClosed) {
|
|
@@ -41225,6 +41735,7 @@ data: ${JSON.stringify(data)}
|
|
|
41225
41735
|
const toolIdx = toolCalls.size;
|
|
41226
41736
|
const toolId = `toolu_${Date.now()}_${toolIdx}`;
|
|
41227
41737
|
const blockIndex = curIdx++;
|
|
41738
|
+
opts.onToolCallObserved?.(part.functionCall.name);
|
|
41228
41739
|
let args = JSON.stringify(part.functionCall.args || {});
|
|
41229
41740
|
if (opts.repairToolArgs) {
|
|
41230
41741
|
try {
|
|
@@ -41563,6 +42074,7 @@ data: ${JSON.stringify(data)}
|
|
|
41563
42074
|
log(`[ResponsesSSE] Event: ${event.type}`);
|
|
41564
42075
|
}
|
|
41565
42076
|
if (event.type === "response.output_text.delta") {
|
|
42077
|
+
opts.onAssistantText?.(event.delta ?? "", "text");
|
|
41566
42078
|
closeReasoning();
|
|
41567
42079
|
if (textIdx < 0) {
|
|
41568
42080
|
textIdx = curIdx++;
|
|
@@ -41598,6 +42110,7 @@ data: ${JSON.stringify(data)}
|
|
|
41598
42110
|
functionCalls.set(itemId, fnCallData);
|
|
41599
42111
|
}
|
|
41600
42112
|
openToolBlocks.add(fnCallData);
|
|
42113
|
+
opts.onToolCallObserved?.(fnName);
|
|
41601
42114
|
if (pendingReasoning.length > 0) {
|
|
41602
42115
|
rememberReasoningForCall(callId, pendingReasoning);
|
|
41603
42116
|
pendingReasoning = [];
|
|
@@ -41610,6 +42123,7 @@ data: ${JSON.stringify(data)}
|
|
|
41610
42123
|
hasToolUse = true;
|
|
41611
42124
|
}
|
|
41612
42125
|
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
42126
|
+
opts.onAssistantText?.(event.delta ?? "", "reasoning");
|
|
41613
42127
|
const summaryIndex = typeof event.summary_index === "number" ? event.summary_index : 0;
|
|
41614
42128
|
if (reasoningIdx < 0) {
|
|
41615
42129
|
closeText();
|
|
@@ -41772,6 +42286,7 @@ data: ${JSON.stringify(data)}
|
|
|
41772
42286
|
if (opts.middlewareManager) {
|
|
41773
42287
|
await opts.middlewareManager.afterStreamComplete(opts.modelName, streamMetadata);
|
|
41774
42288
|
}
|
|
42289
|
+
opts.onTurnEnd?.();
|
|
41775
42290
|
safeClose();
|
|
41776
42291
|
} catch (error46) {
|
|
41777
42292
|
if (pingInterval) {
|
|
@@ -41838,6 +42353,10 @@ var init_openai_responses_sse = __esm(() => {
|
|
|
41838
42353
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
41839
42354
|
import { homedir as homedir22 } from "os";
|
|
41840
42355
|
import { dirname as dirname7, join as join22 } from "path";
|
|
42356
|
+
function stripProviderPrefix(name) {
|
|
42357
|
+
const at = name.indexOf("@");
|
|
42358
|
+
return at === -1 ? name : name.slice(at + 1);
|
|
42359
|
+
}
|
|
41841
42360
|
|
|
41842
42361
|
class TokenTracker {
|
|
41843
42362
|
port;
|
|
@@ -41928,6 +42447,9 @@ class TokenTracker {
|
|
|
41928
42447
|
setContextWindow(contextWindow) {
|
|
41929
42448
|
this.config.contextWindow = contextWindow;
|
|
41930
42449
|
}
|
|
42450
|
+
getContextWindow() {
|
|
42451
|
+
return this.config.contextWindow;
|
|
42452
|
+
}
|
|
41931
42453
|
getTotalCost() {
|
|
41932
42454
|
return this.sessionTotalCost;
|
|
41933
42455
|
}
|
|
@@ -41974,8 +42496,9 @@ class TokenTracker {
|
|
|
41974
42496
|
is_free: isFreeModel,
|
|
41975
42497
|
is_estimated: isEstimate || false
|
|
41976
42498
|
};
|
|
41977
|
-
|
|
41978
|
-
|
|
42499
|
+
const displayModel = stripProviderPrefix(this.modelNameOverride || this.config.modelName || "");
|
|
42500
|
+
if (displayModel) {
|
|
42501
|
+
data.model_name = displayModel;
|
|
41979
42502
|
}
|
|
41980
42503
|
if (this.quotaRemaining !== undefined) {
|
|
41981
42504
|
data.quota_remaining = this.quotaRemaining;
|
|
@@ -42026,7 +42549,7 @@ class ComposedHandler {
|
|
|
42026
42549
|
this.options = options;
|
|
42027
42550
|
this.explicitAdapter = options.adapter;
|
|
42028
42551
|
this.isInteractive = options.isInteractive ?? false;
|
|
42029
|
-
this.adapterManager = new DialectManager(this.bareModelName);
|
|
42552
|
+
this.adapterManager = new DialectManager(this.bareModelName, this.explicitAdapter?.getStreamFormat());
|
|
42030
42553
|
const resolvedModelAdapter = this.adapterManager.getAdapter();
|
|
42031
42554
|
if (resolvedModelAdapter.getName() !== "DefaultAPIFormat") {
|
|
42032
42555
|
this.modelAdapter = resolvedModelAdapter;
|
|
@@ -42209,7 +42732,13 @@ class ComposedHandler {
|
|
|
42209
42732
|
}
|
|
42210
42733
|
}
|
|
42211
42734
|
if (this.provider.getContextWindow) {
|
|
42212
|
-
this.
|
|
42735
|
+
const providerWindow = this.provider.getContextWindow();
|
|
42736
|
+
if (providerWindow > 0) {
|
|
42737
|
+
this.tokenTracker.setContextWindow(providerWindow);
|
|
42738
|
+
}
|
|
42739
|
+
}
|
|
42740
|
+
if (this.tokenTracker.getContextWindow() <= 0) {
|
|
42741
|
+
requestCatalogContextWindow(this.bareModelName, (cw) => this.tokenTracker.setContextWindow(cw));
|
|
42213
42742
|
}
|
|
42214
42743
|
if (this.provider.transformPayload) {
|
|
42215
42744
|
requestPayload = this.provider.transformPayload(requestPayload);
|
|
@@ -42574,7 +43103,10 @@ class ComposedHandler {
|
|
|
42574
43103
|
case "openai-sse":
|
|
42575
43104
|
return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens, behaviorSession && {
|
|
42576
43105
|
shouldBufferTool: (name) => behaviorSession.interceptsTool(name),
|
|
42577
|
-
onToolCall: (name, argsJson) => behaviorSession.repairToolCall(name, argsJson)
|
|
43106
|
+
onToolCall: (name, argsJson) => behaviorSession.repairToolCall(name, argsJson),
|
|
43107
|
+
onAssistantText: (text, kind) => behaviorSession.observeText(text, kind),
|
|
43108
|
+
onToolCallObserved: (name) => behaviorSession.observeToolCall(name),
|
|
43109
|
+
onTurnEnd: () => behaviorSession.finishTurn()
|
|
42578
43110
|
});
|
|
42579
43111
|
case "openai-responses-sse":
|
|
42580
43112
|
return createResponsesStreamHandler(c, response, {
|
|
@@ -42586,15 +43118,21 @@ class ComposedHandler {
|
|
|
42586
43118
|
priorInputTokens,
|
|
42587
43119
|
middlewareManager: this.middlewareManager,
|
|
42588
43120
|
shouldBufferTool: (name) => behaviorSession?.interceptsTool(name) ?? false,
|
|
42589
|
-
onToolCall: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null
|
|
43121
|
+
onToolCall: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null,
|
|
43122
|
+
onAssistantText: (text, kind) => behaviorSession?.observeText(text, kind),
|
|
43123
|
+
onToolCallObserved: (name) => behaviorSession?.observeToolCall(name),
|
|
43124
|
+
onTurnEnd: () => behaviorSession?.finishTurn()
|
|
42590
43125
|
});
|
|
42591
43126
|
case "anthropic-sse":
|
|
42592
43127
|
return createAnthropicPassthroughStream(c, response, {
|
|
42593
43128
|
modelName: this.bareModelName,
|
|
42594
43129
|
onTokenUpdate,
|
|
42595
|
-
adapter,
|
|
43130
|
+
adapter: this.modelAdapter ?? adapter,
|
|
42596
43131
|
shouldBufferTool: (name) => behaviorSession?.interceptsTool(name) ?? false,
|
|
42597
|
-
repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null
|
|
43132
|
+
repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null,
|
|
43133
|
+
onAssistantText: (text, kind) => behaviorSession?.observeText(text, kind),
|
|
43134
|
+
onToolCallObserved: (name) => behaviorSession?.observeToolCall(name),
|
|
43135
|
+
onTurnEnd: () => behaviorSession?.finishTurn()
|
|
42598
43136
|
});
|
|
42599
43137
|
case "gemini-sse": {
|
|
42600
43138
|
const onToolCall = (toolId, name, thoughtSignature) => {
|
|
@@ -42609,6 +43147,9 @@ class ComposedHandler {
|
|
|
42609
43147
|
onTokenUpdate,
|
|
42610
43148
|
onToolCall,
|
|
42611
43149
|
repairToolArgs: (name, argsJson) => behaviorSession?.repairToolCall(name, argsJson) ?? null,
|
|
43150
|
+
onAssistantText: (text, kind) => behaviorSession?.observeText(text, kind),
|
|
43151
|
+
onToolCallObserved: (name) => behaviorSession?.observeToolCall(name),
|
|
43152
|
+
onTurnEnd: () => behaviorSession?.finishTurn(),
|
|
42612
43153
|
unwrapResponse: this.options.unwrapGeminiResponse,
|
|
42613
43154
|
priorInputTokens
|
|
42614
43155
|
});
|
|
@@ -42694,6 +43235,7 @@ var init_composed_handler = __esm(() => {
|
|
|
42694
43235
|
init_transform();
|
|
42695
43236
|
init_anthropic_error();
|
|
42696
43237
|
init_connection_error();
|
|
43238
|
+
init_context_window_fallback();
|
|
42697
43239
|
init_openai_compat();
|
|
42698
43240
|
init_stream_head_sniffer();
|
|
42699
43241
|
init_anthropic_sse();
|
|
@@ -43151,11 +43693,11 @@ ${a.text}`).join(`
|
|
|
43151
43693
|
}
|
|
43152
43694
|
}
|
|
43153
43695
|
async function fetchMultiModelAdvice(_toolUseId, messages, models, collector, apiKeys) {
|
|
43154
|
-
const
|
|
43696
|
+
const results2 = await Promise.allSettled(models.map((model) => callAdvisorModel(model, messages, apiKeys)));
|
|
43155
43697
|
const sections = [];
|
|
43156
43698
|
const successfulAdvice = [];
|
|
43157
43699
|
for (let i = 0;i < models.length; i++) {
|
|
43158
|
-
const result =
|
|
43700
|
+
const result = results2[i];
|
|
43159
43701
|
if (result.status === "fulfilled") {
|
|
43160
43702
|
sections.push(`## ${models[i]}
|
|
43161
43703
|
${result.value}`);
|
|
@@ -43474,6 +44016,7 @@ var init_api_key_map = __esm(() => {
|
|
|
43474
44016
|
envVar: "SAKANA_SUBSCRIPTION_API_KEY",
|
|
43475
44017
|
aliases: ["SAKANA_CODING_API_KEY"]
|
|
43476
44018
|
},
|
|
44019
|
+
"qwen-cloud": { envVar: "QWEN_CLOUD_PLAN_API_KEY" },
|
|
43477
44020
|
ollamacloud: { envVar: "OLLAMA_API_KEY" },
|
|
43478
44021
|
"opencode-zen": { envVar: "OPENCODE_API_KEY" },
|
|
43479
44022
|
"opencode-zen-go": { envVar: "OPENCODE_API_KEY" },
|
|
@@ -43699,90 +44242,127 @@ var init_config_schema = __esm(() => {
|
|
|
43699
44242
|
DefaultProviderSchema = exports_external.union([BuiltinDefaultProviderSchema, exports_external.string().min(1)]);
|
|
43700
44243
|
});
|
|
43701
44244
|
|
|
43702
|
-
// src/providers/
|
|
43703
|
-
|
|
43704
|
-
|
|
43705
|
-
|
|
43706
|
-
|
|
43707
|
-
|
|
43708
|
-
|
|
43709
|
-
|
|
43710
|
-
|
|
43711
|
-
this.apiKey = apiKey;
|
|
43712
|
-
this.name = provider.name;
|
|
43713
|
-
this.displayName = AnthropicProviderTransport.formatDisplayName(provider.name);
|
|
44245
|
+
// src/providers/model-discovery.ts
|
|
44246
|
+
function resolveBaseUrl2(catalogName) {
|
|
44247
|
+
const def = getProviderByName(catalogName);
|
|
44248
|
+
if (!def)
|
|
44249
|
+
return null;
|
|
44250
|
+
for (const envVar of def.baseUrlEnvVars ?? []) {
|
|
44251
|
+
const v = process.env[envVar];
|
|
44252
|
+
if (v)
|
|
44253
|
+
return v.replace(/\/+$/, "");
|
|
43714
44254
|
}
|
|
43715
|
-
|
|
43716
|
-
|
|
44255
|
+
return (def.baseUrl || "").replace(/\/+$/, "") || null;
|
|
44256
|
+
}
|
|
44257
|
+
function readContextWindow(row) {
|
|
44258
|
+
for (const field of ["context_length", "context_window", "max_context_length"]) {
|
|
44259
|
+
const v = row[field];
|
|
44260
|
+
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
44261
|
+
return v;
|
|
43717
44262
|
}
|
|
43718
|
-
|
|
43719
|
-
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
43724
|
-
|
|
43725
|
-
|
|
43726
|
-
|
|
43727
|
-
|
|
43728
|
-
|
|
43729
|
-
|
|
43730
|
-
|
|
43731
|
-
|
|
43732
|
-
|
|
43733
|
-
|
|
43734
|
-
|
|
43735
|
-
|
|
43736
|
-
|
|
43737
|
-
|
|
43738
|
-
|
|
43739
|
-
|
|
43740
|
-
|
|
43741
|
-
|
|
44263
|
+
return;
|
|
44264
|
+
}
|
|
44265
|
+
function readCreatedDate(row) {
|
|
44266
|
+
const raw2 = row.created;
|
|
44267
|
+
const seconds = typeof raw2 === "number" ? raw2 : typeof raw2 === "string" ? Number(raw2) : NaN;
|
|
44268
|
+
if (!Number.isFinite(seconds))
|
|
44269
|
+
return;
|
|
44270
|
+
if (seconds < MIN_CREATED_SECONDS || seconds > MAX_CREATED_SECONDS)
|
|
44271
|
+
return;
|
|
44272
|
+
const iso = new Date(seconds * 1000).toISOString();
|
|
44273
|
+
return iso.slice(0, 10);
|
|
44274
|
+
}
|
|
44275
|
+
function parseOpenAIModelsList(body) {
|
|
44276
|
+
const data = body?.data;
|
|
44277
|
+
if (!Array.isArray(data))
|
|
44278
|
+
return [];
|
|
44279
|
+
const models = [];
|
|
44280
|
+
for (const raw2 of data) {
|
|
44281
|
+
if (!raw2 || typeof raw2 !== "object")
|
|
44282
|
+
continue;
|
|
44283
|
+
const row = raw2;
|
|
44284
|
+
const id = row.id;
|
|
44285
|
+
if (typeof id !== "string" || id.trim().length === 0)
|
|
44286
|
+
continue;
|
|
44287
|
+
const displayName = typeof row.display_name === "string" ? row.display_name : undefined;
|
|
44288
|
+
models.push({
|
|
44289
|
+
id,
|
|
44290
|
+
displayName,
|
|
44291
|
+
contextWindow: readContextWindow(row),
|
|
44292
|
+
releaseDate: readCreatedDate(row)
|
|
44293
|
+
});
|
|
43742
44294
|
}
|
|
43743
|
-
|
|
43744
|
-
|
|
43745
|
-
|
|
43746
|
-
|
|
43747
|
-
|
|
43748
|
-
|
|
43749
|
-
|
|
43750
|
-
|
|
43751
|
-
|
|
43752
|
-
|
|
43753
|
-
|
|
43754
|
-
|
|
43755
|
-
|
|
43756
|
-
|
|
43757
|
-
|
|
43758
|
-
|
|
43759
|
-
|
|
43760
|
-
|
|
43761
|
-
|
|
43762
|
-
|
|
43763
|
-
|
|
43764
|
-
continue;
|
|
43765
|
-
}
|
|
43766
|
-
return response;
|
|
43767
|
-
}
|
|
43768
|
-
return lastResponse;
|
|
44295
|
+
return models;
|
|
44296
|
+
}
|
|
44297
|
+
async function discoverProviderModels(providerName) {
|
|
44298
|
+
const cached2 = _cache.get(providerName);
|
|
44299
|
+
if (cached2 && cached2.expiresAt > Date.now())
|
|
44300
|
+
return cached2.models;
|
|
44301
|
+
const def = getProviderByName(providerName);
|
|
44302
|
+
const descriptor = def?.modelDiscovery;
|
|
44303
|
+
if (!def || !descriptor)
|
|
44304
|
+
return [];
|
|
44305
|
+
const baseUrl = resolveBaseUrl2(providerName);
|
|
44306
|
+
if (!baseUrl)
|
|
44307
|
+
return [];
|
|
44308
|
+
const endpoint = `${baseUrl}${descriptor.path}`;
|
|
44309
|
+
let headers = {};
|
|
44310
|
+
try {
|
|
44311
|
+
const auth = await credentials.getRequestAuth(providerName, { model: "" });
|
|
44312
|
+
headers = { ...auth.headers };
|
|
44313
|
+
} catch (e) {
|
|
44314
|
+
log(`[model-discovery:${providerName}] no credentials, skipping: ${e?.message}`);
|
|
44315
|
+
return [];
|
|
43769
44316
|
}
|
|
43770
|
-
|
|
43771
|
-
|
|
43772
|
-
|
|
43773
|
-
|
|
43774
|
-
|
|
43775
|
-
|
|
43776
|
-
|
|
43777
|
-
|
|
43778
|
-
};
|
|
43779
|
-
return
|
|
44317
|
+
let response;
|
|
44318
|
+
try {
|
|
44319
|
+
response = await fetch(endpoint, {
|
|
44320
|
+
method: "GET",
|
|
44321
|
+
headers,
|
|
44322
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
44323
|
+
});
|
|
44324
|
+
} catch (e) {
|
|
44325
|
+
log(`[model-discovery:${providerName}] fetch failed: ${e?.message}`);
|
|
44326
|
+
return [];
|
|
44327
|
+
}
|
|
44328
|
+
if (!response.ok) {
|
|
44329
|
+
log(`[model-discovery:${providerName}] HTTP ${response.status} from ${endpoint}`);
|
|
44330
|
+
return [];
|
|
43780
44331
|
}
|
|
44332
|
+
let body;
|
|
44333
|
+
try {
|
|
44334
|
+
body = await response.json();
|
|
44335
|
+
} catch {
|
|
44336
|
+
log(`[model-discovery:${providerName}] response was not JSON`);
|
|
44337
|
+
return [];
|
|
44338
|
+
}
|
|
44339
|
+
const models = parseOpenAIModelsList(body);
|
|
44340
|
+
if (models.length === 0) {
|
|
44341
|
+
log(`[model-discovery:${providerName}] endpoint reachable but listed no models`);
|
|
44342
|
+
return [];
|
|
44343
|
+
}
|
|
44344
|
+
log(`[model-discovery:${providerName}] discovered ${models.length} models: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
|
|
44345
|
+
_cache.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
44346
|
+
return models;
|
|
43781
44347
|
}
|
|
43782
|
-
|
|
44348
|
+
async function discoverContextWindow(providerName, modelId) {
|
|
44349
|
+
const models = await discoverProviderModels(providerName);
|
|
44350
|
+
const match2 = models.find((m) => m.id.toLowerCase() === modelId.toLowerCase());
|
|
44351
|
+
return match2?.contextWindow;
|
|
44352
|
+
}
|
|
44353
|
+
function rankDiscoveredModels(models) {
|
|
44354
|
+
return [...models].sort((a, b) => {
|
|
44355
|
+
const diff = (b.contextWindow ?? 0) - (a.contextWindow ?? 0);
|
|
44356
|
+
return diff !== 0 ? diff : a.id.localeCompare(b.id);
|
|
44357
|
+
});
|
|
44358
|
+
}
|
|
44359
|
+
var CACHE_TTL_MS, FETCH_TIMEOUT_MS = 5000, _cache, MIN_CREATED_SECONDS = 946684800, MAX_CREATED_SECONDS = 4102444800;
|
|
44360
|
+
var init_model_discovery = __esm(() => {
|
|
43783
44361
|
init_authority();
|
|
43784
44362
|
init_logger();
|
|
43785
|
-
|
|
44363
|
+
init_provider_definitions();
|
|
44364
|
+
CACHE_TTL_MS = 5 * 60 * 1000;
|
|
44365
|
+
_cache = new Map;
|
|
43786
44366
|
});
|
|
43787
44367
|
|
|
43788
44368
|
// src/providers/transport/probe-discovery.ts
|
|
@@ -43813,11 +44393,11 @@ function rankProbeCandidates(names) {
|
|
|
43813
44393
|
});
|
|
43814
44394
|
}
|
|
43815
44395
|
function cacheGet(key, exclude = new Set) {
|
|
43816
|
-
const hit =
|
|
44396
|
+
const hit = _cache2.get(key);
|
|
43817
44397
|
if (!hit)
|
|
43818
44398
|
return;
|
|
43819
44399
|
if (Date.now() > hit.expiresAt) {
|
|
43820
|
-
|
|
44400
|
+
_cache2.delete(key);
|
|
43821
44401
|
return;
|
|
43822
44402
|
}
|
|
43823
44403
|
if (hit.ranked.length === 0) {
|
|
@@ -43833,10 +44413,10 @@ function cacheGet(key, exclude = new Set) {
|
|
|
43833
44413
|
return { model: pick2 };
|
|
43834
44414
|
}
|
|
43835
44415
|
function cacheSetFailure(key, reason) {
|
|
43836
|
-
|
|
44416
|
+
_cache2.set(key, { ranked: [], reason, expiresAt: Date.now() + CACHE_TTL_MS2 });
|
|
43837
44417
|
}
|
|
43838
44418
|
function cacheSetRanked(key, ranked) {
|
|
43839
|
-
|
|
44419
|
+
_cache2.set(key, { ranked, expiresAt: Date.now() + CACHE_TTL_MS2 });
|
|
43840
44420
|
}
|
|
43841
44421
|
async function discoverViaOpenAIModels(endpoint, headers, cacheKey) {
|
|
43842
44422
|
const cached2 = cacheGet(cacheKey.key, cacheKey.exclude);
|
|
@@ -43847,7 +44427,7 @@ async function discoverViaOpenAIModels(endpoint, headers, cacheKey) {
|
|
|
43847
44427
|
response = await fetch(endpoint, {
|
|
43848
44428
|
method: "GET",
|
|
43849
44429
|
headers,
|
|
43850
|
-
signal: AbortSignal.timeout(
|
|
44430
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
43851
44431
|
});
|
|
43852
44432
|
} catch (e) {
|
|
43853
44433
|
const reason = classifyFetchError(e, endpoint);
|
|
@@ -43901,7 +44481,7 @@ function classifyFetchError(e, endpoint) {
|
|
|
43901
44481
|
const host = url2?.host ?? endpoint;
|
|
43902
44482
|
const isLocal = !!url2 && /^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1)$/i.test(url2.hostname);
|
|
43903
44483
|
if (name === "TimeoutError" || name === "AbortError" || /timeout/i.test(msg)) {
|
|
43904
|
-
return `${host} unresponsive (>${
|
|
44484
|
+
return `${host} unresponsive (>${FETCH_TIMEOUT_MS2 / 1000}s) \u2014 check if the server is overloaded`;
|
|
43905
44485
|
}
|
|
43906
44486
|
if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
|
|
43907
44487
|
return `cannot resolve host ${url2?.hostname ?? endpoint} \u2014 check the URL`;
|
|
@@ -43984,7 +44564,7 @@ async function discoverViaLMStudio(baseUrl, headers, cacheKey) {
|
|
|
43984
44564
|
response = await fetch(`${baseUrl}/api/v0/models`, {
|
|
43985
44565
|
method: "GET",
|
|
43986
44566
|
headers,
|
|
43987
|
-
signal: AbortSignal.timeout(
|
|
44567
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
43988
44568
|
});
|
|
43989
44569
|
} catch (e) {
|
|
43990
44570
|
return discoverViaOpenAIModels(`${baseUrl}/v1/models`, headers, cacheKey);
|
|
@@ -44056,7 +44636,7 @@ function extractLMStudioModels(body) {
|
|
|
44056
44636
|
async function fetchOllamaModels2(url2) {
|
|
44057
44637
|
const response = await fetch(url2, {
|
|
44058
44638
|
method: "GET",
|
|
44059
|
-
signal: AbortSignal.timeout(
|
|
44639
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
44060
44640
|
});
|
|
44061
44641
|
if (!response.ok)
|
|
44062
44642
|
return [];
|
|
@@ -44069,17 +44649,17 @@ async function fetchOllamaModels2(url2) {
|
|
|
44069
44649
|
})).filter((m) => m.name.length > 0);
|
|
44070
44650
|
}
|
|
44071
44651
|
function invalidateProbeDiscovery(providerSlug) {
|
|
44072
|
-
for (const key of
|
|
44652
|
+
for (const key of _cache2.keys()) {
|
|
44073
44653
|
if (key.startsWith(`${providerSlug}:`)) {
|
|
44074
|
-
|
|
44654
|
+
_cache2.delete(key);
|
|
44075
44655
|
}
|
|
44076
44656
|
}
|
|
44077
44657
|
}
|
|
44078
|
-
var
|
|
44658
|
+
var _cache2, CACHE_TTL_MS2, FETCH_TIMEOUT_MS2 = 5000, SMALL_MODEL_PATTERNS, NON_CHAT_PATTERNS, STANDARD_VENDOR_PREFIXES;
|
|
44079
44659
|
var init_probe_discovery = __esm(() => {
|
|
44080
44660
|
init_logger();
|
|
44081
|
-
|
|
44082
|
-
|
|
44661
|
+
_cache2 = new Map;
|
|
44662
|
+
CACHE_TTL_MS2 = 5 * 60 * 1000;
|
|
44083
44663
|
SMALL_MODEL_PATTERNS = [
|
|
44084
44664
|
/\bmini\b/i,
|
|
44085
44665
|
/\bnano\b/i,
|
|
@@ -44127,6 +44707,127 @@ var init_probe_discovery = __esm(() => {
|
|
|
44127
44707
|
];
|
|
44128
44708
|
});
|
|
44129
44709
|
|
|
44710
|
+
// src/providers/transport/anthropic-compat.ts
|
|
44711
|
+
class AnthropicProviderTransport {
|
|
44712
|
+
name;
|
|
44713
|
+
displayName;
|
|
44714
|
+
streamFormat = "anthropic-sse";
|
|
44715
|
+
provider;
|
|
44716
|
+
apiKey;
|
|
44717
|
+
constructor(provider, apiKey) {
|
|
44718
|
+
this.provider = provider;
|
|
44719
|
+
this.apiKey = apiKey;
|
|
44720
|
+
this.name = provider.name;
|
|
44721
|
+
this.displayName = AnthropicProviderTransport.formatDisplayName(provider.name);
|
|
44722
|
+
}
|
|
44723
|
+
getEndpoint() {
|
|
44724
|
+
return `${this.provider.baseUrl}${this.provider.apiPath}`;
|
|
44725
|
+
}
|
|
44726
|
+
async getHeaders() {
|
|
44727
|
+
const headers = {
|
|
44728
|
+
"anthropic-version": "2023-06-01"
|
|
44729
|
+
};
|
|
44730
|
+
if (this.provider.authScheme === "bearer") {
|
|
44731
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
44732
|
+
} else {
|
|
44733
|
+
headers["x-api-key"] = this.apiKey;
|
|
44734
|
+
}
|
|
44735
|
+
if (this.provider.headers) {
|
|
44736
|
+
Object.assign(headers, this.provider.headers);
|
|
44737
|
+
}
|
|
44738
|
+
if (this.provider.name === "kimi-coding") {
|
|
44739
|
+
try {
|
|
44740
|
+
const auth = await credentials.getRequestAuth("kimi-coding", { model: "" });
|
|
44741
|
+
if (auth.headers.Authorization) {
|
|
44742
|
+
delete headers["x-api-key"];
|
|
44743
|
+
}
|
|
44744
|
+
Object.assign(headers, auth.headers);
|
|
44745
|
+
} catch (e) {
|
|
44746
|
+
log(`[${this.displayName}] OAuth path failed, falling back to API key: ${e.message}`);
|
|
44747
|
+
}
|
|
44748
|
+
}
|
|
44749
|
+
return headers;
|
|
44750
|
+
}
|
|
44751
|
+
async discoverProbeModel(exclude) {
|
|
44752
|
+
const def = getProviderByName(this.provider.name);
|
|
44753
|
+
if (!def?.modelDiscovery) {
|
|
44754
|
+
return {
|
|
44755
|
+
model: null,
|
|
44756
|
+
reason: `${this.displayName} publishes no live model list (no modelDiscovery endpoint) \u2014 its probe model must come from the cloud catalog`
|
|
44757
|
+
};
|
|
44758
|
+
}
|
|
44759
|
+
const discovered = await discoverProviderModels(this.provider.name);
|
|
44760
|
+
if (discovered.length === 0) {
|
|
44761
|
+
return {
|
|
44762
|
+
model: null,
|
|
44763
|
+
reason: `${this.displayName} listed no models at ${def.modelDiscovery.path} \u2014 check the API key and that the subscription is active`
|
|
44764
|
+
};
|
|
44765
|
+
}
|
|
44766
|
+
const ranked = rankDiscoveredModels(discovered).map((m) => m.id).filter(isChatCapable);
|
|
44767
|
+
if (ranked.length === 0) {
|
|
44768
|
+
return {
|
|
44769
|
+
model: null,
|
|
44770
|
+
reason: `no chat-capable model among the ${discovered.length} listed by ${this.displayName}`
|
|
44771
|
+
};
|
|
44772
|
+
}
|
|
44773
|
+
const pick2 = ranked.find((m) => !exclude?.has(m));
|
|
44774
|
+
if (!pick2) {
|
|
44775
|
+
return {
|
|
44776
|
+
model: null,
|
|
44777
|
+
reason: `all ${ranked.length} candidate model(s) already tried`
|
|
44778
|
+
};
|
|
44779
|
+
}
|
|
44780
|
+
return { model: pick2 };
|
|
44781
|
+
}
|
|
44782
|
+
async enqueueRequest(fetchFn) {
|
|
44783
|
+
const maxRetries = 2;
|
|
44784
|
+
let lastResponse = null;
|
|
44785
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
44786
|
+
const response = await fetchFn();
|
|
44787
|
+
if (response.status === 429 && attempt < maxRetries) {
|
|
44788
|
+
const bodyText = await response.clone().text().catch(() => "");
|
|
44789
|
+
if (isTerminal429(bodyText)) {
|
|
44790
|
+
log(`[${this.displayName}] 429 is terminal (billing/quota), not retrying`);
|
|
44791
|
+
return response;
|
|
44792
|
+
}
|
|
44793
|
+
lastResponse = response;
|
|
44794
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
44795
|
+
let delayMs;
|
|
44796
|
+
if (retryAfter && !Number.isNaN(Number(retryAfter))) {
|
|
44797
|
+
delayMs = Math.min(Number(retryAfter) * 1000, 2000);
|
|
44798
|
+
} else {
|
|
44799
|
+
delayMs = 500 * (attempt + 1);
|
|
44800
|
+
}
|
|
44801
|
+
log(`[${this.displayName}] 429 rate limited, retry ${attempt + 1}/${maxRetries} in ${(delayMs / 1000).toFixed(1)}s`);
|
|
44802
|
+
await new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
44803
|
+
continue;
|
|
44804
|
+
}
|
|
44805
|
+
return response;
|
|
44806
|
+
}
|
|
44807
|
+
return lastResponse;
|
|
44808
|
+
}
|
|
44809
|
+
static formatDisplayName(name) {
|
|
44810
|
+
const map3 = {
|
|
44811
|
+
minimax: "MiniMax",
|
|
44812
|
+
"minimax-coding": "MiniMax Coding",
|
|
44813
|
+
kimi: "Kimi",
|
|
44814
|
+
"kimi-coding": "Kimi Coding",
|
|
44815
|
+
"qwen-cloud": "Qwen Plan",
|
|
44816
|
+
moonshot: "Kimi",
|
|
44817
|
+
"z-ai": "Z.AI"
|
|
44818
|
+
};
|
|
44819
|
+
return map3[name.toLowerCase()] || name.charAt(0).toUpperCase() + name.slice(1);
|
|
44820
|
+
}
|
|
44821
|
+
}
|
|
44822
|
+
var init_anthropic_compat = __esm(() => {
|
|
44823
|
+
init_authority();
|
|
44824
|
+
init_logger();
|
|
44825
|
+
init_model_discovery();
|
|
44826
|
+
init_provider_definitions();
|
|
44827
|
+
init_openai();
|
|
44828
|
+
init_probe_discovery();
|
|
44829
|
+
});
|
|
44830
|
+
|
|
44130
44831
|
// src/providers/transport/litellm.ts
|
|
44131
44832
|
class LiteLLMProviderTransport {
|
|
44132
44833
|
name = "litellm";
|
|
@@ -44549,14 +45250,14 @@ function resolveApiKeyProvenance(envVar, aliases) {
|
|
|
44549
45250
|
}
|
|
44550
45251
|
return {
|
|
44551
45252
|
envVar: runtimeVar,
|
|
44552
|
-
|
|
45253
|
+
hasValue: !!runtimeValue,
|
|
44553
45254
|
effectiveMasked: maskKey(runtimeValue),
|
|
44554
45255
|
effectiveSource,
|
|
44555
45256
|
layers
|
|
44556
45257
|
};
|
|
44557
45258
|
}
|
|
44558
45259
|
function formatProvenanceLog(p) {
|
|
44559
|
-
if (!p.
|
|
45260
|
+
if (!p.hasValue) {
|
|
44560
45261
|
return `${p.envVar}=(not set)`;
|
|
44561
45262
|
}
|
|
44562
45263
|
return `${p.envVar}=${p.effectiveMasked} [from: ${p.effectiveSource}]`;
|
|
@@ -45324,6 +46025,7 @@ var init_provider_profiles = __esm(() => {
|
|
|
45324
46025
|
"minimax-coding": anthropicCompatProfile,
|
|
45325
46026
|
kimi: anthropicCompatProfile,
|
|
45326
46027
|
"kimi-coding": anthropicCompatProfile,
|
|
46028
|
+
"qwen-cloud": anthropicCompatProfile,
|
|
45327
46029
|
"z-ai": anthropicCompatProfile,
|
|
45328
46030
|
glm: glmProfile,
|
|
45329
46031
|
"glm-coding": glmProfile,
|
|
@@ -46097,7 +46799,7 @@ function loadDiskCache() {
|
|
|
46097
46799
|
return false;
|
|
46098
46800
|
const stat2 = statSync4(CACHE_FILE);
|
|
46099
46801
|
const age = Date.now() - stat2.mtimeMs;
|
|
46100
|
-
const isFresh = age <
|
|
46802
|
+
const isFresh = age < CACHE_TTL_MS3;
|
|
46101
46803
|
const raw2 = readFileSync15(CACHE_FILE, "utf-8");
|
|
46102
46804
|
const data = JSON.parse(raw2);
|
|
46103
46805
|
for (const [key, pricing] of Object.entries(data)) {
|
|
@@ -46108,7 +46810,7 @@ function loadDiskCache() {
|
|
|
46108
46810
|
return false;
|
|
46109
46811
|
}
|
|
46110
46812
|
}
|
|
46111
|
-
var pricingMap, CACHE_DIR, CACHE_FILE,
|
|
46813
|
+
var pricingMap, CACHE_DIR, CACHE_FILE, CACHE_TTL_MS3, cacheWarmed = false;
|
|
46112
46814
|
var init_pricing_cache = __esm(() => {
|
|
46113
46815
|
init_remote_provider_types();
|
|
46114
46816
|
init_logger();
|
|
@@ -46116,7 +46818,7 @@ var init_pricing_cache = __esm(() => {
|
|
|
46116
46818
|
pricingMap = new Map;
|
|
46117
46819
|
CACHE_DIR = join24(homedir24(), ".claudish");
|
|
46118
46820
|
CACHE_FILE = join24(CACHE_DIR, "pricing-cache.json");
|
|
46119
|
-
|
|
46821
|
+
CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
46120
46822
|
});
|
|
46121
46823
|
|
|
46122
46824
|
// src/proxy-server.ts
|
|
@@ -47407,6 +48109,10 @@ function fuzzyScore(text, query) {
|
|
|
47407
48109
|
}
|
|
47408
48110
|
return queryIndex === lowerQuery.length ? score / lowerText.length : 0;
|
|
47409
48111
|
}
|
|
48112
|
+
function orderingKey(model) {
|
|
48113
|
+
const releaseDate = typeof model?.releaseDate === "string" ? model.releaseDate : typeof model?.created === "number" && Number.isFinite(model.created) ? new Date(model.created * 1000).toISOString() : undefined;
|
|
48114
|
+
return { releaseDate, id: typeof model?.id === "string" ? model.id : "" };
|
|
48115
|
+
}
|
|
47410
48116
|
function fmtSize(n) {
|
|
47411
48117
|
if (n <= 0)
|
|
47412
48118
|
return "0B";
|
|
@@ -47634,13 +48340,17 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
|
47634
48340
|
isError: true
|
|
47635
48341
|
};
|
|
47636
48342
|
}
|
|
47637
|
-
const
|
|
48343
|
+
const results2 = allModels.map((model) => {
|
|
47638
48344
|
const nameScore = fuzzyScore(model.name || "", query);
|
|
47639
48345
|
const idScore = fuzzyScore(model.id || "", query);
|
|
47640
48346
|
const descScore = fuzzyScore(model.description || "", query) * 0.5;
|
|
47641
48347
|
return { model, score: Math.max(nameScore, idScore, descScore) };
|
|
47642
|
-
}).filter((item) => item.score > 0.2).sort((a, b) =>
|
|
47643
|
-
|
|
48348
|
+
}).filter((item) => item.score > 0.2).sort((a, b) => {
|
|
48349
|
+
if (Math.abs(a.score - b.score) > SCORE_TIE_EPSILON)
|
|
48350
|
+
return b.score - a.score;
|
|
48351
|
+
return compareByReleaseDateDesc(orderingKey(a.model), orderingKey(b.model));
|
|
48352
|
+
}).slice(0, maxResults);
|
|
48353
|
+
if (results2.length === 0) {
|
|
47644
48354
|
return {
|
|
47645
48355
|
content: [{ type: "text", text: `No models found matching "${query}"` }]
|
|
47646
48356
|
};
|
|
@@ -47652,7 +48362,7 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
|
47652
48362
|
`;
|
|
47653
48363
|
output += `|-------|----------|---------|----------|
|
|
47654
48364
|
`;
|
|
47655
|
-
for (const { model } of
|
|
48365
|
+
for (const { model } of results2) {
|
|
47656
48366
|
const provider = model.id.split("/")[0];
|
|
47657
48367
|
const promptPrice = Number.parseFloat(model.pricing?.prompt || "0") * 1e6;
|
|
47658
48368
|
const completionPrice = Number.parseFloat(model.pricing?.completion || "0") * 1e6;
|
|
@@ -47663,7 +48373,7 @@ Tokens: ${result.usage.input} input, ${result.usage.output} output`;
|
|
|
47663
48373
|
`;
|
|
47664
48374
|
}
|
|
47665
48375
|
output += `
|
|
47666
|
-
Use with: run_prompt(model="${
|
|
48376
|
+
Use with: run_prompt(model="${results2[0].model.id}", prompt="your prompt")`;
|
|
47667
48377
|
return { content: [{ type: "text", text: output }] };
|
|
47668
48378
|
}
|
|
47669
48379
|
});
|
|
@@ -47693,13 +48403,13 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
47693
48403
|
const prompt = args.prompt;
|
|
47694
48404
|
const systemPrompt = args.system_prompt;
|
|
47695
48405
|
const maxTokens = args.max_tokens;
|
|
47696
|
-
const
|
|
48406
|
+
const results2 = [];
|
|
47697
48407
|
for (const model of modelIds) {
|
|
47698
48408
|
try {
|
|
47699
48409
|
const result = await runPromptViaProxy(model, prompt, systemPrompt, maxTokens);
|
|
47700
|
-
|
|
48410
|
+
results2.push({ model, response: result.content, tokens: result.usage });
|
|
47701
48411
|
} catch (error46) {
|
|
47702
|
-
|
|
48412
|
+
results2.push({
|
|
47703
48413
|
model,
|
|
47704
48414
|
response: "",
|
|
47705
48415
|
error: error46 instanceof Error ? error46.message : String(error46)
|
|
@@ -47712,7 +48422,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
47712
48422
|
output += `**Prompt:** ${prompt.slice(0, 100)}${prompt.length > 100 ? "..." : ""}
|
|
47713
48423
|
|
|
47714
48424
|
`;
|
|
47715
|
-
for (const result of
|
|
48425
|
+
for (const result of results2) {
|
|
47716
48426
|
output += `## ${result.model}
|
|
47717
48427
|
|
|
47718
48428
|
`;
|
|
@@ -47734,7 +48444,7 @@ Use with: run_prompt(model="${results[0].model.id}", prompt="your prompt")`;
|
|
|
47734
48444
|
|
|
47735
48445
|
`;
|
|
47736
48446
|
}
|
|
47737
|
-
const failed =
|
|
48447
|
+
const failed = results2.filter((r) => r.error);
|
|
47738
48448
|
if (failed.length > 0) {
|
|
47739
48449
|
output += '---\n**To report failed model(s)**, use the `report_error` tool with `error_type: "provider_failure"` and the model ID(s) above.\n';
|
|
47740
48450
|
}
|
|
@@ -48296,7 +49006,7 @@ When channel mode is active, you receive <channel source="claudish" ...> notific
|
|
|
48296
49006
|
5. Use list_sessions to see all active/completed sessions.
|
|
48297
49007
|
6. Use cancel_session to stop a running session.
|
|
48298
49008
|
|
|
48299
|
-
The session_id in the channel tag's meta attributes is the key for all tool calls.`, proxyInstance = null, proxyStarting = null, NEXT_STEP, sanitize, EVENT_TO_TASK_STATUS;
|
|
49009
|
+
The session_id in the channel tag's meta attributes is the key for all tool calls.`, proxyInstance = null, proxyStarting = null, SCORE_TIE_EPSILON = 0.000001, NEXT_STEP, sanitize, EVENT_TO_TASK_STATUS;
|
|
48300
49010
|
var init_mcp_server = __esm(() => {
|
|
48301
49011
|
init_server2();
|
|
48302
49012
|
init_stdio2();
|
|
@@ -48482,6 +49192,28 @@ Behavior rules
|
|
|
48482
49192
|
console.log(` ${dim2(`observer model: ${obs.model}`)}`);
|
|
48483
49193
|
console.log();
|
|
48484
49194
|
}
|
|
49195
|
+
function printByModel(records) {
|
|
49196
|
+
const byModel = new Map;
|
|
49197
|
+
for (const r of records) {
|
|
49198
|
+
const m = r.model ?? "unknown";
|
|
49199
|
+
const e = byModel.get(m) ?? { ok: 0, degraded: 0 };
|
|
49200
|
+
if (r.outcome === "degraded")
|
|
49201
|
+
e.degraded++;
|
|
49202
|
+
else
|
|
49203
|
+
e.ok++;
|
|
49204
|
+
byModel.set(m, e);
|
|
49205
|
+
}
|
|
49206
|
+
if (byModel.size === 0)
|
|
49207
|
+
return;
|
|
49208
|
+
console.log(bold2(` by model (degraded / ok)
|
|
49209
|
+
`));
|
|
49210
|
+
const ranked = [...byModel.entries()].sort((a, b) => b[1].degraded - a[1].degraded || b[1].ok - a[1].ok);
|
|
49211
|
+
for (const [model, v] of ranked) {
|
|
49212
|
+
const flag = v.degraded > 0 ? yellow(String(v.degraded)) : dim2(String(v.degraded));
|
|
49213
|
+
console.log(` ${model.padEnd(26)} ${flag} / ${v.ok}`);
|
|
49214
|
+
}
|
|
49215
|
+
console.log();
|
|
49216
|
+
}
|
|
48485
49217
|
function showCorpus(write, json2) {
|
|
48486
49218
|
const result = buildCorpus({ write });
|
|
48487
49219
|
if (json2) {
|
|
@@ -48500,25 +49232,7 @@ Behavior divergence corpus
|
|
|
48500
49232
|
console.log(` ${yellow("degraded (no plan)")} : ${degraded.length}`);
|
|
48501
49233
|
console.log(` of those, a rule would have fired on ${catchable.length}
|
|
48502
49234
|
`);
|
|
48503
|
-
|
|
48504
|
-
for (const r of result.records) {
|
|
48505
|
-
const m = r.model ?? "unknown";
|
|
48506
|
-
const e = byModel.get(m) ?? { ok: 0, degraded: 0 };
|
|
48507
|
-
if (r.outcome === "degraded")
|
|
48508
|
-
e.degraded++;
|
|
48509
|
-
else
|
|
48510
|
-
e.ok++;
|
|
48511
|
-
byModel.set(m, e);
|
|
48512
|
-
}
|
|
48513
|
-
if (byModel.size > 0) {
|
|
48514
|
-
console.log(bold2(` by model (degraded / ok)
|
|
48515
|
-
`));
|
|
48516
|
-
for (const [model, v] of [...byModel.entries()].sort((a, b) => b[1].degraded - a[1].degraded || b[1].ok - a[1].ok)) {
|
|
48517
|
-
const flag = v.degraded > 0 ? yellow(String(v.degraded)) : dim2("0");
|
|
48518
|
-
console.log(` ${model.padEnd(26)} ${flag} / ${v.ok}`);
|
|
48519
|
-
}
|
|
48520
|
-
console.log();
|
|
48521
|
-
}
|
|
49235
|
+
printByModel(result.records);
|
|
48522
49236
|
if (result.outputPath) {
|
|
48523
49237
|
console.log(dim2(` appended to ${result.outputPath}
|
|
48524
49238
|
`));
|
|
@@ -48544,9 +49258,9 @@ async function behaviorCommand(argv) {
|
|
|
48544
49258
|
default:
|
|
48545
49259
|
console.error(`Unknown action "${action}".
|
|
48546
49260
|
|
|
48547
|
-
|
|
48548
|
-
|
|
48549
|
-
|
|
49261
|
+
Usage:
|
|
49262
|
+
claudish behavior rules [--json]
|
|
49263
|
+
claudish behavior corpus [--write] [--json]
|
|
48550
49264
|
`);
|
|
48551
49265
|
process.exit(1);
|
|
48552
49266
|
}
|
|
@@ -60761,13 +61475,13 @@ var init_dist14 = __esm(() => {
|
|
|
60761
61475
|
setSearchError(undefined);
|
|
60762
61476
|
const fetchResults = async () => {
|
|
60763
61477
|
try {
|
|
60764
|
-
const
|
|
61478
|
+
const results2 = await config3.source(searchTerm || undefined, {
|
|
60765
61479
|
signal: controller.signal
|
|
60766
61480
|
});
|
|
60767
61481
|
if (!controller.signal.aborted) {
|
|
60768
61482
|
setActive(undefined);
|
|
60769
61483
|
setSearchError(undefined);
|
|
60770
|
-
setSearchResults(normalizeChoices4(
|
|
61484
|
+
setSearchResults(normalizeChoices4(results2));
|
|
60771
61485
|
setStatus("idle");
|
|
60772
61486
|
}
|
|
60773
61487
|
} catch (error47) {
|
|
@@ -61475,6 +62189,8 @@ var init_config2 = __esm(() => {
|
|
|
61475
62189
|
CLAUDISH_MODEL: "CLAUDISH_MODEL",
|
|
61476
62190
|
CLAUDISH_PORT: "CLAUDISH_PORT",
|
|
61477
62191
|
CLAUDISH_ACTIVE_MODEL_NAME: "CLAUDISH_ACTIVE_MODEL_NAME",
|
|
62192
|
+
CLAUDISH_TOKEN_FILE: "CLAUDISH_TOKEN_FILE",
|
|
62193
|
+
CLAUDISH_PROVIDER_NAME: "CLAUDISH_PROVIDER_NAME",
|
|
61478
62194
|
ANTHROPIC_MODEL: "ANTHROPIC_MODEL",
|
|
61479
62195
|
ANTHROPIC_SMALL_FAST_MODEL: "ANTHROPIC_SMALL_FAST_MODEL",
|
|
61480
62196
|
CLAUDISH_MODEL_OPUS: "CLAUDISH_MODEL_OPUS",
|
|
@@ -61655,114 +62371,6 @@ var init_model_catalog2 = __esm(() => {
|
|
|
61655
62371
|
NO_CATALOG_VENDOR_SLUGS = new Set(["litellm", "ollama", "lmstudio", "lm-studio"]);
|
|
61656
62372
|
});
|
|
61657
62373
|
|
|
61658
|
-
// src/providers/model-discovery.ts
|
|
61659
|
-
function resolveBaseUrl2(catalogName) {
|
|
61660
|
-
const def = getProviderByName(catalogName);
|
|
61661
|
-
if (!def)
|
|
61662
|
-
return null;
|
|
61663
|
-
for (const envVar of def.baseUrlEnvVars ?? []) {
|
|
61664
|
-
const v = process.env[envVar];
|
|
61665
|
-
if (v)
|
|
61666
|
-
return v.replace(/\/+$/, "");
|
|
61667
|
-
}
|
|
61668
|
-
return (def.baseUrl || "").replace(/\/+$/, "") || null;
|
|
61669
|
-
}
|
|
61670
|
-
function readContextWindow(row) {
|
|
61671
|
-
for (const field of ["context_length", "context_window", "max_context_length"]) {
|
|
61672
|
-
const v = row[field];
|
|
61673
|
-
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
61674
|
-
return v;
|
|
61675
|
-
}
|
|
61676
|
-
return;
|
|
61677
|
-
}
|
|
61678
|
-
function parseOpenAIModelsList(body) {
|
|
61679
|
-
const data = body?.data;
|
|
61680
|
-
if (!Array.isArray(data))
|
|
61681
|
-
return [];
|
|
61682
|
-
const models = [];
|
|
61683
|
-
for (const raw2 of data) {
|
|
61684
|
-
if (!raw2 || typeof raw2 !== "object")
|
|
61685
|
-
continue;
|
|
61686
|
-
const row = raw2;
|
|
61687
|
-
const id = row.id;
|
|
61688
|
-
if (typeof id !== "string" || id.trim().length === 0)
|
|
61689
|
-
continue;
|
|
61690
|
-
const displayName = typeof row.display_name === "string" ? row.display_name : undefined;
|
|
61691
|
-
models.push({ id, displayName, contextWindow: readContextWindow(row) });
|
|
61692
|
-
}
|
|
61693
|
-
return models;
|
|
61694
|
-
}
|
|
61695
|
-
async function discoverProviderModels(providerName) {
|
|
61696
|
-
const cached2 = _cache2.get(providerName);
|
|
61697
|
-
if (cached2 && cached2.expiresAt > Date.now())
|
|
61698
|
-
return cached2.models;
|
|
61699
|
-
const def = getProviderByName(providerName);
|
|
61700
|
-
const descriptor = def?.modelDiscovery;
|
|
61701
|
-
if (!def || !descriptor)
|
|
61702
|
-
return [];
|
|
61703
|
-
const baseUrl = resolveBaseUrl2(providerName);
|
|
61704
|
-
if (!baseUrl)
|
|
61705
|
-
return [];
|
|
61706
|
-
const endpoint = `${baseUrl}${descriptor.path}`;
|
|
61707
|
-
let headers = {};
|
|
61708
|
-
try {
|
|
61709
|
-
const auth = await credentials.getRequestAuth(providerName, { model: "" });
|
|
61710
|
-
headers = { ...auth.headers };
|
|
61711
|
-
} catch (e) {
|
|
61712
|
-
log(`[model-discovery:${providerName}] no credentials, skipping: ${e?.message}`);
|
|
61713
|
-
return [];
|
|
61714
|
-
}
|
|
61715
|
-
let response;
|
|
61716
|
-
try {
|
|
61717
|
-
response = await fetch(endpoint, {
|
|
61718
|
-
method: "GET",
|
|
61719
|
-
headers,
|
|
61720
|
-
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
61721
|
-
});
|
|
61722
|
-
} catch (e) {
|
|
61723
|
-
log(`[model-discovery:${providerName}] fetch failed: ${e?.message}`);
|
|
61724
|
-
return [];
|
|
61725
|
-
}
|
|
61726
|
-
if (!response.ok) {
|
|
61727
|
-
log(`[model-discovery:${providerName}] HTTP ${response.status} from ${endpoint}`);
|
|
61728
|
-
return [];
|
|
61729
|
-
}
|
|
61730
|
-
let body;
|
|
61731
|
-
try {
|
|
61732
|
-
body = await response.json();
|
|
61733
|
-
} catch {
|
|
61734
|
-
log(`[model-discovery:${providerName}] response was not JSON`);
|
|
61735
|
-
return [];
|
|
61736
|
-
}
|
|
61737
|
-
const models = parseOpenAIModelsList(body);
|
|
61738
|
-
if (models.length === 0) {
|
|
61739
|
-
log(`[model-discovery:${providerName}] endpoint reachable but listed no models`);
|
|
61740
|
-
return [];
|
|
61741
|
-
}
|
|
61742
|
-
log(`[model-discovery:${providerName}] discovered ${models.length} models: ` + models.map((m) => `${m.id}(${m.contextWindow ?? "?"})`).join(", "));
|
|
61743
|
-
_cache2.set(providerName, { models, expiresAt: Date.now() + CACHE_TTL_MS3 });
|
|
61744
|
-
return models;
|
|
61745
|
-
}
|
|
61746
|
-
async function discoverContextWindow(providerName, modelId) {
|
|
61747
|
-
const models = await discoverProviderModels(providerName);
|
|
61748
|
-
const match2 = models.find((m) => m.id.toLowerCase() === modelId.toLowerCase());
|
|
61749
|
-
return match2?.contextWindow;
|
|
61750
|
-
}
|
|
61751
|
-
function rankDiscoveredModels(models) {
|
|
61752
|
-
return [...models].sort((a, b) => {
|
|
61753
|
-
const diff = (b.contextWindow ?? 0) - (a.contextWindow ?? 0);
|
|
61754
|
-
return diff !== 0 ? diff : a.id.localeCompare(b.id);
|
|
61755
|
-
});
|
|
61756
|
-
}
|
|
61757
|
-
var CACHE_TTL_MS3, FETCH_TIMEOUT_MS2 = 5000, _cache2;
|
|
61758
|
-
var init_model_discovery = __esm(() => {
|
|
61759
|
-
init_authority();
|
|
61760
|
-
init_logger();
|
|
61761
|
-
init_provider_definitions();
|
|
61762
|
-
CACHE_TTL_MS3 = 5 * 60 * 1000;
|
|
61763
|
-
_cache2 = new Map;
|
|
61764
|
-
});
|
|
61765
|
-
|
|
61766
62374
|
// src/model-selector.ts
|
|
61767
62375
|
var exports_model_selector = {};
|
|
61768
62376
|
__export(exports_model_selector, {
|
|
@@ -61778,7 +62386,8 @@ __export(exports_model_selector, {
|
|
|
61778
62386
|
isUserDeployedProvider: () => isUserDeployedProvider,
|
|
61779
62387
|
confirmAction: () => confirmAction,
|
|
61780
62388
|
compareByReleaseDateDesc: () => compareByReleaseDateDesc,
|
|
61781
|
-
buildExplicitModelSpec: () => buildExplicitModelSpec
|
|
62389
|
+
buildExplicitModelSpec: () => buildExplicitModelSpec,
|
|
62390
|
+
buildDiscoveredModelRows: () => buildDiscoveredModelRows
|
|
61782
62391
|
});
|
|
61783
62392
|
function isUserDeployedProvider(value) {
|
|
61784
62393
|
return LOCAL_OR_USER_DEPLOYED.has(value);
|
|
@@ -61810,7 +62419,7 @@ function formatFirebaseProviderLabel(slug) {
|
|
|
61810
62419
|
async function loadRecommendedModels(forceRefresh = false) {
|
|
61811
62420
|
try {
|
|
61812
62421
|
const doc2 = await getRecommendedModels({ forceRefresh });
|
|
61813
|
-
return doc2.models.map((model) => ({
|
|
62422
|
+
return sortModelsNewestFirst(doc2.models.map((model) => ({
|
|
61814
62423
|
id: model.id,
|
|
61815
62424
|
name: model.name,
|
|
61816
62425
|
description: model.description,
|
|
@@ -61823,7 +62432,7 @@ async function loadRecommendedModels(forceRefresh = false) {
|
|
|
61823
62432
|
supportsReasoning: model.supportsReasoning,
|
|
61824
62433
|
supportsVision: model.supportsVision,
|
|
61825
62434
|
source: formatFirebaseProviderLabel(model.provider)
|
|
61826
|
-
}));
|
|
62435
|
+
})));
|
|
61827
62436
|
} catch {
|
|
61828
62437
|
return [];
|
|
61829
62438
|
}
|
|
@@ -61867,6 +62476,48 @@ function formatAveragePricing(pricing) {
|
|
|
61867
62476
|
average: avg === 0 ? "FREE" : `$${avg.toFixed(2)}/1M`
|
|
61868
62477
|
};
|
|
61869
62478
|
}
|
|
62479
|
+
function resolveDiscoveredContextLength(m) {
|
|
62480
|
+
if (typeof m.contextWindow === "number" && m.contextWindow > 0)
|
|
62481
|
+
return m.contextWindow;
|
|
62482
|
+
try {
|
|
62483
|
+
return lookupModel(m.id)?.contextWindow ?? 0;
|
|
62484
|
+
} catch {
|
|
62485
|
+
return 0;
|
|
62486
|
+
}
|
|
62487
|
+
}
|
|
62488
|
+
function resolveDiscoveredReleaseDate(m) {
|
|
62489
|
+
try {
|
|
62490
|
+
const catalogDate = lookupModel(m.id)?.releaseDate;
|
|
62491
|
+
if (catalogDate)
|
|
62492
|
+
return catalogDate;
|
|
62493
|
+
} catch {}
|
|
62494
|
+
return m.releaseDate;
|
|
62495
|
+
}
|
|
62496
|
+
async function resolveMissingContextWindows(ids, timeoutMs = DISCOVERY_CONTEXT_LOOKUP_TIMEOUT_MS) {
|
|
62497
|
+
const resolved = new Map;
|
|
62498
|
+
if (ids.length === 0)
|
|
62499
|
+
return resolved;
|
|
62500
|
+
let timer;
|
|
62501
|
+
const budget = new Promise((resolve4) => {
|
|
62502
|
+
timer = setTimeout(() => resolve4(null), timeoutMs);
|
|
62503
|
+
timer.unref?.();
|
|
62504
|
+
});
|
|
62505
|
+
try {
|
|
62506
|
+
const lookups = Promise.all(ids.map(async (id) => [id, await resolveCatalogContextWindow(id)]));
|
|
62507
|
+
const settled = await Promise.race([lookups, budget]);
|
|
62508
|
+
if (settled) {
|
|
62509
|
+
for (const [id, contextWindow] of settled) {
|
|
62510
|
+
if (typeof contextWindow === "number" && contextWindow > 0) {
|
|
62511
|
+
resolved.set(id, contextWindow);
|
|
62512
|
+
}
|
|
62513
|
+
}
|
|
62514
|
+
}
|
|
62515
|
+
} catch {} finally {
|
|
62516
|
+
if (timer)
|
|
62517
|
+
clearTimeout(timer);
|
|
62518
|
+
}
|
|
62519
|
+
return resolved;
|
|
62520
|
+
}
|
|
61870
62521
|
function modelDocToModelInfo(model) {
|
|
61871
62522
|
const providerLabel = formatFirebaseProviderLabel(model.provider || "unknown");
|
|
61872
62523
|
const contextLength = model.contextWindow || 0;
|
|
@@ -61918,63 +62569,6 @@ function dedupeModels(models) {
|
|
|
61918
62569
|
}
|
|
61919
62570
|
return deduped;
|
|
61920
62571
|
}
|
|
61921
|
-
function extractVersionParts(modelId) {
|
|
61922
|
-
const tokens = modelId.toLowerCase().split(/[\/_-]+/);
|
|
61923
|
-
let started = false;
|
|
61924
|
-
const parts = [];
|
|
61925
|
-
for (const token of tokens) {
|
|
61926
|
-
const match2 = token.match(/\d+(?:\.\d+)*/);
|
|
61927
|
-
if (!match2) {
|
|
61928
|
-
if (started)
|
|
61929
|
-
break;
|
|
61930
|
-
continue;
|
|
61931
|
-
}
|
|
61932
|
-
if (!started) {
|
|
61933
|
-
started = true;
|
|
61934
|
-
for (const part of match2[0].split(".")) {
|
|
61935
|
-
parts.push(Number.parseInt(part, 10));
|
|
61936
|
-
}
|
|
61937
|
-
if (!/^\d+(?:\.\d+)*$/.test(token)) {
|
|
61938
|
-
break;
|
|
61939
|
-
}
|
|
61940
|
-
continue;
|
|
61941
|
-
}
|
|
61942
|
-
if (!/^\d{1,2}(?:\.\d+)?$/.test(token)) {
|
|
61943
|
-
break;
|
|
61944
|
-
}
|
|
61945
|
-
for (const part of token.split(".")) {
|
|
61946
|
-
parts.push(Number.parseInt(part, 10));
|
|
61947
|
-
}
|
|
61948
|
-
}
|
|
61949
|
-
return parts;
|
|
61950
|
-
}
|
|
61951
|
-
function compareVersionPartsDesc(a, b) {
|
|
61952
|
-
const maxLength = Math.max(a.length, b.length);
|
|
61953
|
-
for (let i = 0;i < maxLength; i++) {
|
|
61954
|
-
const aPart = a[i] ?? -1;
|
|
61955
|
-
const bPart = b[i] ?? -1;
|
|
61956
|
-
if (aPart !== bPart) {
|
|
61957
|
-
return bPart - aPart;
|
|
61958
|
-
}
|
|
61959
|
-
}
|
|
61960
|
-
return 0;
|
|
61961
|
-
}
|
|
61962
|
-
function compareByReleaseDateDesc(a, b) {
|
|
61963
|
-
const aReleaseRaw = a.releaseDate ? Date.parse(a.releaseDate) : 0;
|
|
61964
|
-
const bReleaseRaw = b.releaseDate ? Date.parse(b.releaseDate) : 0;
|
|
61965
|
-
const aRelease = Number.isNaN(aReleaseRaw) ? 0 : aReleaseRaw;
|
|
61966
|
-
const bRelease = Number.isNaN(bReleaseRaw) ? 0 : bReleaseRaw;
|
|
61967
|
-
if (aRelease !== bRelease) {
|
|
61968
|
-
return bRelease - aRelease;
|
|
61969
|
-
}
|
|
61970
|
-
const aId = a.id ?? a.modelId ?? "";
|
|
61971
|
-
const bId = b.id ?? b.modelId ?? "";
|
|
61972
|
-
const versionCompare = compareVersionPartsDesc(extractVersionParts(aId), extractVersionParts(bId));
|
|
61973
|
-
if (versionCompare !== 0) {
|
|
61974
|
-
return versionCompare;
|
|
61975
|
-
}
|
|
61976
|
-
return aId.localeCompare(bId);
|
|
61977
|
-
}
|
|
61978
62572
|
function sortModelsNewestFirst(models) {
|
|
61979
62573
|
return [...models].sort(compareByReleaseDateDesc);
|
|
61980
62574
|
}
|
|
@@ -62272,22 +62866,42 @@ async function pickModelFromList(provider, displayName, tierName, models) {
|
|
|
62272
62866
|
});
|
|
62273
62867
|
return selected === CUSTOM_VALUE ? null : selected;
|
|
62274
62868
|
}
|
|
62869
|
+
async function buildDiscoveredModelRows(provider, displayName, catalog) {
|
|
62870
|
+
const discovered = rankDiscoveredModels(await discoverProviderModels(provider)).filter((m) => isChatCapable(m.id));
|
|
62871
|
+
if (discovered.length === 0)
|
|
62872
|
+
return [];
|
|
62873
|
+
const subscription = isSubscriptionProvider(provider);
|
|
62874
|
+
const pricingById = subscription ? new Map : new Map((await loadModelsForPickerProvider(provider, catalog)).map((m) => [
|
|
62875
|
+
m.id.toLowerCase(),
|
|
62876
|
+
m.pricing
|
|
62877
|
+
]));
|
|
62878
|
+
const offlineContext = new Map(discovered.map((m) => [m.id, resolveDiscoveredContextLength(m)]));
|
|
62879
|
+
const cloudContext = await resolveMissingContextWindows(discovered.filter((m) => !offlineContext.get(m.id)).map((m) => m.id));
|
|
62880
|
+
const rows = discovered.map((m) => {
|
|
62881
|
+
const contextLength = offlineContext.get(m.id) || cloudContext.get(m.id) || 0;
|
|
62882
|
+
return {
|
|
62883
|
+
id: m.id,
|
|
62884
|
+
name: m.displayName || m.id,
|
|
62885
|
+
description: contextLength ? `${m.displayName ?? m.id} \xB7 ${Math.round(contextLength / 1024)}K context` : m.displayName ?? m.id,
|
|
62886
|
+
provider: displayName,
|
|
62887
|
+
releaseDate: resolveDiscoveredReleaseDate(m),
|
|
62888
|
+
pricing: subscription ? SUBSCRIPTION_PRICING : pricingById.get(m.id.toLowerCase()),
|
|
62889
|
+
context: formatContextLength(contextLength),
|
|
62890
|
+
contextLength,
|
|
62891
|
+
supportsTools: true,
|
|
62892
|
+
isFree: subscription,
|
|
62893
|
+
source: displayName
|
|
62894
|
+
};
|
|
62895
|
+
});
|
|
62896
|
+
return sortModelsNewestFirst(rows);
|
|
62897
|
+
}
|
|
62275
62898
|
async function selectModelFromProvider(provider, tierName, recommendedModels, _forceUpdate, catalog) {
|
|
62276
62899
|
const prefix = PROVIDER_MODEL_PREFIX[provider] || `${provider}@`;
|
|
62277
62900
|
const displayName = getPickerDisplayName(provider);
|
|
62278
62901
|
const def = getProviderByName(provider);
|
|
62279
62902
|
if (def?.modelDiscovery) {
|
|
62280
|
-
const
|
|
62281
|
-
if (
|
|
62282
|
-
const discoveredModels = discovered.map((m) => ({
|
|
62283
|
-
id: m.id,
|
|
62284
|
-
name: m.displayName || m.id,
|
|
62285
|
-
description: m.contextWindow ? `${m.displayName ?? m.id} \xB7 ${Math.round(m.contextWindow / 1024)}K context` : m.displayName ?? m.id,
|
|
62286
|
-
provider: displayName,
|
|
62287
|
-
supportsTools: true,
|
|
62288
|
-
isFree: true,
|
|
62289
|
-
source: displayName
|
|
62290
|
-
}));
|
|
62903
|
+
const discoveredModels = await buildDiscoveredModelRows(provider, displayName, catalog);
|
|
62904
|
+
if (discoveredModels.length > 0) {
|
|
62291
62905
|
const picked = await pickModelFromList(provider, displayName, tierName, discoveredModels);
|
|
62292
62906
|
if (picked)
|
|
62293
62907
|
return picked;
|
|
@@ -62295,7 +62909,7 @@ async function selectModelFromProvider(provider, tierName, recommendedModels, _f
|
|
|
62295
62909
|
}
|
|
62296
62910
|
if (provider === "ollama") {
|
|
62297
62911
|
const ollamaModels = await fetchOllamaModels({ enrichCapabilities: false });
|
|
62298
|
-
const chatModels = ollamaModels.map((m) => ({
|
|
62912
|
+
const chatModels = sortModelsNewestFirst(ollamaModels.map((m) => ({
|
|
62299
62913
|
id: m.name,
|
|
62300
62914
|
name: m.name,
|
|
62301
62915
|
description: m.description,
|
|
@@ -62303,7 +62917,7 @@ async function selectModelFromProvider(provider, tierName, recommendedModels, _f
|
|
|
62303
62917
|
supportsTools: m.supportsTools,
|
|
62304
62918
|
isFree: true,
|
|
62305
62919
|
source: displayName
|
|
62306
|
-
}));
|
|
62920
|
+
})));
|
|
62307
62921
|
if (chatModels.length > 0) {
|
|
62308
62922
|
const picked = await pickModelFromList(provider, displayName, tierName, chatModels);
|
|
62309
62923
|
if (picked)
|
|
@@ -62464,14 +63078,18 @@ async function selectProfile(profiles) {
|
|
|
62464
63078
|
async function confirmAction(message) {
|
|
62465
63079
|
return dist_default4({ message, default: false });
|
|
62466
63080
|
}
|
|
62467
|
-
var pickerProviderToFirebaseSlug, LOCAL_OR_USER_DEPLOYED, PROVIDER_FILTER_ALIASES, ALL_PROVIDER_CHOICES, PROVIDER_MODEL_PREFIX;
|
|
63081
|
+
var pickerProviderToFirebaseSlug, LOCAL_OR_USER_DEPLOYED, SUBSCRIPTION_PRICING, DISCOVERY_CONTEXT_LOOKUP_TIMEOUT_MS = 1500, PROVIDER_FILTER_ALIASES, ALL_PROVIDER_CHOICES, PROVIDER_MODEL_PREFIX;
|
|
62468
63082
|
var init_model_selector = __esm(() => {
|
|
62469
63083
|
init_dist16();
|
|
63084
|
+
init_model_catalog();
|
|
62470
63085
|
init_authority();
|
|
63086
|
+
init_context_window_fallback();
|
|
63087
|
+
init_remote_provider_types();
|
|
62471
63088
|
init_model_loader();
|
|
62472
63089
|
init_model_catalog2();
|
|
62473
63090
|
init_model_discovery();
|
|
62474
63091
|
init_provider_definitions();
|
|
63092
|
+
init_probe_discovery();
|
|
62475
63093
|
pickerProviderToFirebaseSlug = {
|
|
62476
63094
|
openrouter: "openrouter",
|
|
62477
63095
|
google: "google",
|
|
@@ -62495,6 +63113,11 @@ var init_model_selector = __esm(() => {
|
|
|
62495
63113
|
ollamacloud: "ollamacloud"
|
|
62496
63114
|
};
|
|
62497
63115
|
LOCAL_OR_USER_DEPLOYED = new Set(["litellm", "ollama", "lmstudio"]);
|
|
63116
|
+
SUBSCRIPTION_PRICING = {
|
|
63117
|
+
input: "SUB",
|
|
63118
|
+
output: "SUB",
|
|
63119
|
+
average: "SUB"
|
|
63120
|
+
};
|
|
62498
63121
|
PROVIDER_FILTER_ALIASES = {
|
|
62499
63122
|
openrouter: "openrouter",
|
|
62500
63123
|
or: "openrouter",
|
|
@@ -62531,7 +63154,9 @@ var init_model_selector = __esm(() => {
|
|
|
62531
63154
|
sakana: "sakana",
|
|
62532
63155
|
fugu: "sakana",
|
|
62533
63156
|
"sakana-subscription": "sakana-subscription",
|
|
62534
|
-
sc: "sakana-subscription"
|
|
63157
|
+
sc: "sakana-subscription",
|
|
63158
|
+
"qwen-cloud": "qwen-cloud",
|
|
63159
|
+
qc: "qwen-cloud"
|
|
62535
63160
|
};
|
|
62536
63161
|
ALL_PROVIDER_CHOICES = [
|
|
62537
63162
|
{
|
|
@@ -62582,6 +63207,12 @@ var init_model_selector = __esm(() => {
|
|
|
62582
63207
|
description: "Coding subscription",
|
|
62583
63208
|
provider: "kimi-coding"
|
|
62584
63209
|
},
|
|
63210
|
+
{
|
|
63211
|
+
name: "Qwen Plan",
|
|
63212
|
+
value: "qwen-cloud",
|
|
63213
|
+
description: "Alibaba Model Studio subscription",
|
|
63214
|
+
provider: "qwen-cloud"
|
|
63215
|
+
},
|
|
62585
63216
|
{ name: "GLM / Zhipu", value: "glm", description: "Direct API", provider: "glm" },
|
|
62586
63217
|
{
|
|
62587
63218
|
name: "GLM Coding Plan",
|
|
@@ -62628,6 +63259,7 @@ var init_model_selector = __esm(() => {
|
|
|
62628
63259
|
kimi: "kimi@",
|
|
62629
63260
|
"minimax-coding": "mmc@",
|
|
62630
63261
|
"kimi-coding": "kc@",
|
|
63262
|
+
"qwen-cloud": "qc@",
|
|
62631
63263
|
glm: "glm@",
|
|
62632
63264
|
"glm-coding": "gc@",
|
|
62633
63265
|
"z-ai": "z-ai@",
|
|
@@ -63251,7 +63883,7 @@ function wordWrap(text, maxWidth) {
|
|
|
63251
63883
|
lines.push(current);
|
|
63252
63884
|
return lines;
|
|
63253
63885
|
}
|
|
63254
|
-
function computeBarScales(
|
|
63886
|
+
function computeBarScales(results2) {
|
|
63255
63887
|
let maxTokPerSec = 1;
|
|
63256
63888
|
const liveTotals = [];
|
|
63257
63889
|
const consider = (probe) => {
|
|
@@ -63264,7 +63896,7 @@ function computeBarScales(results) {
|
|
|
63264
63896
|
if (scaledTps > maxTokPerSec)
|
|
63265
63897
|
maxTokPerSec = scaledTps;
|
|
63266
63898
|
};
|
|
63267
|
-
for (const r of
|
|
63899
|
+
for (const r of results2) {
|
|
63268
63900
|
consider(r.directProbe);
|
|
63269
63901
|
for (const c of r.chain ?? [])
|
|
63270
63902
|
consider(c.probe);
|
|
@@ -63564,7 +64196,7 @@ function formatContextWindow(ctx) {
|
|
|
63564
64196
|
function buildKeyLine(activeEntry, directKeyVar) {
|
|
63565
64197
|
if (activeEntry?.provenance) {
|
|
63566
64198
|
const p = activeEntry.provenance;
|
|
63567
|
-
if (p.
|
|
64199
|
+
if (p.hasValue) {
|
|
63568
64200
|
return `${pc.bold}Key${pc.reset} $${p.envVar} ${pc.dim}(${p.effectiveSource})${pc.reset}`;
|
|
63569
64201
|
}
|
|
63570
64202
|
return `${pc.bold}Key${pc.reset} $${p.envVar} ${pc.dim}(not set)${pc.reset}`;
|
|
@@ -63720,8 +64352,8 @@ function pickRepresentative(result) {
|
|
|
63720
64352
|
}
|
|
63721
64353
|
return { model: result.model, provider: result.nativeProvider };
|
|
63722
64354
|
}
|
|
63723
|
-
function renderLeaderboard(
|
|
63724
|
-
const reps =
|
|
64355
|
+
function renderLeaderboard(results2, scales, maxWidth, w) {
|
|
64356
|
+
const reps = results2.map(pickRepresentative);
|
|
63725
64357
|
const live = reps.filter((r) => r.timing).sort((a, b) => a.timing.totalMs - b.timing.totalMs);
|
|
63726
64358
|
const unavailable = reps.filter((r) => !r.timing);
|
|
63727
64359
|
if (live.length === 0)
|
|
@@ -63822,16 +64454,16 @@ function renderLeaderboard(results, scales, maxWidth, w) {
|
|
|
63822
64454
|
w(`
|
|
63823
64455
|
`);
|
|
63824
64456
|
}
|
|
63825
|
-
function printProbeResults(
|
|
64457
|
+
function printProbeResults(results2, isLiveProbe) {
|
|
63826
64458
|
const w = process.stderr.write.bind(process.stderr);
|
|
63827
64459
|
w(`
|
|
63828
64460
|
`);
|
|
63829
|
-
const scales = computeBarScales(
|
|
63830
|
-
const anyTimedLive =
|
|
64461
|
+
const scales = computeBarScales(results2);
|
|
64462
|
+
const anyTimedLive = results2.some((r) => r.directProbe?.state === "live" && r.directProbe.timing !== undefined) || results2.some((r) => (r.chain ?? []).some((c) => c.probe?.state === "live" && c.probe.timing !== undefined));
|
|
63831
64463
|
if (isLiveProbe && anyTimedLive) {
|
|
63832
64464
|
renderLegend(w);
|
|
63833
64465
|
}
|
|
63834
|
-
const requiredWidths =
|
|
64466
|
+
const requiredWidths = results2.map((r) => computeRequiredWidth(r, isLiveProbe));
|
|
63835
64467
|
const termCols = process.stderr.columns ?? process.stdout.columns ?? 100;
|
|
63836
64468
|
const maxAllowed = Math.max(MIN_CARD_WIDTH, termCols - 4);
|
|
63837
64469
|
let globalWidth = requiredWidths.reduce((a, b) => Math.max(a, b), MIN_CARD_WIDTH);
|
|
@@ -63839,14 +64471,14 @@ function printProbeResults(results, isLiveProbe) {
|
|
|
63839
64471
|
globalWidth = maxAllowed;
|
|
63840
64472
|
const showedLeaderboard = isLiveProbe && anyTimedLive;
|
|
63841
64473
|
if (showedLeaderboard) {
|
|
63842
|
-
renderLeaderboard(
|
|
64474
|
+
renderLeaderboard(results2, scales, maxAllowed, w);
|
|
63843
64475
|
}
|
|
63844
64476
|
if (showedLeaderboard) {
|
|
63845
64477
|
w(` ${pc.bold}${pc.cyan}Details${pc.reset}${pc.dim} \u2014 per-model routing chains${pc.reset}
|
|
63846
64478
|
|
|
63847
64479
|
`);
|
|
63848
64480
|
}
|
|
63849
|
-
for (const result of
|
|
64481
|
+
for (const result of results2) {
|
|
63850
64482
|
renderCard(result, isLiveProbe, w, globalWidth, scales);
|
|
63851
64483
|
w(`
|
|
63852
64484
|
`);
|
|
@@ -63898,8 +64530,8 @@ class ProbeStore {
|
|
|
63898
64530
|
for (const fn of this.listeners)
|
|
63899
64531
|
fn();
|
|
63900
64532
|
}
|
|
63901
|
-
setResults(
|
|
63902
|
-
this.setState((prev) => ({ ...prev, results, phase: "done" }));
|
|
64533
|
+
setResults(results2) {
|
|
64534
|
+
this.setState((prev) => ({ ...prev, results: results2, phase: "done" }));
|
|
63903
64535
|
}
|
|
63904
64536
|
setActiveTab(tab) {
|
|
63905
64537
|
this.setState((prev) => ({ ...prev, activeTab: tab }));
|
|
@@ -64740,24 +65372,24 @@ function DetailModel({
|
|
|
64740
65372
|
}, undefined, true, undefined, this);
|
|
64741
65373
|
}
|
|
64742
65374
|
function DetailsView({
|
|
64743
|
-
results,
|
|
65375
|
+
results: results2,
|
|
64744
65376
|
layout,
|
|
64745
65377
|
termWidth,
|
|
64746
65378
|
maxTotalMs,
|
|
64747
65379
|
maxTokPerSec
|
|
64748
65380
|
}) {
|
|
64749
|
-
const provW = Math.min(22, Math.max(8, ...
|
|
65381
|
+
const provW = Math.min(22, Math.max(8, ...results2.flatMap((r) => r.links.map((l) => l.displayName.length))));
|
|
64750
65382
|
const headerW = Math.max(24, Math.min(detailRowWidth(provW, layout), (termWidth || 100) - 3));
|
|
64751
65383
|
return /* @__PURE__ */ jsxDEV("box", {
|
|
64752
65384
|
flexDirection: "column",
|
|
64753
|
-
children:
|
|
65385
|
+
children: results2.map((r, idx) => /* @__PURE__ */ jsxDEV(DetailModel, {
|
|
64754
65386
|
result: r,
|
|
64755
65387
|
provW,
|
|
64756
65388
|
headerW,
|
|
64757
65389
|
layout,
|
|
64758
65390
|
maxTotalMs,
|
|
64759
65391
|
maxTokPerSec,
|
|
64760
|
-
isLast: idx ===
|
|
65392
|
+
isLast: idx === results2.length - 1
|
|
64761
65393
|
}, r.model, false, undefined, this))
|
|
64762
65394
|
}, undefined, false, undefined, this);
|
|
64763
65395
|
}
|
|
@@ -64931,12 +65563,12 @@ function LeaderLiveRow({
|
|
|
64931
65563
|
}, undefined, true, undefined, this);
|
|
64932
65564
|
}
|
|
64933
65565
|
function LeaderboardView({
|
|
64934
|
-
results,
|
|
65566
|
+
results: results2,
|
|
64935
65567
|
layout,
|
|
64936
65568
|
maxTotalMs,
|
|
64937
65569
|
maxTokPerSec
|
|
64938
65570
|
}) {
|
|
64939
|
-
const reps =
|
|
65571
|
+
const reps = results2.map(pickRepresentativeLink);
|
|
64940
65572
|
const live = reps.filter((r) => r.timing).sort((a, b) => a.timing.totalMs - b.timing.totalMs);
|
|
64941
65573
|
const unavailable = reps.filter((r) => !r.timing);
|
|
64942
65574
|
const nameW = Math.min(28, Math.max(5, ...reps.map((r) => r.model.length)));
|
|
@@ -65785,16 +66417,16 @@ function formatModelDocCaps(caps) {
|
|
|
65785
66417
|
return parts.length > 0 ? parts.join("") : "\xB7";
|
|
65786
66418
|
}
|
|
65787
66419
|
async function searchAndPrintModels(query, jsonOutput) {
|
|
65788
|
-
let
|
|
66420
|
+
let results2;
|
|
65789
66421
|
try {
|
|
65790
66422
|
console.error(`\uD83D\uDD04 Searching Firebase catalog for "${query}"...`);
|
|
65791
|
-
|
|
66423
|
+
results2 = await searchModels(query, 50);
|
|
65792
66424
|
} catch (error46) {
|
|
65793
66425
|
console.error(`\u274C Failed to reach Firebase model catalog: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
65794
66426
|
console.error(" Check your network connection.");
|
|
65795
66427
|
process.exit(1);
|
|
65796
66428
|
}
|
|
65797
|
-
if (
|
|
66429
|
+
if (results2.length === 0) {
|
|
65798
66430
|
if (jsonOutput) {
|
|
65799
66431
|
console.log(JSON.stringify({ query, count: 0, models: [] }, null, 2));
|
|
65800
66432
|
} else {
|
|
@@ -65805,8 +66437,8 @@ async function searchAndPrintModels(query, jsonOutput) {
|
|
|
65805
66437
|
if (jsonOutput) {
|
|
65806
66438
|
console.log(JSON.stringify({
|
|
65807
66439
|
query,
|
|
65808
|
-
count:
|
|
65809
|
-
models:
|
|
66440
|
+
count: results2.length,
|
|
66441
|
+
models: results2.map((m) => ({
|
|
65810
66442
|
id: m.modelId,
|
|
65811
66443
|
provider: m.provider,
|
|
65812
66444
|
contextWindow: m.contextWindow,
|
|
@@ -65819,9 +66451,9 @@ async function searchAndPrintModels(query, jsonOutput) {
|
|
|
65819
66451
|
return;
|
|
65820
66452
|
}
|
|
65821
66453
|
console.log(`
|
|
65822
|
-
Found ${
|
|
66454
|
+
Found ${results2.length} matching models:
|
|
65823
66455
|
`);
|
|
65824
|
-
const sorted = [...
|
|
66456
|
+
const sorted = [...results2].sort(compareByReleaseDateDesc);
|
|
65825
66457
|
renderModelDocTable(sorted, false);
|
|
65826
66458
|
console.log("");
|
|
65827
66459
|
console.log("Caps: T = tools R = reasoning V = vision");
|
|
@@ -66112,7 +66744,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66112
66744
|
hasCredentials = true;
|
|
66113
66745
|
} else {
|
|
66114
66746
|
provenance = resolveApiKeyProvenance(keyInfo.envVar, keyInfo.aliases);
|
|
66115
|
-
hasCredentials =
|
|
66747
|
+
hasCredentials = provenance.hasValue;
|
|
66116
66748
|
if (!hasCredentials && keyInfo.aliases) {
|
|
66117
66749
|
hasCredentials = keyInfo.aliases.some((a) => !!process.env[a]);
|
|
66118
66750
|
}
|
|
@@ -66185,7 +66817,14 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66185
66817
|
const modelName = resolvedSpec?.modelName || parsedModel;
|
|
66186
66818
|
let formatAdapterName = "OpenAIAPIFormat";
|
|
66187
66819
|
let declaredStreamFormat = "openai-sse";
|
|
66188
|
-
const anthropicCompatProviders = [
|
|
66820
|
+
const anthropicCompatProviders = [
|
|
66821
|
+
"minimax",
|
|
66822
|
+
"minimax-coding",
|
|
66823
|
+
"kimi",
|
|
66824
|
+
"kimi-coding",
|
|
66825
|
+
"qwen-cloud",
|
|
66826
|
+
"z-ai"
|
|
66827
|
+
];
|
|
66189
66828
|
const isMinimaxModel = modelName.toLowerCase().includes("minimax");
|
|
66190
66829
|
if (anthropicCompatProviders.includes(providerName)) {
|
|
66191
66830
|
formatAdapterName = "AnthropicAPIFormat";
|
|
@@ -66246,7 +66885,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66246
66885
|
}
|
|
66247
66886
|
}
|
|
66248
66887
|
try {
|
|
66249
|
-
const
|
|
66888
|
+
const results2 = [];
|
|
66250
66889
|
for (const modelInput of models) {
|
|
66251
66890
|
const { parsed, chain, chainDetails } = buildModelChain(modelInput);
|
|
66252
66891
|
let directProbeResult;
|
|
@@ -66284,7 +66923,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66284
66923
|
}
|
|
66285
66924
|
}
|
|
66286
66925
|
const wiring = await computeWiring(chainDetails, parsed.model);
|
|
66287
|
-
|
|
66926
|
+
results2.push({
|
|
66288
66927
|
model: modelInput,
|
|
66289
66928
|
nativeProvider: parsed.provider,
|
|
66290
66929
|
isExplicit: parsed.isExplicitProvider,
|
|
@@ -66295,7 +66934,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66295
66934
|
wiring
|
|
66296
66935
|
});
|
|
66297
66936
|
}
|
|
66298
|
-
console.log(JSON.stringify(
|
|
66937
|
+
console.log(JSON.stringify(results2, null, 2));
|
|
66299
66938
|
} finally {
|
|
66300
66939
|
if (liveProxy2) {
|
|
66301
66940
|
try {
|
|
@@ -66439,7 +67078,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66439
67078
|
}
|
|
66440
67079
|
const isLiveProbe = !!liveProxy;
|
|
66441
67080
|
const printable = [];
|
|
66442
|
-
const
|
|
67081
|
+
const results2 = [];
|
|
66443
67082
|
for (const { modelInput, parsed, chain, chainDetails } of modelChains) {
|
|
66444
67083
|
const wiring = await computeWiring(chainDetails, parsed.model);
|
|
66445
67084
|
const directProbe = directProbeResults.get(modelInput);
|
|
@@ -66461,7 +67100,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66461
67100
|
directProbe,
|
|
66462
67101
|
wiring
|
|
66463
67102
|
});
|
|
66464
|
-
|
|
67103
|
+
results2.push({
|
|
66465
67104
|
model: modelInput,
|
|
66466
67105
|
nativeProvider: parsed.provider,
|
|
66467
67106
|
isExplicit: parsed.isExplicitProvider,
|
|
@@ -66480,7 +67119,7 @@ async function probeModelRouting(models, jsonOutput, options = { live: true, tim
|
|
|
66480
67119
|
} catch {}
|
|
66481
67120
|
liveProxy = null;
|
|
66482
67121
|
}
|
|
66483
|
-
tui.store.setResults(
|
|
67122
|
+
tui.store.setResults(results2);
|
|
66484
67123
|
await tui.waitForQuit();
|
|
66485
67124
|
await tui.shutdown();
|
|
66486
67125
|
} else {
|
|
@@ -67856,8 +68495,8 @@ async function pingLocalProvider(catalogName, timeoutMs = PING_TIMEOUT_MS) {
|
|
|
67856
68495
|
}
|
|
67857
68496
|
}
|
|
67858
68497
|
async function pingLocalProviders(catalogNames, timeoutMs = PING_TIMEOUT_MS) {
|
|
67859
|
-
const
|
|
67860
|
-
return Object.fromEntries(
|
|
68498
|
+
const results2 = await Promise.all(catalogNames.map(async (name) => [name, await pingLocalProvider(name, timeoutMs)]));
|
|
68499
|
+
return Object.fromEntries(results2);
|
|
67861
68500
|
}
|
|
67862
68501
|
var PING_TIMEOUT_MS = 2000, HEALTH_PATH;
|
|
67863
68502
|
var init_local_liveness = __esm(() => {
|
|
@@ -71764,6 +72403,7 @@ var init_RoutingContent = __esm(() => {
|
|
|
71764
72403
|
"minimax-coding": "MiniMax Coding Plan",
|
|
71765
72404
|
glm: "Native GLM API",
|
|
71766
72405
|
"glm-coding": "GLM Coding Plan",
|
|
72406
|
+
"qwen-cloud": "Qwen Plan",
|
|
71767
72407
|
google: "Direct Gemini API",
|
|
71768
72408
|
openai: "Direct OpenAI API",
|
|
71769
72409
|
"openai-codex": "OpenAI Codex (Responses API)",
|
|
@@ -74334,13 +74974,20 @@ __export(exports_claude_runner, {
|
|
|
74334
74974
|
resolveContextWindowEnv: () => resolveContextWindowEnv,
|
|
74335
74975
|
managedSettingsForcesClaudeAi: () => managedSettingsForcesClaudeAi,
|
|
74336
74976
|
isProxyAuthMode: () => isProxyAuthMode,
|
|
74977
|
+
initializeTokenFile: () => initializeTokenFile,
|
|
74978
|
+
discoverUserStatusLineCommand: () => discoverUserStatusLineCommand,
|
|
74337
74979
|
createTempSettingsFile: () => createTempSettingsFile,
|
|
74338
74980
|
createStatusLineScript: () => createStatusLineScript,
|
|
74339
74981
|
computeMainThreadContextWindow: () => computeMainThreadContextWindow,
|
|
74982
|
+
cleanupStaleTokenFiles: () => cleanupStaleTokenFiles,
|
|
74340
74983
|
checkClaudeInstalled: () => checkClaudeInstalled,
|
|
74341
74984
|
buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay,
|
|
74985
|
+
buildChainedStatusCommand: () => buildChainedStatusCommand,
|
|
74986
|
+
USER_STATUS_LINE_TIMEOUT_SECONDS: () => USER_STATUS_LINE_TIMEOUT_SECONDS,
|
|
74987
|
+
STALE_TOKEN_FILE_MS: () => STALE_TOKEN_FILE_MS,
|
|
74342
74988
|
MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW,
|
|
74343
|
-
CLAUDE_CODE_DEFAULT_MAX_CONTEXT: () => CLAUDE_CODE_DEFAULT_MAX_CONTEXT
|
|
74989
|
+
CLAUDE_CODE_DEFAULT_MAX_CONTEXT: () => CLAUDE_CODE_DEFAULT_MAX_CONTEXT,
|
|
74990
|
+
CATALOG_WINDOW_TIMEOUT_MS: () => CATALOG_WINDOW_TIMEOUT_MS
|
|
74344
74991
|
});
|
|
74345
74992
|
import { spawn as spawn4 } from "child_process";
|
|
74346
74993
|
import {
|
|
@@ -74349,11 +74996,13 @@ import {
|
|
|
74349
74996
|
mkdirSync as mkdirSync16,
|
|
74350
74997
|
openSync as openSync5,
|
|
74351
74998
|
readFileSync as readFileSync24,
|
|
74999
|
+
readdirSync as readdirSync6,
|
|
75000
|
+
statSync as statSync5,
|
|
74352
75001
|
unlinkSync as unlinkSync9,
|
|
74353
75002
|
writeFileSync as writeFileSync18
|
|
74354
75003
|
} from "fs";
|
|
74355
75004
|
import { homedir as homedir29, tmpdir as tmpdir2 } from "os";
|
|
74356
|
-
import { join as join31 } from "path";
|
|
75005
|
+
import { dirname as dirname11, join as join31 } from "path";
|
|
74357
75006
|
import { isatty } from "tty";
|
|
74358
75007
|
function releaseTerminalIsolation() {
|
|
74359
75008
|
if (!restoreTerminal)
|
|
@@ -74395,9 +75044,9 @@ function managedSettingsPath() {
|
|
|
74395
75044
|
}
|
|
74396
75045
|
return "/etc/claude-code/managed-settings.json";
|
|
74397
75046
|
}
|
|
74398
|
-
function managedSettingsForcesClaudeAi(
|
|
75047
|
+
function managedSettingsForcesClaudeAi(readFile2 = readFileSync24) {
|
|
74399
75048
|
try {
|
|
74400
|
-
const raw2 =
|
|
75049
|
+
const raw2 = readFile2(managedSettingsPath(), "utf-8");
|
|
74401
75050
|
const parsed = JSON.parse(raw2);
|
|
74402
75051
|
return parsed.forceLoginMethod === "claudeai";
|
|
74403
75052
|
} catch {
|
|
@@ -74532,7 +75181,111 @@ process.stdin.on('end', () => {
|
|
|
74532
75181
|
writeFileSync18(scriptPath, script, "utf-8");
|
|
74533
75182
|
return scriptPath;
|
|
74534
75183
|
}
|
|
74535
|
-
function
|
|
75184
|
+
function initializeTokenFile(tokenFilePath) {
|
|
75185
|
+
try {
|
|
75186
|
+
mkdirSync16(dirname11(tokenFilePath), { recursive: true });
|
|
75187
|
+
writeFileSync18(tokenFilePath, JSON.stringify({
|
|
75188
|
+
input_tokens: 0,
|
|
75189
|
+
output_tokens: 0,
|
|
75190
|
+
total_tokens: 0,
|
|
75191
|
+
total_cost: 0,
|
|
75192
|
+
context_window: "unknown",
|
|
75193
|
+
context_left_percent: -1,
|
|
75194
|
+
updated_at: Date.now(),
|
|
75195
|
+
is_free: false,
|
|
75196
|
+
is_estimated: false
|
|
75197
|
+
}), "utf-8");
|
|
75198
|
+
} catch (e) {
|
|
75199
|
+
log(`[claude-runner] Could not initialize token file ${tokenFilePath}: ${e}`);
|
|
75200
|
+
}
|
|
75201
|
+
}
|
|
75202
|
+
function cleanupStaleTokenFiles(dir, now = Date.now(), maxAgeMs = STALE_TOKEN_FILE_MS) {
|
|
75203
|
+
let removed = 0;
|
|
75204
|
+
let entries;
|
|
75205
|
+
try {
|
|
75206
|
+
entries = readdirSync6(dir);
|
|
75207
|
+
} catch {
|
|
75208
|
+
return 0;
|
|
75209
|
+
}
|
|
75210
|
+
const cutoff = now - maxAgeMs;
|
|
75211
|
+
let scanned = 0;
|
|
75212
|
+
for (const name of entries) {
|
|
75213
|
+
if (scanned >= MAX_TOKEN_FILES_SCANNED)
|
|
75214
|
+
break;
|
|
75215
|
+
if (!name.startsWith("tokens-") || !name.endsWith(".json"))
|
|
75216
|
+
continue;
|
|
75217
|
+
scanned++;
|
|
75218
|
+
const full = join31(dir, name);
|
|
75219
|
+
try {
|
|
75220
|
+
if (statSync5(full).mtimeMs >= cutoff)
|
|
75221
|
+
continue;
|
|
75222
|
+
unlinkSync9(full);
|
|
75223
|
+
removed++;
|
|
75224
|
+
} catch {}
|
|
75225
|
+
}
|
|
75226
|
+
if (removed > 0) {
|
|
75227
|
+
log(`[claude-runner] Removed ${removed} stale token file(s) from ${dir}`);
|
|
75228
|
+
}
|
|
75229
|
+
return removed;
|
|
75230
|
+
}
|
|
75231
|
+
function parseSettingsArg(value) {
|
|
75232
|
+
if (value.trimStart().startsWith("{")) {
|
|
75233
|
+
return JSON.parse(value);
|
|
75234
|
+
}
|
|
75235
|
+
return JSON.parse(readFileSync24(value, "utf-8"));
|
|
75236
|
+
}
|
|
75237
|
+
function parseSettingsArgSafe(value) {
|
|
75238
|
+
try {
|
|
75239
|
+
const parsed = parseSettingsArg(value);
|
|
75240
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
75241
|
+
} catch {
|
|
75242
|
+
return null;
|
|
75243
|
+
}
|
|
75244
|
+
}
|
|
75245
|
+
function userSettingsFileCandidates(cwd) {
|
|
75246
|
+
return [
|
|
75247
|
+
join31(homedir29(), ".claude", "settings.json"),
|
|
75248
|
+
join31(cwd, ".claude", "settings.json"),
|
|
75249
|
+
join31(cwd, ".claude", "settings.local.json")
|
|
75250
|
+
];
|
|
75251
|
+
}
|
|
75252
|
+
function discoverUserStatusLineCommand(claudeArgs = [], cwd = process.cwd()) {
|
|
75253
|
+
const sources = userSettingsFileCandidates(cwd).filter((file2) => existsSync25(file2));
|
|
75254
|
+
const idx = claudeArgs.indexOf("--settings");
|
|
75255
|
+
const settingsArg = idx === -1 ? undefined : claudeArgs[idx + 1];
|
|
75256
|
+
if (settingsArg)
|
|
75257
|
+
sources.push(settingsArg);
|
|
75258
|
+
let effective;
|
|
75259
|
+
for (const source of sources) {
|
|
75260
|
+
const layer = parseSettingsArgSafe(source);
|
|
75261
|
+
if (layer && "statusLine" in layer)
|
|
75262
|
+
effective = layer.statusLine;
|
|
75263
|
+
}
|
|
75264
|
+
return chainableCommandOf(effective);
|
|
75265
|
+
}
|
|
75266
|
+
function chainableCommandOf(statusLine) {
|
|
75267
|
+
if (!statusLine || typeof statusLine !== "object")
|
|
75268
|
+
return null;
|
|
75269
|
+
const { type, command } = statusLine;
|
|
75270
|
+
if (type !== "command" || typeof command !== "string")
|
|
75271
|
+
return null;
|
|
75272
|
+
const trimmed = command.trim();
|
|
75273
|
+
if (!trimmed)
|
|
75274
|
+
return null;
|
|
75275
|
+
if (trimmed.includes("CLAUDISH_ACTIVE_MODEL_NAME") || trimmed.includes("CLAUDISH_IS_LOCAL")) {
|
|
75276
|
+
return null;
|
|
75277
|
+
}
|
|
75278
|
+
return trimmed;
|
|
75279
|
+
}
|
|
75280
|
+
function buildChainedStatusCommand(userCommand, claudishBody, claudishSegment) {
|
|
75281
|
+
const quotedUser = `'${userCommand.replace(/'/g, `'\\''`)}'`;
|
|
75282
|
+
const ESC2 = "\x1B";
|
|
75283
|
+
const separator = `SEP=' ${ESC2}[2m\u2022${ESC2}[0m '`;
|
|
75284
|
+
const runUser = `if command -v timeout >/dev/null 2>&1; then _CT="timeout ${USER_STATUS_LINE_TIMEOUT_SECONDS}"; elif command -v gtimeout >/dev/null 2>&1; then _CT="gtimeout ${USER_STATUS_LINE_TIMEOUT_SECONDS}"; else _CT=""; fi; USER_OUT=$(printf '%s' "$JSON" | $_CT bash -c ${quotedUser} 2>/dev/null)`;
|
|
75285
|
+
const emit2 = `if [ -n "$USER_OUT" ]; then LAST="\${USER_OUT##*$'\\n'}"; if [ "$LAST" = "$USER_OUT" ]; then printf '%s%s%s\\n' "$USER_OUT" "$SEP" "$SEG"; else printf '%s\\n%s%s%s\\n' "\${USER_OUT%$'\\n'*}" "$LAST" "$SEP" "$SEG"; fi; else printf '%s\\n' "$SEG"; fi`;
|
|
75286
|
+
return `JSON=$(cat); ${runUser}; ${claudishBody}; SEG=$(${claudishSegment}); ${separator}; ${emit2}`;
|
|
75287
|
+
}
|
|
75288
|
+
function createTempSettingsFile(_modelDisplay, port, proxyAuthMode, userStatusLineCommand) {
|
|
74536
75289
|
const homeDir = process.env.HOME || process.env.USERPROFILE || tmpdir2();
|
|
74537
75290
|
const claudishDir = join31(homeDir, ".claudish");
|
|
74538
75291
|
try {
|
|
@@ -74541,6 +75294,8 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
|
74541
75294
|
const timestamp = Date.now();
|
|
74542
75295
|
const tempPath = join31(claudishDir, `settings-${timestamp}.json`);
|
|
74543
75296
|
const tokenFilePath = join31(claudishDir, `tokens-${port}.json`);
|
|
75297
|
+
cleanupStaleTokenFiles(claudishDir);
|
|
75298
|
+
initializeTokenFile(tokenFilePath);
|
|
74544
75299
|
let statusCommand;
|
|
74545
75300
|
if (isWindows2()) {
|
|
74546
75301
|
const scriptPath = createStatusLineScript(tokenFilePath);
|
|
@@ -74555,7 +75310,13 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
|
74555
75310
|
const BOLD4 = "\\033[1m";
|
|
74556
75311
|
const formatTokensBash = `fmt_tok() { local n=\${1:-0}; if [ "$n" -ge 1000000 ]; then echo "$((n/1000000))M"; elif [ "$n" -ge 1000 ]; then echo "$((n/1000))k"; else echo "$n"; fi; }`;
|
|
74557
75312
|
const effWinBash = `eff_win() { local w=\${1:-0}; local m=\${CLAUDE_CODE_MAX_CONTEXT_TOKENS:-}; local a=\${CLAUDE_CODE_AUTO_COMPACT_WINDOW:-}; case "$m" in ''|*[!0-9]*) m=${CLAUDE_CODE_DEFAULT_MAX_CONTEXT};; esac; case "$a" in ''|*[!0-9]*) a=0;; esac; case "$w" in ''|*[!0-9]*) w=0;; esac; if [ "$w" -gt 0 ]; then if [ "$m" -gt 0 ] && [ "$m" -lt "$w" ]; then w=$m; fi; if [ "$a" -gt 0 ] && [ "$a" -lt "$w" ]; then w=$a; fi; fi; echo "$w"; }`;
|
|
74558
|
-
|
|
75313
|
+
const dirPrelude = `DIR=$(basename "$(pwd)"); [ \${#DIR} -gt 15 ] && DIR="\${DIR:0:12}..." || true; `;
|
|
75314
|
+
const readState = `CTX=-1; COST="0"; IS_FREE="false"; IS_EST="false"; PROVIDER=""; TOKEN_MODEL=""; IN_TOK=0; CTX_WIN=0; ${formatTokensBash}; ${effWinBash}; if [ -f "${tokenFilePath}" ]; then TOKENS=$(cat "${tokenFilePath}" 2>/dev/null | tr -d '\\n\\r'); V=$(echo "$TOKENS" | grep -o '"context_left_percent": *-\\?[0-9]*' | grep -o '\\-\\?[0-9]*'); [ -n "$V" ] && CTX="$V"; V=$(echo "$TOKENS" | grep -o '"total_cost": *[0-9.]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && COST="$V"; V=$(echo "$TOKENS" | grep -o '"input_tokens": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && IN_TOK="$V"; V=$(echo "$TOKENS" | grep -o '"context_window": *[0-9]*' | grep -o '[0-9]*'); [ -n "$V" ] && CTX_WIN="$V"; V=$(echo "$TOKENS" | grep -o '"is_free": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_FREE="$V"; V=$(echo "$TOKENS" | grep -o '"is_estimated": *[a-z]*' | cut -d: -f2 | tr -d ' '); [ -n "$V" ] && IS_EST="$V"; V=$(echo "$TOKENS" | grep -o '"provider_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && PROVIDER="$V"; V=$(echo "$TOKENS" | grep -o '"model_name": *"[^"]*"' | cut -d'"' -f4); [ -n "$V" ] && TOKEN_MODEL="$V"; fi; if [ "$CLAUDISH_IS_LOCAL" = "true" ]; then COST_DISPLAY="LOCAL"; elif [ "$IS_FREE" = "true" ]; then COST_DISPLAY="FREE"; elif [ "$IS_EST" = "true" ]; then COST_DISPLAY=$(printf "~\\$%.3f" "$COST"); else COST_DISPLAY=$(printf "\\$%.3f" "$COST"); fi; MODEL_DISPLAY="\${TOKEN_MODEL:-$CLAUDISH_ACTIVE_MODEL_NAME}"; if [ -n "$PROVIDER" ]; then MODEL_DISPLAY="$PROVIDER $MODEL_DISPLAY"; fi; EFF_WIN=$(eff_win $CTX_WIN); if [ "$EFF_WIN" -gt 0 ] 2>/dev/null && [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX=$(( ((EFF_WIN - IN_TOK) * 200 / EFF_WIN + 1) / 2 )); if [ "$CTX" -lt 0 ]; then CTX=0; fi; fi; if [ "$CTX" -lt 0 ] 2>/dev/null || [ "$EFF_WIN" -le 0 ] 2>/dev/null; then if [ "$IN_TOK" -gt 0 ] 2>/dev/null; then CTX_DISPLAY="$(fmt_tok $IN_TOK) tokens"; else CTX_DISPLAY="N/A"; fi; elif [ "$IN_TOK" -gt 0 ] 2>/dev/null; then if [ "$EFF_WIN" -lt "$CTX_WIN" ] 2>/dev/null; then CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN) of $(fmt_tok $CTX_WIN))"; else CTX_DISPLAY="$CTX% ($(fmt_tok $IN_TOK)/$(fmt_tok $EFF_WIN))"; fi; else CTX_DISPLAY="$CTX%"; fi`;
|
|
75315
|
+
const segmentWithDir = `printf "${CYAN4}${BOLD4}%s${RESET4} ${DIM4}\u2022${RESET4} ${YELLOW3}%s${RESET4} ${DIM4}\u2022${RESET4} ${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$DIR" "$MODEL_DISPLAY" "$COST_DISPLAY" "$CTX_DISPLAY"`;
|
|
75316
|
+
const segmentNoDirWithProvider = `printf "${YELLOW3}%s${RESET4} ${DIM4}\u2022${RESET4} ${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$PROVIDER" "$COST_DISPLAY" "$CTX_DISPLAY"`;
|
|
75317
|
+
const segmentNoDirNoProvider = `printf "${GREEN4}%s${RESET4} ${DIM4}\u2022${RESET4} ${MAGENTA3}%s${RESET4}\\n" "$COST_DISPLAY" "$CTX_DISPLAY"`;
|
|
75318
|
+
const segmentNoDir = `if [ -n "$PROVIDER" ]; then ${segmentNoDirWithProvider}; else ${segmentNoDirNoProvider}; fi`;
|
|
75319
|
+
statusCommand = userStatusLineCommand ? buildChainedStatusCommand(userStatusLineCommand, readState, segmentNoDir) : `JSON=$(cat); ${dirPrelude}${readState}; ${segmentWithDir}`;
|
|
74559
75320
|
}
|
|
74560
75321
|
const statusLine = {
|
|
74561
75322
|
type: "command",
|
|
@@ -74564,7 +75325,7 @@ function createTempSettingsFile(_modelDisplay, port, proxyAuthMode) {
|
|
|
74564
75325
|
};
|
|
74565
75326
|
const settings = buildClaudishSettingsOverlay(statusLine, proxyAuthMode);
|
|
74566
75327
|
writeFileSync18(tempPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
74567
|
-
return { path: tempPath, statusLine };
|
|
75328
|
+
return { path: tempPath, statusLine, tokenFilePath };
|
|
74568
75329
|
}
|
|
74569
75330
|
function buildClaudishSettingsOverlay(statusLine, proxyAuthMode) {
|
|
74570
75331
|
const settings = { statusLine, disableClaudeAiConnectors: true };
|
|
@@ -74580,13 +75341,7 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
74580
75341
|
}
|
|
74581
75342
|
const userSettingsValue = config3.claudeArgs[idx + 1];
|
|
74582
75343
|
try {
|
|
74583
|
-
|
|
74584
|
-
if (userSettingsValue.trimStart().startsWith("{")) {
|
|
74585
|
-
userSettings = JSON.parse(userSettingsValue);
|
|
74586
|
-
} else {
|
|
74587
|
-
const rawUserSettings = readFileSync24(userSettingsValue, "utf-8");
|
|
74588
|
-
userSettings = JSON.parse(rawUserSettings);
|
|
74589
|
-
}
|
|
75344
|
+
const userSettings = parseSettingsArg(userSettingsValue);
|
|
74590
75345
|
userSettings.statusLine = statusLine;
|
|
74591
75346
|
if (!("disableClaudeAiConnectors" in userSettings)) {
|
|
74592
75347
|
userSettings.disableClaudeAiConnectors = true;
|
|
@@ -74602,27 +75357,64 @@ function mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxy
|
|
|
74602
75357
|
}
|
|
74603
75358
|
config3.claudeArgs.splice(idx, 2);
|
|
74604
75359
|
}
|
|
75360
|
+
function withDeadline(promise3, ms) {
|
|
75361
|
+
return new Promise((resolve4) => {
|
|
75362
|
+
const timer = setTimeout(() => resolve4(null), ms);
|
|
75363
|
+
timer.unref?.();
|
|
75364
|
+
promise3.then((value) => {
|
|
75365
|
+
clearTimeout(timer);
|
|
75366
|
+
resolve4(value);
|
|
75367
|
+
}).catch(() => {
|
|
75368
|
+
clearTimeout(timer);
|
|
75369
|
+
resolve4(null);
|
|
75370
|
+
});
|
|
75371
|
+
});
|
|
75372
|
+
}
|
|
75373
|
+
async function resolveLocalContextWindow(spec, cachePath) {
|
|
75374
|
+
const parsed = parseModelSpec(spec);
|
|
75375
|
+
let provider = parsed.provider;
|
|
75376
|
+
if (!parsed.isExplicitProvider) {
|
|
75377
|
+
const plan = await route(spec);
|
|
75378
|
+
if (plan.kind !== "ok")
|
|
75379
|
+
return null;
|
|
75380
|
+
provider = plan.primary.provider;
|
|
75381
|
+
}
|
|
75382
|
+
const win = await discoverContextWindow(provider, parsed.model) ?? lookupModelForProvider(parsed.model, provider, cachePath);
|
|
75383
|
+
return {
|
|
75384
|
+
modelId: parsed.model,
|
|
75385
|
+
window: typeof win === "number" && win > 0 ? win : null
|
|
75386
|
+
};
|
|
75387
|
+
}
|
|
75388
|
+
async function catalogWindowMin(modelIds) {
|
|
75389
|
+
const misses = [...new Set(modelIds)];
|
|
75390
|
+
if (misses.length === 0)
|
|
75391
|
+
return Number.POSITIVE_INFINITY;
|
|
75392
|
+
const windows = await withDeadline(Promise.all(misses.map((id) => resolveCatalogContextWindow(id).catch(() => null))), CATALOG_WINDOW_TIMEOUT_MS);
|
|
75393
|
+
let min = Number.POSITIVE_INFINITY;
|
|
75394
|
+
for (const win of windows ?? []) {
|
|
75395
|
+
if (typeof win === "number" && win > 0)
|
|
75396
|
+
min = Math.min(min, win);
|
|
75397
|
+
}
|
|
75398
|
+
return min;
|
|
75399
|
+
}
|
|
74605
75400
|
async function computeMainThreadContextWindow(config3, cachePath) {
|
|
74606
75401
|
const specs = [config3.model, config3.modelOpus, config3.modelSonnet].filter((s) => typeof s === "string" && s.length > 0);
|
|
74607
75402
|
if (specs.length === 0)
|
|
74608
75403
|
return 0;
|
|
74609
75404
|
let min = Number.POSITIVE_INFINITY;
|
|
75405
|
+
const unresolved = [];
|
|
74610
75406
|
for (const spec of specs) {
|
|
74611
75407
|
try {
|
|
74612
|
-
const
|
|
74613
|
-
|
|
74614
|
-
|
|
74615
|
-
|
|
74616
|
-
|
|
74617
|
-
|
|
74618
|
-
|
|
74619
|
-
}
|
|
74620
|
-
const win = await discoverContextWindow(provider, parsed.model) ?? lookupModelForProvider(parsed.model, provider, cachePath);
|
|
74621
|
-
if (typeof win === "number" && win > 0) {
|
|
74622
|
-
min = Math.min(min, win);
|
|
74623
|
-
}
|
|
75408
|
+
const resolved = await resolveLocalContextWindow(spec, cachePath);
|
|
75409
|
+
if (!resolved)
|
|
75410
|
+
continue;
|
|
75411
|
+
if (resolved.window !== null)
|
|
75412
|
+
min = Math.min(min, resolved.window);
|
|
75413
|
+
else
|
|
75414
|
+
unresolved.push(resolved.modelId);
|
|
74624
75415
|
} catch {}
|
|
74625
75416
|
}
|
|
75417
|
+
min = Math.min(min, await catalogWindowMin(unresolved));
|
|
74626
75418
|
return Number.isFinite(min) ? min : 0;
|
|
74627
75419
|
}
|
|
74628
75420
|
function resolveContextWindowEnv(realWindow, processEnv = process.env) {
|
|
@@ -74659,7 +75451,12 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
74659
75451
|
onCleanup?.();
|
|
74660
75452
|
return 1;
|
|
74661
75453
|
}
|
|
74662
|
-
const
|
|
75454
|
+
const userStatusLineCommand = discoverUserStatusLineCommand(config3.claudeArgs);
|
|
75455
|
+
const {
|
|
75456
|
+
path: tempSettingsPath,
|
|
75457
|
+
statusLine,
|
|
75458
|
+
tokenFilePath
|
|
75459
|
+
} = createTempSettingsFile(modelId ?? "default", port, proxyAuthMode, userStatusLineCommand);
|
|
74663
75460
|
mergeUserSettingsIfPresent(config3, tempSettingsPath, statusLine, proxyAuthMode);
|
|
74664
75461
|
const claudeArgs = [];
|
|
74665
75462
|
claudeArgs.push("--settings", tempSettingsPath);
|
|
@@ -74692,8 +75489,16 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
|
|
|
74692
75489
|
...process.env,
|
|
74693
75490
|
ANTHROPIC_BASE_URL: proxyUrl,
|
|
74694
75491
|
[ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelDisplayName,
|
|
74695
|
-
CLAUDISH_IS_LOCAL: isLocalModel2 ? "true" : "false"
|
|
75492
|
+
CLAUDISH_IS_LOCAL: isLocalModel2 ? "true" : "false",
|
|
75493
|
+
[ENV.CLAUDISH_TOKEN_FILE]: tokenFilePath
|
|
74696
75494
|
};
|
|
75495
|
+
if (modelId) {
|
|
75496
|
+
const parsedSpec = parseModelSpec(modelId);
|
|
75497
|
+
const providerDisplayName = parsedSpec.isExplicitProvider ? getProviderByName(parsedSpec.provider)?.displayName : undefined;
|
|
75498
|
+
if (providerDisplayName) {
|
|
75499
|
+
env[ENV.CLAUDISH_PROVIDER_NAME] = providerDisplayName;
|
|
75500
|
+
}
|
|
75501
|
+
}
|
|
74697
75502
|
let hidAnthropicApiKey = false;
|
|
74698
75503
|
delete env.CLAUDECODE;
|
|
74699
75504
|
if (config3.monitor) {
|
|
@@ -74904,17 +75709,20 @@ async function checkClaudeInstalled() {
|
|
|
74904
75709
|
const binary = await findClaudeBinary();
|
|
74905
75710
|
return binary !== null;
|
|
74906
75711
|
}
|
|
74907
|
-
var restoreTerminal = null, CLAUDE_CODE_DEFAULT_MAX_CONTEXT = 200000, MIN_AUTO_COMPACT_WINDOW = 200000;
|
|
75712
|
+
var restoreTerminal = null, 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, CATALOG_WINDOW_TIMEOUT_MS = 1500;
|
|
74908
75713
|
var init_claude_runner = __esm(() => {
|
|
74909
75714
|
init_model_catalog();
|
|
74910
75715
|
init_config2();
|
|
75716
|
+
init_context_window_fallback();
|
|
74911
75717
|
init_logger();
|
|
74912
75718
|
init_profile_config();
|
|
74913
75719
|
init_model_discovery();
|
|
74914
75720
|
init_model_parser();
|
|
75721
|
+
init_provider_definitions();
|
|
74915
75722
|
init_routing_rules();
|
|
74916
75723
|
init_telemetry();
|
|
74917
75724
|
init_terminal_isolation();
|
|
75725
|
+
STALE_TOKEN_FILE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
74918
75726
|
});
|
|
74919
75727
|
|
|
74920
75728
|
// src/diag-output.ts
|
|
@@ -75148,7 +75956,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
75148
75956
|
import { execSync as execSync2 } from "child_process";
|
|
75149
75957
|
import { existsSync as existsSync26, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
|
|
75150
75958
|
import { connect as netConnect } from "net";
|
|
75151
|
-
import { dirname as
|
|
75959
|
+
import { dirname as dirname12, join as join33 } from "path";
|
|
75152
75960
|
import { setTimeout as wait } from "timers/promises";
|
|
75153
75961
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
75154
75962
|
function resolveRouteInfo(modelId) {
|
|
@@ -75241,7 +76049,7 @@ function buildPaneHeader(model, prompt, bg) {
|
|
|
75241
76049
|
}
|
|
75242
76050
|
function findMagmuxBinary() {
|
|
75243
76051
|
const thisFile = fileURLToPath3(import.meta.url);
|
|
75244
|
-
const thisDir =
|
|
76052
|
+
const thisDir = dirname12(thisFile);
|
|
75245
76053
|
const pkgRoot = join33(thisDir, "..");
|
|
75246
76054
|
const platform3 = process.platform;
|
|
75247
76055
|
const arch = process.arch;
|
|
@@ -75255,7 +76063,7 @@ function findMagmuxBinary() {
|
|
|
75255
76063
|
const candidate = join33(searchDir, "node_modules", pkgName, "bin", "magmux");
|
|
75256
76064
|
if (existsSync26(candidate))
|
|
75257
76065
|
return candidate;
|
|
75258
|
-
const parent =
|
|
76066
|
+
const parent = dirname12(searchDir);
|
|
75259
76067
|
if (parent === searchDir)
|
|
75260
76068
|
break;
|
|
75261
76069
|
searchDir = parent;
|
|
@@ -75316,12 +76124,12 @@ async function subscribeToMagmux(sockPath, onEvent) {
|
|
|
75316
76124
|
client.once("error", done);
|
|
75317
76125
|
});
|
|
75318
76126
|
}
|
|
75319
|
-
function buildTeamStatus(manifest, startedAt,
|
|
76127
|
+
function buildTeamStatus(manifest, startedAt, results2) {
|
|
75320
76128
|
const anonIds = Object.keys(manifest.models);
|
|
75321
76129
|
const models = {};
|
|
75322
76130
|
for (let i = 0;i < anonIds.length; i++) {
|
|
75323
76131
|
const anonId = anonIds[i];
|
|
75324
|
-
const result =
|
|
76132
|
+
const result = results2?.find((r) => r.pane === i);
|
|
75325
76133
|
if (!result) {
|
|
75326
76134
|
models[anonId] = {
|
|
75327
76135
|
state: "TIMEOUT",
|
|
@@ -75390,8 +76198,8 @@ async function runWithGrid(sessionPath, models, input, opts) {
|
|
|
75390
76198
|
proc.on("exit", () => resolve4());
|
|
75391
76199
|
proc.on("error", () => resolve4());
|
|
75392
76200
|
});
|
|
75393
|
-
const [{ results }] = await Promise.all([subscription, procExit]);
|
|
75394
|
-
const status = buildTeamStatus(manifest, startedAt,
|
|
76201
|
+
const [{ results: results2 }] = await Promise.all([subscription, procExit]);
|
|
76202
|
+
const status = buildTeamStatus(manifest, startedAt, results2?.panes ?? null);
|
|
75395
76203
|
const statusPath = join33(sessionPath, "status.json");
|
|
75396
76204
|
writeFileSync20(statusPath, JSON.stringify(status, null, 2), "utf-8");
|
|
75397
76205
|
return status;
|