@tonyclaw/agent-inspector 2.0.23 → 2.0.24

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 (37) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-DnYQtd8R.js → CompareDrawer-DrY-gAzy.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-CiLvRNie.js +115 -0
  4. package/.output/public/assets/{ReplayDialog-B-3V95xT.js → ReplayDialog-CFyw6Vu4.js} +1 -1
  5. package/.output/public/assets/{RequestAnatomy-CT8hLGLa.js → RequestAnatomy-DHGJ9py7.js} +1 -1
  6. package/.output/public/assets/{ResponseView-DK3CYom0.js → ResponseView-CB_3yc08.js} +1 -1
  7. package/.output/public/assets/{StreamingChunkSequence-D3jJutjp.js → StreamingChunkSequence-CqhHwgDn.js} +1 -1
  8. package/.output/public/assets/_sessionId-CgG9CQ9r.js +1 -0
  9. package/.output/public/assets/index-CViEXkqa.js +1 -0
  10. package/.output/public/assets/{main-hF_572U6.js → main-CVw7-JyE.js} +2 -2
  11. package/.output/server/{_sessionId-BqhNE2M8.mjs → _sessionId-V33sBWBC.mjs} +2 -2
  12. package/.output/server/_ssr/{CompareDrawer-C4LQW4S1.mjs → CompareDrawer-C_Fk9joM.mjs} +2 -2
  13. package/.output/server/_ssr/{ProxyViewerContainer-BKInvawk.mjs → ProxyViewerContainer-CyFKksQa.mjs} +75 -32
  14. package/.output/server/_ssr/{ReplayDialog-C3ZiRihL.mjs → ReplayDialog-BpQHN7O2.mjs} +3 -3
  15. package/.output/server/_ssr/{RequestAnatomy-DlVAPIQZ.mjs → RequestAnatomy-CuhmKAma.mjs} +2 -2
  16. package/.output/server/_ssr/{ResponseView-nMS0rkxu.mjs → ResponseView-CO6LyBmj.mjs} +2 -2
  17. package/.output/server/_ssr/{StreamingChunkSequence-PDWqrNiO.mjs → StreamingChunkSequence-DLeVetNR.mjs} +2 -2
  18. package/.output/server/_ssr/{index-Cd1zD-lo.mjs → index-DWUKl9Bf.mjs} +2 -2
  19. package/.output/server/_ssr/index.mjs +2 -2
  20. package/.output/server/_ssr/{router-R9gm7_sh.mjs → router-BrK_DcTS.mjs} +191 -14
  21. package/.output/server/{_tanstack-start-manifest_v-BnLVH_EX.mjs → _tanstack-start-manifest_v-BjW2XeWE.mjs} +1 -1
  22. package/.output/server/index.mjs +61 -61
  23. package/package.json +1 -1
  24. package/src/components/ProxyViewer.tsx +11 -1
  25. package/src/components/ProxyViewerContainer.tsx +21 -15
  26. package/src/lib/export-logs.ts +54 -11
  27. package/src/lib/providerTestPrompt.ts +4 -4
  28. package/src/mcp/toolHandlers.ts +58 -8
  29. package/src/proxy/logFinalizer.ts +79 -1
  30. package/src/proxy/logIndex.ts +6 -1
  31. package/src/proxy/schemas.ts +3 -0
  32. package/src/proxy/store.ts +79 -2
  33. package/src/routes/api/logs.stream.ts +5 -2
  34. package/src/routes/api/logs.ts +4 -1
  35. package/.output/public/assets/ProxyViewerContainer-BTYGkg36.js +0 -115
  36. package/.output/public/assets/_sessionId-DpdfAzbo.js +0 -1
  37. package/.output/public/assets/index-BpJNbm9G.js +0 -1
@@ -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_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, P as ProviderConfigSchema, r as requestFormatForPath, j as createPendingProviderTestResults, k as ProviderTestResultsSchema, l as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, n as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, m as maskApiKey, h as providerHasContextMetadata, i as findProviderModelMetadata, g as getSessionPath, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, o as resolveProviderContextWindow, K as KnowledgeCandidateSchema, f as stripClaudeCodeBillingHeader, q as isPlainRecord } from "./router-R9gm7_sh.mjs";
2
+ import { C as CapturedLogSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, P as ProviderConfigSchema, r as requestFormatForPath, j as createPendingProviderTestResults, k as ProviderTestResultsSchema, l as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, n as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, m as maskApiKey, h as providerHasContextMetadata, i as findProviderModelMetadata, g as getSessionPath, p as parseOpenAIResponse, O as OpenAIRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, o as resolveProviderContextWindow, K as KnowledgeCandidateSchema, f as stripClaudeCodeBillingHeader, q as isPlainRecord } from "./router-BrK_DcTS.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";
@@ -299,6 +299,34 @@ const SECRET_TEXT_PATTERNS = [
299
299
  /\bghp_[A-Za-z0-9_]{12,}\b/g,
300
300
  /\bglpat-[A-Za-z0-9_-]{12,}\b/g
301
301
  ];
