@tonyclaw/agent-inspector 2.0.3 → 2.0.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 (68) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-D5A4bTfV.js → CompareDrawer-3nRwtk8J.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-CbW5VRER.js +101 -0
  4. package/.output/public/assets/ReplayDialog-Cl62N9PI.js +1 -0
  5. package/.output/public/assets/RequestAnatomy-DgQWGvjs.js +1 -0
  6. package/.output/public/assets/ResponseView-Cvc-ct4E.js +1 -0
  7. package/.output/public/assets/StreamingChunkSequence-BCQaCAIe.js +1 -0
  8. package/.output/public/assets/_sessionId-CcD_aLGq.js +1 -0
  9. package/.output/public/assets/index-B_dffD3u.js +1 -0
  10. package/.output/public/assets/index-CX796gvi.css +1 -0
  11. package/.output/public/assets/{json-viewer-BbU0n8eM.js → json-viewer-IXejqXB0.js} +1 -1
  12. package/.output/public/assets/{main-CZT_F-gu.js → main-2NlGzgOe.js} +2 -2
  13. package/.output/server/_libs/lucide-react.mjs +181 -114
  14. package/.output/server/{_sessionId-B-s9P7fJ.mjs → _sessionId-DWCTasJU.mjs} +3 -3
  15. package/.output/server/_ssr/{CompareDrawer-C08L3UOO.mjs → CompareDrawer-DhrN1uC2.mjs} +6 -6
  16. package/.output/server/_ssr/{ProxyViewerContainer-CMWl3Ijy.mjs → ProxyViewerContainer-DRl51s_n.mjs} +910 -186
  17. package/.output/server/_ssr/{ReplayDialog-CPDo9_G5.mjs → ReplayDialog-BQT_ygxC.mjs} +240 -14
  18. package/.output/server/_ssr/{RequestAnatomy-D9wt_K1E.mjs → RequestAnatomy-DS2tZOgq.mjs} +5 -5
  19. package/.output/server/_ssr/{ResponseView-DXaL7nY3.mjs → ResponseView-e0kL2C3x.mjs} +25 -21
  20. package/.output/server/_ssr/{StreamingChunkSequence-B_hudZyb.mjs → StreamingChunkSequence-BJG-m7xs.mjs} +3 -3
  21. package/.output/server/_ssr/{index-CuE_BN86.mjs → index-Dea3OeRw.mjs} +2 -2
  22. package/.output/server/_ssr/index.mjs +2 -2
  23. package/.output/server/_ssr/{json-viewer-Ci6kkjde.mjs → json-viewer-DDU55MLK.mjs} +3 -3
  24. package/.output/server/_ssr/{router-BemxgIg7.mjs → router-Dl7oh0zx.mjs} +164 -82
  25. package/.output/server/_tanstack-start-manifest_v-m-FJNBVf.mjs +4 -0
  26. package/.output/server/index.mjs +70 -70
  27. package/package.json +1 -1
  28. package/src/components/OnboardingBanner.tsx +11 -19
  29. package/src/components/ProxyViewer.tsx +26 -16
  30. package/src/components/ProxyViewerContainer.tsx +2 -1
  31. package/src/components/providers/ProviderCard.tsx +6 -20
  32. package/src/components/providers/SettingsDialog.tsx +140 -3
  33. package/src/components/proxy-viewer/AgentTraceSummary.tsx +731 -72
  34. package/src/components/proxy-viewer/AnswerMarkdown.tsx +16 -0
  35. package/src/components/proxy-viewer/CompareDrawer.tsx +4 -2
  36. package/src/components/proxy-viewer/ConversationGroup.tsx +12 -0
  37. package/src/components/proxy-viewer/ConversationHeader.tsx +6 -6
  38. package/src/components/proxy-viewer/LogEntry.tsx +5 -5
  39. package/src/components/proxy-viewer/LogEntryHeader.tsx +21 -36
  40. package/src/components/proxy-viewer/ReplayDialog.tsx +190 -8
  41. package/src/components/proxy-viewer/ResponseView.tsx +4 -8
  42. package/src/components/proxy-viewer/ToolTraceEvents.tsx +37 -17
  43. package/src/components/proxy-viewer/TurnGroup.tsx +18 -2
  44. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +2 -2
  45. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +6 -12
  46. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +2 -2
  47. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +10 -14
  48. package/src/components/proxy-viewer/replayComparison.ts +131 -0
  49. package/src/components/proxy-viewer/useKeyboardNavigation.ts +64 -22
  50. package/src/components/proxy-viewer/viewerState.ts +14 -2
  51. package/src/knowledge/candidateStore.ts +32 -1
  52. package/src/lib/runtimeConfig.ts +6 -0
  53. package/src/lib/timeDisplay.ts +22 -0
  54. package/src/lib/useOnboarding.ts +2 -0
  55. package/src/lib/useStripConfig.ts +16 -0
  56. package/src/proxy/config.ts +3 -0
  57. package/src/routes/api/config.ts +5 -1
  58. package/src/routes/api/knowledge.candidates.$candidateId.ts +50 -0
  59. package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +12 -2
  60. package/.output/public/assets/ProxyViewerContainer-Da0jpBkp.js +0 -101
  61. package/.output/public/assets/ReplayDialog-CxUk_TF0.js +0 -1
  62. package/.output/public/assets/RequestAnatomy-DIlzjgjJ.js +0 -1
  63. package/.output/public/assets/ResponseView-DQCuKJ1G.js +0 -1
  64. package/.output/public/assets/StreamingChunkSequence-DHk4SGGL.js +0 -1
  65. package/.output/public/assets/_sessionId-dY1TTl7N.js +0 -1
  66. package/.output/public/assets/index-D7wwbwly.css +0 -1
  67. package/.output/public/assets/index-FqQZbfl2.js +0 -1
  68. package/.output/server/_tanstack-start-manifest_v--L1_b4sd.mjs +0 -4
