@tonyclaw/llm-inspector 1.17.1 → 1.18.1

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 (52) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/CompareDrawer-CAhlM_Gq.js +1 -0
  3. package/.output/public/assets/ProxyViewerContainer--miVHNPZ.js +101 -0
  4. package/.output/public/assets/ReplayDialog-Bqu2f5HE.js +1 -0
  5. package/.output/public/assets/RequestAnatomy-CpVNH0CD.js +1 -0
  6. package/.output/public/assets/ResponseView-B_Gg37Lr.js +1 -0
  7. package/.output/public/assets/StreamingChunkSequence-E2M_SS1A.js +1 -0
  8. package/.output/public/assets/_sessionId-P9LgC1bF.js +1 -0
  9. package/.output/public/assets/index-C0wv3YP9.css +1 -0
  10. package/.output/public/assets/index-kboKku6a.js +1 -0
  11. package/.output/public/assets/{json-viewer-C8ttTXtv.js → json-viewer-DqhA-ODG.js} +1 -1
  12. package/.output/public/assets/{main-Dgme52Fp.js → main-DpH7JlHv.js} +8 -7
  13. package/.output/server/_libs/lucide-react.mjs +3 -3
  14. package/.output/server/_sessionId-DcJ0RDNl.mjs +122 -0
  15. package/.output/server/_ssr/{CompareDrawer-D-Nj8wmx.mjs → CompareDrawer-DajC3x7u.mjs} +55 -54
  16. package/.output/server/_ssr/{index-nUG0H1oS.mjs → ProxyViewerContainer-C2dnFXoC.mjs} +95 -149
  17. package/.output/server/_ssr/{ReplayDialog-DcucC22E.mjs → ReplayDialog-BnCLuA5z.mjs} +56 -55
  18. package/.output/server/_ssr/{RequestAnatomy-aL8GAcW2.mjs → RequestAnatomy-OHE3iT-f.mjs} +3 -2
  19. package/.output/server/_ssr/{ResponseView-BHgpoGaF.mjs → ResponseView-NPshHwOv.mjs} +4 -3
  20. package/.output/server/_ssr/{StreamingChunkSequence-DrT7StyS.mjs → StreamingChunkSequence-BfukoR7F.mjs} +55 -54
  21. package/.output/server/_ssr/index-CF8M0tsv.mjs +117 -0
  22. package/.output/server/_ssr/index.mjs +2 -2
  23. package/.output/server/_ssr/{json-viewer-DLsDT0RE.mjs → json-viewer-CHBa-Oas.mjs} +3 -2
  24. package/.output/server/_ssr/{router-DG_jmXCF.mjs → router-B5hOtKSn.mjs} +710 -119
  25. package/.output/server/_tanstack-start-manifest_v-CFyWvIH6.mjs +4 -0
  26. package/.output/server/index.mjs +69 -55
  27. package/package.json +1 -1
  28. package/src/components/ProxyViewer.tsx +44 -18
  29. package/src/components/ProxyViewerContainer.tsx +18 -2
  30. package/src/components/proxy-viewer/ConversationGroup.tsx +1 -8
  31. package/src/components/proxy-viewer/ConversationHeader.tsx +47 -4
  32. package/src/components/proxy-viewer/TurnGroup.tsx +10 -13
  33. package/src/proxy/handler.ts +52 -84
  34. package/src/proxy/logFinalizer.ts +301 -0
  35. package/src/proxy/logFinalizer.worker.ts +24 -0
  36. package/src/proxy/schemas.ts +8 -3
  37. package/src/proxy/sessionProcess.ts +133 -0
  38. package/src/proxy/sessionRuntime.ts +85 -0
  39. package/src/proxy/sessionSupervisor.ts +282 -0
  40. package/src/proxy/sessionWorkerEntry.ts +26 -0
  41. package/src/proxy/store.ts +64 -20
  42. package/src/routes/api/logs.stream.ts +2 -2
  43. package/src/routes/api/sessions.ts +9 -2
  44. package/src/routes/session/$sessionId.tsx +75 -0
  45. package/.output/public/assets/CompareDrawer-BhXCLr7m.js +0 -1
  46. package/.output/public/assets/ReplayDialog-CzRPSXwa.js +0 -1
  47. package/.output/public/assets/RequestAnatomy-lMQonao2.js +0 -1
  48. package/.output/public/assets/ResponseView-Bt0vngo0.js +0 -1
  49. package/.output/public/assets/StreamingChunkSequence-Dq9XY2E9.js +0 -1
  50. package/.output/public/assets/index-B4nxi_tZ.js +0 -101
  51. package/.output/public/assets/index-DoGvsnbA.css +0 -1
  52. package/.output/server/_tanstack-start-manifest_v-D0JtrQPv.mjs +0 -4
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
2
- import { C as CapturedLogSchema, D as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, R as RuntimeConfigSchema, r as requestFormatForPath, c as createPendingProviderTestResults, P as ProviderTestResultsSchema, b as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, d as ProviderConfigSchema, s as stripClaudeCodeBillingHeader, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, a as AnthropicRequestSchema } from "./router-DG_jmXCF.mjs";
2
+ import { C as CapturedLogSchema, D as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, a as RuntimeConfigSchema, r as requestFormatForPath, c as createPendingProviderTestResults, P as ProviderTestResultsSchema, d as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, e as ProviderConfigSchema, s as stripClaudeCodeBillingHeader, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, b as AnthropicRequestSchema } from "./router-B5hOtKSn.mjs";
3
3
  import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
