@tonyclaw/llm-inspector 1.16.3 → 1.16.5

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.
Files changed (58) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/CompareDrawer-C1w4KUGZ.js +1 -0
  3. package/.output/public/assets/ReplayDialog-DR2Sgq_g.js +1 -0
  4. package/.output/public/assets/RequestAnatomy-DAre35kj.js +1 -0
  5. package/.output/public/assets/ResponseView-ackes7_g.js +1 -0
  6. package/.output/public/assets/StreamingChunkSequence-GrXwIGKA.js +1 -0
  7. package/.output/public/assets/index-BGzHFOEX.css +1 -0
  8. package/.output/public/assets/index-DX88k9br.js +101 -0
  9. package/.output/public/assets/json-viewer-C_QUhGeu.js +14 -0
  10. package/.output/public/assets/{main-Cpts3Ifr.js → main-CDMdNDY_.js} +1 -1
  11. package/.output/server/_libs/lucide-react.mjs +96 -76
  12. package/.output/server/_ssr/CompareDrawer-ftkJxyk6.mjs +1040 -0
  13. package/.output/server/_ssr/ReplayDialog-DcmE3lj5.mjs +321 -0
  14. package/.output/server/_ssr/RequestAnatomy-rK_LNMdG.mjs +351 -0
  15. package/.output/server/_ssr/ResponseView-CbQ4n-aJ.mjs +601 -0
  16. package/.output/server/_ssr/StreamingChunkSequence-84FZkIzv.mjs +301 -0
  17. package/.output/server/_ssr/{index-CjvQZBI0.mjs → index-CDjLoMsk.mjs} +1036 -2352
  18. package/.output/server/_ssr/index.mjs +2 -2
  19. package/.output/server/_ssr/json-viewer-B-qpM5xC.mjs +510 -0
  20. package/.output/server/_ssr/{router-CO9_4CVh.mjs → router-BrdjOUEW.mjs} +24 -14
  21. package/.output/server/{_tanstack-start-manifest_v-D-9SW7K3.mjs → _tanstack-start-manifest_v-DmOZEcJ3.mjs} +1 -1
  22. package/.output/server/index.mjs +72 -30
  23. package/package.json +1 -1
  24. package/src/components/OnboardingBanner.tsx +2 -2
  25. package/src/components/ProxyViewer.tsx +38 -26
  26. package/src/components/ProxyViewerContainer.tsx +3 -24
  27. package/src/components/proxy-viewer/CompareDrawer.tsx +6 -6
  28. package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
  29. package/src/components/proxy-viewer/ConversationHeader.tsx +4 -1
  30. package/src/components/proxy-viewer/LogEntry.tsx +230 -163
  31. package/src/components/proxy-viewer/LogEntryHeader.tsx +134 -36
  32. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +1 -1
  33. package/src/components/proxy-viewer/ThreadConnector.tsx +17 -2
  34. package/src/components/proxy-viewer/TurnGroup.tsx +94 -71
  35. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
  36. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
  37. package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
  38. package/src/components/proxy-viewer/anatomy/types.ts +39 -0
  39. package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
  40. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +4 -24
  41. package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
  42. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +6 -4
  43. package/src/components/proxy-viewer/lazy.ts +37 -0
  44. package/src/components/proxy-viewer/log-formats/anthropic.ts +146 -0
  45. package/src/components/proxy-viewer/log-formats/openai.ts +127 -0
  46. package/src/components/proxy-viewer/log-formats/types.ts +7 -0
  47. package/src/components/proxy-viewer/log-formats/unknown.ts +4 -0
  48. package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
  49. package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
  50. package/src/components/proxy-viewer/viewerState.ts +8 -0
  51. package/src/components/ui/crab-variants.tsx +11 -0
  52. package/src/components/ui/json-expansion-button.tsx +56 -0
  53. package/src/components/ui/json-viewer-bulk.ts +97 -0
  54. package/src/components/ui/json-viewer.tsx +129 -118
  55. package/src/lib/utils.ts +2 -3
  56. package/src/routes/api/logs.stream.ts +26 -16
  57. package/.output/public/assets/index-DRRCmu5p.css +0 -1
  58. package/.output/public/assets/index-DfjhkDNi.js +0 -107