@@ -1,11 +1,11 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import { ResponseView } from "./ResponseView-DXaL7nY3.mjs";
4
- import "./router-BemxgIg7.mjs";
2
+ import { u as useProviders, D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer-DRl51s_n.mjs";
3
+ import { ResponseView } from "./ResponseView-e0kL2C3x.mjs";
4
+ import "./router-Dl7oh0zx.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
- import "./json-viewer-Ci6kkjde.mjs";
8
- import { s as RotateCcw } from "../_libs/lucide-react.mjs";
7
+ import "./json-viewer-DDU55MLK.mjs";
8
+ import { I as RotateCcw } from "../_libs/lucide-react.mjs";
9
9
  import { d as object, c as boolean, n as number, b as string } from "../_libs/zod.mjs";
10
10
  import "../_libs/swr.mjs";
11
11
  import "../_libs/use-sync-external-store.mjs";
@@ -168,17 +168,174 @@ import "../_libs/lie.mjs";
168
168
  import "../_libs/immediate.mjs";
169
169
  import "../_libs/setimmediate.mjs";
170
170
  import "../_libs/pako.mjs";
171
+ function isJsonObject(value) {
172
+ return typeof value === "object" && value !== null && !Array.isArray(value);
173
+ }
174
+ function byteLength(value) {
175
+ if (value === null || value === void 0) return null;
176
+ return new TextEncoder().encode(value).length;
177
+ }
178
+ function readRequestModel(body) {
179
+ try {
180
+ const parsed = JSON.parse(body);
181
+ if (!isJsonObject(parsed)) return null;
182
+ const model = parsed["model"];
183
+ return typeof model === "string" && model.length > 0 ? model : null;
184
+ } catch {
185
+ return null;
186
+ }
187
+ }
188
+ function replaceRequestModel(body, model) {
189
+ try {
190
+ const parsed = JSON.parse(body);
191
+ if (!isJsonObject(parsed)) {
192
+ return { body, error: "Request body must be a JSON object." };
193
+ }
194
+ return {
195
+ body: JSON.stringify({ ...parsed, model }, null, 2),
196
+ error: null
197
+ };
198
+ } catch {
199
+ return { body, error: "Request body must be valid JSON before changing the replay model." };
200
+ }
201
+ }
202
+ function buildReplayMetrics(input) {
203
+ return {
204
+ status: input.status ?? null,
205
+ elapsedMs: input.elapsedMs ?? null,
206
+ inputTokens: input.inputTokens ?? null,
207
+ outputTokens: input.outputTokens ?? null,
208
+ responseBytes: byteLength(input.responseText),
209
+ streaming: input.streaming === true
210
+ };
211
+ }
212
+ function numericDelta(original, replay) {
213
+ if (original === null || replay === null) return null;
214
+ return replay - original;
215
+ }
216
+ function buildReplayComparisons(original, replay) {
217
+ return [
218
+ {
219
+ id: "status",
220
+ label: "Status",
221
+ original: original.status,
222
+ replay: replay.status,
223
+ delta: numericDelta(original.status, replay.status)
224
+ },
225
+ {
226
+ id: "elapsed",
227
+ label: "Elapsed",
228
+ original: original.elapsedMs,
229
+ replay: replay.elapsedMs,
230
+ delta: numericDelta(original.elapsedMs, replay.elapsedMs)
231
+ },
232
+ {
233
+ id: "input",
234
+ label: "Input",
235
+ original: original.inputTokens,
236
+ replay: replay.inputTokens,
237
+ delta: numericDelta(original.inputTokens, replay.inputTokens)
238
+ },
239
+ {
240
+ id: "output",
241
+ label: "Output",
242
+ original: original.outputTokens,
243
+ replay: replay.outputTokens,
244
+ delta: numericDelta(original.outputTokens, replay.outputTokens)
245
+ },
246
+ {
247
+ id: "bytes",
248
+ label: "Bytes",
249
+ original: original.responseBytes,
250
+ replay: replay.responseBytes,
251
+ delta: numericDelta(original.responseBytes, replay.responseBytes)
252
+ },
253
+ {
254
+ id: "streaming",
255
+ label: "Stream",
256
+ original: original.streaming,
257
+ replay: replay.streaming,
258
+ delta: null
259
+ }
260
+ ];
261
+ }
171
262
  const ReplayResultSchema = object({
172
263
  success: boolean(),
173
264
  error: string().optional(),
174
- responseStatus: number().optional(),
175
- responseText: string().optional(),
176
- inputTokens: number().optional(),
177
- outputTokens: number().optional(),
178
- elapsedMs: number().optional(),
265
+ responseStatus: number().nullable().optional(),
266
+ responseText: string().nullable().optional(),
267
+ inputTokens: number().nullable().optional(),
268
+ outputTokens: number().nullable().optional(),
269
+ elapsedMs: number().nullable().optional(),
179
270
  streaming: boolean().optional()
180
271
  });
272
+ function formatElapsed(ms) {
273
+ if (ms < 1e3) return `${String(ms)}ms`;
274
+ return `${(ms / 1e3).toFixed(1)}s`;
275
+ }
276
+ function formatMetricValue(value, metricId) {
277
+ if (value === null) return "-";
278
+ if (typeof value === "boolean") return value ? "stream" : "non-stream";
279
+ switch (metricId) {
280
+ case "elapsed":
281
+ return formatElapsed(value);
282
+ case "input":
283
+ case "output":
284
+ case "bytes":
285
+ return value.toLocaleString();
286
+ case "status":
287
+ return String(value);
288
+ case "streaming":
289
+ return value ? "stream" : "non-stream";
290
+ }
291
+ }
292
+ function formatDelta(delta, metricId) {
293
+ if (delta === null) return "-";
294
+ const sign = delta > 0 ? "+" : "";
295
+ switch (metricId) {
296
+ case "elapsed":
297
+ return `${sign}${formatElapsed(delta)}`;
298
+ case "input":
299
+ case "output":
300
+ case "bytes":
301
+ case "status":
302
+ return `${sign}${delta.toLocaleString()}`;
303
+ case "streaming":
304
+ return "-";
305
+ }
306
+ }
307
+ function deltaToneClass(delta) {
308
+ if (delta === null || delta === 0) return "text-muted-foreground";
309
+ if (delta > 0) return "text-amber-400";
310
+ return "text-emerald-400";
311
+ }
312
+ function ReplayComparisonTable({
313
+ comparisons
314
+ }) {
315
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden rounded-md border border-border", children: [
316
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_1fr] bg-muted/40 px-3 py-2 text-[11px] font-medium text-muted-foreground", children: [
317
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Metric" }),
318
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Original" }),
319
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Replay" }),
320
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Delta" })
321
+ ] }),
322
+ comparisons.map((comparison) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
323
+ "div",
324
+ {
325
+ className: "grid grid-cols-[1fr_1fr_1fr_1fr] border-t border-border px-3 py-2 text-xs",
326
+ children: [
327
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: comparison.label }),
328
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatMetricValue(comparison.original, comparison.id) }),
329
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatMetricValue(comparison.replay, comparison.id) }),
330
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-mono ${deltaToneClass(comparison.delta)}`, children: formatDelta(comparison.delta, comparison.id) })
331
+ ]
332
+ },
333
+ comparison.id
334
+ ))
335
+ ] });
336
+ }
181
337
  function ReplayDialog({ log, open, onOpenChange }) {
338
+ const { providers } = useProviders();
182
339
  const [modifiedBody, setModifiedBody] = reactExports.useState(() => {
183
340
  return log.rawRequestBody ?? "{}";
184
341
  });
@@ -218,6 +375,48 @@ function ReplayDialog({ log, open, onOpenChange }) {
218
375
  setError(null);
219
376
  onOpenChange(false);
220
377
  }
378
+ const replayModelOptions = reactExports.useMemo(() => {
379
+ const options = [];
380
+ for (const provider of providers) {
381
+ for (const model of provider.models) {
382
+ if (model.trim().length === 0) continue;
383
+ options.push({
384
+ key: `${provider.id}:${model}`,
385
+ providerName: provider.name,
386
+ model
387
+ });
388
+ }
389
+ }
390
+ return options;
391
+ }, [providers]);
392
+ const currentReplayModel = readRequestModel(modifiedBody) ?? log.model ?? "";
393
+ function handleReplayModelChange(model) {
394
+ const result = replaceRequestModel(modifiedBody, model);
395
+ if (result.error !== null) {
396
+ setError(result.error);
397
+ return;
398
+ }
399
+ setModifiedBody(result.body);
400
+ setReplayResult(null);
401
+ setError(null);
402
+ }
403
+ const originalMetrics = buildReplayMetrics({
404
+ status: log.responseStatus,
405
+ elapsedMs: log.elapsedMs,
406
+ inputTokens: log.inputTokens,
407
+ outputTokens: log.outputTokens,
408
+ responseText: log.responseText,
409
+ streaming: log.streaming
410
+ });
411
+ const replayMetrics = replayResult === null ? null : buildReplayMetrics({
412
+ status: replayResult.responseStatus,
413
+ elapsedMs: replayResult.elapsedMs,
414
+ inputTokens: replayResult.inputTokens,
415
+ outputTokens: replayResult.outputTokens,
416
+ responseText: replayResult.responseText,
417
+ streaming: replayResult.streaming
418
+ });
419
+ const replayComparisons = replayMetrics === null ? [] : buildReplayComparisons(originalMetrics, replayMetrics);
221
420
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-4xl max-h-[85vh] overflow-auto", children: [
222
421
  /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
223
422
  /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" }),
@@ -228,9 +427,31 @@ function ReplayDialog({ log, open, onOpenChange }) {
228
427
  /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
229
428
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "modified", children: "Modified Request" }),
230
429
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "original", children: "Original Response" }),
231
- replayResult && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "replay", children: "Replay Response" })
430
+ replayResult && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "replay", children: "Replay Response" }),
431
+ replayResult && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "compare", children: "Compare" })
232
432
  ] }),
233
433
  /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsContent, { value: "modified", className: "space-y-4", children: [
434
+ replayModelOptions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-1.5", children: [
435
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: `replay-model-${String(log.id)}`, className: "text-sm font-medium", children: "Replay target" }),
436
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
437
+ "select",
438
+ {
439
+ id: `replay-model-${String(log.id)}`,
440
+ value: currentReplayModel,
441
+ onChange: (event) => handleReplayModelChange(event.currentTarget.value),
442
+ className: "h-8 rounded-md border border-input bg-background px-2 text-sm",
443
+ children: [
444
+ currentReplayModel === "" && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "Select model" }),
445
+ currentReplayModel !== "" && !replayModelOptions.some((option) => option.model === currentReplayModel) && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: currentReplayModel, children: currentReplayModel }),
446
+ replayModelOptions.map((option) => /* @__PURE__ */ jsxRuntimeExports.jsxs("option", { value: option.model, children: [
447
+ option.providerName,
448
+ " / ",
449
+ option.model
450
+ ] }, option.key))
451
+ ]
452
+ }
453
+ )
454
+ ] }),
234
455
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
235
456
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium mb-2 block", children: "Request Body (JSON)" }),
236
457
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
@@ -257,6 +478,7 @@ function ReplayDialog({ log, open, onOpenChange }) {
257
478
  children: loading ? "Replaying..." : "Replay"
258
479
  }
259
480
  ) }),
481
+ replayResult !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ReplayComparisonTable, { comparisons: replayComparisons.slice(0, 4) }),
260
482
  replayResult && replayResult.success && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { defaultValue: "parsed", children: [
261
483
  /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
262
484
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "parsed", children: "Response" }),
@@ -296,7 +518,7 @@ function ReplayDialog({ log, open, onOpenChange }) {
296
518
  ) }),
297
519
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap bg-muted p-3 rounded-md max-h-96 overflow-auto", children: log.responseText }) })
298
520
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground italic", children: "No original response" }) }),
299
- replayResult && replayResult.success && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "replay", children: replayResult.responseText !== null ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { defaultValue: "parsed", children: [
521
+ replayResult && replayResult.success && /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "replay", children: (replayResult.responseText ?? null) !== null ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Tabs, { defaultValue: "parsed", children: [
300
522
  /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { children: [
301
523
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "parsed", children: "Response" }),
302
524
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "raw", children: "Raw Response" })
@@ -312,8 +534,12 @@ function ReplayDialog({ log, open, onOpenChange }) {
312
534
  apiFormat: log.apiFormat
313
535
  }
314
536
  ) }),
315
- /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap bg-muted p-3 rounded-md max-h-96 overflow-auto", children: replayResult.responseText }) })
316
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground italic", children: "No replay response" }) })
537
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "raw", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-mono text-xs whitespace-pre-wrap bg-muted p-3 rounded-md max-h-96 overflow-auto", children: replayResult.responseText ?? "" }) })
538
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground italic", children: "No replay response" }) }),
539
+ replayResult && /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsContent, { value: "compare", className: "space-y-3", children: [
540
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ReplayComparisonTable, { comparisons: replayComparisons }),
541
+ replayResult.success ? null : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: replayResult.error ?? "Replay failed" })
542
+ ] })
317
543
  ] })
318
544
  ] }) });
319
545
  }
@@ -1,9 +1,9 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { k as TooltipProvider, f as formatTokens, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import "./router-BemxgIg7.mjs";
2
+ import { k as TooltipProvider, f as formatTokens, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-DRl51s_n.mjs";
3
+ import "./router-Dl7oh0zx.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
- import { V as Info } from "../_libs/lucide-react.mjs";
6
+ import { a4 as Info } from "../_libs/lucide-react.mjs";
7
7
  import "../_libs/swr.mjs";
8
8
  import "../_libs/use-sync-external-store.mjs";
9
9
  import "../_libs/dequal.mjs";
@@ -116,14 +116,14 @@ const ROLE_COLOR_CLASSES = {
116
116
  system: "bg-sky-500/70",
117
117
  user: "bg-emerald-500/70",
118
118
  assistant: "bg-violet-500/70",
119
- tool: "bg-amber-500/70",
119
+ tool: "bg-sky-400/55",
120
120
  tools: "bg-slate-500/70"
121
121
  };
122
122
  const ROLE_FOCUS_RING = {
123
123
  system: "focus-visible:ring-sky-300",
124
124
  user: "focus-visible:ring-emerald-300",
125
125
  assistant: "focus-visible:ring-violet-300",
126
- tool: "focus-visible:ring-amber-300",
126
+ tool: "focus-visible:ring-sky-300",
127
127
  tools: "focus-visible:ring-slate-300"
128
128
  };
129
129
  const MAX_VISIBLE_SEGMENTS = 12;
@@ -1,10 +1,10 @@
1
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 "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import { JsonViewer } from "./json-viewer-Ci6kkjde.mjs";
4
- import "./router-BemxgIg7.mjs";
2
+ import { g as getLogFormatAdapter, f as formatTokens, c as cn, p as getStatusCategory, B as Badge, s as safeJsonValue } from "./ProxyViewerContainer-DRl51s_n.mjs";
3
+ import { JsonViewer } from "./json-viewer-DDU55MLK.mjs";
4
+ import "./router-Dl7oh0zx.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
- import { Z as Zap, i as TriangleAlert, Y as CircleStop, B as Brain, b as ChevronDown, f as ChevronRight, _ as Terminal } from "../_libs/lucide-react.mjs";
7
+ import { Z as Zap, j as TriangleAlert, a5 as CircleStop, B as Brain, b as ChevronDown, f as ChevronRight, T as Terminal } from "../_libs/lucide-react.mjs";
8
8
  import { M as Markdown } from "../_libs/react-markdown.mjs";
9
9
  import { R as Root } from "../_libs/radix-ui__react-separator.mjs";
10
10
  import { R as Root$1, C as CollapsibleTrigger$1, a as CollapsibleContent$1 } from "../_libs/radix-ui__react-collapsible.mjs";
@@ -167,6 +167,10 @@ import "../_libs/inline-style-parser.mjs";
167
167
  import "../_libs/hast-util-whitespace.mjs";
168
168
  import "../_libs/estree-util-is-identifier-name.mjs";
169
169
  import "../_libs/html-url-attributes.mjs";
170
+ const ANSWER_MARKDOWN_CLASS = "prose prose-sm dark:prose-invert max-w-none text-[13px] leading-[1.65] [&_pre]:bg-muted [&_pre]:text-foreground [&_code]:text-[0.8em] [&_p]:my-1 [&_p]:leading-[1.65] [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0.5 [&_li]:leading-[1.6]";
171
+ function AnswerMarkdown({ text }) {
172
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ANSWER_MARKDOWN_CLASS, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { children: text }) });
173
+ }
170
174
  function Separator({
171
175
  className,
172
176
  orientation = "horizontal",
@@ -276,7 +280,7 @@ function SystemReminderBlock({ text }) {
276
280
  open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" }),
277
281
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-xs italic select-none opacity-60", children: "[system-reminder]" })
278
282
  ] }),
279
- /* @__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 }) }) }) })
283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-4 pt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text }) }) })
280
284
  ] });
281
285
  }
282
286
  const TextBlock = reactExports.memo(function TextBlock2({ text }) {
@@ -286,7 +290,7 @@ const TextBlock = reactExports.memo(function TextBlock2({ text }) {
286
290
  const { thinking, remainingText } = extractThinkingFromContent(text);
287
291
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
288
292
  thinking !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking }),
289
- 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 }) }),
293
+ remainingText.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text: remainingText }),
290
294
  thinking === null && remainingText.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Empty text block" })
291
295
  ] });
292
296
  });
@@ -320,9 +324,9 @@ const ToolUseBlock = reactExports.memo(function ToolUseBlock2({
320
324
  input
321
325
  }) {
322
326
  const [open, setOpen] = reactExports.useState(false);
323
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-blue-500/40 my-1", children: [
324
- /* @__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: [
325
- /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-blue-400 shrink-0" }),
327
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-sky-400/25 my-1", children: [
328
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group", children: [
329
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-sky-400/70 shrink-0" }),
326
330
  /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-[10px] font-mono px-1.5 py-0 h-4", children: name }),
327
331
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
328
332
  open ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })
@@ -372,11 +376,11 @@ const StructuredResponseViewAnthropic = reactExports.memo(function StructuredRes
372
376
  " out"
373
377
  ] }),
374
378
  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: [
375
- "Cache +",
379
+ "KV Cache +",
376
380
  formatTokens(response.usage.cache_creation_input_tokens)
377
381
  ] }),
378
382
  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: [
379
- "Cache ~",
383
+ "KV Cache ~",
380
384
  formatTokens(response.usage.cache_read_input_tokens)
381
385
  ] })
382
386
  ] })
@@ -400,9 +404,9 @@ function OpenAIToolCallBlock({ call }) {
400
404
  const [open, setOpen] = reactExports.useState(false);
401
405
  const name = call.function.name ?? "(unnamed tool)";
402
406
  const parsed = parseToolArguments(call.function.arguments);
403
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-blue-500/40 my-1", children: [
404
- /* @__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: [
405
- /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-blue-400 shrink-0" }),
407
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-l-2 border-sky-400/25 my-1", children: [
408
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(CollapsibleTrigger, { className: "flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group", children: [
409
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Terminal, { className: "size-3.5 text-sky-400/70 shrink-0" }),
406
410
  /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-[10px] font-mono px-1.5 py-0 h-4", children: name }),
407
411
  call.id !== void 0 && call.id !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-mono text-muted-foreground/60 truncate", children: call.id }),
408
412
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
@@ -454,17 +458,17 @@ const OpenAIResponseView = reactExports.memo(function OpenAIResponseView2({
454
458
  const { thinking, remainingText } = extractThinkingFromContent(message.content);
455
459
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
456
460
  thinking !== null && !hasReasoningField && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingBlock, { thinking }),
457
- 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 }) })
461
+ remainingText.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text: remainingText })
458
462
  ] });
459
463
  })(),
460
464
  toolCalls.map((call, i) => (
461
465
  // biome-ignore lint/suspicious/noArrayIndexKey: tool_calls is the positionally stable list from the response
462
466
  /* @__PURE__ */ jsxRuntimeExports.jsx(OpenAIToolCallBlock, { call }, call.id ?? `tc-${i}`)
463
467
  )),
464
- 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: [
465
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-blue-400 font-mono mb-1", children: "function_call" }),
468
+ message?.function_call !== null && message?.function_call !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-sky-400/20 rounded-md p-3 bg-muted/20", children: [
469
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-sky-400/80 font-mono mb-1", children: "function_call" }),
466
470
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono text-xs", children: [
467
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-300", children: message.function_call.name }),
471
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground/80", children: message.function_call.name }),
468
472
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
469
473
  "(",
470
474
  message.function_call.arguments,
@@ -521,7 +525,7 @@ function ErrorResponseView({ text }) {
521
525
  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 }) });
522
526
  }
523
527
  function MarkdownFallbackView({ text }) {
524
- 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 }) });
528
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text });
525
529
  }
526
530
  const ResponseView = reactExports.memo(function ResponseView2({
527
531
  responseText,
@@ -585,11 +589,11 @@ const ResponseView = reactExports.memo(function ResponseView2({
585
589
  " out"
586
590
  ] }),
587
591
  cacheCreationInputTokens !== null && cacheCreationInputTokens !== void 0 && cacheCreationInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-emerald-400", children: [
588
- "Cache +",
592
+ "KV Cache +",
589
593
  formatTokens(cacheCreationInputTokens)
590
594
  ] }),
591
595
  cacheReadInputTokens !== null && cacheReadInputTokens !== void 0 && cacheReadInputTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums text-purple-400", children: [
592
- "Cache ~",
596
+ "KV Cache ~",
593
597
  formatTokens(cacheReadInputTokens)
594
598
  ] })
595
599
  ] })
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent } from "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import { JsonViewer } from "./json-viewer-Ci6kkjde.mjs";
4
- import "./router-BemxgIg7.mjs";
2
+ import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent } from "./ProxyViewerContainer-DRl51s_n.mjs";
3
+ import { JsonViewer } from "./json-viewer-DDU55MLK.mjs";
4
+ import "./router-Dl7oh0zx.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
7
  import { b as ChevronDown, f as ChevronRight, L as LoaderCircle } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
- import { P as ProxyViewerContainer } from "./ProxyViewerContainer-CMWl3Ijy.mjs";
1
+ import { P as ProxyViewerContainer } from "./ProxyViewerContainer-DRl51s_n.mjs";
2
2
  import "../_libs/react.mjs";
3
- import "./router-BemxgIg7.mjs";
3
+ import "./router-Dl7oh0zx.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import "../_libs/swr.mjs";
@@ -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--L1_b4sd.mjs");
201
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-m-FJNBVf.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-BemxgIg7.mjs").then((n) => n.h);
770
+ const routerEntry = await import("./router-Dl7oh0zx.mjs").then((n) => n.i);
771
771
  const startEntry = await import("./start-HYkvq4Ni.mjs");
772
772
  return { startEntry, routerEntry };
773
773
  }
@@ -1,9 +1,9 @@
1
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 "./ProxyViewerContainer-CMWl3Ijy.mjs";
3
- import "./router-BemxgIg7.mjs";
2
+ import { q as parseJsonText, c as cn, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-DRl51s_n.mjs";
3
+ import "./router-Dl7oh0zx.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
- import { C as Check, a as Copy, b as ChevronDown, f as ChevronRight, q as ChevronsDown } from "../_libs/lucide-react.mjs";
6
+ import { C as Check, a as Copy, b as ChevronDown, f as ChevronRight, y as ChevronsDown } from "../_libs/lucide-react.mjs";
7
7
  import { M as Markdown } from "../_libs/react-markdown.mjs";
8
8
  import "../_libs/swr.mjs";
9
9
  import "../_libs/use-sync-external-store.mjs";