4
4
  import { J as JSZip } from "../_libs/jszip.mjs";
5
5
  import { c as clsx } from "../_libs/clsx.mjs";
@@ -9,106 +9,11 @@ import { R as Root, T as Trigger$1, C as Content, a as Close, b as Title, P as P
9
9
  import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
10
10
  import { u as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
11
11
  import { R as Root2, T as Trigger, I as Icon, V as Value, P as Portal, C as Content2, a as Viewport, b as Item, c as ItemIndicator, d as ItemText, S as ScrollUpButton, e as ScrollDownButton } from "../_libs/radix-ui__react-select.mjs";
12
- import { C as Check, X, D as Download, S as Settings, a as ChevronDown, U as Upload, b as Scan, P as Plus, c as Copy, d as CircleAlert, e as ChevronUp, L as LoaderCircle, f as ChevronRight, g as User, h as Clock, M as MessageSquare, Z as Zap, T as Trash2, i as TriangleAlert, E as EyeOff, j as Eye, k as ExternalLink, R as RotateCw, l as Pencil, G as GitCompareArrows, m as Minus, n as CircleCheckBig, O as OctagonAlert, W as Wrench, o as Globe, F as FileTerminal, p as Radio, q as ChevronsUp, r as ChevronsDown, s as RotateCcw, t as CircleQuestionMark, u as Server, v as Gauge, w as Lock, x as Wifi, y as WifiOff, A as ArrowUp, z as ArrowDown, B as Rows3, H as Columns2 } from "../_libs/lucide-react.mjs";
12
+ import { C as Check, X, D as Download, S as Settings, a as ChevronDown, U as Upload, b as Scan, P as Plus, c as Copy, d as CircleAlert, e as ChevronUp, L as LoaderCircle, f as ChevronRight, g as User, h as Clock, M as MessageSquare, Z as Zap, E as ExternalLink, T as Trash2, i as TriangleAlert, j as EyeOff, k as Eye, R as RotateCw, l as Pencil, G as GitCompareArrows, m as Minus, n as CircleCheckBig, O as OctagonAlert, W as Wrench, o as Globe, F as FileTerminal, p as Radio, q as ChevronsUp, r as ChevronsDown, s as RotateCcw, t as CircleQuestionMark, u as Server, v as Gauge, w as Lock, x as Wifi, y as WifiOff, A as ArrowUp, z as ArrowDown, B as Rows3, H as Columns2 } from "../_libs/lucide-react.mjs";
13
13
  import { u as union, d as object, a as array, l as literal, b as string, n as number, c as boolean, _ as _enum } from "../_libs/zod.mjs";
14
14
  import { R as Root2$1, L as List, T as Trigger$2, C as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
15
15
  import { P as Provider, R as Root3, T as Trigger$3, a as Portal$2, C as Content2$1, A as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
16
16
  import { S as Slot } from "../_libs/radix-ui__react-slot.mjs";
17
- import "../_libs/tanstack__react-router.mjs";
18
- import "../_libs/tiny-warning.mjs";
19
- import "../_libs/tanstack__router-core.mjs";
20
- import "../_libs/cookie-es.mjs";
21
- import "../_libs/tanstack__history.mjs";
22
- import "../_libs/tiny-invariant.mjs";
23
- import "../_libs/seroval.mjs";
24
- import "../_libs/seroval-plugins.mjs";
25
- import "node:stream/web";
26
- import "node:stream";
27
- import "../_libs/react-dom.mjs";
28
- import "util";
29
- import "async_hooks";
30
- import "stream";
31
- import "crypto";
32
- import "../_libs/isbot.mjs";
33
- import "node:fs";
34
- import "node:fs/promises";
35
- import "node:buffer";
36
- import "node:path";
37
- import "../_libs/conf.mjs";
38
- import "node:util";
39
- import "node:process";
40
- import "node:crypto";
41
- import "node:assert";
42
- import "../_libs/dot-prop.mjs";
43
- import "../_libs/env-paths.mjs";
44
- import "node:os";
45
- import "../_libs/atomically.mjs";
46
- import "../_libs/stubborn-fs.mjs";
47
- import "../_libs/stubborn-utils.mjs";
48
- import "../_libs/when-exit.mjs";
49
- import "../_libs/ajv.mjs";
50
- import "../_libs/fast-deep-equal.mjs";
51
- import "../_libs/json-schema-traverse.mjs";
52
- import "../_libs/fast-uri.mjs";
53
- import "../_libs/ajv-formats.mjs";
54
- import "../_libs/debounce-fn.mjs";
55
- import "../_libs/mimic-function.mjs";
56
- import "../_libs/semver.mjs";
57
- import "../_libs/uint8array-extras.mjs";
58
- import "node:child_process";
59
- import "../_libs/modelcontextprotocol__server.mjs";
60
- import "../_libs/use-sync-external-store.mjs";
61
- import "../_libs/dequal.mjs";
62
- import "../_libs/readable-stream.mjs";
63
- import "events";
64
- import "node:string_decoder";
65
- import "../_libs/process-nextick-args.mjs";
66
- import "../_libs/isarray.mjs";
67
- import "../_libs/safe-buffer.mjs";
68
- import "buffer";
69
- import "../_libs/core-util-is.mjs";
70
- import "../_libs/inherits.mjs";
71
- import "../_libs/util-deprecate.mjs";
72
- import "../_libs/lie.mjs";
73
- import "../_libs/immediate.mjs";
74
- import "../_libs/setimmediate.mjs";
75
- import "../_libs/pako.mjs";
76
- import "../_libs/radix-ui__primitive.mjs";
77
- import "../_libs/radix-ui__react-compose-refs.mjs";
78
- import "../_libs/radix-ui__react-context.mjs";
79
- import "../_libs/radix-ui__react-id.mjs";
80
- import "../_libs/@radix-ui/react-use-layout-effect+[...].mjs";
81
- import "../_libs/@radix-ui/react-use-controllable-state+[...].mjs";
82
- import "../_libs/@radix-ui/react-dismissable-layer+[...].mjs";
83
- import "../_libs/radix-ui__react-primitive.mjs";
84
- import "../_libs/@radix-ui/react-use-callback-ref+[...].mjs";
85
- import "../_libs/@radix-ui/react-use-escape-keydown+[...].mjs";
86
- import "../_libs/radix-ui__react-focus-scope.mjs";
87
- import "../_libs/radix-ui__react-portal.mjs";
88
- import "../_libs/radix-ui__react-presence.mjs";
89
- import "../_libs/radix-ui__react-focus-guards.mjs";
90
- import "../_libs/react-remove-scroll.mjs";
91
- import "tslib";
92
- import "../_libs/react-remove-scroll-bar.mjs";
93
- import "../_libs/react-style-singleton.mjs";
94
- import "../_libs/get-nonce.mjs";
95
- import "../_libs/use-sidecar.mjs";
96
- import "../_libs/use-callback-ref.mjs";
97
- import "../_libs/aria-hidden.mjs";
98
- import "../_libs/tanstack__virtual-core.mjs";
99
- import "../_libs/radix-ui__number.mjs";
100
- import "../_libs/radix-ui__react-collection.mjs";
101
- import "../_libs/radix-ui__react-direction.mjs";
102
- import "../_libs/radix-ui__react-popper.mjs";
103
- import "../_libs/floating-ui__react-dom.mjs";
104
- import "../_libs/floating-ui__dom.mjs";
105
- import "../_libs/floating-ui__core.mjs";
106
- import "../_libs/floating-ui__utils.mjs";
107
- import "../_libs/radix-ui__react-arrow.mjs";
108
- import "../_libs/radix-ui__react-use-size.mjs";
109
- import "../_libs/radix-ui__react-use-previous.mjs";
110
- import "../_libs/@radix-ui/react-visually-hidden+[...].mjs";
111
- import "../_libs/radix-ui__react-roving-focus.mjs";
112
17
  const ApiErrorSchema = object({
113
18
  error: string()
114
19
  });
@@ -370,7 +275,7 @@ function getStatusCategory(status) {
370
275
  if (status >= 500) return "server_error";
371
276
  return "pending";
372
277
  }
373
- const version = "1.17.1";
278
+ const version = "1.18.1";
374
279
  const packageJson = {
375
280
  version
376
281
  };
@@ -589,6 +494,20 @@ function ConversationHeader({
589
494
  if (onClear === void 0) return;
590
495
  setConfirmOpen(true);
591
496
  };
497
+ const handleOpenInNewTab = reactExports.useCallback(
498
+ (e) => {
499
+ e.stopPropagation();
500
+ let encoded;
501
+ try {
502
+ encoded = btoa(conversationId).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
503
+ } catch {
504
+ encoded = encodeURIComponent(conversationId);
505
+ }
506
+ const url = `/session/${encoded}`;
507
+ window.open(url, "_blank", "noopener,noreferrer");
508
+ },
509
+ [conversationId]
510
+ );
592
511
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
593
512
  "div",
594
513
  {
@@ -618,7 +537,7 @@ function ConversationHeader({
618
537
  {
619
538
  className: "text-purple-400/90 font-mono text-xs font-semibold shrink-0",
620
539
  title: conversationId,
621
- children: conversationId.length > 24 ? conversationId.slice(0, 12) + "…" + conversationId.slice(-12) : conversationId
540
+ children: conversationId.startsWith("PID:") || conversationId.includes("|") ? conversationId : conversationId.length > 24 ? conversationId.slice(0, 12) + "…" + conversationId.slice(-12) : conversationId
622
541
  }
623
542
  ),
624
543
  userAgent !== null && userAgent !== void 0 && userAgent !== "" && /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -670,6 +589,22 @@ function ConversationHeader({
670
589
  ] })
671
590
  ] }),
672
591
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" }),
592
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
593
+ "button",
594
+ {
595
+ type: "button",
596
+ onClick: handleOpenInNewTab,
597
+ onKeyDown: (e) => {
598
+ if (e.key === "Enter" || e.key === " ") {
599
+ handleOpenInNewTab(e);
600
+ }
601
+ },
602
+ "aria-label": `Open session ${conversationId} in a new tab`,
603
+ title: "Open this session in a new tab",
604
+ className: "text-muted-foreground hover:text-foreground transition-colors shrink-0 inline-flex items-center justify-center size-8 rounded hover:bg-muted cursor-pointer",
605
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3.5" })
606
+ }
607
+ ),
673
608
  onClear !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
674
609
  "button",
675
610
  {
@@ -1119,8 +1054,8 @@ const crabVariants = [
1119
1054
  Crab11,
1120
1055
  Crab12
1121
1056
  ];
1122
- function getCrabVariant(index2) {
1123
- return crabVariants[Math.abs(index2) % crabVariants.length] ?? Crab1;
1057
+ function getCrabVariant(index) {
1058
+ return crabVariants[Math.abs(index) % crabVariants.length] ?? Crab1;
1124
1059
  }
1125
1060
  function getInteriorCrabVariantIndex(seed) {
1126
1061
  const interiorCount = crabVariants.length - 2;
@@ -1423,27 +1358,27 @@ function TabsContent({
1423
1358
  );
1424
1359
  }
1425
1360
  const LazyCompareDrawer = reactExports.lazy(
1426
- () => import("./CompareDrawer-D-Nj8wmx.mjs").then((m) => ({ default: m.CompareDrawer }))
1361
+ () => import("./CompareDrawer-DajC3x7u.mjs").then((m) => ({ default: m.CompareDrawer }))
1427
1362
  );
1428
1363
  const LazyReplayDialog = reactExports.lazy(
1429
- () => import("./ReplayDialog-DcucC22E.mjs").then((m) => ({ default: m.ReplayDialog }))
1364
+ () => import("./ReplayDialog-BnCLuA5z.mjs").then((m) => ({ default: m.ReplayDialog }))
1430
1365
  );
1431
1366
  const LazyRequestAnatomy = reactExports.lazy(
1432
- () => import("./RequestAnatomy-aL8GAcW2.mjs").then((m) => ({ default: m.RequestAnatomy }))
1367
+ () => import("./RequestAnatomy-OHE3iT-f.mjs").then((m) => ({ default: m.RequestAnatomy }))
1433
1368
  );
1434
1369
  const LazyResponseView = reactExports.lazy(
1435
- () => import("./ResponseView-BHgpoGaF.mjs").then((m) => ({ default: m.ResponseView }))
1370
+ () => import("./ResponseView-NPshHwOv.mjs").then((m) => ({ default: m.ResponseView }))
1436
1371
  );
1437
1372
  const LazyStreamingChunkSequence = reactExports.lazy(
1438
- () => import("./StreamingChunkSequence-DrT7StyS.mjs").then((m) => ({
1373
+ () => import("./StreamingChunkSequence-BfukoR7F.mjs").then((m) => ({
1439
1374
  default: m.StreamingChunkSequence
1440
1375
  }))
1441
1376
  );
1442
1377
  const LazyJsonViewer = reactExports.lazy(
1443
- () => import("./json-viewer-DLsDT0RE.mjs").then((m) => ({ default: m.JsonViewer }))
1378
+ () => import("./json-viewer-CHBa-Oas.mjs").then((m) => ({ default: m.JsonViewer }))
1444
1379
  );
1445
1380
  const LazyJsonViewerFromString = reactExports.lazy(
1446
- () => import("./json-viewer-DLsDT0RE.mjs").then((m) => ({ default: m.JsonViewerFromString }))
1381
+ () => import("./json-viewer-CHBa-Oas.mjs").then((m) => ({ default: m.JsonViewerFromString }))
1447
1382
  );
1448
1383
  const HIGHLIGHT_DURATION_MS = 1200;
1449
1384
  const MAX_HIGHLIGHT_ATTEMPTS = 12;
@@ -2243,12 +2178,12 @@ const anthropicLogFormatAdapter = {
2243
2178
  }
2244
2179
  }
2245
2180
  if (Array.isArray(body.messages)) {
2246
- body.messages.forEach((message, index2) => {
2181
+ body.messages.forEach((message, index) => {
2247
2182
  if (message === null || typeof message !== "object") return;
2248
2183
  const m = message;
2249
2184
  const role = m.role === "user" || m.role === "assistant" ? m.role : "user";
2250
2185
  const text = contentToText$1(m.content);
2251
- segments.push(segment$1(role, `[${index2}] ${role}`, text, `/messages/${index2}`));
2186
+ segments.push(segment$1(role, `[${index}] ${role}`, text, `/messages/${index}`));
2252
2187
  });
2253
2188
  }
2254
2189
  if (Array.isArray(body.tools) && body.tools.length > 0) {
@@ -2349,12 +2284,12 @@ const openAILogFormatAdapter = {
2349
2284
  const body = parsed;
2350
2285
  const segments = [];
2351
2286
  if (Array.isArray(body.messages)) {
2352
- body.messages.forEach((message, index2) => {
2287
+ body.messages.forEach((message, index) => {
2353
2288
  if (message === null || typeof message !== "object") return;
2354
2289
  const m = message;
2355
2290
  const role = m.role === "user" || m.role === "assistant" || m.role === "system" || m.role === "tool" ? m.role : "user";
2356
2291
  const text = messageToText(m);
2357
- segments.push(segment(role, `[${index2}] ${role}`, text, `/messages/${index2}`));
2292
+ segments.push(segment(role, `[${index}] ${role}`, text, `/messages/${index}`));
2358
2293
  });
2359
2294
  }
2360
2295
  if (Array.isArray(body.tools) && body.tools.length > 0) {
@@ -2858,9 +2793,9 @@ function buildTurnGroups(logs) {
2858
2793
  function buildValidPredecessors(groups) {
2859
2794
  const predecessors = /* @__PURE__ */ new Map();
2860
2795
  for (const group of groups) {
2861
- for (let index2 = 1; index2 < group.logs.length; index2 += 1) {
2862
- const current = group.logs[index2];
2863
- const previous = group.logs[index2 - 1];
2796
+ for (let index = 1; index < group.logs.length; index += 1) {
2797
+ const current = group.logs[index];
2798
+ const previous = group.logs[index - 1];
2864
2799
  if (current === void 0 || previous === void 0) continue;
2865
2800
  const currentFormat = resolveLogFormat(current);
2866
2801
  const previousFormat = resolveLogFormat(previous);
@@ -2906,9 +2841,8 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
2906
2841
  const aggregate = reactExports.useMemo(() => {
2907
2842
  let totalInput = 0;
2908
2843
  let totalOutput = 0;
2909
- let totalElapsed = 0;
2844
+ let maxElapsed = null;
2910
2845
  let hasTokens = false;
2911
- let hasElapsed = false;
2912
2846
  for (const e of entries) {
2913
2847
  if (e.log.inputTokens !== null) {
2914
2848
  totalInput += e.log.inputTokens;
@@ -2919,16 +2853,14 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
2919
2853
  hasTokens = true;
2920
2854
  }
2921
2855
  if (e.log.elapsedMs !== null) {
2922
- totalElapsed += e.log.elapsedMs;
2923
- hasElapsed = true;
2856
+ maxElapsed = maxElapsed === null ? e.log.elapsedMs : Math.max(maxElapsed, e.log.elapsedMs);
2924
2857
  }
2925
2858
  }
2926
2859
  return {
2927
2860
  totalInput,
2928
2861
  totalOutput,
2929
2862
  hasTokens,
2930
- totalElapsed,
2931
- hasElapsed
2863
+ maxElapsed
2932
2864
  };
2933
2865
  }, [entries, lastIdx]);
2934
2866
  const uniqueProviders = reactExports.useMemo(() => {
@@ -2942,7 +2874,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
2942
2874
  const StartCrab = reactExports.useMemo(() => getCrabVariant(entries[0]?.log.id ?? 0), [entries]);
2943
2875
  const EndCrab = reactExports.useMemo(() => getCrabVariant(entries[lastIdx]?.log.id ?? 0), [entries, lastIdx]);
2944
2876
  const bgClass = turnIndex % 2 === 0 ? "bg-muted/10" : "bg-muted/25";
2945
- const aggregateIsSlow = aggregate.hasElapsed && slowResponseThresholdSeconds > 0 && aggregate.totalElapsed > slowResponseThresholdSeconds * 1e3;
2877
+ const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
2946
2878
  const [layoutVersion, setLayoutVersion] = reactExports.useState(0);
2947
2879
  const containerRef = reactExports.useRef(null);
2948
2880
  reactExports.useEffect(() => {
@@ -3063,7 +2995,7 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
3063
2995
  entries.length > 1 ? "s" : ""
3064
2996
  ] }),
3065
2997
  uniqueProviders.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center gap-0.5 shrink-0", children: uniqueProviders.map((p) => /* @__PURE__ */ jsxRuntimeExports.jsx(ProviderLogo, { provider: p, className: "size-4" }, p)) }),
3066
- aggregate.hasElapsed && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
2998
+ aggregate.maxElapsed !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
3067
2999
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
3068
3000
  "span",
3069
3001
  {
@@ -3073,14 +3005,14 @@ const TurnGroup = reactExports.memo(function TurnGroup2({
3073
3005
  ),
3074
3006
  children: [
3075
3007
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
3076
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed(aggregate.totalElapsed) }),
3008
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed(aggregate.maxElapsed) }),
3077
3009
  aggregateIsSlow && /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Slow response" })
3078
3010
  ]
3079
3011
  }
3080
3012
  ) }),
3081
3013
  /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: aggregateIsSlow ? `Slow response: ${formatElapsed(
3082
- aggregate.totalElapsed
3083
- )} exceeds ${formatElapsed(slowResponseThresholdSeconds * 1e3)}` : "Total elapsed response time" })
3014
+ aggregate.maxElapsed
3015
+ )} exceeds ${formatElapsed(slowResponseThresholdSeconds * 1e3)}` : "Slowest request in this turn" })
3084
3016
  ] }) }),
3085
3017
  aggregate.hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 shrink-0", children: [
3086
3018
  /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3 text-muted-foreground" }),
@@ -3168,12 +3100,11 @@ const ConversationGroup = reactExports.memo(function({
3168
3100
  const mixed = hasMixedApiFormat(group.logs);
3169
3101
  const isLoading = group.logs.some((log) => log.responseStatus === null);
3170
3102
  const turnGroups = reactExports.useMemo(() => buildTurnGroups(group.logs), [group.logs]);
3171
- const displayId = group.conversationId.startsWith("PID:") || group.conversationId.includes("|") ? group.conversationId : group.conversationId.length > 24 ? group.conversationId.slice(0, 12) + "…" + group.conversationId.slice(-12) : group.conversationId;
3172
3103
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
3173
3104
  !standalone && /* @__PURE__ */ jsxRuntimeExports.jsx(
3174
3105
  ConversationHeader,
3175
3106
  {
3176
- conversationId: displayId,
3107
+ conversationId: group.conversationId,
3177
3108
  startTime,
3178
3109
  endTime,
3179
3110
  totalCalls: group.logs.length,
@@ -3491,13 +3422,13 @@ function ImportWizardDialog({
3491
3422
  scan();
3492
3423
  }
3493
3424
  }, [open, scan]);
3494
- const toggleProvider = reactExports.useCallback((index2) => {
3425
+ const toggleProvider = reactExports.useCallback((index) => {
3495
3426
  setSelected((prev) => {
3496
3427
  const next = new Set(prev);
3497
- if (next.has(index2)) {
3498
- next.delete(index2);
3428
+ if (next.has(index)) {
3429
+ next.delete(index);
3499
3430
  } else {
3500
- next.add(index2);
3431
+ next.add(index);
3501
3432
  }
3502
3433
  return next;
3503
3434
  });
@@ -4022,10 +3953,10 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
4022
3953
  const modelRowRefs = reactExports.useRef([]);
4023
3954
  reactExports.useEffect(() => {
4024
3955
  if (openModelDropdown === null) return;
4025
- const index2 = openModelDropdown;
3956
+ const index = openModelDropdown;
4026
3957
  function handleClick(e) {
4027
3958
  if (!(e.target instanceof Node)) return;
4028
- const ref = modelRowRefs.current[index2];
3959
+ const ref = modelRowRefs.current[index];
4029
3960
  if (ref !== null && ref !== void 0 && !ref.contains(e.target)) {
4030
3961
  setOpenModelDropdown(null);
4031
3962
  }
@@ -5134,8 +5065,8 @@ function focusAndScroll(el) {
5134
5065
  el.focus({ preventScroll: true });
5135
5066
  el.scrollIntoView({ block: "nearest", behavior: "smooth" });
5136
5067
  }
5137
- function safeItemAt(items, index2) {
5138
- const el = items[index2];
5068
+ function safeItemAt(items, index) {
5069
+ const el = items[index];
5139
5070
  return el ?? null;
5140
5071
  }
5141
5072
  function isEditableTarget(target) {
@@ -5329,7 +5260,8 @@ function ProxyViewer({
5329
5260
  viewMode,
5330
5261
  onViewModeChange,
5331
5262
  strip,
5332
- slowResponseThresholdSeconds
5263
+ slowResponseThresholdSeconds,
5264
+ hideSessionFilter = false
5333
5265
  }) {
5334
5266
  const { totalIn, totalOut } = reactExports.useMemo(() => computeTokenSummary(logs), [logs]);
5335
5267
  const [exporting, setExporting] = reactExports.useState(false);
@@ -5420,7 +5352,7 @@ function ProxyViewer({
5420
5352
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsDialog, {}) })
5421
5353
  ] }),
5422
5354
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
5423
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
5355
+ !hideSessionFilter && /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: selectedSession, onValueChange: onSessionChange, children: [
5424
5356
  /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "flex-1 max-w-[350px] text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "All sessions" }) }),
5425
5357
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
5426
5358
  /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "__all__", children: "All sessions" }),
@@ -5488,7 +5420,23 @@ function ProxyViewer({
5488
5420
  }
5489
5421
  )
5490
5422
  ] }),
5491
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: logs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
5423
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: logs.length === 0 ? selectedSession !== "__all__" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
5424
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "Session not found" }),
5425
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-mono bg-muted px-3 py-1 rounded inline-block max-w-[500px] break-all", children: truncateSessionId(selectedSession) }),
5426
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs", children: [
5427
+ "This session may have been cleared or never existed.",
5428
+ " ",
5429
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
5430
+ "button",
5431
+ {
5432
+ type: "button",
5433
+ onClick: () => onSessionChange("__all__"),
5434
+ className: "underline hover:text-foreground transition-colors",
5435
+ children: "Show all sessions"
5436
+ }
5437
+ )
5438
+ ] })
5439
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-muted-foreground py-16 space-y-4", children: [
5492
5440
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No requests captured yet." }),
5493
5441
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs", children: "Route AI coding tools through the proxy:" }),
5494
5442
  /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableCommand, { command: "LLM_BASE_URL=http://localhost:25947/proxy <your-tool>" })
@@ -5551,9 +5499,11 @@ function filterLogs(logs, selectedSession, selectedModel) {
5551
5499
  });
5552
5500
  }
5553
5501
  const DEBOUNCE_MS = 50;
5554
- function ProxyViewerContainer() {
5502
+ function ProxyViewerContainer({
5503
+ initialSessionId
5504
+ } = {}) {
5555
5505
  const [allLogs, setAllLogs] = reactExports.useState([]);
5556
- const [selectedSession, setSelectedSession] = reactExports.useState("__all__");
5506
+ const [selectedSession, setSelectedSession] = reactExports.useState(initialSessionId ?? "__all__");
5557
5507
  const [selectedModel, setSelectedModel] = reactExports.useState("__all__");
5558
5508
  const [viewMode, setViewMode] = reactExports.useState("simple");
5559
5509
  const [error, setError] = reactExports.useState(null);
@@ -5724,19 +5674,16 @@ function ProxyViewerContainer() {
5724
5674
  viewMode,
5725
5675
  onViewModeChange: setViewMode,
5726
5676
  strip,
5727
- slowResponseThresholdSeconds
5677
+ slowResponseThresholdSeconds,
5678
+ hideSessionFilter: initialSessionId !== void 0
5728
5679
  }
5729
5680
  )
5730
5681
  ] });
5731
5682
  }
5732
- const SplitComponent = ProxyViewerContainer;
5733
- const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
5734
- __proto__: null,
5735
- component: SplitComponent
5736
- }, Symbol.toStringTag, { value: "Module" }));
5737
5683
  export {
5738
5684
  Badge as B,
5739
5685
  Dialog as D,
5686
+ ProxyViewerContainer as P,
5740
5687
  Tabs as T,
5741
5688
  getConversationId as a,
5742
5689
  DialogContent as b,
@@ -5756,6 +5703,5 @@ export {
5756
5703
  getStatusCategory as p,
5757
5704
  parseJsonText as q,
5758
5705
  resolveLogFormat as r,
5759
- safeJsonValue as s,
5760
- index as t
5706
+ safeJsonValue as s
5761
5707
  };
@@ -1,10 +1,10 @@
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 "./index-nUG0H1oS.mjs";
3
- import { ResponseView } from "./ResponseView-BHgpoGaF.mjs";
4
- import "./router-DG_jmXCF.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-C2dnFXoC.mjs";
3
+ import { ResponseView } from "./ResponseView-NPshHwOv.mjs";
4
+ import "./router-B5hOtKSn.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
- import "./json-viewer-DLsDT0RE.mjs";
7
+ import "./json-viewer-CHBa-Oas.mjs";
8
8
  import { s 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";
@@ -61,57 +61,6 @@ import "../_libs/@radix-ui/react-visually-hidden+[...].mjs";
61
61
  import "../_libs/radix-ui__react-tabs.mjs";
62
62
  import "../_libs/radix-ui__react-roving-focus.mjs";
63
63
  import "../_libs/radix-ui__react-tooltip.mjs";
64
- import "../_libs/tanstack__react-router.mjs";
65
- import "../_libs/tiny-warning.mjs";
66
- import "../_libs/tanstack__router-core.mjs";
67
- import "../_libs/cookie-es.mjs";
68
- import "../_libs/tanstack__history.mjs";
69
- import "../_libs/tiny-invariant.mjs";
70
- import "../_libs/seroval.mjs";
71
- import "../_libs/seroval-plugins.mjs";
72
- import "node:stream/web";
73
- import "node:stream";
74
- import "../_libs/isbot.mjs";
75
- import "node:fs";
76
- import "node:fs/promises";
77
- import "node:buffer";
78
- import "node:path";
79
- import "../_libs/conf.mjs";
80
- import "node:util";
81
- import "node:process";
82
- import "node:crypto";
83
- import "node:assert";
84
- import "../_libs/dot-prop.mjs";
85
- import "../_libs/env-paths.mjs";
86
- import "node:os";
87
- import "../_libs/atomically.mjs";
88
- import "../_libs/stubborn-fs.mjs";
89
- import "../_libs/stubborn-utils.mjs";
90
- import "../_libs/when-exit.mjs";
91
- import "../_libs/ajv.mjs";
92
- import "../_libs/fast-deep-equal.mjs";
93
- import "../_libs/json-schema-traverse.mjs";
94
- import "../_libs/fast-uri.mjs";
95
- import "../_libs/ajv-formats.mjs";
96
- import "../_libs/debounce-fn.mjs";
97
- import "../_libs/mimic-function.mjs";
98
- import "../_libs/semver.mjs";
99
- import "../_libs/uint8array-extras.mjs";
100
- import "node:child_process";
101
- import "../_libs/readable-stream.mjs";
102
- import "events";
103
- import "node:string_decoder";
104
- import "../_libs/process-nextick-args.mjs";
105
- import "../_libs/isarray.mjs";
106
- import "../_libs/safe-buffer.mjs";
107
- import "buffer";
108
- import "../_libs/core-util-is.mjs";
109
- import "../_libs/inherits.mjs";
110
- import "../_libs/util-deprecate.mjs";
111
- import "../_libs/lie.mjs";
112
- import "../_libs/immediate.mjs";
113
- import "../_libs/setimmediate.mjs";
114
- import "../_libs/pako.mjs";
115
64
  import "../_libs/react-markdown.mjs";
116
65
  import "../_libs/devlop.mjs";
117
66
  import "../_libs/unified.mjs";
@@ -122,6 +71,8 @@ import "../_libs/trough.mjs";
122
71
  import "../_libs/vfile.mjs";
123
72
  import "../_libs/vfile-message.mjs";
124
73
  import "../_libs/unist-util-stringify-position.mjs";
74
+ import "node:process";
75
+ import "node:path";
125
76
  import "node:url";
126
77
  import "../_libs/remark-parse.mjs";
127
78
  import "../_libs/mdast-util-from-markdown.mjs";
@@ -167,6 +118,56 @@ import "../_libs/html-url-attributes.mjs";
167
118
  import "../_libs/radix-ui__react-separator.mjs";
168
119
  import "../_libs/radix-ui__react-collapsible.mjs";
169
120
  import "../_libs/radix-ui__react-scroll-area.mjs";
121
+ import "../_libs/tanstack__react-router.mjs";
122
+ import "../_libs/tiny-warning.mjs";
123
+ import "../_libs/tanstack__router-core.mjs";
124
+ import "../_libs/cookie-es.mjs";
125
+ import "../_libs/tanstack__history.mjs";
126
+ import "../_libs/tiny-invariant.mjs";
127
+ import "../_libs/seroval.mjs";
128
+ import "../_libs/seroval-plugins.mjs";
129
+ import "node:stream/web";
130
+ import "node:stream";
131
+ import "../_libs/isbot.mjs";
132
+ import "node:fs";
133
+ import "node:fs/promises";
134
+ import "node:buffer";
135
+ import "../_libs/conf.mjs";
136
+ import "node:util";
137
+ import "node:crypto";
138
+ import "node:assert";
139
+ import "../_libs/dot-prop.mjs";
140
+ import "../_libs/env-paths.mjs";
141
+ import "node:os";
142
+ import "../_libs/atomically.mjs";
143
+ import "../_libs/stubborn-fs.mjs";
144
+ import "../_libs/stubborn-utils.mjs";
145
+ import "../_libs/when-exit.mjs";
146
+ import "../_libs/ajv.mjs";
147
+ import "../_libs/fast-deep-equal.mjs";
148
+ import "../_libs/json-schema-traverse.mjs";
149
+ import "../_libs/fast-uri.mjs";
150
+ import "../_libs/ajv-formats.mjs";
151
+ import "../_libs/debounce-fn.mjs";
152
+ import "../_libs/mimic-function.mjs";
153
+ import "../_libs/semver.mjs";
154
+ import "../_libs/uint8array-extras.mjs";
155
+ import "node:child_process";
156
+ import "node:worker_threads";
157
+ import "../_libs/readable-stream.mjs";
158
+ import "events";
159
+ import "node:string_decoder";
160
+ import "../_libs/process-nextick-args.mjs";
161
+ import "../_libs/isarray.mjs";
162
+ import "../_libs/safe-buffer.mjs";
163
+ import "buffer";
164
+ import "../_libs/core-util-is.mjs";
165
+ import "../_libs/inherits.mjs";
166
+ import "../_libs/util-deprecate.mjs";
167
+ import "../_libs/lie.mjs";
168
+ import "../_libs/immediate.mjs";
169
+ import "../_libs/setimmediate.mjs";
170
+ import "../_libs/pako.mjs";
170
171
  const ReplayResultSchema = object({
171
172
  success: boolean(),
172
173
  error: string().optional(),
@@ -1,6 +1,6 @@
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 "./index-nUG0H1oS.mjs";
3
- import "./router-DG_jmXCF.mjs";
2
+ import { k as TooltipProvider, f as formatTokens, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-C2dnFXoC.mjs";
3
+ import "./router-B5hOtKSn.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import { J as Info } from "../_libs/lucide-react.mjs";
@@ -96,6 +96,7 @@ import "../_libs/mimic-function.mjs";
96
96
  import "../_libs/semver.mjs";
97
97
  import "../_libs/uint8array-extras.mjs";
98
98
  import "node:child_process";
99
+ import "node:worker_threads";
99
100
  import "../_libs/readable-stream.mjs";
100
101
  import "events";
101
102
  import "node:string_decoder";
@@ -1,7 +1,7 @@
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 "./index-nUG0H1oS.mjs";
3
- import { JsonViewer } from "./json-viewer-DLsDT0RE.mjs";
4
- import "./router-DG_jmXCF.mjs";
2
+ import { g as getLogFormatAdapter, f as formatTokens, c as cn, p as getStatusCategory, B as Badge, s as safeJsonValue } from "./ProxyViewerContainer-C2dnFXoC.mjs";
3
+ import { JsonViewer } from "./json-viewer-CHBa-Oas.mjs";
4
+ import "./router-B5hOtKSn.mjs";
5
5
  import "../_libs/modelcontextprotocol__server.mjs";
6
6
  import "../_libs/jszip.mjs";
7
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";
@@ -101,6 +101,7 @@ import "../_libs/mimic-function.mjs";
101
101
  import "../_libs/semver.mjs";
102
102
  import "../_libs/uint8array-extras.mjs";
103
103
  import "node:child_process";
104
+ import "node:worker_threads";
104
105
  import "../_libs/readable-stream.mjs";
105
106
  import "events";
106
107
  import "node:string_decoder";