302
+ const MAX_EXPORT_LOGS = 200;
303
+ const MAX_EXPORT_TEXT_CHARS = 25e6;
304
+ const MAX_STREAMING_CHUNK_EXPORTS = 50;
305
+ function formatApproxSize(chars) {
306
+ if (chars < 1024) return `${chars} chars`;
307
+ if (chars < 1024 * 1024) return `${Math.ceil(chars / 1024)} KB`;
308
+ return `${Math.ceil(chars / (1024 * 1024))} MB`;
309
+ }
310
+ function estimateExportTextChars(logs) {
311
+ let total = 0;
312
+ for (const log of logs) {
313
+ total += log.rawRequestBody?.length ?? 0;
314
+ total += log.responseText?.length ?? 0;
315
+ }
316
+ return total;
317
+ }
318
+ function exportLimitMessage(logs) {
319
+ if (logs.length > MAX_EXPORT_LOGS) {
320
+ return `Export is limited to ${MAX_EXPORT_LOGS} logs at once. Narrow the filter and try again.`;
321
+ }
322
+ const estimatedChars = estimateExportTextChars(logs);
323
+ if (estimatedChars > MAX_EXPORT_TEXT_CHARS) {
324
+ return `Export is too large (${formatApproxSize(
325
+ estimatedChars
326
+ )} of text). Narrow the filter and try again.`;
327
+ }
328
+ return null;
329
+ }
302
330
  async function fetchStreamingChunks(logId) {
303
331
  try {
304
332
  const response = await fetch(`/api/logs/${logId}/chunks`);
@@ -340,8 +368,11 @@ function exportText(text, mode) {
340
368
  return mode === "redacted" ? redactJsonText(text) : text;
341
369
  }
342
370
  async function exportLogsAsZip(logs, mode = "redacted") {
371
+ const limitMessage = exportLimitMessage(logs);
372
+ if (limitMessage !== null) return { ok: false, message: limitMessage };
343
373
  const zip = new JSZip();
344
374
  const suffix = mode === "redacted" ? "redacted" : "raw";
375
+ const streamingLogs = logs.filter((log) => log.streaming).slice(0, MAX_STREAMING_CHUNK_EXPORTS);
345
376
  zip.file(
346
377
  "manifest.json",
347
378
  JSON.stringify(
@@ -350,7 +381,9 @@ async function exportLogsAsZip(logs, mode = "redacted") {
350
381
  mode,
351
382
  redacted: mode === "redacted",
352
383
  logCount: logs.length,
353
- logIds: logs.map((log) => log.id)
384
+ logIds: logs.map((log) => log.id),
385
+ streamingChunkExportLimit: MAX_STREAMING_CHUNK_EXPORTS,
386
+ streamingChunkLogIds: streamingLogs.map((log) => log.id)
354
387
  },
355
388
  null,
356
389
  2
@@ -364,15 +397,12 @@ async function exportLogsAsZip(logs, mode = "redacted") {
364
397
  zip.file(`#${log.id}.Response.json`, exportText(log.responseText, mode));
365
398
  }
366
399
  }
367
- const streamingLogs = logs.filter((log) => log.streaming);
368
- await Promise.allSettled(
369
- streamingLogs.map(async (log) => {
370
- const chunks = await fetchStreamingChunks(log.id);
371
- if (chunks !== null) {
372
- zip.file(`#${log.id}.SSE.Response.json`, exportText(chunks, mode));
373
- }
374
- })
375
- );
400
+ for (const log of streamingLogs) {
401
+ const chunks = await fetchStreamingChunks(log.id);
402
+ if (chunks !== null) {
403
+ zip.file(`#${log.id}.SSE.Response.json`, exportText(chunks, mode));
404
+ }
405
+ }
376
406
  const blob = await zip.generateAsync({ type: "blob" });
377
407
  const url = URL.createObjectURL(blob);
378
408
  const anchor = document.createElement("a");
@@ -382,6 +412,7 @@ async function exportLogsAsZip(logs, mode = "redacted") {
382
412
  anchor.click();
383
413
  document.body.removeChild(anchor);
384
414
  URL.revokeObjectURL(url);
415
+ return { ok: true };
385
416
  }
386
417
  function formatTimestamp(iso, format) {
387
418
  switch (format) {
@@ -442,7 +473,7 @@ function useProviders() {
442
473
  mutate: response.mutate
443
474
  };
444
475
  }
445
- const version = "2.0.23";
476
+ const version = "2.0.24";
446
477
  const packageJson = {
447
478
  version
448
479
  };
@@ -1503,19 +1534,19 @@ function useCopyFeedback(text) {
1503
1534
  return { copied, copy };
1504
1535
  }
1505
1536
  const LazyCompareDrawer = reactExports.lazy(
1506
- () => import("./CompareDrawer-C4LQW4S1.mjs").then((m) => ({ default: m.CompareDrawer }))
1537
+ () => import("./CompareDrawer-C_Fk9joM.mjs").then((m) => ({ default: m.CompareDrawer }))
1507
1538
  );
1508
1539
  const LazyReplayDialog = reactExports.lazy(
1509
- () => import("./ReplayDialog-C3ZiRihL.mjs").then((m) => ({ default: m.ReplayDialog }))
1540
+ () => import("./ReplayDialog-BpQHN7O2.mjs").then((m) => ({ default: m.ReplayDialog }))
1510
1541
  );
1511
1542
  const LazyRequestAnatomy = reactExports.lazy(
1512
- () => import("./RequestAnatomy-DlVAPIQZ.mjs").then((m) => ({ default: m.RequestAnatomy }))
1543
+ () => import("./RequestAnatomy-CuhmKAma.mjs").then((m) => ({ default: m.RequestAnatomy }))
1513
1544
  );
1514
1545
  const LazyResponseView = reactExports.lazy(
1515
- () => import("./ResponseView-nMS0rkxu.mjs").then((m) => ({ default: m.ResponseView }))
1546
+ () => import("./ResponseView-CO6LyBmj.mjs").then((m) => ({ default: m.ResponseView }))
1516
1547
  );
1517
1548
  const LazyStreamingChunkSequence = reactExports.lazy(
1518
- () => import("./StreamingChunkSequence-PDWqrNiO.mjs").then((m) => ({
1549
+ () => import("./StreamingChunkSequence-DLeVetNR.mjs").then((m) => ({
1519
1550
  default: m.StreamingChunkSequence
1520
1551
  }))
1521
1552
  );
@@ -9440,6 +9471,7 @@ function ProxyViewer({
9440
9471
  const { totalIn, totalOut } = reactExports.useMemo(() => computeTokenSummary(logs), [logs]);
9441
9472
  const { providers } = useProviders();
9442
9473
  const [exporting, setExporting] = reactExports.useState(null);
9474
+ const [exportError, setExportError] = reactExports.useState(null);
9443
9475
  const [comparePair, setComparePair] = reactExports.useState(null);
9444
9476
  const [crabEntrancePhase, setCrabEntrancePhase] = reactExports.useState(
9445
9477
  "hidden"
@@ -9469,8 +9501,12 @@ function ProxyViewer({
9469
9501
  const handleExport = reactExports.useCallback(
9470
9502
  async (mode) => {
9471
9503
  setExporting(mode);
9504
+ setExportError(null);
9472
9505
  try {
9473
- await exportLogsAsZip(logs, mode);
9506
+ const result = await exportLogsAsZip(logs, mode);
9507
+ if (!result.ok) {
9508
+ setExportError(result.message);
9509
+ }
9474
9510
  } finally {
9475
9511
  setExporting(null);
9476
9512
  }
@@ -9658,7 +9694,8 @@ function ProxyViewer({
9658
9694
  children: "Clear"
9659
9695
  }
9660
9696
  )
9661
- ] })
9697
+ ] }),
9698
+ exportError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: exportError })
9662
9699
  ] }),
9663
9700
  /* @__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: [
9664
9701
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", children: "Session not found" }),
@@ -9746,11 +9783,24 @@ function filterLogs(logs, selectedSession, selectedModel) {
9746
9783
  const DEBOUNCE_MS = 50;
9747
9784
  const HASH_SCROLL_ATTEMPTS = 12;
9748
9785
  const HASH_HIGHLIGHT_MS = 1800;
9786
+ const MAX_CLIENT_LOGS = 500;
9749
9787
  function buildLogsStreamUrl(sessionId) {
9750
9788
  if (sessionId === void 0) return "/api/logs/stream";
9751
9789
  const params = new URLSearchParams({ sessionId });
9752
9790
  return `/api/logs/stream?${params.toString()}`;
9753
9791
  }
9792
+ function buildLogIndex(logs) {
9793
+ const idx = /* @__PURE__ */ new Map();
9794
+ for (let i = 0; i < logs.length; i++) {
9795
+ const log = logs[i];
9796
+ if (log !== void 0) idx.set(log.id, i);
9797
+ }
9798
+ return idx;
9799
+ }
9800
+ function trimClientLogs(logs) {
9801
+ if (logs.length <= MAX_CLIENT_LOGS) return logs;
9802
+ return logs.slice(logs.length - MAX_CLIENT_LOGS);
9803
+ }
9754
9804
  function ProxyViewerContainer({
9755
9805
  initialSessionId
9756
9806
  } = {}) {
@@ -9787,6 +9837,8 @@ function ProxyViewerContainer({
9787
9837
  next = [...next, log];
9788
9838
  }
9789
9839
  }
9840
+ next = trimClientLogs(next);
9841
+ logIndexRef.current = buildLogIndex(next);
9790
9842
  return next;
9791
9843
  });
9792
9844
  }, []);
