@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.
@@ -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-CsCLdrXq.mjs";
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("img", { src: OpenAILogoSvg, alt: "OpenAI", className, style: sizeStyle })
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
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
2152
- /* @__PURE__ */ jsxRuntimeExports.jsx(Minus, { className: "size-3" }),
2153
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Not configured" })
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
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
2167
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
2168
- "div",
2169
- {
2170
- className: "flex items-center gap-1 text-xs text-red-600 min-w-0",
2171
- title: error?.details ?? errorMessage,
2172
- children: [
2173
- getErrorIcon(errorType),
2174
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: errorMessage })
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, isTesting })
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, isTesting })
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
- onProvidersChange,
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 ?? internalProviders;
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
- }, [fetchProviders]);
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: { notConfigured: true }, streaming: { notConfigured: true } },
2570
- openai: { nonStreaming: { notConfigured: true }, streaming: { notConfigured: true } }
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
- await fetchProviders();
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
- await fetchProviders();
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
- await fetchProviders();
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
- await fetchProviders();
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 (isLoading && providers.length === 0) {
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(Button, { variant: "outline", size: "sm", onClick: () => handleExport(), className: "gap-1", children: [
2822
- /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "size-3" }),
2823
- "Export"
2824
- ] }),
2825
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", size: "sm", onClick: handleImportClick, className: "gap-1", children: [
2826
- /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "size-3" }),
2827
- "Import"
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 [providers, setProviders] = reactExports.useState([]);
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
- onProvidersChange: setProviders,
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-BF6ge6dS.mjs");
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-CsCLdrXq.mjs").then((n) => n.r);
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-B3RwBPLW.css";
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-CAIDMqNv.mjs");
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(`Stream read error: ${readErr}`, latencyMs, true);
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-BrU8NdGQ.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-CB8ZIeEk.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-BrU8NdGQ.js" });
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
  };
@@ -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-04T00:12:14.535Z",
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-04T00:12:14.537Z",
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-BrU8NdGQ.js": {
114
+ "/assets/main-Beo3LJDa.js": {
122
115
  "type": "text/javascript; charset=utf-8",
123
- "etag": '"4db57-Aw3zM46XAKLPcPLc9vLSzFsuUjI"',
124
- "mtime": "2026-06-04T00:12:14.537Z",
125
- "size": 318295,
126
- "path": "../public/assets/main-BrU8NdGQ.js"
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-04T00:12:14.535Z",
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-04T00:12:14.535Z",
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-CB8ZIeEk.js": {
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": '"840e2-X78/yEmQlQ7ABa9KL5bfVykPAUY"',
145
- "mtime": "2026-06-04T00:12:14.537Z",
146
- "size": 540898,
147
- "path": "../public/assets/index-CB8ZIeEk.js"
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) {