@@ -198,7 +198,7 @@ function getResponse() {
198
198
  return event.res;
199
199
  }
200
200
  async function getStartManifest(matchedRoutes) {
201
- const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-D-9SW7K3.mjs");
201
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DmOZEcJ3.mjs");
202
202
  const startManifest = tsrStartManifest();
203
203
  const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
204
204
  rootRoute.assets = rootRoute.assets || [];
@@ -767,7 +767,7 @@ let entriesPromise;
767
767
  let baseManifestPromise;
768
768
  let cachedFinalManifestPromise;
769
769
  async function loadEntries() {
770
- const routerEntry = await import("./router-CO9_4CVh.mjs").then((n) => n.e);
770
+ const routerEntry = await import("./router-BrdjOUEW.mjs").then((n) => n.e);
771
771
  const startEntry = await import("./start-HYkvq4Ni.mjs");
772
772
  return { startEntry, routerEntry };
773
773
  }
@@ -0,0 +1,510 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { q as parseJsonText, c as cn, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./index-CDjLoMsk.mjs";
3
+ import "./router-BrdjOUEW.mjs";
4
+ import "../_libs/modelcontextprotocol__server.mjs";
5
+ import "../_libs/jszip.mjs";
6
+ import { C as Check, c as Copy, a as ChevronDown, f as ChevronRight, r as ChevronsDown } from "../_libs/lucide-react.mjs";
7
+ import { M as Markdown } from "../_libs/react-markdown.mjs";
8
+ import "../_libs/swr.mjs";
9
+ import "../_libs/use-sync-external-store.mjs";
10
+ import "../_libs/dequal.mjs";
11
+ import "../_libs/clsx.mjs";
12
+ import "../_libs/tailwind-merge.mjs";
13
+ import "../_libs/class-variance-authority.mjs";
14
+ import "../_libs/radix-ui__react-dialog.mjs";
15
+ import "../_libs/radix-ui__primitive.mjs";
16
+ import "../_libs/radix-ui__react-compose-refs.mjs";
17
+ import "../_libs/radix-ui__react-context.mjs";
18
+ import "../_libs/radix-ui__react-id.mjs";
19
+ import "../_libs/@radix-ui/react-use-layout-effect+[...].mjs";
20
+ import "../_libs/@radix-ui/react-use-controllable-state+[...].mjs";
21
+ import "../_libs/@radix-ui/react-dismissable-layer+[...].mjs";
22
+ import "../_libs/radix-ui__react-primitive.mjs";
23
+ import "../_libs/react-dom.mjs";
24
+ import "util";
25
+ import "async_hooks";
26
+ import "stream";
27
+ import "crypto";
28
+ import "../_libs/radix-ui__react-slot.mjs";
29
+ import "../_libs/@radix-ui/react-use-callback-ref+[...].mjs";
30
+ import "../_libs/@radix-ui/react-use-escape-keydown+[...].mjs";
31
+ import "../_libs/radix-ui__react-focus-scope.mjs";
32
+ import "../_libs/radix-ui__react-portal.mjs";
33
+ import "../_libs/radix-ui__react-presence.mjs";
34
+ import "../_libs/radix-ui__react-focus-guards.mjs";
35
+ import "../_libs/react-remove-scroll.mjs";
36
+ import "tslib";
37
+ import "../_libs/react-remove-scroll-bar.mjs";
38
+ import "../_libs/react-style-singleton.mjs";
39
+ import "../_libs/get-nonce.mjs";
40
+ import "../_libs/use-sidecar.mjs";
41
+ import "../_libs/use-callback-ref.mjs";
42
+ import "../_libs/aria-hidden.mjs";
43
+ import "../_libs/diff.mjs";
44
+ import "../_libs/tanstack__react-virtual.mjs";
45
+ import "../_libs/tanstack__virtual-core.mjs";
46
+ import "../_libs/radix-ui__react-select.mjs";
47
+ import "../_libs/radix-ui__number.mjs";
48
+ import "../_libs/radix-ui__react-collection.mjs";
49
+ import "../_libs/radix-ui__react-direction.mjs";
50
+ import "../_libs/radix-ui__react-popper.mjs";
51
+ import "../_libs/floating-ui__react-dom.mjs";
52
+ import "../_libs/floating-ui__dom.mjs";
53
+ import "../_libs/floating-ui__core.mjs";
54
+ import "../_libs/floating-ui__utils.mjs";
55
+ import "../_libs/radix-ui__react-arrow.mjs";
56
+ import "../_libs/radix-ui__react-use-size.mjs";
57
+ import "../_libs/radix-ui__react-use-previous.mjs";
58
+ import "../_libs/@radix-ui/react-visually-hidden+[...].mjs";
59
+ import "../_libs/zod.mjs";
60
+ import "../_libs/radix-ui__react-tabs.mjs";
61
+ import "../_libs/radix-ui__react-roving-focus.mjs";
62
+ import "../_libs/radix-ui__react-tooltip.mjs";
63
+ import "../_libs/tanstack__react-router.mjs";
64
+ import "../_libs/tiny-warning.mjs";
65
+ import "../_libs/tanstack__router-core.mjs";
66
+ import "../_libs/cookie-es.mjs";
67
+ import "../_libs/tanstack__history.mjs";
68
+ import "../_libs/tiny-invariant.mjs";
69
+ import "../_libs/seroval.mjs";
70
+ import "../_libs/seroval-plugins.mjs";
71
+ import "node:stream/web";
72
+ import "node:stream";
73
+ import "../_libs/isbot.mjs";
74
+ import "node:fs";
75
+ import "node:fs/promises";
76
+ import "node:buffer";
77
+ import "node:path";
78
+ import "../_libs/conf.mjs";
79
+ import "node:util";
80
+ import "node:process";
81
+ import "node:crypto";
82
+ import "node:assert";
83
+ import "../_libs/dot-prop.mjs";
84
+ import "../_libs/env-paths.mjs";
85
+ import "node:os";
86
+ import "../_libs/atomically.mjs";
87
+ import "../_libs/stubborn-fs.mjs";
88
+ import "../_libs/stubborn-utils.mjs";
89
+ import "../_libs/when-exit.mjs";
90
+ import "../_libs/ajv.mjs";
91
+ import "../_libs/fast-deep-equal.mjs";
92
+ import "../_libs/json-schema-traverse.mjs";
93
+ import "../_libs/fast-uri.mjs";
94
+ import "../_libs/ajv-formats.mjs";
95
+ import "../_libs/debounce-fn.mjs";
96
+ import "../_libs/mimic-function.mjs";
97
+ import "../_libs/semver.mjs";
98
+ import "../_libs/uint8array-extras.mjs";
99
+ import "node:child_process";
100
+ import "../_libs/readable-stream.mjs";
101
+ import "events";
102
+ import "node:string_decoder";
103
+ import "../_libs/process-nextick-args.mjs";
104
+ import "../_libs/isarray.mjs";
105
+ import "../_libs/safe-buffer.mjs";
106
+ import "buffer";
107
+ import "../_libs/core-util-is.mjs";
108
+ import "../_libs/inherits.mjs";
109
+ import "../_libs/util-deprecate.mjs";
110
+ import "../_libs/lie.mjs";
111
+ import "../_libs/immediate.mjs";
112
+ import "../_libs/setimmediate.mjs";
113
+ import "../_libs/pako.mjs";
114
+ import "../_libs/devlop.mjs";
115
+ import "../_libs/unified.mjs";
116
+ import "../_libs/bail.mjs";
117
+ import "../_libs/extend.mjs";
118
+ import "../_libs/is-plain-obj.mjs";
119
+ import "../_libs/trough.mjs";
120
+ import "../_libs/vfile.mjs";
121
+ import "../_libs/vfile-message.mjs";
122
+ import "../_libs/unist-util-stringify-position.mjs";
123
+ import "node:url";
124
+ import "../_libs/remark-parse.mjs";
125
+ import "../_libs/mdast-util-from-markdown.mjs";
126
+ import "../_libs/micromark-util-decode-numeric-character-reference+[...].mjs";
127
+ import "../_libs/micromark-util-decode-string.mjs";
128
+ import "../_libs/decode-named-character-reference+[...].mjs";
129
+ import "../_libs/character-entities.mjs";
130
+ import "../_libs/micromark-util-normalize-identifier+[...].mjs";
131
+ import "../_libs/micromark.mjs";
132
+ import "../_libs/micromark-util-combine-extensions+[...].mjs";
133
+ import "../_libs/micromark-util-chunked.mjs";
134
+ import "../_libs/micromark-factory-space.mjs";
135
+ import "../_libs/micromark-util-character.mjs";
136
+ import "../_libs/micromark-core-commonmark.mjs";
137
+ import "../_libs/micromark-util-classify-character+[...].mjs";
138
+ import "../_libs/micromark-util-resolve-all.mjs";
139
+ import "../_libs/micromark-util-subtokenize.mjs";
140
+ import "../_libs/micromark-factory-destination.mjs";
141
+ import "../_libs/micromark-factory-label.mjs";
142
+ import "../_libs/micromark-factory-title.mjs";
143
+ import "../_libs/micromark-factory-whitespace.mjs";
144
+ import "../_libs/micromark-util-html-tag-name.mjs";
145
+ import "../_libs/mdast-util-to-string.mjs";
146
+ import "../_libs/remark-rehype.mjs";
147
+ import "../_libs/mdast-util-to-hast.mjs";
148
+ import "../_libs/ungap__structured-clone.mjs";
149
+ import "../_libs/micromark-util-sanitize-uri.mjs";
150
+ import "../_libs/unist-util-position.mjs";
151
+ import "../_libs/trim-lines.mjs";
152
+ import "../_libs/unist-util-visit.mjs";
153
+ import "../_libs/unist-util-visit-parents.mjs";
154
+ import "../_libs/unist-util-is.mjs";
155
+ import "../_libs/hast-util-to-jsx-runtime.mjs";
156
+ import "../_libs/comma-separated-tokens.mjs";
157
+ import "../_libs/property-information.mjs";
158
+ import "../_libs/space-separated-tokens.mjs";
159
+ import "../_libs/style-to-js.mjs";
160
+ import "../_libs/style-to-object.mjs";
161
+ import "../_libs/inline-style-parser.mjs";
162
+ import "../_libs/hast-util-whitespace.mjs";
163
+ import "../_libs/estree-util-is-identifier-name.mjs";
164
+ import "../_libs/html-url-attributes.mjs";
165
+ function classifyValue(value) {
166
+ if (value === null) return "null";
167
+ if (Array.isArray(value)) return "array";
168
+ switch (typeof value) {
169
+ case "string":
170
+ return "string";
171
+ case "number":
172
+ return "number";
173
+ case "boolean":
174
+ return "boolean";
175
+ case "object":
176
+ return "object";
177
+ case "bigint":
178
+ case "symbol":
179
+ case "undefined":
180
+ case "function":
181
+ return "object";
182
+ }
183
+ }
184
+ function isExpandable(value) {
185
+ return value !== null && (Array.isArray(value) || typeof value === "object");
186
+ }
187
+ function getEntries(value) {
188
+ if (Array.isArray(value)) {
189
+ return value.map((item, index) => [String(index), item]);
190
+ }
191
+ if (typeof value === "object" && value !== null) {
192
+ return Object.entries(value);
193
+ }
194
+ return [];
195
+ }
196
+ const STRING_TRUNCATE_LIMIT = 120;
197
+ function StringValue({ text }) {
198
+ const [expanded, setExpanded] = reactExports.useState(false);
199
+ const isLong = text.length > STRING_TRUNCATE_LIMIT;
200
+ if (!isLong) {
201
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400 break-all", children: [
202
+ '"',
203
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "prose prose-sm dark:prose-invert inline max-w-none [&_p]:inline [&_p]:my-0 [&_code]:text-emerald-300 [&_a]:text-emerald-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text }) }),
204
+ '"'
205
+ ] });
206
+ }
207
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400 break-all", children: [
208
+ '"',
209
+ expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
210
+ "span",
211
+ {
212
+ className: "cursor-pointer prose prose-sm dark:prose-invert inline max-w-none [&_p]:inline [&_p]:my-0 [&_code]:text-emerald-300 [&_a]:text-emerald-300",
213
+ onClick: (e) => {
214
+ e.stopPropagation();
215
+ setExpanded(false);
216
+ },
217
+ onKeyDown: (e) => {
218
+ if (e.key === "Enter" || e.key === " ") {
219
+ e.stopPropagation();
220
+ setExpanded(false);
221
+ }
222
+ },
223
+ role: "button",
224
+ tabIndex: 0,
225
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text })
226
+ }
227
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { delayDuration: 300, children: [
228
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
229
+ TooltipTrigger,
230
+ {
231
+ onClick: (e) => {
232
+ e.stopPropagation();
233
+ setExpanded(true);
234
+ },
235
+ className: "text-left cursor-pointer",
236
+ children: [
237
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: text.slice(0, STRING_TRUNCATE_LIMIT) }),
238
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-emerald-400/50", children: "…" })
239
+ ]
240
+ }
241
+ ),
242
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
243
+ TooltipContent,
244
+ {
245
+ side: "bottom",
246
+ className: "max-w-md text-xs p-2 break-words whitespace-pre-wrap",
247
+ children: [
248
+ text.slice(0, 500),
249
+ text.length > 500 ? "…" : ""
250
+ ]
251
+ }
252
+ )
253
+ ] }),
254
+ '"'
255
+ ] });
256
+ }
257
+ function PrimitiveValue({ value }) {
258
+ if (value === null) {
259
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-rose-400 italic", children: "null" });
260
+ }
261
+ switch (typeof value) {
262
+ case "string":
263
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StringValue, { text: value });
264
+ case "number":
265
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: value });
266
+ case "boolean":
267
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: value ? "true" : "false" });
268
+ case "object":
269
+ case "bigint":
270
+ case "symbol":
271
+ case "undefined":
272
+ case "function":
273
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: JSON.stringify(value) });
274
+ }
275
+ }
276
+ function CopyValueButton({ value }) {
277
+ const [copied, setCopied] = reactExports.useState(false);
278
+ function handleCopy(e) {
279
+ e.stopPropagation();
280
+ void window.navigator.clipboard.writeText(JSON.stringify(value, null, 2)).then(() => {
281
+ setCopied(true);
282
+ setTimeout(() => {
283
+ setCopied(false);
284
+ }, 2e3);
285
+ });
286
+ }
287
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
288
+ "button",
289
+ {
290
+ type: "button",
291
+ onClick: handleCopy,
292
+ className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors",
293
+ title: "Copy JSON",
294
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3 text-green-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3" })
295
+ }
296
+ );
297
+ }
298
+ function CopyButton({ value }) {
299
+ const [copied, setCopied] = reactExports.useState(false);
300
+ function handleCopy(e) {
301
+ e.stopPropagation();
302
+ void window.navigator.clipboard.writeText(JSON.stringify(value, null, 2)).then(() => {
303
+ setCopied(true);
304
+ setTimeout(() => {
305
+ setCopied(false);
306
+ }, 2e3);
307
+ });
308
+ }
309
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
310
+ "button",
311
+ {
312
+ type: "button",
313
+ onClick: handleCopy,
314
+ className: "opacity-0 group-hover/row:opacity-100 hover:bg-muted p-0.5 rounded transition-opacity shrink-0",
315
+ title: "Copy to clipboard",
316
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3 text-green-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3 text-muted-foreground" })
317
+ }
318
+ );
319
+ }
320
+ function ExpandCollapseButton({
321
+ onClick
322
+ }) {
323
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
324
+ "button",
325
+ {
326
+ type: "button",
327
+ onClick,
328
+ className: "opacity-0 group-hover/row:opacity-100 hover:bg-muted p-0.5 rounded transition-opacity shrink-0",
329
+ title: "Expand all descendants",
330
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsDown, { className: "size-3.5 text-muted-foreground" })
331
+ }
332
+ );
333
+ }
334
+ const JsonNode = reactExports.memo(function JsonNode2({
335
+ name,
336
+ value,
337
+ level,
338
+ defaultExpandDepth,
339
+ isArrayItem,
340
+ path,
341
+ expandTargetPath,
342
+ anatomyPaths
343
+ }) {
344
+ const isAncestorOfTarget = reactExports.useMemo(() => {
345
+ if (expandTargetPath === null) return false;
346
+ if (path === "") return expandTargetPath.length > 0;
347
+ return expandTargetPath === path || expandTargetPath.startsWith(`${path}/`);
348
+ }, [expandTargetPath, path]);
349
+ const initialExpanded = level < defaultExpandDepth || isAncestorOfTarget && isExpandable(value);
350
+ const [expanded, setExpanded] = reactExports.useState(initialExpanded);
351
+ reactExports.useEffect(() => {
352
+ if (isAncestorOfTarget && isExpandable(value) && !expanded) {
353
+ setExpanded(true);
354
+ }
355
+ }, [expandTargetPath]);
356
+ const [childResetKey, setChildResetKey] = reactExports.useState(0);
357
+ const [childDepthOverride, setChildDepthOverride] = reactExports.useState(null);
358
+ const expandable = isExpandable(value);
359
+ const fullyExpanded = childDepthOverride === Number.POSITIVE_INFINITY;
360
+ const entries = reactExports.useMemo(() => getEntries(value), [value]);
361
+ const hasExpandableChild = reactExports.useMemo(
362
+ () => entries.some(([, child]) => isExpandable(child)),
363
+ [entries]
364
+ );
365
+ const dataType = classifyValue(value);
366
+ const openBracket = dataType === "array" ? "[" : "{";
367
+ const closeBracket = dataType === "array" ? "]" : "}";
368
+ const hasAnatomyPath = anatomyPaths !== null && anatomyPaths.has(path);
369
+ function expandAllDeep() {
370
+ setExpanded(true);
371
+ setChildDepthOverride(Number.POSITIVE_INFINITY);
372
+ setChildResetKey((k) => k + 1);
373
+ }
374
+ function collapseToDefault() {
375
+ setExpanded(false);
376
+ setChildDepthOverride(0);
377
+ setChildResetKey((k) => k + 1);
378
+ }
379
+ function handleRowToggle() {
380
+ if (fullyExpanded) {
381
+ collapseToDefault();
382
+ } else {
383
+ setExpanded(!expanded);
384
+ }
385
+ }
386
+ function handleExpandAll(e) {
387
+ e.stopPropagation();
388
+ expandAllDeep();
389
+ }
390
+ const effectiveChildDepth = childDepthOverride ?? defaultExpandDepth;
391
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(level > 0 && "border-l border-border/50 ml-2"), children: [
392
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
393
+ "div",
394
+ {
395
+ className: cn(
396
+ "flex items-start gap-1 py-0.5 px-1 -ml-1 rounded-sm group/row",
397
+ expandable && "cursor-pointer hover:bg-muted/50"
398
+ ),
399
+ "data-anatomy-path": hasAnatomyPath ? path : void 0,
400
+ onClick: expandable ? handleRowToggle : void 0,
401
+ onKeyDown: expandable ? (e) => {
402
+ if (e.key === "Enter" || e.key === " ") {
403
+ e.preventDefault();
404
+ handleRowToggle();
405
+ }
406
+ } : void 0,
407
+ onDoubleClick: expandable && hasExpandableChild ? () => expandAllDeep() : void 0,
408
+ role: expandable ? "button" : void 0,
409
+ tabIndex: expandable ? 0 : void 0,
410
+ children: [
411
+ expandable ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-4 h-5 flex items-center justify-center shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-4 shrink-0" }),
412
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("shrink-0", isArrayItem ? "text-muted-foreground" : "text-cyan-400"), children: isArrayItem ? name : `"${name}"` }),
413
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground shrink-0", children: expandable ? "" : ":" }),
414
+ expandable ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
415
+ openBracket,
416
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground/60 text-xs", children: [
417
+ " ",
418
+ entries.length,
419
+ " ",
420
+ entries.length === 1 ? "item" : "items",
421
+ " ",
422
+ closeBracket
423
+ ] })
424
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrimitiveValue, { value }) }),
425
+ expandable && hasExpandableChild && !fullyExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandCollapseButton, { onClick: handleExpandAll }),
426
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CopyButton, { value })
427
+ ]
428
+ }
429
+ ),
430
+ expandable && expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pl-4", children: [
431
+ entries.map(([key, childValue]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
432
+ JsonNode2,
433
+ {
434
+ name: key,
435
+ value: childValue,
436
+ level: level + 1,
437
+ defaultExpandDepth: effectiveChildDepth,
438
+ isArrayItem: dataType === "array",
439
+ path: path === "" ? `/${key}` : `${path}/${key}`,
440
+ expandTargetPath,
441
+ anatomyPaths
442
+ },
443
+ key
444
+ )),
445
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground py-0.5 px-1", children: closeBracket })
446
+ ] }, childResetKey)
447
+ ] });
448
+ });
449
+ function JsonViewer({
450
+ data,
451
+ defaultExpandDepth = 0,
452
+ className,
453
+ showCopy = false,
454
+ bulkDepth: controlledBulkDepth,
455
+ bulkRevision: controlledBulkRevision,
456
+ anatomyPaths = null,
457
+ expandToPath = null
458
+ }) {
459
+ const expandable = isExpandable(data);
460
+ const entries = reactExports.useMemo(() => getEntries(data), [data]);
461
+ const bulkDepth = controlledBulkDepth ?? defaultExpandDepth;
462
+ const bulkRevision = controlledBulkRevision ?? 0;
463
+ if (!expandable) {
464
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("font-mono text-xs leading-relaxed", className), children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
465
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PrimitiveValue, { value: data }),
466
+ showCopy && /* @__PURE__ */ jsxRuntimeExports.jsx(CopyValueButton, { value: data })
467
+ ] }) }) });
468
+ }
469
+ const dataType = classifyValue(data);
470
+ const isArray = dataType === "array";
471
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("font-mono text-xs leading-relaxed", className), children: [
472
+ showCopy && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2 flex items-center justify-end gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyValueButton, { value: data }) }),
473
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: entries.map(([key, childValue]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
474
+ JsonNode,
475
+ {
476
+ name: key,
477
+ value: childValue,
478
+ level: 0,
479
+ defaultExpandDepth: bulkDepth,
480
+ isArrayItem: isArray,
481
+ path: `/${key}`,
482
+ expandTargetPath: expandToPath,
483
+ anatomyPaths
484
+ },
485
+ key
486
+ )) }, bulkRevision)
487
+ ] }) });
488
+ }
489
+ const JsonViewerFromString = reactExports.memo(function JsonViewerFromString2({
490
+ text,
491
+ defaultExpandDepth = 0,
492
+ className
493
+ }) {
494
+ const parsed = reactExports.useMemo(() => parseJsonText(text), [text]);
495
+ if (parsed.kind === "json") {
496
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
497
+ JsonViewer,
498
+ {
499
+ data: parsed.data,
500
+ defaultExpandDepth,
501
+ className
502
+ }
503
+ );
504
+ }
505
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: cn("font-mono text-xs whitespace-pre-wrap break-words", className), children: text });
506
+ });
507
+ export {
508
+ JsonViewer,
509
+ JsonViewerFromString
510
+ };
@@ -46,7 +46,7 @@ import "../_libs/debounce-fn.mjs";
46
46
  import "../_libs/mimic-function.mjs";
