@tonyclaw/llm-inspector 1.16.4 → 1.17.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.
Files changed (62) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/CompareDrawer-C4fie5g5.js +1 -0
  3. package/.output/public/assets/ReplayDialog-Dme5uOR9.js +1 -0
  4. package/.output/public/assets/RequestAnatomy-ChBLDNFH.js +1 -0
  5. package/.output/public/assets/ResponseView-wGeqBzVU.js +1 -0
  6. package/.output/public/assets/StreamingChunkSequence-zeJZQLqT.js +1 -0
  7. package/.output/public/assets/index-DoGvsnbA.css +1 -0
  8. package/.output/public/assets/index-DpbutOvo.js +101 -0
  9. package/.output/public/assets/json-viewer-BV-WUszW.js +14 -0
  10. package/.output/public/assets/{main-DbWwVQFh.js → main-DRu10KNQ.js} +1 -1
  11. package/.output/server/_libs/lucide-react.mjs +105 -85
  12. package/.output/server/_ssr/CompareDrawer-C4-CQL5w.mjs +1040 -0
  13. package/.output/server/_ssr/ReplayDialog-BTb1Bam8.mjs +321 -0
  14. package/.output/server/_ssr/RequestAnatomy-CZFV1IvL.mjs +351 -0
  15. package/.output/server/_ssr/ResponseView-CTZekh65.mjs +601 -0
  16. package/.output/server/_ssr/StreamingChunkSequence-C38Ynabd.mjs +301 -0
  17. package/.output/server/_ssr/{index-C-z-fZtq.mjs → index-Cnu-QzAy.mjs} +1141 -2443
  18. package/.output/server/_ssr/index.mjs +2 -2
  19. package/.output/server/_ssr/json-viewer-DROqpjS9.mjs +510 -0
  20. package/.output/server/_ssr/{router-CNM9Kbi0.mjs → router-pP4GCTQx.mjs} +42 -18
  21. package/.output/server/{_tanstack-start-manifest_v-BWfLeIsC.mjs → _tanstack-start-manifest_v-CphS4rZd.mjs} +1 -1
  22. package/.output/server/index.mjs +69 -27
  23. package/package.json +1 -1
  24. package/src/components/OnboardingBanner.tsx +2 -2
  25. package/src/components/ProxyViewer.tsx +44 -27
  26. package/src/components/ProxyViewerContainer.tsx +5 -25
  27. package/src/components/providers/SettingsDialog.tsx +52 -1
  28. package/src/components/proxy-viewer/ConversationGroup.tsx +5 -1
  29. package/src/components/proxy-viewer/ConversationHeader.tsx +4 -1
  30. package/src/components/proxy-viewer/LogEntry.tsx +217 -181
  31. package/src/components/proxy-viewer/LogEntryHeader.tsx +181 -40
  32. package/src/components/proxy-viewer/ThreadConnector.tsx +17 -2
  33. package/src/components/proxy-viewer/TurnGroup.tsx +124 -72
  34. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
  35. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
  36. package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
  37. package/src/components/proxy-viewer/anatomy/types.ts +39 -0
  38. package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
  39. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +3 -23
  40. package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
  41. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +5 -3
  42. package/src/components/proxy-viewer/lazy.ts +37 -0
  43. package/src/components/proxy-viewer/log-formats/anthropic.ts +146 -0
  44. package/src/components/proxy-viewer/log-formats/openai.ts +127 -0
  45. package/src/components/proxy-viewer/log-formats/types.ts +7 -0
  46. package/src/components/proxy-viewer/log-formats/unknown.ts +4 -0
  47. package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
  48. package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
  49. package/src/components/proxy-viewer/viewerState.ts +8 -0
  50. package/src/components/ui/crab-variants.tsx +11 -0
  51. package/src/components/ui/json-expansion-button.tsx +56 -0
  52. package/src/components/ui/json-viewer-bulk.ts +97 -0
  53. package/src/components/ui/json-viewer.tsx +58 -183
  54. package/src/lib/runtimeConfig.ts +9 -0
  55. package/src/lib/useOnboarding.ts +7 -1
  56. package/src/lib/useStripConfig.ts +33 -2
  57. package/src/lib/utils.ts +2 -3
  58. package/src/proxy/config.ts +17 -7
  59. package/src/routes/api/config.ts +7 -0
  60. package/src/routes/api/logs.stream.ts +26 -16
  61. package/.output/public/assets/index-DRRCmu5p.css +0 -1
  62. package/.output/public/assets/index-X7CHS7fS.js +0 -107