@@ -9821,13 +9873,9 @@ function ProxyViewerContainer({
9821
9873
  flushTimerRef.current = null;
9822
9874
  }
9823
9875
  pendingUpdatesRef.current = [];
9824
- const idx = /* @__PURE__ */ new Map();
9825
- for (let i = 0; i < update.logs.length; i++) {
9826
- const log = update.logs[i];
9827
- if (log !== void 0) idx.set(log.id, i);
9828
- }
9829
- logIndexRef.current = idx;
9830
- setAllLogs(update.logs);
9876
+ const nextLogs = trimClientLogs(update.logs);
9877
+ logIndexRef.current = buildLogIndex(nextLogs);
9878
+ setAllLogs(nextLogs);
9831
9879
  setError(null);
9832
9880
  } else if (update.type === "update") {
9833
9881
  scheduleUpdate(update.log);
@@ -9950,12 +9998,7 @@ function ProxyViewerContainer({
9950
9998
  const idSet = new Set(ids);
9951
9999
  setAllLogs((prev) => {
9952
10000
  const remaining = prev.filter((l) => !idSet.has(l.id));
9953
- const idx = /* @__PURE__ */ new Map();
9954
- for (let i = 0; i < remaining.length; i++) {
9955
- const log = remaining[i];
9956
- if (log !== void 0) idx.set(log.id, i);
9957
- }
9958
- logIndexRef.current = idx;
10001
+ logIndexRef.current = buildLogIndex(remaining);
9959
10002
  return remaining;
9960
10003
  });
9961
10004
  setError(null);
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.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 Button, l as TooltipProvider, m as Tooltip, n as TooltipTrigger, o as TooltipContent, p as dispatchLogFocusRequest } from "./ProxyViewerContainer-BKInvawk.mjs";
3
- import { ResponseView } from "./ResponseView-nMS0rkxu.mjs";
4
- import { C as CapturedLogSchema } from "./router-R9gm7_sh.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 Button, l as TooltipProvider, m as Tooltip, n as TooltipTrigger, o as TooltipContent, p as dispatchLogFocusRequest } from "./ProxyViewerContainer-CyFKksQa.mjs";
3
+ import { ResponseView } from "./ResponseView-CO6LyBmj.mjs";
4
+ import { C as CapturedLogSchema } from "./router-BrK_DcTS.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import "../_libs/modelcontextprotocol__server.mjs";
7
7
  import { K as RotateCcw, ac as Braces, ad as Minimize2 } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useProviders, q as analyzeContextIntelligence, f as formatTokens, l as TooltipProvider, c as cn, m as Tooltip, n as TooltipTrigger, o as TooltipContent, S as SegmentBar, R as ROLE_COLOR_CLASSES, A as ANATOMY_ROLE_LABELS, s as formatContextWindowTokens, C as CONTEXT_USAGE_THRESHOLDS } from "./ProxyViewerContainer-BKInvawk.mjs";
3
- import "./router-R9gm7_sh.mjs";
2
+ import { u as useProviders, q as analyzeContextIntelligence, f as formatTokens, l as TooltipProvider, c as cn, m as Tooltip, n as TooltipTrigger, o as TooltipContent, S as SegmentBar, R as ROLE_COLOR_CLASSES, A as ANATOMY_ROLE_LABELS, s as formatContextWindowTokens, C as CONTEXT_USAGE_THRESHOLDS } from "./ProxyViewerContainer-CyFKksQa.mjs";
3
+ import "./router-BrK_DcTS.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import { ae as Info, b as ChevronDown, i as ChevronRight } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { g as getLogFormatAdapter, f as formatTokens, c as cn, t as getStatusCategory, B as Badge, v as Collapsible, w as CollapsibleTrigger, x as CollapsibleContent, y as ScrollArea, z as JsonViewer, E as safeJsonValue } from "./ProxyViewerContainer-BKInvawk.mjs";
3
- import "./router-R9gm7_sh.mjs";
2
+ import { g as getLogFormatAdapter, f as formatTokens, c as cn, t as getStatusCategory, B as Badge, v as Collapsible, w as CollapsibleTrigger, x as CollapsibleContent, y as ScrollArea, z as JsonViewer, E as safeJsonValue } from "./ProxyViewerContainer-CyFKksQa.mjs";
3
+ import "./router-BrK_DcTS.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import { Z as Zap, o as TriangleAlert, af as CircleStop, B as Brain, b as ChevronDown, i as ChevronRight, T as Terminal } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { l as TooltipProvider, m as Tooltip, n as TooltipTrigger, B as Badge, o as TooltipContent, z as JsonViewer } from "./ProxyViewerContainer-BKInvawk.mjs";
3
- import "./router-R9gm7_sh.mjs";
2
+ import { l as TooltipProvider, m as Tooltip, n as TooltipTrigger, B as Badge, o as TooltipContent, z as JsonViewer } from "./ProxyViewerContainer-CyFKksQa.mjs";
3
+ import "./router-BrK_DcTS.mjs";
4
4
  import "../_libs/modelcontextprotocol__server.mjs";
5
5
  import "../_libs/jszip.mjs";
6
6
  import { b as ChevronDown, i as ChevronRight, L as LoaderCircle } from "../_libs/lucide-react.mjs";
@@ -1,6 +1,6 @@
1
- import { P as ProxyViewerContainer } from "./ProxyViewerContainer-BKInvawk.mjs";
1
+ import { P as ProxyViewerContainer } from "./ProxyViewerContainer-CyFKksQa.mjs";
2
2
  import "../_libs/react.mjs";
3
- import "./router-R9gm7_sh.mjs";
3
+ import "./router-BrK_DcTS.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-BnLVH_EX.mjs");
201
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-BjW2XeWE.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-R9gm7_sh.mjs").then((n) => n.t);
770
+ const routerEntry = await import("./router-BrK_DcTS.mjs").then((n) => n.t);
771
771
  const startEntry = await import("./start-HYkvq4Ni.mjs");
772
772
  return { startEntry, routerEntry };
773
773
  }
@@ -93,7 +93,7 @@ function RootDocument({ children }) {
93
93
  ] })
94
94
  ] });
95
95
  }
96
- const $$splitComponentImporter$1 = () => import("./index-Cd1zD-lo.mjs");
96
+ const $$splitComponentImporter$1 = () => import("./index-DWUKl9Bf.mjs");
97
97
  const Route$r = createFileRoute("/")({
98
98
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
99
99
  });
@@ -136,7 +136,7 @@ function decodeSessionIdFromPath(encoded) {
136
136
  function getSessionPath(sessionId) {
137
137
  return `/session/${encodeSessionIdForPath(sessionId)}`;
138
138
  }
139
- const $$splitComponentImporter = () => import("../_sessionId-BqhNE2M8.mjs");
139
+ const $$splitComponentImporter = () => import("../_sessionId-V33sBWBC.mjs");
140
140
  const Route$q = createFileRoute("/session/$sessionId")({
141
141
  component: lazyRouteComponent($$splitComponentImporter, "component"),
142
142
  parseParams: (params) => ({
@@ -729,6 +729,9 @@ const CapturedLogSchema = object({
729
729
  clientProjectFolder: string().nullable().optional(),
730
730
  streamingChunks: StreamingChunksArraySchema.optional(),
731
731
  streamingChunksPath: string().nullable().optional(),
732
+ rawRequestBodyBytes: number().int().nonnegative().nullable().optional(),
733
+ responseTextBytes: number().int().nonnegative().nullable().optional(),
734
+ bodyContentMode: _enum(["full", "compact", "truncated"]).optional(),
732
735
  /** Error message from streaming response (e.g., SSE error event) */
733
736
  error: string().nullable().optional()
734
737
  });
@@ -927,6 +930,10 @@ async function findInIndex(id) {
927
930
  const index = await loadIndex();
928
931
  return index.entries[id] ?? null;
929
932
  }
933
+ async function listIndexEntries() {
934
+ const index = await loadIndex();
935
+ return Object.values(index.entries).sort((left, right) => left.id - right.id);
936
+ }
930
937
  async function indexFile(filePath, file) {
931
938
  const entries = {};
932
939
  let maxId = 0;
@@ -1341,6 +1348,26 @@ function addToCache(log) {
1341
1348
  function removeFromCache(id) {
1342
1349
  memoryCache.delete(id);
1343
1350
  }
1351
+ function textByteLength$1(value) {
1352
+ if (value === null) return null;
1353
+ return Buffer.byteLength(value, "utf8");
1354
+ }
1355
+ function compactLogForList(log) {
1356
+ return {
1357
+ ...log,
1358
+ rawRequestBody: null,
1359
+ responseText: null,
1360
+ rawHeaders: void 0,
1361
+ headers: void 0,
1362
+ streamingChunks: void 0,
1363
+ rawRequestBodyBytes: textByteLength$1(log.rawRequestBody),
1364
+ responseTextBytes: textByteLength$1(log.responseText),
1365
+ bodyContentMode: "compact"
1366
+ };
1367
+ }
1368
+ function prepareLogForList(log, includeBodies) {
1369
+ return includeBodies ? log : compactLogForList(log);
1370
+ }
1344
1371
  async function addTestLogEntry(entry) {
1345
1372
  const id = await getNextLogId();
1346
1373
  let streamingChunksPath = null;
@@ -1542,11 +1569,50 @@ async function visitPersistedLogFile(filePath, visitor) {
1542
1569
  logger.error("[store] Failed to read persisted log file:", filePath, String(err));
1543
1570
  }
1544
1571
  }
1572
+ function canUseIndexedListPage(options) {
1573
+ return options.sessionId === void 0 && options.model === void 0;
1574
+ }
1575
+ function hasUsableIndexOffset(entry) {
1576
+ return entry.byteOffset >= 0 && entry.byteLength > 0;
1577
+ }
1578
+ async function listLogsPageFromIndex(options, allowRebuild) {
1579
+ if (!canUseIndexedListPage(options)) return null;
1580
+ let entries = await listIndexEntries();
1581
+ if (entries.length === 0 && allowRebuild) {
1582
+ await rebuildIndex();
1583
+ entries = await listIndexEntries();
1584
+ }
1585
+ const pageStart = options.offset;
1586
+ const pageEnd = options.offset + options.limit;
1587
+ const pageEntries = entries.slice(pageStart, pageEnd);
1588
+ const hasIncompleteOffset = pageEntries.some((entry) => !hasUsableIndexOffset(entry));
1589
+ if (hasIncompleteOffset) {
1590
+ if (!allowRebuild) return null;
1591
+ await rebuildIndex();
1592
+ return await listLogsPageFromIndex(options, false);
1593
+ }
1594
+ const logs = [];
1595
+ const includeBodies = options.includeBodies !== false;
1596
+ for (const entry of pageEntries) {
1597
+ const log = await getLogById(entry.id);
1598
+ if (log === null) return null;
1599
+ logs.push(prepareLogForList(log, includeBodies));
1600
+ }
1601
+ return {
1602
+ logs,
1603
+ total: entries.length,
1604
+ offset: options.offset,
1605
+ limit: options.limit
1606
+ };
1607
+ }
1545
1608
  async function listLogsPage(options) {
1609
+ const indexedPage = await listLogsPageFromIndex(options, true);
1610
+ if (indexedPage !== null) return indexedPage;
1546
1611
  const seenIds = /* @__PURE__ */ new Set();
1547
1612
  const pageById = /* @__PURE__ */ new Map();
1548
1613
  const pageStart = options.offset;
1549
1614
  const pageEnd = options.offset + options.limit;
1615
+ const includeBodies = options.includeBodies !== false;
1550
1616
  let total = 0;
1551
1617
  const visitLog = (log) => {
1552
1618
  if (!matchesLogFilters(log, options.sessionId, options.model)) return;
@@ -1555,12 +1621,12 @@ async function listLogsPage(options) {
1555
1621
  const position = total;
1556
1622
  total += 1;
1557
1623
  if (position >= pageStart && position < pageEnd) {
1558
- pageById.set(log.id, log);
1624
+ pageById.set(log.id, prepareLogForList(log, includeBodies));
1559
1625
  }
1560
1626
  return;
1561
1627
  }
1562
1628
  if (pageById.has(log.id)) {
1563
- pageById.set(log.id, log);
1629
+ pageById.set(log.id, prepareLogForList(log, includeBodies));
1564
1630
  }
1565
1631
  };
1566
1632
  await visitPersistedLogs((log) => {
@@ -3851,6 +3917,14 @@ function stripOpenAIOrphanToolMessages(rawBody) {
3851
3917
  parsed.messages = kept;
3852
3918
  return { body: JSON.stringify(parsed), removed: indices.length, orphanIds };
3853
3919
  }
3920
+ const DEFAULT_MAX_FINALIZE_STREAM_BYTES = 20 * 1024 * 1024;
3921
+ function resolveMaxFinalizeStreamBytes() {
3922
+ const raw = process.env["AGENT_INSPECTOR_MAX_FINALIZE_STREAM_BYTES"];
3923
+ if (raw === void 0 || raw === "") return DEFAULT_MAX_FINALIZE_STREAM_BYTES;
3924
+ const parsed = Number(raw);
3925
+ if (!Number.isFinite(parsed) || parsed < 1) return DEFAULT_MAX_FINALIZE_STREAM_BYTES;
3926
+ return Math.floor(parsed);
3927
+ }
3854
3928
  function buildFileLogEntry(log, upstreamUrl) {
3855
3929
  return {
3856
3930
  timestamp: log.timestamp,
@@ -3933,6 +4007,37 @@ function cleanupPathForRawStream(rawStream) {
3933
4007
  return rawStream.path;
3934
4008
  }
3935
4009
  }
4010
+ function rawStreamByteLength(rawStream) {
4011
+ if (typeof rawStream === "string") {
4012
+ return Buffer.byteLength(rawStream, "utf8");
4013
+ }
4014
+ switch (rawStream.type) {
4015
+ case "memory":
4016
+ return Buffer.byteLength(rawStream.rawStream, "utf8");
4017
+ case "file":
4018
+ try {
4019
+ return statSync(rawStream.path).size;
4020
+ } catch {
4021
+ return null;
4022
+ }
4023
+ }
4024
+ }
4025
+ function getOversizedRawStream(rawStream) {
4026
+ const limit = resolveMaxFinalizeStreamBytes();
4027
+ const byteLength = rawStreamByteLength(rawStream);
4028
+ if (byteLength === null || byteLength <= limit) return null;
4029
+ return { byteLength, limit };
4030
+ }
4031
+ function formatBytes(bytes) {
4032
+ if (bytes < 1024) return `${bytes} bytes`;
4033
+ if (bytes < 1024 * 1024) return `${Math.ceil(bytes / 1024)} KB`;
4034
+ return `${Math.ceil(bytes / (1024 * 1024))} MB`;
4035
+ }
4036
+ function oversizedRawStreamText(oversized) {
4037
+ return `Streaming response omitted because the captured raw stream is ${formatBytes(
4038
+ oversized.byteLength
4039
+ )}, exceeding the finalize limit of ${formatBytes(oversized.limit)}. Increase AGENT_INSPECTOR_MAX_FINALIZE_STREAM_BYTES if this response must be parsed.`;
4040
+ }
3936
4041
  function readRawStream(rawStream) {
3937
4042
  if (typeof rawStream === "string") {
3938
4043
  return { rawStreamText: rawStream, cleanupRawStreamPath: null };
@@ -3959,6 +4064,18 @@ function finalizeStreaming(job, log) {
3959
4064
  cleanupPathForRawStream(job.rawStream)
3960
4065
  );
3961
4066
  }
4067
+ const oversized = getOversizedRawStream(job.rawStream);
4068
+ if (oversized !== null) {
4069
+ log.elapsedMs = job.elapsedMs;
4070
+ log.responseStatus = job.responseStatus;
4071
+ log.responseText = oversizedRawStreamText(oversized);
4072
+ return {
4073
+ log,
4074
+ upstreamUrl: job.upstreamUrl,
4075
+ error: null,
4076
+ cleanupRawStreamPath: cleanupPathForRawStream(job.rawStream)
4077
+ };
4078
+ }
3962
4079
  let rawStreamText = "";
3963
4080
  let cleanupRawStreamPath = null;
3964
4081
  try {
@@ -4003,6 +4120,16 @@ function finalizeStreamAbort(job, log) {
4003
4120
  try {
4004
4121
  log.elapsedMs = job.elapsedMs;
4005
4122
  if (job.hasChunks && formatHandler !== null) {
4123
+ const oversized = getOversizedRawStream(job.rawStream);
4124
+ if (oversized !== null) {
4125
+ log.responseText = `Client aborted. ${oversizedRawStreamText(oversized)}`;
4126
+ return {
4127
+ log,
4128
+ upstreamUrl: job.upstreamUrl,
4129
+ error: "Client aborted",
4130
+ cleanupRawStreamPath: cleanupPathForRawStream(job.rawStream)
4131
+ };
4132
+ }
4006
4133
  const raw = readRawStream(job.rawStream);
4007
4134
  rawStreamText = raw.rawStreamText;
4008
4135
  cleanupRawStreamPath = raw.cleanupRawStreamPath;
@@ -4756,6 +4883,7 @@ const LogsListResponseSchema = object({
4756
4883
  });
4757
4884
  const PAGINATION_DEFAULTS = { offset: 0, limit: 3 };
4758
4885
  const LIMIT_HARD_CAP = 5;
4886
+ const LOG_DETAIL_TEXT_LIMIT = 2e5;
4759
4887
  function clampLimit(input) {
4760
4888
  if (input === void 0) return PAGINATION_DEFAULTS.limit;
4761
4889
  if (!Number.isFinite(input) || input < 1) return 1;
@@ -4767,8 +4895,46 @@ function textJson(data) {
4767
4895
  function toolError(message) {
4768
4896
  return { content: [{ type: "text", text: message }], isError: true };
4769
4897
  }
4898
+ function textByteLength(value) {
4899
+ if (value === null) return null;
4900
+ return Buffer.byteLength(value, "utf8");
4901
+ }
4902
+ function hasBodyText(value, byteLength) {
4903
+ if (value !== null && value.length > 0) return true;
4904
+ return byteLength !== void 0 && byteLength !== null && byteLength > 0;
4905
+ }
4906
+ function truncateToolText(value) {
4907
+ if (value === null) return { value: null, byteLength: null, truncated: false };
4908
+ const byteLength = textByteLength(value);
4909
+ if (value.length <= LOG_DETAIL_TEXT_LIMIT) {
4910
+ return { value, byteLength, truncated: false };
4911
+ }
4912
+ const suffix = `
4913
+ [truncated by agent-inspector MCP: original ${byteLength ?? 0} bytes]`;
4914
+ return {
4915
+ value: `${value.slice(0, LOG_DETAIL_TEXT_LIMIT)}${suffix}`,
4916
+ byteLength,
4917
+ truncated: true
4918
+ };
4919
+ }
4920
+ function buildBoundedLogDetail(log) {
4921
+ const { streamingChunks: _chunks, rawRequestBody, responseText, ...rest } = log;
4922
+ const boundedRequest = truncateToolText(rawRequestBody);
4923
+ const boundedResponse = truncateToolText(responseText);
4924
+ return {
4925
+ ...rest,
4926
+ rawRequestBody: boundedRequest.value,
4927
+ responseText: boundedResponse.value,
4928
+ rawRequestBodyBytes: boundedRequest.byteLength,
4929
+ responseTextBytes: boundedResponse.byteLength,
4930
+ rawRequestBodyTruncated: boundedRequest.truncated,
4931
+ responseTextTruncated: boundedResponse.truncated
4932
+ };
4933
+ }
4770
4934
  function buildLogSummary(log) {
4771
4935
  const hasError = log.error !== null && log.error !== void 0 && log.error.length > 0 || log.responseStatus !== null && log.responseStatus !== void 0 && log.responseStatus >= 400;
4936
+ const rawRequestBodyBytes = log.rawRequestBodyBytes ?? textByteLength(log.rawRequestBody);
4937
+ const responseTextBytes = log.responseTextBytes ?? textByteLength(log.responseText);
4772
4938
  return {
4773
4939
  id: log.id,
4774
4940
  timestamp: log.timestamp,
@@ -4792,13 +4958,19 @@ function buildLogSummary(log) {
4792
4958
  lastUserMessagePreview: extractLastUserMessagePreview(log),
4793
4959
  responsePreview: extractResponsePreview(log),
4794
4960
  hasChunks: log.streamingChunks !== void 0 && log.streamingChunks !== null || log.streamingChunksPath !== null && log.streamingChunksPath !== void 0,
4795
- hasRawRequestBody: log.rawRequestBody !== null && log.rawRequestBody !== void 0
4961
+ hasRawRequestBody: hasBodyText(log.rawRequestBody, rawRequestBodyBytes),
4962
+ rawRequestBodyBytes,
4963
+ responseTextBytes
4796
4964
  };
4797
4965
  }
4798
4966
  async function listLogsImpl(callApi2, args) {
4799
4967
  const offset = args.offset ?? PAGINATION_DEFAULTS.offset;
4800
4968
  const limit = clampLimit(args.limit);
4801
- const params = new URLSearchParams({ offset: String(offset), limit: String(limit) });
4969
+ const params = new URLSearchParams({
4970
+ offset: String(offset),
4971
+ limit: String(limit),
4972
+ compact: "1"
4973
+ });
4802
4974
  if (args.sessionId !== void 0 && args.sessionId.length > 0) {
4803
4975
  params.set("sessionId", args.sessionId);
4804
4976
  }
@@ -4821,8 +4993,7 @@ async function getLogImpl(callApi2, id) {
4821
4993
  if (!parsed.success) {
4822
4994
  return toolError(`GET /api/logs/${id} returned an unparseable CapturedLog`);
4823
4995
  }
4824
- const { streamingChunks: _chunks, ...rest } = parsed.data;
4825
- return textJson(rest);
4996
+ return textJson(buildBoundedLogDetail(parsed.data));
4826
4997
  }
4827
4998
  async function getLogChunksImpl(callApi2, id) {
4828
4999
  const res = await callApi2(`/api/logs/${id}/chunks`);
@@ -5259,7 +5430,10 @@ const Route$k = createFileRoute("/api/logs")({
5259
5430
  const model = url.searchParams.get("model") ?? void 0;
5260
5431
  const offset = parseNonNegativeInt(url.searchParams.get("offset"), 0);
5261
5432
  const limit = parsePositiveInt(url.searchParams.get("limit"), 50);
5262
- return Response.json(await listLogsPage({ sessionId, model, offset, limit }));
5433
+ const includeBodies = url.searchParams.get("compact") !== "1";
5434
+ return Response.json(
5435
+ await listLogsPage({ sessionId, model, offset, limit, includeBodies })
5436
+ );
5263
5437
  },
5264
5438
  DELETE: async ({ request }) => {
5265
5439
  let body = void 0;
@@ -5902,6 +6076,7 @@ const Route$d = createFileRoute("/api/logs/stream")({
5902
6076
  const url = new URL(request.url);
5903
6077
  const sessionId = url.searchParams.get("sessionId") ?? void 0;
5904
6078
  const model = url.searchParams.get("model") ?? void 0;
6079
+ const includeBodies = url.searchParams.get("compact") !== "1";
5905
6080
  let controllerRef = null;
5906
6081
  let cleanedUp = false;
5907
6082
  const unsubscribe = onLogUpdate((log) => {
@@ -5909,7 +6084,8 @@ const Route$d = createFileRoute("/api/logs/stream")({
5909
6084
  if (sessionId !== void 0 && getLogSessionId(log) !== sessionId) return;
5910
6085
  if (model !== void 0 && log.model !== model) return;
5911
6086
  try {
5912
- const data = `data: ${JSON.stringify({ type: "update", log })}
6087
+ const payloadLog = includeBodies ? log : compactLogForList(log);
6088
+ const data = `data: ${JSON.stringify({ type: "update", log: payloadLog })}
5913
6089
 
5914
6090
  `;
5915
6091
  controllerRef.enqueue(new TextEncoder().encode(data));
@@ -5942,7 +6118,8 @@ const Route$d = createFileRoute("/api/logs/stream")({
5942
6118
  sessionId,
5943
6119
  model,
5944
6120
  offset: 0,
5945
- limit: INITIAL_STREAM_LOG_LIMIT
6121
+ limit: INITIAL_STREAM_LOG_LIMIT,
6122
+ includeBodies
5946
6123
  });
5947
6124
  const logs = result.logs;
5948
6125
  const initData = `data: ${JSON.stringify({ type: "init", logs })}
@@ -6642,9 +6819,9 @@ function modeInstruction(mode) {
6642
6819
  function maxTokensForMode(mode) {
6643
6820
  switch (mode) {
6644
6821
  case "non-streaming":
6645
- return 1024;
6822
+ return 256;
6646
6823
  case "streaming":
6647
- return 384;
6824
+ return 256;
6648
6825
  }
6649
6826
  }
6650
6827
  function buildProviderTestUserPrompt(mode) {
@@ -6675,7 +6852,7 @@ function buildProviderTestRequestBody(model, mode) {
6675
6852
  };
6676
6853
  switch (mode) {
6677
6854
  case "non-streaming":
6678
- return base;
6855
+ return { ...base, stream: false };
6679
6856
  case "streaming":
6680
6857
  return { ...base, stream: true };
6681
6858
  }