47
47
  import "../_libs/semver.mjs";
48
48
  import "../_libs/uint8array-extras.mjs";
49
- const appCss = "/assets/index-DRRCmu5p.css";
49
+ const appCss = "/assets/index-BGzHFOEX.css";
50
50
  const Route$k = createRootRoute({
51
51
  head: () => ({
52
52
  meta: [
@@ -70,7 +70,7 @@ function RootDocument({ children }) {
70
70
  ] })
71
71
  ] });
72
72
  }
73
- const $$splitComponentImporter = () => import("./index-CjvQZBI0.mjs");
73
+ const $$splitComponentImporter = () => import("./index-CDjLoMsk.mjs").then((n) => n.t);
74
74
  const Route$j = createFileRoute("/")({
75
75
  component: lazyRouteComponent($$splitComponentImporter, "component")
76
76
  });
@@ -3817,16 +3817,9 @@ const Route$6 = createFileRoute("/api/logs/stream")({
3817
3817
  const sessionId = url.searchParams.get("sessionId") ?? void 0;
3818
3818
  const model = url.searchParams.get("model") ?? void 0;
3819
3819
  let controllerRef = null;
3820
- const heartbeat = setInterval(() => {
3821
- if (controllerRef) {
3822
- try {
3823
- controllerRef.enqueue(new TextEncoder().encode(": heartbeat\n\n"));
3824
- } catch {
3825
- }
3826
- }
3827
- }, 3e4);
3820
+ let cleanedUp = false;
3828
3821
  const unsubscribe = onLogUpdate((log) => {
3829
- if (!controllerRef) return;
3822
+ if (controllerRef === null) return;
3830
3823
  if (sessionId !== void 0 && log.sessionId !== sessionId) return;
3831
3824
  if (model !== void 0 && log.model !== model) return;
3832
3825
  try {
@@ -3835,8 +3828,27 @@ const Route$6 = createFileRoute("/api/logs/stream")({
3835
3828
  `;
3836
3829
  controllerRef.enqueue(new TextEncoder().encode(data));
3837
3830
  } catch {
3831
+ cleanup();
3838
3832
  }
3839
3833
  });
3834
+ const cleanup = () => {
3835
+ if (cleanedUp) return;
3836
+ cleanedUp = true;
3837
+ clearInterval(heartbeat);
3838
+ unsubscribe();
3839
+ controllerRef = null;
3840
+ request.signal.removeEventListener("abort", cleanup);
3841
+ };
3842
+ const heartbeat = setInterval(() => {
3843
+ if (controllerRef !== null) {
3844
+ try {
3845
+ controllerRef.enqueue(new TextEncoder().encode(": heartbeat\n\n"));
3846
+ } catch {
3847
+ cleanup();
3848
+ }
3849
+ }
3850
+ }, 3e4);
3851
+ request.signal.addEventListener("abort", cleanup, { once: true });
3840
3852
  const stream = new ReadableStream({
3841
3853
  start(controller) {
3842
3854
  controllerRef = controller;
@@ -3847,9 +3859,7 @@ const Route$6 = createFileRoute("/api/logs/stream")({
3847
3859
  controller.enqueue(new TextEncoder().encode(initData));
3848
3860
  },
3849
3861
  cancel() {
3850
- clearInterval(heartbeat);
3851
- unsubscribe();
3852
- controllerRef = null;
3862
+ cleanup();
3853
3863
  }
3854
3864
  });
3855
3865
  return new Response(stream, {
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], "preloads": ["/assets/main-Cpts3Ifr.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-DfjhkDNi.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/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/mcp": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/mcp.ts" }, "/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/providers/scan"] }, "/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/providers/scan": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.scan.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", "children": ["/api/providers/$providerId/test/log"] }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-Cpts3Ifr.js" });
1
+ const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$"], "preloads": ["/assets/main-CDMdNDY_.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-DX88k9br.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/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/mcp": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/mcp.ts" }, "/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/providers/scan"] }, "/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/providers/scan": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.scan.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", "children": ["/api/providers/$providerId/test/log"] }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-CDMdNDY_.js" });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };