@tonyclaw/llm-inspector 1.7.9 → 1.8.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/.output/nitro.json +1 -1
- package/.output/public/assets/index-BLVa7n9b.css +1 -0
- package/.output/public/assets/index-DH3FOgcK.js +97 -0
- package/.output/public/assets/main-Beo3LJDa.js +17 -0
- package/.output/server/_libs/dequal.mjs +27 -0
- package/.output/server/_libs/swr.mjs +938 -0
- package/.output/server/_libs/use-sync-external-store.mjs +64 -1
- package/.output/server/_ssr/{index-CAIDMqNv.mjs → index-HkueJ4Un.mjs} +114 -62
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-CsCLdrXq.mjs → router-DTswxb7l.mjs} +25 -11
- package/.output/server/{_tanstack-start-manifest_v-BF6ge6dS.mjs → _tanstack-start-manifest_v-DhUuivt-.mjs} +1 -1
- package/.output/server/index.mjs +21 -21
- package/package.json +2 -1
- package/src/components/ProxyViewer.tsx +2 -0
- package/src/components/providers/ProviderCard.tsx +38 -33
- package/src/components/providers/ProviderLogo.tsx +6 -1
- package/src/components/providers/ProvidersPanel.tsx +29 -34
- package/src/components/providers/SettingsDialog.tsx +5 -3
- package/src/lib/useProviders.ts +30 -0
- package/src/routes/__root.tsx +4 -1
- package/.output/public/assets/index-B3RwBPLW.css +0 -1
- package/.output/public/assets/index-CB8ZIeEk.js +0 -97
- package/.output/public/assets/main-BrU8NdGQ.js +0 -17
|
@@ -1 +1,64 @@
|
|
|
1
|
-
|
|
1
|
+
import { b as requireReact } from "./react.mjs";
|
|
2
|
+
var shim = { exports: {} };
|
|
3
|
+
var useSyncExternalStoreShim_production = {};
|
|
4
|
+
var hasRequiredUseSyncExternalStoreShim_production;
|
|
5
|
+
function requireUseSyncExternalStoreShim_production() {
|
|
6
|
+
if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
|
|
7
|
+
hasRequiredUseSyncExternalStoreShim_production = 1;
|
|
8
|
+
var React = /* @__PURE__ */ requireReact();
|
|
9
|
+
function is(x, y) {
|
|
10
|
+
return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
|
|
11
|
+
}
|
|
12
|
+
var objectIs = "function" === typeof Object.is ? Object.is : is, useState = React.useState, useEffect = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue = React.useDebugValue;
|
|
13
|
+
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
14
|
+
var value = getSnapshot(), _useState = useState({ inst: { value, getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1];
|
|
15
|
+
useLayoutEffect(
|
|
16
|
+
function() {
|
|
17
|
+
inst.value = value;
|
|
18
|
+
inst.getSnapshot = getSnapshot;
|
|
19
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
20
|
+
},
|
|
21
|
+
[subscribe, value, getSnapshot]
|
|
22
|
+
);
|
|
23
|
+
useEffect(
|
|
24
|
+
function() {
|
|
25
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
26
|
+
return subscribe(function() {
|
|
27
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
[subscribe]
|
|
31
|
+
);
|
|
32
|
+
useDebugValue(value);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function checkIfSnapshotChanged(inst) {
|
|
36
|
+
var latestGetSnapshot = inst.getSnapshot;
|
|
37
|
+
inst = inst.value;
|
|
38
|
+
try {
|
|
39
|
+
var nextValue = latestGetSnapshot();
|
|
40
|
+
return !objectIs(inst, nextValue);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
46
|
+
return getSnapshot();
|
|
47
|
+
}
|
|
48
|
+
var shim2 = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
49
|
+
useSyncExternalStoreShim_production.useSyncExternalStore = void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim2;
|
|
50
|
+
return useSyncExternalStoreShim_production;
|
|
51
|
+
}
|
|
52
|
+
var hasRequiredShim;
|
|
53
|
+
function requireShim() {
|
|
54
|
+
if (hasRequiredShim) return shim.exports;
|
|
55
|
+
hasRequiredShim = 1;
|
|
56
|
+
{
|
|
57
|
+
shim.exports = /* @__PURE__ */ requireUseSyncExternalStoreShim_production();
|
|
58
|
+
}
|
|
59
|
+
return shim.exports;
|
|
60
|
+
}
|
|
61
|
+
var shimExports = /* @__PURE__ */ requireShim();
|
|
62
|
+
export {
|
|
63
|
+
shimExports as s
|
|
64
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-
|
|
2
|
+
import { C as CapturedLogSchema, a as parseRequest, p as parseOpenAIResponse, I as InspectorResponseSchema } from "./router-DTswxb7l.mjs";
|
|
3
3
|
import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
4
4
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -7,6 +7,7 @@ import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
|
7
7
|
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
8
8
|
import { R as Root, T as Trigger$1, C as Content, a as Close, b as Title, P as Portal$1, O as Overlay } from "../_libs/radix-ui__react-dialog.mjs";
|
|
9
9
|
import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
|
|
10
|
+
import { u as useSWR } from "../_libs/swr.mjs";
|
|
10
11
|
import { D as Download, L as LayoutGrid, a as List, S as Settings, C as ChevronDown, b as Check, R as RotateCcw, X, U as Upload, P as Plus, c as Copy, d as CircleAlert, e as ChevronUp, f as ChevronRight, g as Clock, M as MessageSquare, Z as Zap, h as LoaderCircle, W as Wrench, G as Globe, i as User, F as FileTerminal, j as Radio, E as ExternalLink, k as EyeOff, l as Eye, m as RotateCw, n as Pencil, T as Trash2, o as TriangleAlert, p as Minus, q as CircleCheckBig, r as CircleStop, s as CircleQuestionMark, t as Server, u as Gauge, v as Lock, w as Wifi, x as WifiOff, y as ChevronsUp, z as ChevronsDown, A as Terminal, B as Brain } from "../_libs/lucide-react.mjs";
|
|
11
12
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
12
13
|
import { a as array, s as string, u as union, o as object, l as literal, n as number, b as boolean } from "../_libs/zod.mjs";
|
|
@@ -57,6 +58,8 @@ import "../_libs/mimic-function.mjs";
|
|
|
57
58
|
import "../_libs/semver.mjs";
|
|
58
59
|
import "../_libs/uint8array-extras.mjs";
|
|
59
60
|
import "node:child_process";
|
|
61
|
+
import "../_libs/use-sync-external-store.mjs";
|
|
62
|
+
import "../_libs/dequal.mjs";
|
|
60
63
|
import "../_libs/tanstack__virtual-core.mjs";
|
|
61
64
|
import "../_libs/readable-stream.mjs";
|
|
62
65
|
import "../_libs/process-nextick-args.mjs";
|
|
@@ -196,6 +199,10 @@ async function exportLogsAsZip(logs) {
|
|
|
196
199
|
document.body.removeChild(anchor);
|
|
197
200
|
URL.revokeObjectURL(url);
|
|
198
201
|
}
|
|
202
|
+
const version = "1.8.0";
|
|
203
|
+
const packageJson = {
|
|
204
|
+
version
|
|
205
|
+
};
|
|
199
206
|
function cn(...inputs) {
|
|
200
207
|
return twMerge(clsx(inputs));
|
|
201
208
|
}
|
|
@@ -891,7 +898,15 @@ const AnthropicLogo = React.memo(
|
|
|
891
898
|
({ className }) => /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: AnthropicLogoSvg, alt: "Anthropic", className, style: sizeStyle })
|
|
892
899
|
);
|
|
893
900
|
const OpenAILogo = React.memo(
|
|
894
|
-
({ className }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
901
|
+
({ className }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
902
|
+
"img",
|
|
903
|
+
{
|
|
904
|
+
src: OpenAILogoSvg,
|
|
905
|
+
alt: "OpenAI",
|
|
906
|
+
className,
|
|
907
|
+
style: { ...sizeStyle, background: "white", borderRadius: "4px" }
|
|
908
|
+
}
|
|
909
|
+
)
|
|
895
910
|
);
|
|
896
911
|
const DeepSeekLogo = React.memo(
|
|
897
912
|
({ className }) => /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: DeepSeekLogoSvg, alt: "DeepSeek", className, style: sizeStyle })
|
|
@@ -2120,6 +2135,9 @@ function maskApiKey(apiKey) {
|
|
|
2120
2135
|
function hasSuccessField(result) {
|
|
2121
2136
|
return Object.prototype.hasOwnProperty.call(result, "success");
|
|
2122
2137
|
}
|
|
2138
|
+
function isNotConfiguredState(result) {
|
|
2139
|
+
return Object.prototype.hasOwnProperty.call(result, "notConfigured");
|
|
2140
|
+
}
|
|
2123
2141
|
function getErrorIcon(type) {
|
|
2124
2142
|
const iconProps = { className: "size-3", strokeWidth: 2 };
|
|
2125
2143
|
switch (type) {
|
|
@@ -2143,18 +2161,21 @@ function getErrorIcon(type) {
|
|
|
2143
2161
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { ...iconProps });
|
|
2144
2162
|
}
|
|
2145
2163
|
}
|
|
2146
|
-
function TestStatus({
|
|
2147
|
-
result,
|
|
2148
|
-
isTesting
|
|
2149
|
-
}) {
|
|
2164
|
+
function TestStatus({ result }) {
|
|
2150
2165
|
if (!hasSuccessField(result)) {
|
|
2151
|
-
|
|
2152
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
2153
|
-
|
|
2166
|
+
if (isNotConfiguredState(result)) {
|
|
2167
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground shrink-0", children: [
|
|
2168
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Minus, { className: "size-3" }),
|
|
2169
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Not configured" })
|
|
2170
|
+
] });
|
|
2171
|
+
}
|
|
2172
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground shrink-0", children: [
|
|
2173
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-3 animate-spin" }),
|
|
2174
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Testing..." })
|
|
2154
2175
|
] });
|
|
2155
2176
|
}
|
|
2156
2177
|
if (result.success) {
|
|
2157
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600", children: [
|
|
2178
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600 shrink-0", children: [
|
|
2158
2179
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "size-3" }),
|
|
2159
2180
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Connected" })
|
|
2160
2181
|
] });
|
|
@@ -2163,20 +2184,18 @@ function TestStatus({
|
|
|
2163
2184
|
const errorMessage = error?.message ?? "Connection failed";
|
|
2164
2185
|
const errorHint = error?.hint;
|
|
2165
2186
|
const errorType = error?.type ?? "unknown";
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
errorHint !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground pl-4 truncate", title: errorHint, children: errorHint })
|
|
2179
|
-
] });
|
|
2187
|
+
const fullMessage = errorHint !== void 0 ? `${errorMessage} — ${errorHint}` : errorMessage;
|
|
2188
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2189
|
+
"div",
|
|
2190
|
+
{
|
|
2191
|
+
className: "flex items-center gap-1 text-xs text-red-600 shrink-0 max-w-[200px]",
|
|
2192
|
+
title: error?.details ?? fullMessage,
|
|
2193
|
+
children: [
|
|
2194
|
+
getErrorIcon(errorType),
|
|
2195
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: errorMessage })
|
|
2196
|
+
]
|
|
2197
|
+
}
|
|
2198
|
+
);
|
|
2180
2199
|
}
|
|
2181
2200
|
function ProviderCard({
|
|
2182
2201
|
provider,
|
|
@@ -2228,7 +2247,7 @@ function ProviderCard({
|
|
|
2228
2247
|
" ",
|
|
2229
2248
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.anthropicBaseUrl })
|
|
2230
2249
|
] }),
|
|
2231
|
-
testResults && /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: testResults.anthropic.nonStreaming
|
|
2250
|
+
testResults && /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: testResults.anthropic.nonStreaming })
|
|
2232
2251
|
] }),
|
|
2233
2252
|
provider.openaiBaseUrl !== void 0 && provider.openaiBaseUrl !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2234
2253
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground min-w-0 flex-1", children: [
|
|
@@ -2236,7 +2255,7 @@ function ProviderCard({
|
|
|
2236
2255
|
" ",
|
|
2237
2256
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: provider.openaiBaseUrl })
|
|
2238
2257
|
] }),
|
|
2239
|
-
testResults && /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: testResults.openai.nonStreaming
|
|
2258
|
+
testResults && /* @__PURE__ */ jsxRuntimeExports.jsx(TestStatus, { result: testResults.openai.nonStreaming })
|
|
2240
2259
|
] }),
|
|
2241
2260
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-1 border-t", children: [
|
|
2242
2261
|
onTest !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2505,13 +2524,11 @@ function ProvidersPanel({
|
|
|
2505
2524
|
externalTestResults,
|
|
2506
2525
|
externalTestingProviders,
|
|
2507
2526
|
externalTestingTimeLeft,
|
|
2508
|
-
|
|
2527
|
+
onProvidersMutate,
|
|
2509
2528
|
onTestResultsChange,
|
|
2510
2529
|
onTestingProvidersChange,
|
|
2511
2530
|
onTestingTimeLeftChange
|
|
2512
2531
|
}) {
|
|
2513
|
-
const [internalProviders, setInternalProviders] = reactExports.useState([]);
|
|
2514
|
-
const [isLoading, setIsLoading] = reactExports.useState(true);
|
|
2515
2532
|
const [showForm, setShowForm] = reactExports.useState(false);
|
|
2516
2533
|
const [editingProvider, setEditingProvider] = reactExports.useState();
|
|
2517
2534
|
const [error, setError] = reactExports.useState(null);
|
|
@@ -2522,8 +2539,7 @@ function ProvidersPanel({
|
|
|
2522
2539
|
);
|
|
2523
2540
|
const [configPath, setConfigPath] = reactExports.useState(null);
|
|
2524
2541
|
const [configPathCopied, setConfigPathCopied] = reactExports.useState(false);
|
|
2525
|
-
const providers = externalProviders ??
|
|
2526
|
-
const setProviders = onProvidersChange ?? setInternalProviders;
|
|
2542
|
+
const providers = externalProviders ?? [];
|
|
2527
2543
|
const testResults = externalTestResults ?? internalTestResults;
|
|
2528
2544
|
const testingProviders = externalTestingProviders ?? internalTestingProviders;
|
|
2529
2545
|
const testingTimeLeft = externalTestingTimeLeft ?? internalTestingTimeLeft;
|
|
@@ -2538,19 +2554,7 @@ function ProvidersPanel({
|
|
|
2538
2554
|
setInternalTestingTimeLeft((prev) => ({ ...prev, [id]: seconds }));
|
|
2539
2555
|
}
|
|
2540
2556
|
};
|
|
2541
|
-
const fetchProviders = reactExports.useCallback(async () => {
|
|
2542
|
-
try {
|
|
2543
|
-
const providersRes = await fetch("/api/providers");
|
|
2544
|
-
const providersData = await providersRes.json();
|
|
2545
|
-
setProviders(providersData);
|
|
2546
|
-
} catch {
|
|
2547
|
-
setError("Failed to load providers");
|
|
2548
|
-
} finally {
|
|
2549
|
-
setIsLoading(false);
|
|
2550
|
-
}
|
|
2551
|
-
}, []);
|
|
2552
2557
|
reactExports.useEffect(() => {
|
|
2553
|
-
void fetchProviders();
|
|
2554
2558
|
void (async () => {
|
|
2555
2559
|
try {
|
|
2556
2560
|
const res = await fetch("/api/config/paths");
|
|
@@ -2561,13 +2565,13 @@ function ProvidersPanel({
|
|
|
2561
2565
|
} catch {
|
|
2562
2566
|
}
|
|
2563
2567
|
})();
|
|
2564
|
-
}, [
|
|
2568
|
+
}, []);
|
|
2565
2569
|
const TEST_TIMEOUT_SECONDS = 30;
|
|
2566
2570
|
const runTest = reactExports.useCallback(
|
|
2567
2571
|
async (providerId) => {
|
|
2568
2572
|
const resetResults = {
|
|
2569
|
-
anthropic: { nonStreaming: {
|
|
2570
|
-
openai: { nonStreaming: {
|
|
2573
|
+
anthropic: { nonStreaming: { testing: true }, streaming: { testing: true } },
|
|
2574
|
+
openai: { nonStreaming: { testing: true }, streaming: { testing: true } }
|
|
2571
2575
|
};
|
|
2572
2576
|
if (onTestResultsChange) {
|
|
2573
2577
|
onTestResultsChange(providerId, resetResults);
|
|
@@ -2690,7 +2694,7 @@ function ProvidersPanel({
|
|
|
2690
2694
|
return;
|
|
2691
2695
|
}
|
|
2692
2696
|
const newProvider = await res.json();
|
|
2693
|
-
|
|
2697
|
+
onProvidersMutate?.();
|
|
2694
2698
|
setShowForm(false);
|
|
2695
2699
|
await runTest(newProvider.id);
|
|
2696
2700
|
})();
|
|
@@ -2717,7 +2721,7 @@ function ProvidersPanel({
|
|
|
2717
2721
|
return;
|
|
2718
2722
|
}
|
|
2719
2723
|
const updated = await res.json();
|
|
2720
|
-
|
|
2724
|
+
onProvidersMutate?.();
|
|
2721
2725
|
setEditingProvider(void 0);
|
|
2722
2726
|
await runTest(updated.id);
|
|
2723
2727
|
})();
|
|
@@ -2733,7 +2737,7 @@ function ProvidersPanel({
|
|
|
2733
2737
|
setError(err.error ?? "Failed to delete provider");
|
|
2734
2738
|
return;
|
|
2735
2739
|
}
|
|
2736
|
-
|
|
2740
|
+
onProvidersMutate?.();
|
|
2737
2741
|
})();
|
|
2738
2742
|
}
|
|
2739
2743
|
const fileInputRef = reactExports.useRef(null);
|
|
@@ -2782,7 +2786,7 @@ function ProvidersPanel({
|
|
|
2782
2786
|
});
|
|
2783
2787
|
const data = ImportResponseSchema.parse(await res.json());
|
|
2784
2788
|
if (res.ok && data.imported !== void 0 && data.imported > 0) {
|
|
2785
|
-
|
|
2789
|
+
onProvidersMutate?.();
|
|
2786
2790
|
setError(null);
|
|
2787
2791
|
} else if (data.errors && data.errors.length > 0) {
|
|
2788
2792
|
setError(data.errors.join("; "));
|
|
@@ -2795,7 +2799,7 @@ function ProvidersPanel({
|
|
|
2795
2799
|
e.target.value = "";
|
|
2796
2800
|
})();
|
|
2797
2801
|
}
|
|
2798
|
-
if (
|
|
2802
|
+
if (providers.length === 0) {
|
|
2799
2803
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: "Loading providers..." }) });
|
|
2800
2804
|
}
|
|
2801
2805
|
if (showForm || editingProvider) {
|
|
@@ -2815,17 +2819,35 @@ function ProvidersPanel({
|
|
|
2815
2819
|
] });
|
|
2816
2820
|
}
|
|
2817
2821
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
2818
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between sticky top-0 z-10 bg-background pb-2", children: [
|
|
2819
2823
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium", children: "Providers" }),
|
|
2820
2824
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2821
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2825
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2826
|
+
Button,
|
|
2827
|
+
{
|
|
2828
|
+
variant: "outline",
|
|
2829
|
+
size: "sm",
|
|
2830
|
+
onClick: () => handleExport(),
|
|
2831
|
+
className: "gap-1 hover:bg-muted",
|
|
2832
|
+
children: [
|
|
2833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3" }),
|
|
2834
|
+
"Export"
|
|
2835
|
+
]
|
|
2836
|
+
}
|
|
2837
|
+
),
|
|
2838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2839
|
+
Button,
|
|
2840
|
+
{
|
|
2841
|
+
variant: "outline",
|
|
2842
|
+
size: "sm",
|
|
2843
|
+
onClick: handleImportClick,
|
|
2844
|
+
className: "gap-1 hover:bg-muted",
|
|
2845
|
+
children: [
|
|
2846
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3" }),
|
|
2847
|
+
"Import"
|
|
2848
|
+
]
|
|
2849
|
+
}
|
|
2850
|
+
),
|
|
2829
2851
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2830
2852
|
"input",
|
|
2831
2853
|
{
|
|
@@ -2888,10 +2910,34 @@ function ProvidersPanel({
|
|
|
2888
2910
|
)) })
|
|
2889
2911
|
] });
|
|
2890
2912
|
}
|
|
2913
|
+
async function fetcher(url) {
|
|
2914
|
+
const response = await fetch(url);
|
|
2915
|
+
const data = await response.json();
|
|
2916
|
+
if (!Array.isArray(data)) {
|
|
2917
|
+
return [];
|
|
2918
|
+
}
|
|
2919
|
+
return data;
|
|
2920
|
+
}
|
|
2921
|
+
function useProviders() {
|
|
2922
|
+
const response = useSWR(
|
|
2923
|
+
"/api/providers",
|
|
2924
|
+
fetcher,
|
|
2925
|
+
{
|
|
2926
|
+
revalidateOnFocus: false,
|
|
2927
|
+
revalidateIfStale: false
|
|
2928
|
+
}
|
|
2929
|
+
);
|
|
2930
|
+
return {
|
|
2931
|
+
providers: response.data ?? [],
|
|
2932
|
+
isLoading: response.isLoading,
|
|
2933
|
+
isError: response.error,
|
|
2934
|
+
mutate: response.mutate
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2891
2937
|
function SettingsDialog() {
|
|
2892
2938
|
const [open, setOpen] = reactExports.useState(false);
|
|
2893
2939
|
const [activeTab, setActiveTab] = reactExports.useState("providers");
|
|
2894
|
-
const
|
|
2940
|
+
const { providers, mutate } = useProviders();
|
|
2895
2941
|
const [testResults, setTestResults] = reactExports.useState({});
|
|
2896
2942
|
const [testingProviders, setTestingProviders] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
2897
2943
|
const [testingTimeLeft, setTestingTimeLeft] = reactExports.useState({});
|
|
@@ -2941,7 +2987,9 @@ function SettingsDialog() {
|
|
|
2941
2987
|
externalTestResults: testResults,
|
|
2942
2988
|
externalTestingProviders: testingProviders,
|
|
2943
2989
|
externalTestingTimeLeft: testingTimeLeft,
|
|
2944
|
-
|
|
2990
|
+
onProvidersMutate: () => {
|
|
2991
|
+
void mutate();
|
|
2992
|
+
},
|
|
2945
2993
|
onTestResultsChange: handleTestResultsChange,
|
|
2946
2994
|
onTestingProvidersChange: handleTestingProvidersChange,
|
|
2947
2995
|
onTestingTimeLeftChange: handleTestingTimeLeftChange
|
|
@@ -3051,6 +3099,10 @@ function ProxyViewer({
|
|
|
3051
3099
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-[1200px] mx-auto flex flex-col h-screen", style: { maxHeight: "100vh" }, children: [
|
|
3052
3100
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 mb-4 px-6 pt-6", children: [
|
|
3053
3101
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-bold flex-1", children: "LLM Proxy Inspector" }),
|
|
3102
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground text-xs font-mono", children: [
|
|
3103
|
+
"v",
|
|
3104
|
+
packageJson.version
|
|
3105
|
+
] }),
|
|
3054
3106
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center border border-border rounded-md overflow-hidden", children: [
|
|
3055
3107
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3056
3108
|
"button",
|
|
@@ -197,7 +197,7 @@ function getResponse() {
|
|
|
197
197
|
return event.res;
|
|
198
198
|
}
|
|
199
199
|
async function getStartManifest(matchedRoutes) {
|
|
200
|
-
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-
|
|
200
|
+
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DhUuivt-.mjs");
|
|
201
201
|
const startManifest = tsrStartManifest();
|
|
202
202
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
203
203
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -766,7 +766,7 @@ let entriesPromise;
|
|
|
766
766
|
let baseManifestPromise;
|
|
767
767
|
let cachedFinalManifestPromise;
|
|
768
768
|
async function loadEntries() {
|
|
769
|
-
const routerEntry = await import("./router-
|
|
769
|
+
const routerEntry = await import("./router-DTswxb7l.mjs").then((n) => n.r);
|
|
770
770
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
771
771
|
return { startEntry, routerEntry };
|
|
772
772
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { c as createRouter, a as createRootRoute, b as createFileRoute, l as lazyRouteComponent, O as Outlet, H as HeadContent, S as Scripts } from "../_libs/tanstack__react-router.mjs";
|
|
2
2
|
import { j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
3
|
+
import { S as SWRConfig } from "../_libs/swr.mjs";
|
|
3
4
|
import { mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, existsSync, readFileSync } from "node:fs";
|
|
4
5
|
import path, { join, dirname, isAbsolute } from "node:path";
|
|
5
6
|
import { readFile, mkdir, writeFile, appendFile } from "node:fs/promises";
|
|
@@ -22,6 +23,8 @@ import "util";
|
|
|
22
23
|
import "async_hooks";
|
|
23
24
|
import "stream";
|
|
24
25
|
import "../_libs/isbot.mjs";
|
|
26
|
+
import "../_libs/use-sync-external-store.mjs";
|
|
27
|
+
import "../_libs/dequal.mjs";
|
|
25
28
|
import "node:process";
|
|
26
29
|
import "node:crypto";
|
|
27
30
|
import "node:assert";
|
|
@@ -41,7 +44,7 @@ import "../_libs/debounce-fn.mjs";
|
|
|
41
44
|
import "../_libs/mimic-function.mjs";
|
|
42
45
|
import "../_libs/semver.mjs";
|
|
43
46
|
import "../_libs/uint8array-extras.mjs";
|
|
44
|
-
const appCss = "/assets/index-
|
|
47
|
+
const appCss = "/assets/index-BLVa7n9b.css";
|
|
45
48
|
const Route$g = createRootRoute({
|
|
46
49
|
head: () => ({
|
|
47
50
|
meta: [
|
|
@@ -60,12 +63,12 @@ function RootDocument({ children }) {
|
|
|
60
63
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("html", { lang: "en", className: "dark", children: [
|
|
61
64
|
/* @__PURE__ */ jsxRuntimeExports.jsx("head", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(HeadContent, {}) }),
|
|
62
65
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("body", { children: [
|
|
63
|
-
children,
|
|
66
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SWRConfig, { value: { revalidateOnFocus: false, revalidateIfStale: false }, children }),
|
|
64
67
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Scripts, {})
|
|
65
68
|
] })
|
|
66
69
|
] });
|
|
67
70
|
}
|
|
68
|
-
const $$splitComponentImporter = () => import("./index-
|
|
71
|
+
const $$splitComponentImporter = () => import("./index-HkueJ4Un.mjs");
|
|
69
72
|
const Route$f = createFileRoute("/")({
|
|
70
73
|
component: lazyRouteComponent($$splitComponentImporter, "component")
|
|
71
74
|
});
|
|
@@ -2306,7 +2309,7 @@ function truncateErrorDetails(details) {
|
|
|
2306
2309
|
}
|
|
2307
2310
|
return details.slice(0, MAX_ERROR_DETAILS_LENGTH) + "...";
|
|
2308
2311
|
}
|
|
2309
|
-
function createErrorResult(error, latencyMs, streaming, responseStatus) {
|
|
2312
|
+
function createErrorResult(error, latencyMs, streaming, responseStatus, requestHeaders) {
|
|
2310
2313
|
const { type, details } = classifyError(error, responseStatus);
|
|
2311
2314
|
return {
|
|
2312
2315
|
success: false,
|
|
@@ -2317,7 +2320,8 @@ function createErrorResult(error, latencyMs, streaming, responseStatus) {
|
|
|
2317
2320
|
hint: ERROR_HINTS[type]
|
|
2318
2321
|
},
|
|
2319
2322
|
latencyMs,
|
|
2320
|
-
streaming
|
|
2323
|
+
streaming,
|
|
2324
|
+
requestHeaders
|
|
2321
2325
|
};
|
|
2322
2326
|
}
|
|
2323
2327
|
function getErrorMessage(type) {
|
|
@@ -2394,7 +2398,8 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2394
2398
|
`HTTP ${response.status}: ${response.statusText}`,
|
|
2395
2399
|
latencyMs,
|
|
2396
2400
|
false,
|
|
2397
|
-
response.status
|
|
2401
|
+
response.status,
|
|
2402
|
+
requestHeaders
|
|
2398
2403
|
);
|
|
2399
2404
|
}
|
|
2400
2405
|
const responseText = await response.text();
|
|
@@ -2451,7 +2456,7 @@ async function testEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2451
2456
|
}
|
|
2452
2457
|
} catch (err) {
|
|
2453
2458
|
clearTimeout(timeoutId);
|
|
2454
|
-
return createErrorResult(err, Date.now() - startTime, false);
|
|
2459
|
+
return createErrorResult(err, Date.now() - startTime, false, void 0, requestHeaders);
|
|
2455
2460
|
}
|
|
2456
2461
|
}
|
|
2457
2462
|
async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
@@ -2483,7 +2488,8 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2483
2488
|
`HTTP ${response.status}: ${response.statusText}`,
|
|
2484
2489
|
latencyMs,
|
|
2485
2490
|
true,
|
|
2486
|
-
response.status
|
|
2491
|
+
response.status,
|
|
2492
|
+
requestHeaders
|
|
2487
2493
|
);
|
|
2488
2494
|
}
|
|
2489
2495
|
const chunks = [];
|
|
@@ -2511,7 +2517,9 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2511
2517
|
return createErrorResult(
|
|
2512
2518
|
"Response too large (exceeded 10MB limit)",
|
|
2513
2519
|
Date.now() - startTime,
|
|
2514
|
-
true
|
|
2520
|
+
true,
|
|
2521
|
+
void 0,
|
|
2522
|
+
requestHeaders
|
|
2515
2523
|
);
|
|
2516
2524
|
}
|
|
2517
2525
|
const decoded = decoder.decode(value, { stream: true });
|
|
@@ -2523,7 +2531,13 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2523
2531
|
chunks.push(finalChunk);
|
|
2524
2532
|
}
|
|
2525
2533
|
} catch (readErr) {
|
|
2526
|
-
return createErrorResult(
|
|
2534
|
+
return createErrorResult(
|
|
2535
|
+
`Stream read error: ${readErr}`,
|
|
2536
|
+
latencyMs,
|
|
2537
|
+
true,
|
|
2538
|
+
void 0,
|
|
2539
|
+
requestHeaders
|
|
2540
|
+
);
|
|
2527
2541
|
}
|
|
2528
2542
|
const fullResponse = chunks.join("");
|
|
2529
2543
|
const mockLog = {
|
|
@@ -2607,7 +2621,7 @@ async function testStreamingEndpoint(baseUrl, apiKey, path2, model, isOpenAI) {
|
|
|
2607
2621
|
}
|
|
2608
2622
|
} catch (err) {
|
|
2609
2623
|
clearTimeout(timeoutId);
|
|
2610
|
-
return createErrorResult(err, Date.now() - startTime, true);
|
|
2624
|
+
return createErrorResult(err, Date.now() - startTime, true, void 0, requestHeaders);
|
|
2611
2625
|
}
|
|
2612
2626
|
}
|
|
2613
2627
|
function createTestLogEntry(providerName, path2, body, upstreamUrl, result, isTest) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/health", "/api/logs", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/api/config/paths"], "preloads": ["/assets/main-Beo3LJDa.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-DH3FOgcK.js"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.import.ts" }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts" } }, "clientEntry": "/assets/main-Beo3LJDa.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -97,54 +97,54 @@ const headers = ((m) => function headersRouteRule(event) {
|
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
99
|
const assets = {
|
|
100
|
-
"/assets/index-B3RwBPLW.css": {
|
|
101
|
-
"type": "text/css; charset=utf-8",
|
|
102
|
-
"etag": '"10c74-aXacU4DRFVsUwcC5jHnjoPRSlTA"',
|
|
103
|
-
"mtime": "2026-06-04T00:12:14.535Z",
|
|
104
|
-
"size": 68724,
|
|
105
|
-
"path": "../public/assets/index-B3RwBPLW.css"
|
|
106
|
-
},
|
|
107
100
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
108
101
|
"type": "image/svg+xml",
|
|
109
102
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
110
|
-
"mtime": "2026-06-
|
|
103
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
111
104
|
"size": 5915,
|
|
112
105
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
113
106
|
},
|
|
114
107
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
115
108
|
"type": "image/jpeg",
|
|
116
109
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
117
|
-
"mtime": "2026-06-
|
|
110
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
118
111
|
"size": 6918,
|
|
119
112
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
120
113
|
},
|
|
121
|
-
"/assets/main-
|
|
114
|
+
"/assets/main-Beo3LJDa.js": {
|
|
122
115
|
"type": "text/javascript; charset=utf-8",
|
|
123
|
-
"etag": '"
|
|
124
|
-
"mtime": "2026-06-
|
|
125
|
-
"size":
|
|
126
|
-
"path": "../public/assets/main-
|
|
116
|
+
"etag": '"50591-/XG/Oh/RlDy7LRgwa0Uqfltq6fM"',
|
|
117
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
118
|
+
"size": 329105,
|
|
119
|
+
"path": "../public/assets/main-Beo3LJDa.js"
|
|
127
120
|
},
|
|
128
121
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
129
122
|
"type": "image/svg+xml",
|
|
130
123
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
131
|
-
"mtime": "2026-06-
|
|
124
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
132
125
|
"size": 11256,
|
|
133
126
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
134
127
|
},
|
|
135
128
|
"/assets/qwen-CONDcHqt.png": {
|
|
136
129
|
"type": "image/png",
|
|
137
130
|
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
138
|
-
"mtime": "2026-06-
|
|
131
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
139
132
|
"size": 357059,
|
|
140
133
|
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
141
134
|
},
|
|
142
|
-
"/assets/index-
|
|
135
|
+
"/assets/index-BLVa7n9b.css": {
|
|
136
|
+
"type": "text/css; charset=utf-8",
|
|
137
|
+
"etag": '"10ce0-rnZGppItQl8rOmyih342MZyZcI0"',
|
|
138
|
+
"mtime": "2026-06-04T01:19:08.282Z",
|
|
139
|
+
"size": 68832,
|
|
140
|
+
"path": "../public/assets/index-BLVa7n9b.css"
|
|
141
|
+
},
|
|
142
|
+
"/assets/index-DH3FOgcK.js": {
|
|
143
143
|
"type": "text/javascript; charset=utf-8",
|
|
144
|
-
"etag": '"
|
|
145
|
-
"mtime": "2026-06-
|
|
146
|
-
"size":
|
|
147
|
-
"path": "../public/assets/index-
|
|
144
|
+
"etag": '"8421c-gZ3NyuThEQLW3CYFr8ZxAzJ1zq0"',
|
|
145
|
+
"mtime": "2026-06-04T01:19:08.283Z",
|
|
146
|
+
"size": 541212,
|
|
147
|
+
"path": "../public/assets/index-DH3FOgcK.js"
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
function readAsset(id) {
|