@@ -0,0 +1,601 @@
1
+ import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
+ import { g as getLogFormatAdapter, f as formatTokens, c as cn, p as getStatusCategory, B as Badge, s as safeJsonValue } from "./index-Cnu-QzAy.mjs";
3
+ import { JsonViewer } from "./json-viewer-DROqpjS9.mjs";
4
+ import "./router-pP4GCTQx.mjs";
5
+ import "../_libs/modelcontextprotocol__server.mjs";
6
+ import "../_libs/jszip.mjs";
7
+ import { Z as Zap, i as TriangleAlert, K as CircleStop, N as Brain, a as ChevronDown, f as ChevronRight, Q as Terminal } from "../_libs/lucide-react.mjs";
8
+ import { M as Markdown } from "../_libs/react-markdown.mjs";
9
+ import { R as Root } from "../_libs/radix-ui__react-separator.mjs";
10
+ import { R as Root$1, C as CollapsibleTrigger$1, a as CollapsibleContent$1 } from "../_libs/radix-ui__react-collapsible.mjs";
11
+ import { R as Root$2, V as Viewport, C as Corner, S as ScrollAreaScrollbar, a as ScrollAreaThumb } from "../_libs/radix-ui__react-scroll-area.mjs";
12
+ import "../_libs/swr.mjs";
13
+ import "../_libs/use-sync-external-store.mjs";
14
+ import "../_libs/dequal.mjs";
15
+ import "../_libs/clsx.mjs";
16
+ import "../_libs/tailwind-merge.mjs";
17
+ import "../_libs/class-variance-authority.mjs";
18
+ import "../_libs/radix-ui__react-dialog.mjs";
19
+ import "../_libs/radix-ui__primitive.mjs";
20
+ import "../_libs/radix-ui__react-compose-refs.mjs";
21
+ import "../_libs/radix-ui__react-context.mjs";
22
+ import "../_libs/radix-ui__react-id.mjs";
23
+ import "../_libs/@radix-ui/react-use-layout-effect+[...].mjs";
24
+ import "../_libs/@radix-ui/react-use-controllable-state+[...].mjs";
25
+ import "../_libs/@radix-ui/react-dismissable-layer+[...].mjs";
26
+ import "../_libs/radix-ui__react-primitive.mjs";
27
+ import "../_libs/react-dom.mjs";
28
+ import "util";
29
+ import "async_hooks";
30
+ import "stream";
31
+ import "crypto";
32
+ import "../_libs/radix-ui__react-slot.mjs";
33
+ import "../_libs/@radix-ui/react-use-callback-ref+[...].mjs";
34
+ import "../_libs/@radix-ui/react-use-escape-keydown+[...].mjs";
35
+ import "../_libs/radix-ui__react-focus-scope.mjs";
36
+ import "../_libs/radix-ui__react-portal.mjs";
37
+ import "../_libs/radix-ui__react-presence.mjs";
38
+ import "../_libs/radix-ui__react-focus-guards.mjs";
39
+ import "../_libs/react-remove-scroll.mjs";
40
+ import "tslib";
41
+ import "../_libs/react-remove-scroll-bar.mjs";
42
+ import "../_libs/react-style-singleton.mjs";
43
+ import "../_libs/get-nonce.mjs";
44
+ import "../_libs/use-sidecar.mjs";
45
+ import "../_libs/use-callback-ref.mjs";
46
+ import "../_libs/aria-hidden.mjs";
47
+ import "../_libs/diff.mjs";
48
+ import "../_libs/tanstack__react-virtual.mjs";
49
+ import "../_libs/tanstack__virtual-core.mjs";
50
+ import "../_libs/radix-ui__react-select.mjs";
51
+ import "../_libs/radix-ui__number.mjs";
52
+ import "../_libs/radix-ui__react-collection.mjs";
53
+ import "../_libs/radix-ui__react-direction.mjs";
54
+ import "../_libs/radix-ui__react-popper.mjs";
55
+ import "../_libs/floating-ui__react-dom.mjs";
56
+ import "../_libs/floating-ui__dom.mjs";
57
+ import "../_libs/floating-ui__core.mjs";
58
+ import "../_libs/floating-ui__utils.mjs";
59
+ import "../_libs/radix-ui__react-arrow.mjs";
60
+ import "../_libs/radix-ui__react-use-size.mjs";
61
+ import "../_libs/radix-ui__react-use-previous.mjs";
62
+ import "../_libs/@radix-ui/react-visually-hidden+[...].mjs";
63
+ import "../_libs/zod.mjs";
64
+ import "../_libs/radix-ui__react-tabs.mjs";
65
+ import "../_libs/radix-ui__react-roving-focus.mjs";
66
+ import "../_libs/radix-ui__react-tooltip.mjs";
67
+ import "../_libs/tanstack__react-router.mjs";
68
+ import "../_libs/tiny-warning.mjs";
69
+ import "../_libs/tanstack__router-core.mjs";
70
+ import "../_libs/cookie-es.mjs";
71
+ import "../_libs/tanstack__history.mjs";
72
+ import "../_libs/tiny-invariant.mjs";
73
+ import "../_libs/seroval.mjs";
74
+ import "../_libs/seroval-plugins.mjs";
75
+ import "node:stream/web";
76
+ import "node:stream";
77
+ import "../_libs/isbot.mjs";
78
+ import "node:fs";
79
+ import "node:fs/promises";
80
+ import "node:buffer";
81
+ import "node:path";
82
+ import "../_libs/conf.mjs";
83
+ import "node:util";
84
+ import "node:process";
85
+ import "node:crypto";
86
+ import "node:assert";
87
+ import "../_libs/dot-prop.mjs";
88
+ import "../_libs/env-paths.mjs";
89
+ import "node:os";
90
+ import "../_libs/atomically.mjs";
91
+ import "../_libs/stubborn-fs.mjs";
92
+ import "../_libs/stubborn-utils.mjs";
93
+ import "../_libs/when-exit.mjs";
94
+ import "../_libs/ajv.mjs";
95
+ import "../_libs/fast-deep-equal.mjs";
96
+ import "../_libs/json-schema-traverse.mjs";
97
+ import "../_libs/fast-uri.mjs";
98
+ import "../_libs/ajv-formats.mjs";
99
+ import "../_libs/debounce-fn.mjs";
100
+ import "../_libs/mimic-function.mjs";
101
+ import "../_libs/semver.mjs";
102
+ import "../_libs/uint8array-extras.mjs";
103
+ import "node:child_process";
104
+ import "../_libs/readable-stream.mjs";
105
+ import "events";
106
+ import "node:string_decoder";
107
+ import "../_libs/process-nextick-args.mjs";
108
+ import "../_libs/isarray.mjs";
109
+ import "../_libs/safe-buffer.mjs";
110
+ import "buffer";
111
+ import "../_libs/core-util-is.mjs";
112
+ import "../_libs/inherits.mjs";
113
+ import "../_libs/util-deprecate.mjs";
114
+ import "../_libs/lie.mjs";
115
+ import "../_libs/immediate.mjs";
116
+ import "../_libs/setimmediate.mjs";
117
+ import "../_libs/pako.mjs";
118
+ import "../_libs/devlop.mjs";
119
+ import "../_libs/unified.mjs";
120
+ import "../_libs/bail.mjs";
121
+ import "../_libs/extend.mjs";
122
+ import "../_libs/is-plain-obj.mjs";
123
+ import "../_libs/trough.mjs";
124
+ import "../_libs/vfile.mjs";
125
+ import "../_libs/vfile-message.mjs";
126
+ import "../_libs/unist-util-stringify-position.mjs";
127
+ import "node:url";
128
+ import "../_libs/remark-parse.mjs";
129
+ import "../_libs/mdast-util-from-markdown.mjs";
130
+ import "../_libs/micromark-util-decode-numeric-character-reference+[...].mjs";
131
+ import "../_libs/micromark-util-decode-string.mjs";
132
+ import "../_libs/decode-named-character-reference+[...].mjs";
133
+ import "../_libs/character-entities.mjs";
134
+ import "../_libs/micromark-util-normalize-identifier+[...].mjs";
135
+ import "../_libs/micromark.mjs";
136
+ import "../_libs/micromark-util-combine-extensions+[...].mjs";
137
+ import "../_libs/micromark-util-chunked.mjs";
138
+ import "../_libs/micromark-factory-space.mjs";
139
+ import "../_libs/micromark-util-character.mjs";
140
+ import "../_libs/micromark-core-commonmark.mjs";
141
+ import "../_libs/micromark-util-classify-character+[...].mjs";
142
+ import "../_libs/micromark-util-resolve-all.mjs";
143
+ import "../_libs/micromark-util-subtokenize.mjs";
144
+ import "../_libs/micromark-factory-destination.mjs";
145
+ import "../_libs/micromark-factory-label.mjs";
146
+ import "../_libs/micromark-factory-title.mjs";
147
+ import "../_libs/micromark-factory-whitespace.mjs";
148
+ import "../_libs/micromark-util-html-tag-name.mjs";
149
+ import "../_libs/mdast-util-to-string.mjs";
150
+ import "../_libs/remark-rehype.mjs";
151
+ import "../_libs/mdast-util-to-hast.mjs";
152
+ import "../_libs/ungap__structured-clone.mjs";
153
+ import "../_libs/micromark-util-sanitize-uri.mjs";
154
+ import "../_libs/unist-util-position.mjs";
155
+ import "../_libs/trim-lines.mjs";
156
+ import "../_libs/unist-util-visit.mjs";
157
+ import "../_libs/unist-util-visit-parents.mjs";
158
+ import "../_libs/unist-util-is.mjs";
159
+ import "../_libs/hast-util-to-jsx-runtime.mjs";
160
+ import "../_libs/comma-separated-tokens.mjs";
161
+ import "../_libs/property-information.mjs";
162
+ import "../_libs/space-separated-tokens.mjs";
163
+ import "../_libs/style-to-js.mjs";
164
+ import "../_libs/style-to-object.mjs";
165
+ import "../_libs/inline-style-parser.mjs";
166
+ import "../_libs/hast-util-whitespace.mjs";
167
+ import "../_libs/estree-util-is-identifier-name.mjs";
168
+ import "../_libs/html-url-attributes.mjs";
169
+ function Separator({
170
+ className,
171
+ orientation = "horizontal",
172
+ decorative = true,
173
+ ...props
174
+ }) {
175
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
176
+ Root,
177
+ {
178
+ "data-slot": "separator",
179
+ decorative,
180
+ orientation,
181
+ className: cn(
182
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
183
+ className
184
+ ),
185
+ ...props
186
+ }
187
+ );
188
+ }
189
+ function Collapsible({
190
+ ...props
191
+ }) {
192
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Root$1, { "data-slot": "collapsible", ...props });
193
+ }
194
+ function CollapsibleTrigger({
195
+ ...props
196
+ }) {
197
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleTrigger$1, { "data-slot": "collapsible-trigger", ...props });
198
+ }
199
+ function CollapsibleContent({
200
+ ...props
201
+ }) {
202
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
203
+ }
204
+ function ScrollArea({
205
+ className,
206
+ children,
207
+ ...props
208
+ }) {
209
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
210
+ Root$2,
211
+ {
212
+ "data-slot": "scroll-area",
213
+ className: cn("relative", className),
214
+ ...props,
215
+ children: [
216
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
217
+ Viewport,
218
+ {
219
+ "data-slot": "scroll-area-viewport",
220
+ className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
221
+ children
222
+ }
223
+ ),
224
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollBar, {}),
225
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Corner, {})
226
+ ]
227
+ }
228
+ );
229
+ }
230
+ function ScrollBar({
231
+ className,
232
+ orientation = "vertical",
233
+ ...props
234
+ }) {
235
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
236
+ ScrollAreaScrollbar,
237
+ {
238
+ "data-slot": "scroll-area-scrollbar",
239
+ orientation,
240
+ className: cn(
241
+ "flex touch-none p-px transition-colors select-none",
242
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
243
+ orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
244
+ className
245
+ ),
246
+ ...props,
247
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
248
+ ScrollAreaThumb,
249
+ {
250
+ "data-slot": "scroll-area-thumb",
251
+ className: "bg-border relative flex-1 rounded-full"
252
+ }
253
+ )
254
+ }
255
+ );
256
+ }
257
+ const THINKING_TAG_REGEX = /<think>([\s\S]*?)<\/think>/gi;
258
+ const THINKING_TAG_REGEX_SINGLE = /<think>([\s\S]*?)<\/think>/i;
259
+ function extractThinkingFromContent(text) {
260
+ const match = THINKING_TAG_REGEX_SINGLE.exec(text);
261
+ if (!match || match[1] === void 0) {
262
+ return { thinking: null, remainingText: text };
263
+ }
264
+ const thinking = match[1].trim();
265
+ const remainingText = text.replace(THINKING_TAG_REGEX, "").trim();
266
+ return { thinking, remainingText };
267
+ }
268
+ function assertNever(_value) {
269
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {});
270
+ }
271
+ function SystemReminderBlock({ text }) {
272
+ const [open, setOpen] = reactExports.useState(false);
273
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Collapsible, { open, onOpenChange: setOpen, children: [
274
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 py-0.5 cursor-pointer hover:opacity-80 transition-opacity group", children: [
275
+ open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" }),
276
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-xs italic select-none opacity-60", children: "[system-reminder]" })
277
+ ] }),
278
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-4 pt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text }) }) }) })
279
+ ] });
280
+ }
281
+ const TextBlock = reactExports.memo(function TextBlock2({ text }) {
282
+ if (text.includes("<system-reminder>")) {
283
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SystemReminderBlock, { text });
284
+ }
285
+ const { thinking, remainingText } = extractThinkingFromContent(text);
286
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
287
+ thinking !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking }),
288
+ remainingText.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: remainingText }) }),
289
+ thinking === null && remainingText.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Empty text block" })
290
+ ] });
291
+ });
292
+ const ThinkingBlock = reactExports.memo(function ThinkingBlock2({
293
+ thinking
294
+ }) {
295
+ const [open, setOpen] = reactExports.useState(false);
296
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-purple-500/40 my-1", children: [
297
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-purple-500/5 transition-colors rounded-r-sm group", children: [
298
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Brain, { className: "size-3.5 text-purple-400 shrink-0" }),
299
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-purple-400", children: "Thinking" }),
300
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
301
+ Badge,
302
+ {
303
+ variant: "ghost",
304
+ className: "text-[10px] text-muted-foreground px-1.5 py-0 h-4 font-mono",
305
+ children: [
306
+ thinking.length.toLocaleString(),
307
+ " chars"
308
+ ]
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
312
+ open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })
313
+ ] }),
314
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-[60vh]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs text-muted-foreground whitespace-pre-wrap font-mono leading-relaxed", children: thinking }) }) }) })
315
+ ] }) });
316
+ });
317
+ const ToolUseBlock = reactExports.memo(function ToolUseBlock2({
318
+ name,
319
+ input
320
+ }) {
321
+ const [open, setOpen] = reactExports.useState(false);
322
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-blue-500/40 my-1", children: [
323
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-blue-500/5 transition-colors rounded-r-sm group", children: [
324
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-blue-400 shrink-0" }),
325
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-[10px] font-mono px-1.5 py-0 h-4", children: name }),
326
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
327
+ open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })
328
+ ] }),
329
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-[60vh]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewer, { data: safeJsonValue(input), defaultExpandDepth: 0 }) }) }) })
330
+ ] }) });
331
+ });
332
+ const ResponseContentBlockRenderer = reactExports.memo(function ResponseContentBlockRenderer2({
333
+ block
334
+ }) {
335
+ switch (block.type) {
336
+ case "text":
337
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TextBlock, { text: block.text });
338
+ case "thinking":
339
+ case "think":
340
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking: block.thinking });
341
+ case "tool_use":
342
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ToolUseBlock, { name: block.name, input: block.input });
343
+ default:
344
+ return assertNever();
345
+ }
346
+ });
347
+ const StructuredResponseViewAnthropic = reactExports.memo(function StructuredResponseViewAnthropic2({
348
+ response
349
+ }) {
350
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
351
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
352
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "secondary", className: "text-[10px] px-1.5 py-0 h-5 font-mono", children: response.model }),
353
+ response.stop_reason !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(
354
+ Badge,
355
+ {
356
+ variant: "outline",
357
+ className: "text-[10px] px-1.5 py-0 h-5 font-mono flex items-center gap-1",
358
+ children: [
359
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleStop, { className: "size-2.5" }),
360
+ response.stop_reason
361
+ ]
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs", children: [
365
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
366
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
367
+ formatTokens(response.usage.input_tokens ?? 0),
368
+ " in /",
369
+ " ",
370
+ formatTokens(response.usage.output_tokens ?? 0),
371
+ " out"
372
+ ] }),
373
+ response.usage.cache_creation_input_tokens !== void 0 && response.usage.cache_creation_input_tokens !== null && response.usage.cache_creation_input_tokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
374
+ "Cache +",
375
+ formatTokens(response.usage.cache_creation_input_tokens)
376
+ ] }),
377
+ response.usage.cache_read_input_tokens !== void 0 && response.usage.cache_read_input_tokens !== null && response.usage.cache_read_input_tokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-purple-400", children: [
378
+ "Cache ~",
379
+ formatTokens(response.usage.cache_read_input_tokens)
380
+ ] })
381
+ ] })
382
+ ] }),
383
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "opacity-50" }),
384
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
385
+ response.content.map((block, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(ResponseContentBlockRenderer, { block }, i)),
386
+ response.content.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Empty response content" })
387
+ ] })
388
+ ] });
389
+ });
390
+ function parseToolArguments(raw) {
391
+ if (raw === void 0 || raw === "") return {};
392
+ try {
393
+ return JSON.parse(raw);
394
+ } catch {
395
+ return null;
396
+ }
397
+ }
398
+ function OpenAIToolCallBlock({ call }) {
399
+ const [open, setOpen] = reactExports.useState(false);
400
+ const name = call.function.name ?? "(unnamed tool)";
401
+ const parsed = parseToolArguments(call.function.arguments);
402
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-blue-500/40 my-1", children: [
403
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-blue-500/5 transition-colors rounded-r-sm group", children: [
404
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-blue-400 shrink-0" }),
405
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-[10px] font-mono px-1.5 py-0 h-4", children: name }),
406
+ call.id !== void 0 && call.id !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-mono text-muted-foreground/60 truncate", children: call.id }),
407
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
408
+ open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })
409
+ ] }),
410
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "max-h-[60vh]", children: parsed === null ? (
411
+ // JSON.parse failed — show the raw string so the user can
412
+ // still see what the model tried to call.
413
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap break-words text-rose-300/90", children: call.function.arguments })
414
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewer, { data: safeJsonValue(parsed), defaultExpandDepth: 0 }) }) }) })
415
+ ] }) });
416
+ }
417
+ const OpenAIResponseView = reactExports.memo(function OpenAIResponseView2({
418
+ response
419
+ }) {
420
+ const choice = response.choices[0];
421
+ const message = choice?.message;
422
+ const toolCalls = message?.tool_calls ?? [];
423
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
424
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
425
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "secondary", className: "text-[10px] px-1.5 py-0 h-5 font-mono", children: response.model }),
426
+ choice?.finish_reason !== null && choice?.finish_reason !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
427
+ Badge,
428
+ {
429
+ variant: "outline",
430
+ className: "text-[10px] px-1.5 py-0 h-5 font-mono flex items-center gap-1",
431
+ children: [
432
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircleStop, { className: "size-2.5" }),
433
+ choice.finish_reason
434
+ ]
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs", children: [
438
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
439
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
440
+ formatTokens(response.usage.prompt_tokens ?? 0),
441
+ " in /",
442
+ " ",
443
+ formatTokens(response.usage.completion_tokens ?? 0),
444
+ " out"
445
+ ] })
446
+ ] })
447
+ ] }),
448
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { className: "opacity-50" }),
449
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
450
+ message?.reasoning_content !== null && message?.reasoning_content !== void 0 && message.reasoning_content.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking: message.reasoning_content }),
451
+ message?.content !== null && message?.content !== void 0 && message.content.length > 0 && (() => {
452
+ const hasReasoningField = message.reasoning_content !== null && message.reasoning_content !== void 0 && message.reasoning_content.length > 0;
453
+ const { thinking, remainingText } = extractThinkingFromContent(message.content);
454
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
455
+ thinking !== null && !hasReasoningField && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking }),
456
+ remainingText.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: remainingText }) })
457
+ ] });
458
+ })(),
459
+ toolCalls.map((call, i) => (
460
+ // biome-ignore lint/suspicious/noArrayIndexKey: tool_calls is the positionally stable list from the response
461
+ /* @__PURE__ */ jsxRuntimeExports.jsx(OpenAIToolCallBlock, { call }, call.id ?? `tc-${i}`)
462
+ )),
463
+ message?.function_call !== null && message?.function_call !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-blue-500/30 rounded-md p-3 bg-blue-500/5", children: [
464
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-blue-400 font-mono mb-1", children: "function_call" }),
465
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-xs", children: [
466
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-300", children: message.function_call.name }),
467
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
468
+ "(",
469
+ message.function_call.arguments,
470
+ ")"
471
+ ] })
472
+ ] })
473
+ ] }),
474
+ (message?.content === null || message?.content === void 0 || message.content.length === 0) && (message?.reasoning_content === null || message?.reasoning_content === void 0 || message.reasoning_content.length === 0) && (message?.function_call === null || message?.function_call === void 0) && toolCalls.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Empty response content" })
475
+ ] })
476
+ ] });
477
+ });
478
+ function isRecord(value) {
479
+ return typeof value === "object" && value !== null && !Array.isArray(value);
480
+ }
481
+ function isOpenAIResponse(response) {
482
+ return isRecord(response) && response.object === "chat.completion";
483
+ }
484
+ function isAnthropicResponse(response) {
485
+ return isRecord(response) && response.type === "message" && Array.isArray(response.content);
486
+ }
487
+ function formatViewFor(apiFormat, response) {
488
+ if (apiFormat === "openai" && isOpenAIResponse(response)) {
489
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(OpenAIResponseView, { response });
490
+ }
491
+ if (apiFormat === "anthropic" && isAnthropicResponse(response)) {
492
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StructuredResponseViewAnthropic, { response });
493
+ }
494
+ return null;
495
+ }
496
+ function getStatusClasses(category) {
497
+ switch (category) {
498
+ case "success":
499
+ return "text-emerald-400";
500
+ case "client_error":
501
+ return "text-amber-400";
502
+ case "server_error":
503
+ return "text-red-400";
504
+ case "pending":
505
+ return "text-muted-foreground";
506
+ }
507
+ }
508
+ function StatusIndicator({ status }) {
509
+ const category = getStatusCategory(status);
510
+ const classes = getStatusClasses(category);
511
+ if (status === null) {
512
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground italic", children: "pending" });
513
+ }
514
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: cn("flex items-center gap-1 text-xs font-mono font-semibold", classes), children: [
515
+ category === "server_error" && /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3" }),
516
+ status
517
+ ] });
518
+ }
519
+ function ErrorResponseView({ text }) {
520
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-red-500/30 bg-red-500/5 p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs text-red-300 whitespace-pre-wrap font-mono leading-relaxed overflow-auto max-h-[60vh]", children: text }) });
521
+ }
522
+ function MarkdownFallbackView({ text }) {
523
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text }) });
524
+ }
525
+ const ResponseView = reactExports.memo(function ResponseView2({
526
+ responseText,
527
+ responseStatus,
528
+ streaming,
529
+ inputTokens,
530
+ outputTokens,
531
+ cacheCreationInputTokens,
532
+ cacheReadInputTokens,
533
+ apiFormat,
534
+ error
535
+ }) {
536
+ const resolvedFormat = apiFormat ?? "unknown";
537
+ const parsed = reactExports.useMemo(
538
+ () => getLogFormatAdapter(resolvedFormat).analyzeResponse(responseText).parsed,
539
+ [resolvedFormat, responseText]
540
+ );
541
+ if (responseText === null && error === void 0) {
542
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-3", children: [
543
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
544
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground italic", children: "No response" })
545
+ ] });
546
+ }
547
+ const isHttpError = responseStatus !== null && responseStatus >= 400;
548
+ if (isHttpError) {
549
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
550
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
551
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorResponseView, { text: responseText ?? "" }),
552
+ error !== void 0 && error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
553
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
554
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: error })
555
+ ] })
556
+ ] });
557
+ }
558
+ if (error !== void 0 && error !== null) {
559
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
560
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
561
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded border border-destructive/50 bg-destructive/10 p-3 text-xs", children: [
562
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-destructive mb-1", children: "SSE Error" }),
563
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground font-mono", children: error })
564
+ ] }),
565
+ responseText !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorResponseView, { text: responseText }) })
566
+ ] });
567
+ }
568
+ if (parsed !== null) {
569
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
570
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
571
+ formatViewFor(resolvedFormat, parsed)
572
+ ] });
573
+ }
574
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
575
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
576
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: responseStatus }),
577
+ streaming && (inputTokens !== null || outputTokens !== null) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-muted-foreground text-xs", children: [
578
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
579
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
580
+ inputTokens !== null ? formatTokens(inputTokens) : "—",
581
+ " in /",
582
+ " ",
583
+ outputTokens !== null ? formatTokens(outputTokens) : "—",
584
+ " out"
585
+ ] }),
586
+ cacheCreationInputTokens !== null && cacheCreationInputTokens !== void 0 && cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
587
+ "Cache +",
588
+ formatTokens(cacheCreationInputTokens)
589
+ ] }),
590
+ cacheReadInputTokens !== null && cacheReadInputTokens !== void 0 && cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-purple-400", children: [
591
+ "Cache ~",
592
+ formatTokens(cacheReadInputTokens)
593
+ ] })
594
+ ] })
595
+ ] }),
596
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownFallbackView, { text: responseText ?? "" })
597
+ ] });
598
+ });
599
+ export {
600
+ ResponseView
601
+ };