claudish 6.2.2 → 6.3.1
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 +623 -23
- package/native/mtm/mtm-darwin-arm64 +0 -0
- package/package.json +1 -1
- package/recommended-models.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37103,7 +37103,7 @@ async function fetchGLMCodingModels() {
|
|
|
37103
37103
|
return [];
|
|
37104
37104
|
}
|
|
37105
37105
|
}
|
|
37106
|
-
var __filename4, __dirname4, VERSION = "6.
|
|
37106
|
+
var __filename4, __dirname4, VERSION = "6.3.1", CACHE_MAX_AGE_DAYS2 = 2, CLAUDISH_CACHE_DIR2, BUNDLED_MODELS_PATH, CACHED_MODELS_PATH, ALL_MODELS_JSON_PATH;
|
|
37107
37107
|
var init_cli = __esm(() => {
|
|
37108
37108
|
init_config();
|
|
37109
37109
|
init_model_loader();
|
|
@@ -98318,6 +98318,141 @@ var init_react = __esm(async () => {
|
|
|
98318
98318
|
extend2({ "time-to-first-draw": TimeToFirstDrawRenderable });
|
|
98319
98319
|
});
|
|
98320
98320
|
|
|
98321
|
+
// src/tui/test-provider.ts
|
|
98322
|
+
function resolveBaseUrl(def) {
|
|
98323
|
+
if (def.baseUrlEnvVars) {
|
|
98324
|
+
for (const envVar of def.baseUrlEnvVars) {
|
|
98325
|
+
const val = process.env[envVar];
|
|
98326
|
+
if (val)
|
|
98327
|
+
return val.replace(/\/$/, "");
|
|
98328
|
+
}
|
|
98329
|
+
}
|
|
98330
|
+
return def.baseUrl.replace(/\/$/, "");
|
|
98331
|
+
}
|
|
98332
|
+
function getApiFamily(def) {
|
|
98333
|
+
switch (def.transport) {
|
|
98334
|
+
case "openai":
|
|
98335
|
+
case "openrouter":
|
|
98336
|
+
case "litellm":
|
|
98337
|
+
case "kimi-coding":
|
|
98338
|
+
return "openai";
|
|
98339
|
+
case "anthropic":
|
|
98340
|
+
return "anthropic";
|
|
98341
|
+
case "gemini":
|
|
98342
|
+
case "gemini-oauth":
|
|
98343
|
+
return "gemini";
|
|
98344
|
+
case "ollamacloud":
|
|
98345
|
+
return "ollamacloud";
|
|
98346
|
+
default:
|
|
98347
|
+
return "unsupported";
|
|
98348
|
+
}
|
|
98349
|
+
}
|
|
98350
|
+
async function testOpenAI(baseUrl, apiKey) {
|
|
98351
|
+
const url2 = `${baseUrl}/v1/models`;
|
|
98352
|
+
const signal = AbortSignal.timeout(TIMEOUT_MS);
|
|
98353
|
+
try {
|
|
98354
|
+
const resp = await fetch(url2, {
|
|
98355
|
+
method: "GET",
|
|
98356
|
+
headers: {
|
|
98357
|
+
Authorization: `Bearer ${apiKey}`,
|
|
98358
|
+
"Content-Type": "application/json"
|
|
98359
|
+
},
|
|
98360
|
+
signal
|
|
98361
|
+
});
|
|
98362
|
+
if (resp.ok)
|
|
98363
|
+
return "valid";
|
|
98364
|
+
return `invalid (HTTP ${resp.status})`;
|
|
98365
|
+
} catch (err) {
|
|
98366
|
+
if (err instanceof Error && err.name === "TimeoutError")
|
|
98367
|
+
return "timeout";
|
|
98368
|
+
return `error: ${err instanceof Error ? err.message : String(err)}`;
|
|
98369
|
+
}
|
|
98370
|
+
}
|
|
98371
|
+
async function testAnthropic(baseUrl, apiKey, authScheme = "x-api-key") {
|
|
98372
|
+
const url2 = `${baseUrl}/anthropic/v1/messages`;
|
|
98373
|
+
const signal = AbortSignal.timeout(TIMEOUT_MS);
|
|
98374
|
+
const authHeader = authScheme === "bearer" ? { Authorization: `Bearer ${apiKey}` } : { "x-api-key": apiKey };
|
|
98375
|
+
try {
|
|
98376
|
+
const resp = await fetch(url2, {
|
|
98377
|
+
method: "POST",
|
|
98378
|
+
headers: {
|
|
98379
|
+
"Content-Type": "application/json",
|
|
98380
|
+
"anthropic-version": "2023-06-01",
|
|
98381
|
+
...authHeader
|
|
98382
|
+
},
|
|
98383
|
+
body: JSON.stringify({
|
|
98384
|
+
model: "claude-3-haiku-20240307",
|
|
98385
|
+
max_tokens: 1,
|
|
98386
|
+
messages: [{ role: "user", content: "Hi" }]
|
|
98387
|
+
}),
|
|
98388
|
+
signal
|
|
98389
|
+
});
|
|
98390
|
+
if (resp.ok || resp.status === 400)
|
|
98391
|
+
return "valid";
|
|
98392
|
+
return `invalid (HTTP ${resp.status})`;
|
|
98393
|
+
} catch (err) {
|
|
98394
|
+
if (err instanceof Error && err.name === "TimeoutError")
|
|
98395
|
+
return "timeout";
|
|
98396
|
+
return `error: ${err instanceof Error ? err.message : String(err)}`;
|
|
98397
|
+
}
|
|
98398
|
+
}
|
|
98399
|
+
async function testGemini(baseUrl, apiKey) {
|
|
98400
|
+
const url2 = `${baseUrl}/v1beta/models?key=${encodeURIComponent(apiKey)}`;
|
|
98401
|
+
const signal = AbortSignal.timeout(TIMEOUT_MS);
|
|
98402
|
+
try {
|
|
98403
|
+
const resp = await fetch(url2, { signal });
|
|
98404
|
+
if (resp.ok)
|
|
98405
|
+
return "valid";
|
|
98406
|
+
return `invalid (HTTP ${resp.status})`;
|
|
98407
|
+
} catch (err) {
|
|
98408
|
+
if (err instanceof Error && err.name === "TimeoutError")
|
|
98409
|
+
return "timeout";
|
|
98410
|
+
return `error: ${err instanceof Error ? err.message : String(err)}`;
|
|
98411
|
+
}
|
|
98412
|
+
}
|
|
98413
|
+
async function testOllamaCloud(baseUrl, apiKey) {
|
|
98414
|
+
const url2 = `${baseUrl}/api/tags`;
|
|
98415
|
+
const signal = AbortSignal.timeout(TIMEOUT_MS);
|
|
98416
|
+
try {
|
|
98417
|
+
const resp = await fetch(url2, {
|
|
98418
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
98419
|
+
signal
|
|
98420
|
+
});
|
|
98421
|
+
if (resp.ok)
|
|
98422
|
+
return "valid";
|
|
98423
|
+
return `invalid (HTTP ${resp.status})`;
|
|
98424
|
+
} catch (err) {
|
|
98425
|
+
if (err instanceof Error && err.name === "TimeoutError")
|
|
98426
|
+
return "timeout";
|
|
98427
|
+
return `error: ${err instanceof Error ? err.message : String(err)}`;
|
|
98428
|
+
}
|
|
98429
|
+
}
|
|
98430
|
+
async function testProviderKey(providerName, apiKey) {
|
|
98431
|
+
const allDefs = getAllProviders();
|
|
98432
|
+
const canonicalName = providerName === "gemini" ? "google" : providerName;
|
|
98433
|
+
const def = allDefs.find((d2) => d2.name === canonicalName);
|
|
98434
|
+
if (!def)
|
|
98435
|
+
return "unsupported provider";
|
|
98436
|
+
const family = getApiFamily(def);
|
|
98437
|
+
const baseUrl = resolveBaseUrl(def);
|
|
98438
|
+
switch (family) {
|
|
98439
|
+
case "openai":
|
|
98440
|
+
return testOpenAI(baseUrl, apiKey);
|
|
98441
|
+
case "anthropic":
|
|
98442
|
+
return testAnthropic(baseUrl, apiKey, def.authScheme === "bearer" ? "bearer" : "x-api-key");
|
|
98443
|
+
case "gemini":
|
|
98444
|
+
return testGemini(baseUrl, apiKey);
|
|
98445
|
+
case "ollamacloud":
|
|
98446
|
+
return testOllamaCloud(baseUrl, apiKey);
|
|
98447
|
+
default:
|
|
98448
|
+
return "unsupported provider";
|
|
98449
|
+
}
|
|
98450
|
+
}
|
|
98451
|
+
var TIMEOUT_MS = 1e4;
|
|
98452
|
+
var init_test_provider = __esm(() => {
|
|
98453
|
+
init_provider_definitions();
|
|
98454
|
+
});
|
|
98455
|
+
|
|
98321
98456
|
// src/tui/providers.ts
|
|
98322
98457
|
function toProviderDef(def) {
|
|
98323
98458
|
return {
|
|
@@ -98403,6 +98538,10 @@ function App() {
|
|
|
98403
98538
|
const [chainOrder, setChainOrder] = import_react13.useState([]);
|
|
98404
98539
|
const [chainCursor, setChainCursor] = import_react13.useState(0);
|
|
98405
98540
|
const [statusMsg, setStatusMsg] = import_react13.useState(null);
|
|
98541
|
+
const [testResults, setTestResults] = import_react13.useState({});
|
|
98542
|
+
const [probeMode, setProbeMode] = import_react13.useState("idle");
|
|
98543
|
+
const [probeModel, setProbeModel] = import_react13.useState("");
|
|
98544
|
+
const [probeResults, setProbeResults] = import_react13.useState([]);
|
|
98406
98545
|
const CHAIN_PROVIDERS = PROVIDERS;
|
|
98407
98546
|
const quit = import_react13.useCallback(() => renderer.destroy(), [renderer]);
|
|
98408
98547
|
const displayProviders = import_react13.useMemo(() => {
|
|
@@ -98434,6 +98573,110 @@ function App() {
|
|
|
98434
98573
|
useKeyboard((key) => {
|
|
98435
98574
|
if (key.ctrl && key.name === "c")
|
|
98436
98575
|
return quit();
|
|
98576
|
+
if (probeMode === "input") {
|
|
98577
|
+
if (key.name === "return" || key.name === "enter") {
|
|
98578
|
+
const model = probeModel.trim();
|
|
98579
|
+
if (!model) {
|
|
98580
|
+
setProbeModel("");
|
|
98581
|
+
setProbeMode("idle");
|
|
98582
|
+
return;
|
|
98583
|
+
}
|
|
98584
|
+
const parsed = parseModelSpec(model);
|
|
98585
|
+
const chain = getFallbackChain(model, parsed.provider);
|
|
98586
|
+
if (chain.length === 0) {
|
|
98587
|
+
setProbeResults([
|
|
98588
|
+
{
|
|
98589
|
+
provider: "none",
|
|
98590
|
+
displayName: "No routes found",
|
|
98591
|
+
status: "failed",
|
|
98592
|
+
error: "No credentials configured for any provider"
|
|
98593
|
+
}
|
|
98594
|
+
]);
|
|
98595
|
+
setProbeMode("done");
|
|
98596
|
+
return;
|
|
98597
|
+
}
|
|
98598
|
+
const ruleEntries2 = Object.entries(config3.routing ?? {});
|
|
98599
|
+
const matchedRule = ruleEntries2.find(([pat]) => {
|
|
98600
|
+
if (pat === model)
|
|
98601
|
+
return true;
|
|
98602
|
+
if (pat.includes("*")) {
|
|
98603
|
+
const regex2 = new RegExp("^" + pat.replace(/\*/g, ".*") + "$");
|
|
98604
|
+
return regex2.test(model);
|
|
98605
|
+
}
|
|
98606
|
+
return false;
|
|
98607
|
+
});
|
|
98608
|
+
const initial = chain.map((r) => {
|
|
98609
|
+
const provDef = PROVIDERS.find((p) => p.name === r.provider);
|
|
98610
|
+
const hk = !!(provDef && (config3.apiKeys?.[provDef.apiKeyEnvVar] || process.env[provDef.apiKeyEnvVar]));
|
|
98611
|
+
return {
|
|
98612
|
+
provider: r.provider,
|
|
98613
|
+
displayName: r.displayName,
|
|
98614
|
+
status: hk ? "pending" : "no_key",
|
|
98615
|
+
hasKey: hk,
|
|
98616
|
+
reason: matchedRule ? `Custom rule: ${matchedRule[0]}` : "Default fallback chain"
|
|
98617
|
+
};
|
|
98618
|
+
});
|
|
98619
|
+
setProbeResults(initial);
|
|
98620
|
+
setProbeMode("running");
|
|
98621
|
+
(async () => {
|
|
98622
|
+
for (let i = 0;i < chain.length; i++) {
|
|
98623
|
+
const entry = initial[i];
|
|
98624
|
+
if (!entry.hasKey) {
|
|
98625
|
+
continue;
|
|
98626
|
+
}
|
|
98627
|
+
setProbeResults((prev) => prev.map((e, idx) => idx === i ? { ...e, status: "testing" } : e));
|
|
98628
|
+
const startMs = Date.now();
|
|
98629
|
+
const provDef = PROVIDERS.find((p) => p.name === chain[i].provider);
|
|
98630
|
+
const apiKey = (provDef ? config3.apiKeys?.[provDef.apiKeyEnvVar] || process.env[provDef.apiKeyEnvVar] : undefined) ?? "";
|
|
98631
|
+
const elapsed = () => Date.now() - startMs;
|
|
98632
|
+
const result = await testProviderKey(chain[i].provider, apiKey);
|
|
98633
|
+
const ms = elapsed();
|
|
98634
|
+
const ok = result === "valid";
|
|
98635
|
+
setProbeResults((prev) => prev.map((e, idx) => {
|
|
98636
|
+
if (idx === i)
|
|
98637
|
+
return { ...e, status: ok ? "success" : "failed", error: ok ? undefined : result, ms };
|
|
98638
|
+
if (idx > i && ok && e.status !== "no_key")
|
|
98639
|
+
return { ...e, status: "skipped" };
|
|
98640
|
+
return e;
|
|
98641
|
+
}));
|
|
98642
|
+
if (ok)
|
|
98643
|
+
break;
|
|
98644
|
+
}
|
|
98645
|
+
setProbeMode("done");
|
|
98646
|
+
})();
|
|
98647
|
+
return;
|
|
98648
|
+
} else if (key.name === "escape") {
|
|
98649
|
+
setProbeModel("");
|
|
98650
|
+
setProbeMode("idle");
|
|
98651
|
+
} else if (key.name === "backspace" || key.name === "delete") {
|
|
98652
|
+
setProbeModel((p) => p.slice(0, -1));
|
|
98653
|
+
} else if (key.raw && key.raw.length === 1 && !key.ctrl && !key.meta) {
|
|
98654
|
+
setProbeModel((p) => p + key.raw);
|
|
98655
|
+
}
|
|
98656
|
+
return;
|
|
98657
|
+
}
|
|
98658
|
+
if (probeMode === "running" && activeTab === "routing") {
|
|
98659
|
+
if (key.name === "escape") {
|
|
98660
|
+
setProbeModel("");
|
|
98661
|
+
setProbeResults([]);
|
|
98662
|
+
setProbeMode("idle");
|
|
98663
|
+
}
|
|
98664
|
+
return;
|
|
98665
|
+
}
|
|
98666
|
+
if (probeMode === "done" && activeTab === "routing") {
|
|
98667
|
+
if (key.name === "q") {
|
|
98668
|
+
return quit();
|
|
98669
|
+
} else if (key.name === "escape" || key.name === "p") {
|
|
98670
|
+
setProbeModel("");
|
|
98671
|
+
setProbeResults([]);
|
|
98672
|
+
setProbeMode("idle");
|
|
98673
|
+
} else if (key.name === "return" || key.name === "enter") {
|
|
98674
|
+
setProbeModel("");
|
|
98675
|
+
setProbeResults([]);
|
|
98676
|
+
setProbeMode("input");
|
|
98677
|
+
}
|
|
98678
|
+
return;
|
|
98679
|
+
}
|
|
98437
98680
|
if (mode === "input_key" || mode === "input_endpoint") {
|
|
98438
98681
|
if (key.name === "return" || key.name === "enter") {
|
|
98439
98682
|
const val = inputValue.trim();
|
|
@@ -98591,6 +98834,23 @@ function App() {
|
|
|
98591
98834
|
} else {
|
|
98592
98835
|
setStatusMsg("No stored key to remove.");
|
|
98593
98836
|
}
|
|
98837
|
+
} else if (key.name === "t") {
|
|
98838
|
+
const apiKey = config3.apiKeys?.[selectedProvider.apiKeyEnvVar] || process.env[selectedProvider.apiKeyEnvVar];
|
|
98839
|
+
const provName = selectedProvider.name;
|
|
98840
|
+
if (!apiKey) {
|
|
98841
|
+
setTestResults((prev) => ({ ...prev, [provName]: { status: "failed", error: "No key configured" } }));
|
|
98842
|
+
return;
|
|
98843
|
+
}
|
|
98844
|
+
setTestResults((prev) => ({ ...prev, [provName]: { status: "testing" } }));
|
|
98845
|
+
const startMs = Date.now();
|
|
98846
|
+
testProviderKey(provName, apiKey).then((result) => {
|
|
98847
|
+
const ms = Date.now() - startMs;
|
|
98848
|
+
const ok = result === "valid";
|
|
98849
|
+
setTestResults((prev) => ({
|
|
98850
|
+
...prev,
|
|
98851
|
+
[provName]: ok ? { status: "valid", ms } : { status: "failed", error: result, ms }
|
|
98852
|
+
}));
|
|
98853
|
+
});
|
|
98594
98854
|
}
|
|
98595
98855
|
} else if (activeTab === "routing") {
|
|
98596
98856
|
if (key.name === "a") {
|
|
@@ -98615,6 +98875,11 @@ function App() {
|
|
|
98615
98875
|
setProviderIndex((i) => Math.max(0, i - 1));
|
|
98616
98876
|
} else if (key.name === "down" || key.name === "j") {
|
|
98617
98877
|
setProviderIndex((i) => Math.min(Math.max(0, ruleEntries.length - 1), i + 1));
|
|
98878
|
+
} else if (key.name === "p") {
|
|
98879
|
+
setProbeModel("");
|
|
98880
|
+
setProbeResults([]);
|
|
98881
|
+
setStatusMsg(null);
|
|
98882
|
+
setProbeMode("input");
|
|
98618
98883
|
}
|
|
98619
98884
|
} else if (activeTab === "privacy") {
|
|
98620
98885
|
if (key.name === "t") {
|
|
@@ -98771,6 +99036,21 @@ function App() {
|
|
|
98771
99036
|
const isFirstUnready = !isReady && !separatorRendered;
|
|
98772
99037
|
if (isFirstUnready)
|
|
98773
99038
|
separatorRendered = true;
|
|
99039
|
+
const tr = testResults[p.name];
|
|
99040
|
+
let statusFg = isReady ? C2.green : C2.dim;
|
|
99041
|
+
let statusText = isReady ? "ready " : "not set";
|
|
99042
|
+
if (tr) {
|
|
99043
|
+
if (tr.status === "testing") {
|
|
99044
|
+
statusFg = C2.yellow;
|
|
99045
|
+
statusText = "testing";
|
|
99046
|
+
} else if (tr.status === "valid") {
|
|
99047
|
+
statusFg = C2.green;
|
|
99048
|
+
statusText = tr.ms !== undefined ? `ready ${tr.ms}ms` : "ready \u2713";
|
|
99049
|
+
} else {
|
|
99050
|
+
statusFg = C2.red;
|
|
99051
|
+
statusText = "FAIL ";
|
|
99052
|
+
}
|
|
99053
|
+
}
|
|
98774
99054
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98775
99055
|
flexDirection: "column",
|
|
98776
99056
|
children: [
|
|
@@ -98794,8 +99074,8 @@ function App() {
|
|
|
98794
99074
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98795
99075
|
children: [
|
|
98796
99076
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
98797
|
-
fg: isReady ? C2.green : C2.dim,
|
|
98798
|
-
children: isReady ? "\u25CF" : "\u25CB"
|
|
99077
|
+
fg: tr?.status === "testing" ? C2.yellow : isReady ? C2.green : C2.dim,
|
|
99078
|
+
children: tr?.status === "testing" ? "\u25CC" : isReady ? "\u25CF" : "\u25CB"
|
|
98799
99079
|
}, undefined, false, undefined, this),
|
|
98800
99080
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
98801
99081
|
children: " "
|
|
@@ -98809,13 +99089,10 @@ function App() {
|
|
|
98809
99089
|
fg: C2.dim,
|
|
98810
99090
|
children: " "
|
|
98811
99091
|
}, undefined, false, undefined, this),
|
|
98812
|
-
|
|
98813
|
-
fg:
|
|
98814
|
-
bold:
|
|
98815
|
-
children:
|
|
98816
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
98817
|
-
fg: C2.dim,
|
|
98818
|
-
children: "not set"
|
|
99092
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99093
|
+
fg: statusFg,
|
|
99094
|
+
bold: tr?.status === "valid" || isReady,
|
|
99095
|
+
children: statusText
|
|
98819
99096
|
}, undefined, false, undefined, this),
|
|
98820
99097
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
98821
99098
|
fg: C2.dim,
|
|
@@ -98951,6 +99228,7 @@ function App() {
|
|
|
98951
99228
|
]
|
|
98952
99229
|
}, undefined, true, undefined, this);
|
|
98953
99230
|
}
|
|
99231
|
+
const tr = testResults[selectedProvider.name];
|
|
98954
99232
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98955
99233
|
height: DETAIL_H,
|
|
98956
99234
|
border: true,
|
|
@@ -99055,6 +99333,50 @@ function App() {
|
|
|
99055
99333
|
children: selectedProvider.keyUrl
|
|
99056
99334
|
}, undefined, false, undefined, this)
|
|
99057
99335
|
]
|
|
99336
|
+
}, undefined, true, undefined, this),
|
|
99337
|
+
tr && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99338
|
+
children: [
|
|
99339
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99340
|
+
fg: C2.blue,
|
|
99341
|
+
bold: true,
|
|
99342
|
+
children: "Test: "
|
|
99343
|
+
}, undefined, false, undefined, this),
|
|
99344
|
+
tr.status === "testing" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99345
|
+
fg: C2.yellow,
|
|
99346
|
+
bold: true,
|
|
99347
|
+
children: "\u25CC testing..."
|
|
99348
|
+
}, undefined, false, undefined, this),
|
|
99349
|
+
tr.status === "valid" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
99350
|
+
children: [
|
|
99351
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99352
|
+
fg: C2.green,
|
|
99353
|
+
bold: true,
|
|
99354
|
+
children: "\u25CF valid"
|
|
99355
|
+
}, undefined, false, undefined, this),
|
|
99356
|
+
tr.ms !== undefined && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99357
|
+
fg: C2.dim,
|
|
99358
|
+
children: ` ${tr.ms}ms`
|
|
99359
|
+
}, undefined, false, undefined, this),
|
|
99360
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99361
|
+
fg: C2.fgMuted,
|
|
99362
|
+
children: " API key is valid and endpoint is reachable."
|
|
99363
|
+
}, undefined, false, undefined, this)
|
|
99364
|
+
]
|
|
99365
|
+
}, undefined, true, undefined, this),
|
|
99366
|
+
tr.status === "failed" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
99367
|
+
children: [
|
|
99368
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99369
|
+
fg: C2.red,
|
|
99370
|
+
bold: true,
|
|
99371
|
+
children: "\u2717 failed"
|
|
99372
|
+
}, undefined, false, undefined, this),
|
|
99373
|
+
tr.error && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99374
|
+
fg: C2.red,
|
|
99375
|
+
children: ` ${tr.error}`
|
|
99376
|
+
}, undefined, false, undefined, this)
|
|
99377
|
+
]
|
|
99378
|
+
}, undefined, true, undefined, this)
|
|
99379
|
+
]
|
|
99058
99380
|
}, undefined, true, undefined, this)
|
|
99059
99381
|
]
|
|
99060
99382
|
}, undefined, true, undefined, this);
|
|
@@ -99062,7 +99384,265 @@ function App() {
|
|
|
99062
99384
|
function chainStr(chain) {
|
|
99063
99385
|
return chain.join(" \u2192 ");
|
|
99064
99386
|
}
|
|
99387
|
+
const PROVIDER_REASONS = {
|
|
99388
|
+
litellm: "LiteLLM proxy",
|
|
99389
|
+
"opencode-zen": "Free tier (OpenCode Zen)",
|
|
99390
|
+
"opencode-zen-go": "Zen Go plan",
|
|
99391
|
+
kimi: "Native Kimi API",
|
|
99392
|
+
"kimi-coding": "Kimi Coding Plan",
|
|
99393
|
+
minimax: "Native MiniMax API",
|
|
99394
|
+
"minimax-coding": "MiniMax Coding Plan",
|
|
99395
|
+
glm: "Native GLM API",
|
|
99396
|
+
"glm-coding": "GLM Coding Plan",
|
|
99397
|
+
google: "Direct Gemini API",
|
|
99398
|
+
openai: "Direct OpenAI API",
|
|
99399
|
+
zai: "Z.AI API",
|
|
99400
|
+
ollamacloud: "Cloud Ollama",
|
|
99401
|
+
vertex: "Vertex AI Express",
|
|
99402
|
+
openrouter: "Fallback: 580+ models"
|
|
99403
|
+
};
|
|
99065
99404
|
function RoutingContent() {
|
|
99405
|
+
const probeBoxH = contentH + DETAIL_H + 1;
|
|
99406
|
+
if (probeMode === "input") {
|
|
99407
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99408
|
+
height: probeBoxH,
|
|
99409
|
+
border: true,
|
|
99410
|
+
borderStyle: "single",
|
|
99411
|
+
borderColor: C2.focusBorder,
|
|
99412
|
+
backgroundColor: C2.bg,
|
|
99413
|
+
flexDirection: "column",
|
|
99414
|
+
paddingX: 2,
|
|
99415
|
+
paddingY: 1,
|
|
99416
|
+
children: [
|
|
99417
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99418
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99419
|
+
fg: C2.white,
|
|
99420
|
+
bold: true,
|
|
99421
|
+
children: "Route Probe"
|
|
99422
|
+
}, undefined, false, undefined, this)
|
|
99423
|
+
}, undefined, false, undefined, this),
|
|
99424
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99425
|
+
children: " "
|
|
99426
|
+
}, undefined, false, undefined, this),
|
|
99427
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99428
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99429
|
+
fg: C2.fgMuted,
|
|
99430
|
+
children: "Enter a model name to trace its routing chain:"
|
|
99431
|
+
}, undefined, false, undefined, this)
|
|
99432
|
+
}, undefined, false, undefined, this),
|
|
99433
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99434
|
+
flexDirection: "row",
|
|
99435
|
+
height: 1,
|
|
99436
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99437
|
+
children: [
|
|
99438
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99439
|
+
fg: C2.green,
|
|
99440
|
+
bold: true,
|
|
99441
|
+
children: "> "
|
|
99442
|
+
}, undefined, false, undefined, this),
|
|
99443
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99444
|
+
fg: C2.white,
|
|
99445
|
+
children: probeModel
|
|
99446
|
+
}, undefined, false, undefined, this),
|
|
99447
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99448
|
+
fg: C2.cyan,
|
|
99449
|
+
children: "\u2588"
|
|
99450
|
+
}, undefined, false, undefined, this)
|
|
99451
|
+
]
|
|
99452
|
+
}, undefined, true, undefined, this)
|
|
99453
|
+
}, undefined, false, undefined, this),
|
|
99454
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99455
|
+
children: " "
|
|
99456
|
+
}, undefined, false, undefined, this),
|
|
99457
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99458
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99459
|
+
fg: C2.dim,
|
|
99460
|
+
children: "Examples: kimi-k2 deepseek-r1 gemini-2.0-flash gpt-4o"
|
|
99461
|
+
}, undefined, false, undefined, this)
|
|
99462
|
+
}, undefined, false, undefined, this),
|
|
99463
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99464
|
+
children: " "
|
|
99465
|
+
}, undefined, false, undefined, this),
|
|
99466
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99467
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99468
|
+
fg: C2.fgMuted,
|
|
99469
|
+
children: "The probe resolves the fallback chain and tests each provider's"
|
|
99470
|
+
}, undefined, false, undefined, this)
|
|
99471
|
+
}, undefined, false, undefined, this),
|
|
99472
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99473
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99474
|
+
fg: C2.fgMuted,
|
|
99475
|
+
children: "API key in order, stopping at the first success."
|
|
99476
|
+
}, undefined, false, undefined, this)
|
|
99477
|
+
}, undefined, false, undefined, this)
|
|
99478
|
+
]
|
|
99479
|
+
}, undefined, true, undefined, this);
|
|
99480
|
+
}
|
|
99481
|
+
if (probeMode === "running" || probeMode === "done") {
|
|
99482
|
+
const successEntry = probeResults.find((e) => e.status === "success");
|
|
99483
|
+
const allFailed = probeMode === "done" && !successEntry;
|
|
99484
|
+
const totalMs = successEntry?.ms;
|
|
99485
|
+
const statusBadge = probeMode === "running" ? { text: "probing...", color: C2.yellow } : successEntry ? { text: "routed", color: C2.green } : { text: "no route", color: C2.red };
|
|
99486
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99487
|
+
height: probeBoxH,
|
|
99488
|
+
border: true,
|
|
99489
|
+
borderStyle: "single",
|
|
99490
|
+
borderColor: probeMode === "running" ? C2.focusBorder : C2.blue,
|
|
99491
|
+
backgroundColor: C2.bg,
|
|
99492
|
+
flexDirection: "column",
|
|
99493
|
+
paddingX: 2,
|
|
99494
|
+
paddingY: 1,
|
|
99495
|
+
children: [
|
|
99496
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99497
|
+
flexDirection: "row",
|
|
99498
|
+
height: 1,
|
|
99499
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99500
|
+
children: [
|
|
99501
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99502
|
+
fg: C2.white,
|
|
99503
|
+
bold: true,
|
|
99504
|
+
children: probeMode === "done" ? "Probe: " : "Probing: "
|
|
99505
|
+
}, undefined, false, undefined, this),
|
|
99506
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99507
|
+
fg: C2.cyan,
|
|
99508
|
+
bold: true,
|
|
99509
|
+
children: probeModel
|
|
99510
|
+
}, undefined, false, undefined, this),
|
|
99511
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99512
|
+
fg: C2.dim,
|
|
99513
|
+
children: " "
|
|
99514
|
+
}, undefined, false, undefined, this),
|
|
99515
|
+
probeMode === "done" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99516
|
+
fg: statusBadge.color,
|
|
99517
|
+
bold: true,
|
|
99518
|
+
children: [
|
|
99519
|
+
successEntry ? "\u25CF " : "\u2717 ",
|
|
99520
|
+
statusBadge.text
|
|
99521
|
+
]
|
|
99522
|
+
}, undefined, true, undefined, this),
|
|
99523
|
+
probeMode === "running" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99524
|
+
fg: C2.yellow,
|
|
99525
|
+
children: "\u25CC probing..."
|
|
99526
|
+
}, undefined, false, undefined, this)
|
|
99527
|
+
]
|
|
99528
|
+
}, undefined, true, undefined, this)
|
|
99529
|
+
}, undefined, false, undefined, this),
|
|
99530
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99531
|
+
children: " "
|
|
99532
|
+
}, undefined, false, undefined, this),
|
|
99533
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99534
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99535
|
+
fg: C2.fgMuted,
|
|
99536
|
+
children: probeResults[0]?.reason ?? `Chain (${probeResults.length} providers):`
|
|
99537
|
+
}, undefined, false, undefined, this)
|
|
99538
|
+
}, undefined, false, undefined, this),
|
|
99539
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99540
|
+
children: " "
|
|
99541
|
+
}, undefined, false, undefined, this),
|
|
99542
|
+
probeResults.map((entry, idx) => {
|
|
99543
|
+
const isNoKey = entry.status === "no_key";
|
|
99544
|
+
const isNotReached = entry.status === "skipped";
|
|
99545
|
+
const isSelected = entry.status === "success" && probeMode === "done";
|
|
99546
|
+
const statusIcon = entry.status === "success" ? "\u25CF" : entry.status === "failed" ? "\u2717" : entry.status === "testing" ? "\u25CC" : isNoKey ? "\u25CB" : isNotReached ? "\xB7" : "\u25CB";
|
|
99547
|
+
const statusColor = entry.status === "success" ? C2.green : entry.status === "failed" ? C2.red : entry.status === "testing" ? C2.yellow : C2.dim;
|
|
99548
|
+
const nameCol = entry.displayName.padEnd(18).substring(0, 18);
|
|
99549
|
+
const statusText = entry.status === "success" ? entry.ms !== undefined ? `${entry.ms}ms` : "success" : entry.status === "failed" ? entry.error ?? "failed" : entry.status === "testing" ? "testing..." : isNoKey ? "not configured, skipping" : isNotReached ? "not reached" : "waiting";
|
|
99550
|
+
const reason = PROVIDER_REASONS[entry.provider] ?? entry.provider;
|
|
99551
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99552
|
+
flexDirection: "column",
|
|
99553
|
+
children: [
|
|
99554
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99555
|
+
children: [
|
|
99556
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99557
|
+
fg: C2.dim,
|
|
99558
|
+
children: `${idx + 1}. `
|
|
99559
|
+
}, undefined, false, undefined, this),
|
|
99560
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99561
|
+
fg: isNoKey ? C2.dim : isSelected ? C2.white : isNotReached ? C2.dim : C2.fgMuted,
|
|
99562
|
+
bold: isSelected,
|
|
99563
|
+
children: nameCol
|
|
99564
|
+
}, undefined, false, undefined, this),
|
|
99565
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99566
|
+
fg: C2.dim,
|
|
99567
|
+
children: " "
|
|
99568
|
+
}, undefined, false, undefined, this),
|
|
99569
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99570
|
+
fg: statusColor,
|
|
99571
|
+
bold: entry.status === "success",
|
|
99572
|
+
children: [
|
|
99573
|
+
statusIcon,
|
|
99574
|
+
" ",
|
|
99575
|
+
statusText
|
|
99576
|
+
]
|
|
99577
|
+
}, undefined, true, undefined, this),
|
|
99578
|
+
isSelected && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99579
|
+
fg: C2.green,
|
|
99580
|
+
bold: true,
|
|
99581
|
+
children: " \u2190 routed here"
|
|
99582
|
+
}, undefined, false, undefined, this)
|
|
99583
|
+
]
|
|
99584
|
+
}, undefined, true, undefined, this),
|
|
99585
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99586
|
+
children: [
|
|
99587
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99588
|
+
fg: C2.dim,
|
|
99589
|
+
children: " \u21B3 "
|
|
99590
|
+
}, undefined, false, undefined, this),
|
|
99591
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99592
|
+
fg: isNoKey ? C2.dim : C2.fgMuted,
|
|
99593
|
+
children: reason
|
|
99594
|
+
}, undefined, false, undefined, this)
|
|
99595
|
+
]
|
|
99596
|
+
}, undefined, true, undefined, this)
|
|
99597
|
+
]
|
|
99598
|
+
}, entry.provider, true, undefined, this);
|
|
99599
|
+
}),
|
|
99600
|
+
probeMode === "done" && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
99601
|
+
children: [
|
|
99602
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99603
|
+
children: " "
|
|
99604
|
+
}, undefined, false, undefined, this),
|
|
99605
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
99606
|
+
children: allFailed ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
99607
|
+
children: [
|
|
99608
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99609
|
+
fg: C2.red,
|
|
99610
|
+
bold: true,
|
|
99611
|
+
children: "Result: "
|
|
99612
|
+
}, undefined, false, undefined, this),
|
|
99613
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99614
|
+
fg: C2.red,
|
|
99615
|
+
children: "\u2717 No provider could serve this model"
|
|
99616
|
+
}, undefined, false, undefined, this)
|
|
99617
|
+
]
|
|
99618
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
99619
|
+
children: [
|
|
99620
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99621
|
+
fg: C2.green,
|
|
99622
|
+
bold: true,
|
|
99623
|
+
children: "Result: "
|
|
99624
|
+
}, undefined, false, undefined, this),
|
|
99625
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99626
|
+
fg: C2.fgMuted,
|
|
99627
|
+
children: "Routed to "
|
|
99628
|
+
}, undefined, false, undefined, this),
|
|
99629
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99630
|
+
fg: C2.cyan,
|
|
99631
|
+
bold: true,
|
|
99632
|
+
children: successEntry.displayName
|
|
99633
|
+
}, undefined, false, undefined, this),
|
|
99634
|
+
totalMs !== undefined && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
|
|
99635
|
+
fg: C2.fgMuted,
|
|
99636
|
+
children: ` in ${totalMs}ms`
|
|
99637
|
+
}, undefined, false, undefined, this)
|
|
99638
|
+
]
|
|
99639
|
+
}, undefined, true, undefined, this)
|
|
99640
|
+
}, undefined, false, undefined, this)
|
|
99641
|
+
]
|
|
99642
|
+
}, undefined, true, undefined, this)
|
|
99643
|
+
]
|
|
99644
|
+
}, undefined, true, undefined, this);
|
|
99645
|
+
}
|
|
99066
99646
|
const innerH = contentH - 2;
|
|
99067
99647
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99068
99648
|
height: contentH,
|
|
@@ -99340,6 +99920,9 @@ function App() {
|
|
|
99340
99920
|
}, undefined, true, undefined, this);
|
|
99341
99921
|
}
|
|
99342
99922
|
function RoutingDetail() {
|
|
99923
|
+
if (probeMode !== "idle") {
|
|
99924
|
+
return null;
|
|
99925
|
+
}
|
|
99343
99926
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
99344
99927
|
height: DETAIL_H,
|
|
99345
99928
|
border: true,
|
|
@@ -99661,11 +100244,29 @@ function App() {
|
|
|
99661
100244
|
}
|
|
99662
100245
|
function Footer() {
|
|
99663
100246
|
let keys;
|
|
99664
|
-
if (activeTab === "
|
|
100247
|
+
if (activeTab === "routing" && probeMode === "input") {
|
|
100248
|
+
keys = [
|
|
100249
|
+
[C2.green, "Enter", "probe"],
|
|
100250
|
+
[C2.red, "Esc", "cancel"]
|
|
100251
|
+
];
|
|
100252
|
+
} else if (activeTab === "routing" && probeMode === "running") {
|
|
100253
|
+
keys = [
|
|
100254
|
+
[C2.yellow, "\u25CC", "probing..."],
|
|
100255
|
+
[C2.red, "Esc", "cancel"]
|
|
100256
|
+
];
|
|
100257
|
+
} else if (activeTab === "routing" && probeMode === "done") {
|
|
100258
|
+
keys = [
|
|
100259
|
+
[C2.cyan, "p", "back to routes"],
|
|
100260
|
+
[C2.green, "Enter", "probe another"],
|
|
100261
|
+
[C2.red, "Esc", "back to routes"],
|
|
100262
|
+
[C2.dim, "q", "quit"]
|
|
100263
|
+
];
|
|
100264
|
+
} else if (activeTab === "providers") {
|
|
99665
100265
|
keys = [
|
|
99666
100266
|
[C2.blue, "\u2191\u2193", "navigate"],
|
|
99667
100267
|
[C2.green, "s", "set key"],
|
|
99668
100268
|
[C2.green, "e", "endpoint"],
|
|
100269
|
+
[C2.cyan, "t", "test key"],
|
|
99669
100270
|
[C2.red, "x", "remove"],
|
|
99670
100271
|
[C2.blue, "Tab", "section"],
|
|
99671
100272
|
[C2.dim, "q", "quit"]
|
|
@@ -99675,6 +100276,7 @@ function App() {
|
|
|
99675
100276
|
[C2.blue, "\u2191\u2193", "navigate"],
|
|
99676
100277
|
[C2.green, "a", "add rule"],
|
|
99677
100278
|
[C2.red, "d", "delete"],
|
|
100279
|
+
[C2.cyan, "p", "probe"],
|
|
99678
100280
|
[C2.blue, "Tab", "section"],
|
|
99679
100281
|
[C2.dim, "q", "quit"]
|
|
99680
100282
|
];
|
|
@@ -99801,7 +100403,10 @@ function App() {
|
|
|
99801
100403
|
var import_react13, VERSION2 = "v5.16";
|
|
99802
100404
|
var init_App = __esm(async () => {
|
|
99803
100405
|
init_profile_config();
|
|
100406
|
+
init_auto_route();
|
|
100407
|
+
init_model_parser();
|
|
99804
100408
|
init_stats_buffer();
|
|
100409
|
+
init_test_provider();
|
|
99805
100410
|
init_providers();
|
|
99806
100411
|
init_theme2();
|
|
99807
100412
|
init_jsx_dev_runtime();
|
|
@@ -100506,7 +101111,7 @@ __export(exports_pty_diag_runner, {
|
|
|
100506
101111
|
MtmDiagRunner: () => MtmDiagRunner
|
|
100507
101112
|
});
|
|
100508
101113
|
import { spawn as spawn3 } from "child_process";
|
|
100509
|
-
import { appendFileSync, createWriteStream as createWriteStream3, existsSync as existsSync21, mkdirSync as mkdirSync12, unlinkSync as unlinkSync9
|
|
101114
|
+
import { appendFileSync, createWriteStream as createWriteStream3, existsSync as existsSync21, mkdirSync as mkdirSync12, unlinkSync as unlinkSync9 } from "fs";
|
|
100510
101115
|
import { homedir as homedir20 } from "os";
|
|
100511
101116
|
import { dirname as dirname6, join as join23 } from "path";
|
|
100512
101117
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -100526,17 +101131,13 @@ class MtmDiagRunner {
|
|
|
100526
101131
|
this.statusPath = join23(dir, `status-${process.pid}.txt`);
|
|
100527
101132
|
this.logStream = createWriteStream3(this.logPath, { flags: "w" });
|
|
100528
101133
|
this.logStream.on("error", () => {});
|
|
100529
|
-
try {
|
|
100530
|
-
writeFileSync13(this.statusPath, renderStatusBar({ model: "", provider: "", errorCount: 0, lastError: "" }) + `
|
|
100531
|
-
`);
|
|
100532
|
-
} catch {}
|
|
100533
101134
|
}
|
|
100534
101135
|
async run(claudeCommand, claudeArgs, env2) {
|
|
100535
101136
|
const mtmBin = this.findMtmBinary();
|
|
100536
101137
|
const quotedArgs = claudeArgs.map((a) => shellQuote(a)).join(" ");
|
|
100537
101138
|
const claudeCmd = `${shellQuote(claudeCommand)} ${quotedArgs}`;
|
|
100538
101139
|
const mergedEnv = { ...process.env, ...env2 };
|
|
100539
|
-
this.mtmProc = spawn3(mtmBin, ["-e", claudeCmd, "-S", this.statusPath], {
|
|
101140
|
+
this.mtmProc = spawn3(mtmBin, ["-e", claudeCmd, "-S", this.statusPath, "-L", this.logPath], {
|
|
100540
101141
|
stdio: "inherit",
|
|
100541
101142
|
env: mergedEnv
|
|
100542
101143
|
});
|
|
@@ -100596,7 +101197,6 @@ class MtmDiagRunner {
|
|
|
100596
101197
|
} else if (name.includes("/")) {
|
|
100597
101198
|
this.provider = name.split("/")[0];
|
|
100598
101199
|
}
|
|
100599
|
-
this.refreshStatusBar();
|
|
100600
101200
|
}
|
|
100601
101201
|
refreshStatusBar() {
|
|
100602
101202
|
const bar = renderStatusBar({
|
|
@@ -105265,7 +105865,7 @@ async function describeImage(image, auth) {
|
|
|
105265
105865
|
if (auth["x-api-key"])
|
|
105266
105866
|
headers["x-api-key"] = auth["x-api-key"];
|
|
105267
105867
|
const controller = new AbortController;
|
|
105268
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
105868
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS2);
|
|
105269
105869
|
try {
|
|
105270
105870
|
const response = await fetch(VISION_ENDPOINT, {
|
|
105271
105871
|
method: "POST",
|
|
@@ -105289,7 +105889,7 @@ async function describeImage(image, auth) {
|
|
|
105289
105889
|
} catch (err) {
|
|
105290
105890
|
clearTimeout(timeoutId);
|
|
105291
105891
|
if (err.name === "AbortError") {
|
|
105292
|
-
log(`[VisionProxy] Request timed out after ${
|
|
105892
|
+
log(`[VisionProxy] Request timed out after ${TIMEOUT_MS2}ms`);
|
|
105293
105893
|
} else {
|
|
105294
105894
|
log(`[VisionProxy] Fetch error: ${err.message}`);
|
|
105295
105895
|
}
|
|
@@ -105312,7 +105912,7 @@ async function describeImages(images, auth) {
|
|
|
105312
105912
|
return null;
|
|
105313
105913
|
}
|
|
105314
105914
|
}
|
|
105315
|
-
var VISION_MODEL = "claude-sonnet-4-20250514", MAX_TOKENS_PER_IMAGE = 1024, VISION_ENDPOINT = "https://api.anthropic.com/v1/messages",
|
|
105915
|
+
var VISION_MODEL = "claude-sonnet-4-20250514", MAX_TOKENS_PER_IMAGE = 1024, VISION_ENDPOINT = "https://api.anthropic.com/v1/messages", TIMEOUT_MS2 = 30000, DESCRIPTION_PROMPT = `Describe this image in detail for a model that cannot see images. Provide:
|
|
105316
105916
|
- All visible text content (exact quotes where possible)
|
|
105317
105917
|
- Layout and structure (how elements are arranged spatially)
|
|
105318
105918
|
- Colors, visual style, and key visual elements
|
|
@@ -105491,13 +106091,13 @@ class ComposedHandler {
|
|
|
105491
106091
|
providerDisplayName: this.provider.displayName,
|
|
105492
106092
|
streamFormat: this.provider.streamFormat,
|
|
105493
106093
|
modelId: this.targetModel,
|
|
105494
|
-
httpStatus:
|
|
106094
|
+
httpStatus: 401,
|
|
105495
106095
|
isStreaming: false,
|
|
105496
106096
|
retryAttempted: false,
|
|
105497
106097
|
isInteractive: this.isInteractive,
|
|
105498
106098
|
authType: "oauth"
|
|
105499
106099
|
});
|
|
105500
|
-
return c.json({ error: { type: "
|
|
106100
|
+
return c.json({ error: { type: "authentication_error", message: err.message } }, 401);
|
|
105501
106101
|
}
|
|
105502
106102
|
}
|
|
105503
106103
|
if (this.provider.getContextWindow) {
|
|
Binary file
|
package/package.json
CHANGED