@tonyclaw/agent-inspector 3.0.30 → 3.0.31

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 (44) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-B6cXJohL.js → CompareDrawer-DB2KggLE.js} +1 -1
  3. package/.output/public/assets/{InspectorPet-mAzeGmEE.js → InspectorPet-CfwDw6kD.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-PcrO96_F.js +126 -0
  5. package/.output/public/assets/{ReplayDialog-DodiTL6E.js → ReplayDialog-3Pl7EKjp.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-B3IauToI.js → RequestAnatomy-BcPjcHLX.js} +1 -1
  7. package/.output/public/assets/ResponseView-DOx51wV3.js +2 -0
  8. package/.output/public/assets/{StreamingChunkSequence-vLDOVQM_.js → StreamingChunkSequence-LkYJWM1A.js} +1 -1
  9. package/.output/public/assets/{_sessionId-BFH4TOaI.js → _sessionId-BSg32vC6.js} +1 -1
  10. package/.output/public/assets/{_sessionId-Cj_HIFZx.js → _sessionId-C0CA68QV.js} +1 -1
  11. package/.output/public/assets/{index-Bmj2lcWE.js → index-BpBUqdAB.js} +1 -1
  12. package/.output/public/assets/{index-Ch7uqnCT.js → index-D93dCgAQ.js} +1 -1
  13. package/.output/public/assets/{index-ZlhqCrSg.js → index-FV5sxqx3.js} +1 -1
  14. package/.output/public/assets/{index-DkDdKvLl.js → index-VUsF4nhf.js} +3 -3
  15. package/.output/public/assets/index-hyQHZeQI.css +1 -0
  16. package/.output/public/assets/{json-viewer-BdrnVQu-.js → json-viewer-WctIbAh_.js} +1 -1
  17. package/.output/public/assets/{jszip.min-CS_nt_o1.js → jszip.min-DnSIoTix.js} +1 -1
  18. package/.output/server/_libs/lucide-react.mjs +55 -55
  19. package/.output/server/{_sessionId-C5S3pGZd.mjs → _sessionId-BHBK3VbF.mjs} +2 -2
  20. package/.output/server/{_sessionId-g6D69lKq.mjs → _sessionId-CyuJ6Kfl.mjs} +1 -1
  21. package/.output/server/_ssr/{CompareDrawer-CqUmGHal.mjs → CompareDrawer-27amlv_a.mjs} +3 -3
  22. package/.output/server/_ssr/{InspectorPet-DI0UJd01.mjs → InspectorPet-CQnGXfLs.mjs} +1 -1
  23. package/.output/server/_ssr/{ProxyViewerContainer-CvsUmbJ3.mjs → ProxyViewerContainer-DlAl0uF-.mjs} +426 -47
  24. package/.output/server/_ssr/{ReplayDialog-DS48dpFG.mjs → ReplayDialog-5m2jtlLa.mjs} +4 -4
  25. package/.output/server/_ssr/{RequestAnatomy-DxYVQU1C.mjs → RequestAnatomy--1WtQNY9.mjs} +3 -3
  26. package/.output/server/_ssr/{ResponseView-BLXW73eq.mjs → ResponseView-CgbqS8sr.mjs} +3 -14
  27. package/.output/server/_ssr/{StreamingChunkSequence-DD0iFuy0.mjs → StreamingChunkSequence-BwpnopWx.mjs} +3 -3
  28. package/.output/server/_ssr/{index-B10LIaK0.mjs → index-CNVi1TzT.mjs} +2 -2
  29. package/.output/server/_ssr/{index-RHVJnU2p.mjs → index-DMCjH_4V.mjs} +1 -1
  30. package/.output/server/_ssr/index.mjs +2 -2
  31. package/.output/server/_ssr/{json-viewer-LDu2XBaK.mjs → json-viewer-DNGN2uoe.mjs} +3 -3
  32. package/.output/server/_ssr/{router-GKvrwifJ.mjs → router-CgsqLnk5.mjs} +5382 -4524
  33. package/.output/server/{_tanstack-start-manifest_v-Df2n4mbT.mjs → _tanstack-start-manifest_v-BH5f_kWV.mjs} +1 -1
  34. package/.output/server/index.mjs +89 -89
  35. package/package.json +1 -1
  36. package/src/components/pi-agent/PiAgentPanel.tsx +205 -34
  37. package/src/components/pi-agent/piAgentChatLogic.ts +263 -0
  38. package/src/components/ui/transient-toast.tsx +6 -5
  39. package/src/lib/piAgentContract.ts +80 -0
  40. package/src/services/piAgent.ts +131 -102
  41. package/src/services/piAgentRetrieval.ts +1180 -0
  42. package/.output/public/assets/ProxyViewerContainer-CkFWv_Nm.js +0 -126
  43. package/.output/public/assets/ResponseView-Hn-5ordK.js +0 -3
  44. package/.output/public/assets/index-CgJj-HBC.css +0 -1
@@ -1,10 +1,10 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, R as React } from "../_libs/react.mjs";
2
- import { C as CapturedLogSchema, P as DeleteInspectorGroupsResponseSchema, 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, m as cn, F as LazyFeatureBoundary, x as formatTokens, B as Button, d as RuntimeConfigSchema, g as readStoredUiScalePreference, h as persistUiScalePreference, j as applyUiScalePreference, H as extractStopReason, af as CrabLogo, p as packageJson, k as normalizeUiScalePreference, Q as GroupEvidenceExportResultSchema, V as DeleteInspectorGroupResponseSchema, y as copyTextToClipboard, l as RedactedProviderDtoSchema, U as UI_SCALE_STORAGE_KEY, v as apiFormatForPath, a4 as createPendingProviderTestResults, a5 as ProviderTestResultsSchema, a6 as createFailedProviderTestResults, a7 as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, a8 as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, a9 as TimeDisplayFormatSchema, I as AlertSummarySchema, J as AlertListResponseSchema, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, ai as formatUiScale, N as InspectorGroupsListResponseSchema, M as GroupEvidenceReadResponseSchema, aa as EcosystemPackagesResponseSchema, ab as EcosystemTaskResponseSchema, ac as EcosystemTasksResponseSchema, ae as PiAgentResponseSchema, G as isTurnBoundary, _ as PATH_V1_MESSAGES, $ as PATH_V1_CHAT_COMPLETIONS, a0 as PATH_V1_RESPONSES, X as providerHasContextMetadata, W as ProviderScanResponseSchema, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode, ad as EcosystemExecutionConfirmationResponseSchema, i as isRecord, a1 as formatContextWindowInput, Y as findProviderModelMetadata, Z as formatContextWindowTokens, w as getSessionPath, q as parseOpenAIResponse, t as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, u as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, o as AnthropicRequestSchema, s as safeGetOwnProperty, ag as resolveProviderContextWindow, a2 as parseContextWindowTokensInput, a3 as previewUpstreamUrl, K as KnowledgeCandidateSchema, ah as isPlainRecord, E as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema, z as getStatusCategory } from "./router-GKvrwifJ.mjs";
2
+ import { C as CapturedLogSchema, M as DeleteInspectorGroupsResponseSchema, 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, m as cn, F as LazyFeatureBoundary, x as formatTokens, B as Button, d as RuntimeConfigSchema, g as readStoredUiScalePreference, h as persistUiScalePreference, j as applyUiScalePreference, ac as CrabLogo, p as packageJson, k as normalizeUiScalePreference, N as GroupEvidenceExportResultSchema, P as DeleteInspectorGroupResponseSchema, y as copyTextToClipboard, l as RedactedProviderDtoSchema, U as UI_SCALE_STORAGE_KEY, v as apiFormatForPath, i as isRecord, a2 as createPendingProviderTestResults, a3 as ProviderTestResultsSchema, a4 as createFailedProviderTestResults, a5 as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, a6 as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, a7 as TimeDisplayFormatSchema, G as AlertSummarySchema, H as AlertListResponseSchema, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, af as formatUiScale, J as InspectorGroupsListResponseSchema, I as GroupEvidenceReadResponseSchema, a8 as EcosystemPackagesResponseSchema, a9 as EcosystemTaskResponseSchema, aa as EcosystemTasksResponseSchema, Y as PATH_V1_MESSAGES, Z as PATH_V1_CHAT_COMPLETIONS, _ as PATH_V1_RESPONSES, V as providerHasContextMetadata, Q as ProviderScanResponseSchema, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode, ab as EcosystemExecutionConfirmationResponseSchema, s as safeGetOwnProperty, $ as formatContextWindowInput, W as findProviderModelMetadata, X as formatContextWindowTokens, w as getSessionPath, q as parseOpenAIResponse, t as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, u as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, o as AnthropicRequestSchema, ad as resolveProviderContextWindow, a0 as parseContextWindowTokensInput, a1 as previewUpstreamUrl, K as KnowledgeCandidateSchema, ae as isPlainRecord, E as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema, z as getStatusCategory } from "./router-CgsqLnk5.mjs";
3
3
  import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
4
4
  import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
5
5
  import { c as cva } from "../_libs/class-variance-authority.mjs";
6
6
  import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
7
- import { T as TriangleAlert, C as CircleCheck, X, P as PanelRightOpen, a as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, b as Trash2, I as Info, c as ChevronDown, d as Check, e as Settings, f as Siren, L as LoaderCircle, g as Sun, E as Eye, M as Moon, A as ALargeSmall, h as Layers, i as FlaskConical, j as Sparkles, k as Activity, B as Beaker, N as Network, l as Copy, m as Terminal, n as BrainCircuit, o as Send, p as ArrowLeft, q as ChevronUp, r as ChevronsLeft, s as ChevronLeft, t as ChevronRight, u as ChevronsRight, v as CircleStop, w as Clapperboard, x as Flag, y as Timer, G as Gauge, z as Scan, H as Plus, J as CircleAlert, K as Rocket, O as PackageCheck, Q as History, V as Monitor, W as EyeOff, Y as ExternalLink, Z as Clock, _ as RotateCw, $ as CircleCheckBig, a0 as Pencil, a1 as Bell, a2 as Clock3, a3 as ShieldAlert, a4 as ArrowUpRight, a5 as ArrowDownRight, a6 as CodeXml, a7 as Cpu, a8 as FolderOpen, a9 as MessageSquare, aa as Zap, ab as Wrench, ac as Brain, ad as Minus, ae as CircleQuestionMark, af as Server, ag as Lock, ah as Wifi, ai as WifiOff, aj as CircleX, ak as ShieldCheck, al as Save, am as FileSearch, an as CloudUpload, ao as OctagonAlert, ap as Radio, aq as Globe, ar as FileTerminal, as as ChevronsUp, at as ChevronsDown, au as FileDiff, av as RotateCcw, aw as GitCompareArrows, ax as ArrowUp, ay as ArrowDown, az as Ellipsis, aA as Blocks, aB as MousePointerClick, aC as FileText, aD as Rows3, aE as Columns2 } from "../_libs/lucide-react.mjs";
7
+ import { T as TriangleAlert, C as CircleCheck, X, P as PanelRightOpen, a as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, b as Trash2, I as Info, c as ChevronDown, d as Check, e as Settings, f as Siren, L as LoaderCircle, g as Sun, E as Eye, M as Moon, A as ALargeSmall, h as Layers, i as FlaskConical, j as Sparkles, k as Activity, B as Beaker, N as Network, l as Copy, m as Terminal, n as BrainCircuit, o as RotateCcw, p as Send, q as ArrowLeft, r as ChevronUp, s as ChevronsLeft, t as ChevronLeft, u as ChevronRight, v as ChevronsRight, w as CircleStop, x as Clapperboard, y as Flag, z as Timer, G as Gauge, H as Scan, J as Plus, K as CircleAlert, O as Rocket, Q as PackageCheck, V as History, W as Monitor, Y as EyeOff, Z as ExternalLink, _ as Clock, $ as RotateCw, a0 as CircleCheckBig, a1 as Pencil, a2 as Bell, a3 as Clock3, a4 as ShieldAlert, a5 as ArrowUpRight, a6 as ArrowDownRight, a7 as CodeXml, a8 as Cpu, a9 as FolderOpen, aa as MessageSquare, ab as Zap, ac as Wrench, ad as Brain, ae as Minus, af as CircleQuestionMark, ag as Server, ah as Lock, ai as Wifi, aj as WifiOff, ak as CircleX, al as ShieldCheck, am as Save, an as FileSearch, ao as CloudUpload, ap as OctagonAlert, aq as Radio, ar as Globe, as as FileTerminal, at as ChevronsUp, au as ChevronsDown, av as FileDiff, aw as GitCompareArrows, ax as ArrowUp, ay as ArrowDown, az as Ellipsis, aA as Blocks, aB as MousePointerClick, aC as FileText, aD as Rows3, aE as Columns2 } from "../_libs/lucide-react.mjs";
8
8
  import { u as union, o as object, e as array, l as literal, n as number, d as boolean, b as string } from "../_libs/zod.mjs";
9
9
  import { S as Select$1, a as SelectTrigger$1, b as SelectIcon, c as SelectValue$1, d as SelectPortal, e as SelectContent$1, f as SelectViewport, g as SelectItem$1, h as SelectItemIndicator, i as SelectItemText, j as SelectScrollUpButton$1, k as SelectScrollDownButton$1 } from "../_libs/radix-ui__react-select.mjs";
10
10
  import { D as Dialog$1, a as DialogContent$1, b as DialogClose, c as DialogTitle$1, d as DialogDescription$1, e as DialogTrigger$1, f as DialogPortal$1, g as DialogOverlay$1 } from "../_libs/radix-ui__react-dialog.mjs";
@@ -1886,6 +1886,79 @@ function readLogFocusRequest(event) {
1886
1886
  return null;
1887
1887
  }
1888
1888
  }
1889
+ function normalizeAnthropicStopReason(value) {
1890
+ switch (value) {
1891
+ case "end_turn":
1892
+ case "tool_use":
1893
+ return value;
1894
+ case "max_tokens":
1895
+ return "length";
1896
+ default:
1897
+ return null;
1898
+ }
1899
+ }
1900
+ function normalizeOpenAIFinishReason(value) {
1901
+ switch (value) {
1902
+ case "stop":
1903
+ case "length":
1904
+ return value;
1905
+ case "max_tokens":
1906
+ return "length";
1907
+ default:
1908
+ return null;
1909
+ }
1910
+ }
1911
+ function isResponsesLengthLimitReason(value) {
1912
+ switch (value) {
1913
+ case "max_output_tokens":
1914
+ case "max_tokens":
1915
+ return true;
1916
+ default:
1917
+ return false;
1918
+ }
1919
+ }
1920
+ function extractStopReason(log) {
1921
+ if (log.responseText === null) return null;
1922
+ try {
1923
+ let json = JSON.parse(log.responseText);
1924
+ if (typeof json === "string") {
1925
+ json = JSON.parse(json);
1926
+ }
1927
+ if (!isRecord(json)) return null;
1928
+ if (typeof json.stop_reason === "string") {
1929
+ return normalizeAnthropicStopReason(json.stop_reason);
1930
+ }
1931
+ if (Array.isArray(json.choices)) {
1932
+ for (const choice of json.choices) {
1933
+ if (!isRecord(choice) || typeof choice.finish_reason !== "string") continue;
1934
+ const reason = normalizeOpenAIFinishReason(choice.finish_reason);
1935
+ if (reason !== null) return reason;
1936
+ }
1937
+ }
1938
+ if (Array.isArray(json.output)) {
1939
+ for (const item of json.output) {
1940
+ if (isRecord(item) && item.type === "function_call") {
1941
+ return "tool_use";
1942
+ }
1943
+ }
1944
+ if (json.status === "completed") {
1945
+ return "stop";
1946
+ }
1947
+ }
1948
+ if (json.status === "incomplete" && isRecord(json.incomplete_details)) {
1949
+ const reason = json.incomplete_details.reason;
1950
+ if (typeof reason === "string" && isResponsesLengthLimitReason(reason)) {
1951
+ return "length";
1952
+ }
1953
+ }
1954
+ return null;
1955
+ } catch {
1956
+ return null;
1957
+ }
1958
+ }
1959
+ function isTurnBoundary(stopReason) {
1960
+ return stopReason === "end_turn" || stopReason === "stop" || stopReason === "length";
1961
+ }
1889
1962
  function SvgShell({
1890
1963
  className,
1891
1964
  style,
@@ -2431,30 +2504,30 @@ function useCopyFeedback(text) {
2431
2504
  return { copied, copy };
2432
2505
  }
2433
2506
  const LazyCompareDrawer = reactExports.lazy(
2434
- () => import("./CompareDrawer-CqUmGHal.mjs").then((m) => ({ default: m.CompareDrawer }))
2507
+ () => import("./CompareDrawer-27amlv_a.mjs").then((m) => ({ default: m.CompareDrawer }))
2435
2508
  );
2436
2509
  const LazyInspectorPet = reactExports.lazy(
2437
- () => import("./InspectorPet-DI0UJd01.mjs").then((m) => ({ default: m.InspectorPet }))
2510
+ () => import("./InspectorPet-CQnGXfLs.mjs").then((m) => ({ default: m.InspectorPet }))
2438
2511
  );
2439
2512
  const LazyReplayDialog = reactExports.lazy(
2440
- () => import("./ReplayDialog-DS48dpFG.mjs").then((m) => ({ default: m.ReplayDialog }))
2513
+ () => import("./ReplayDialog-5m2jtlLa.mjs").then((m) => ({ default: m.ReplayDialog }))
2441
2514
  );
2442
2515
  const LazyRequestAnatomy = reactExports.lazy(
2443
- () => import("./RequestAnatomy-DxYVQU1C.mjs").then((m) => ({ default: m.RequestAnatomy }))
2516
+ () => import("./RequestAnatomy--1WtQNY9.mjs").then((m) => ({ default: m.RequestAnatomy }))
2444
2517
  );
2445
2518
  const LazyResponseView = reactExports.lazy(
2446
- () => import("./ResponseView-BLXW73eq.mjs").then((m) => ({ default: m.ResponseView }))
2519
+ () => import("./ResponseView-CgbqS8sr.mjs").then((m) => ({ default: m.ResponseView }))
2447
2520
  );
2448
2521
  const LazyStreamingChunkSequence = reactExports.lazy(
2449
- () => import("./StreamingChunkSequence-DD0iFuy0.mjs").then((m) => ({
2522
+ () => import("./StreamingChunkSequence-BwpnopWx.mjs").then((m) => ({
2450
2523
  default: m.StreamingChunkSequence
2451
2524
  }))
2452
2525
  );
2453
2526
  const LazyJsonViewer = reactExports.lazy(
2454
- () => import("./json-viewer-LDu2XBaK.mjs").then((m) => ({ default: m.JsonViewer }))
2527
+ () => import("./json-viewer-DNGN2uoe.mjs").then((m) => ({ default: m.JsonViewer }))
2455
2528
  );
2456
2529
  const LazyJsonViewerFromString = reactExports.lazy(
2457
- () => import("./json-viewer-LDu2XBaK.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2530
+ () => import("./json-viewer-DNGN2uoe.mjs").then((m) => ({ default: m.JsonViewerFromString }))
2458
2531
  );
2459
2532
  const HIGHLIGHT_DURATION_MS = 1200;
2460
2533
  const MAX_HIGHLIGHT_ATTEMPTS = 12;
@@ -7207,14 +7280,17 @@ function TransientToast({
7207
7280
  "div",
7208
7281
  {
7209
7282
  className: cn(
7210
- "pointer-events-auto flex items-start gap-2 rounded-md border px-3 py-2 text-sm shadow-[0_18px_50px_rgba(0,0,0,0.45)] backdrop-blur",
7211
- isError ? "border-red-400/30 bg-[#16090b]/95 text-red-100" : "border-cyan-300/25 bg-[#071318]/95 text-cyan-100"
7283
+ "pointer-events-auto flex items-start gap-2 rounded-md border bg-popover/95 px-3 py-2 text-sm text-popover-foreground shadow-[0_18px_50px_color-mix(in_oklch,var(--foreground)_16%,transparent)] backdrop-blur",
7284
+ isError ? "border-status-danger/35" : "border-status-success/35"
7212
7285
  ),
7213
7286
  children: [
7214
7287
  /* @__PURE__ */ jsxRuntimeExports.jsx(
7215
7288
  Icon,
7216
7289
  {
7217
- className: cn("mt-0.5 size-4 shrink-0", isError ? "text-red-300" : "text-cyan-200")
7290
+ className: cn(
7291
+ "mt-0.5 size-4 shrink-0",
7292
+ isError ? "text-status-danger" : "text-status-success"
7293
+ )
7218
7294
  }
7219
7295
  ),
7220
7296
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 flex-1 break-words leading-5", children: notice.message }),
@@ -12201,6 +12277,173 @@ function AgentLabDialog({ currentSessionId, logCount }) {
12201
12277
  )
12202
12278
  ] });
12203
12279
  }
12280
+ const PI_AGENT_STARTERS = [
12281
+ {
12282
+ id: "reliability",
12283
+ label: "Reliability",
12284
+ question: "Which requests failed, stalled, or look most likely to hang, and why?"
12285
+ },
12286
+ {
12287
+ id: "performance",
12288
+ label: "Performance",
12289
+ question: "Summarize latency and identify the slowest requests with supporting evidence."
12290
+ },
12291
+ {
12292
+ id: "tokens",
12293
+ label: "Token usage",
12294
+ question: "Where are tokens being spent, and which requests have unusually high usage?"
12295
+ },
12296
+ {
12297
+ id: "providers",
12298
+ label: "Providers",
12299
+ question: "Compare Provider and model reliability, latency, and token usage in this scope."
12300
+ },
12301
+ {
12302
+ id: "tools",
12303
+ label: "Tool activity",
12304
+ question: "Which tools were used most, and where did tool calls fail or produce warnings?"
12305
+ }
12306
+ ];
12307
+ const MAX_HISTORY_CONTENT_CHARS = 4e3;
12308
+ const MAX_METRICS = 12;
12309
+ function createEmptyPiAgentConversation() {
12310
+ return { messages: [], question: "", error: null };
12311
+ }
12312
+ function buildPiAgentHistory(messages) {
12313
+ return messages.filter((message) => message.content.trim().length > 0).slice(-10).map((message) => ({
12314
+ role: message.role,
12315
+ content: message.content.trim().slice(0, MAX_HISTORY_CONTENT_CHARS)
12316
+ }));
12317
+ }
12318
+ function readString(value, ...keys) {
12319
+ for (const key of keys) {
12320
+ const candidate = safeGetOwnProperty(value, key);
12321
+ if (typeof candidate === "string" && candidate.trim().length > 0) return candidate;
12322
+ }
12323
+ return null;
12324
+ }
12325
+ function readNumber(value, ...keys) {
12326
+ for (const key of keys) {
12327
+ const candidate = safeGetOwnProperty(value, key);
12328
+ if (typeof candidate === "number" && Number.isFinite(candidate)) return candidate;
12329
+ }
12330
+ return null;
12331
+ }
12332
+ function readStringArray(value, key) {
12333
+ const candidate = safeGetOwnProperty(value, key);
12334
+ if (!Array.isArray(candidate)) return [];
12335
+ return candidate.filter((item) => typeof item === "string").slice(0, 8);
12336
+ }
12337
+ function evidenceView(value) {
12338
+ const source = readString(value, "source") ?? "log";
12339
+ const id = readString(value, "id") ?? "";
12340
+ const logId = readNumber(value, "logId", "id");
12341
+ if (id === "" && logId === null) return null;
12342
+ if (logId !== null && (!Number.isInteger(logId) || logId < 0)) return null;
12343
+ const inputTokens = readNumber(value, "inputTokens");
12344
+ const outputTokens = readNumber(value, "outputTokens");
12345
+ const explicitTotal = readNumber(value, "totalTokens", "tokenCount");
12346
+ const statusNumber = readNumber(value, "responseStatus", "status");
12347
+ const statusString = readString(value, "responseStatus", "status");
12348
+ return {
12349
+ source,
12350
+ id: id !== "" ? id : String(logId),
12351
+ logId,
12352
+ sessionId: readString(value, "sessionId"),
12353
+ timestamp: readString(value, "timestamp"),
12354
+ model: readString(value, "model"),
12355
+ providerName: readString(value, "providerName", "provider"),
12356
+ path: readString(value, "path"),
12357
+ status: statusNumber ?? statusString,
12358
+ elapsedMs: readNumber(value, "elapsedMs", "latencyMs"),
12359
+ inputTokens,
12360
+ outputTokens,
12361
+ totalTokens: explicitTotal ?? (inputTokens === null && outputTokens === null ? null : (inputTokens ?? 0) + (outputTokens ?? 0)),
12362
+ score: readNumber(value, "score", "relevanceScore"),
12363
+ matchedFields: readStringArray(value, "matchedFields"),
12364
+ excerpt: readString(value, "excerpt", "snippet") ?? "No excerpt available."
12365
+ };
12366
+ }
12367
+ function humanizeMetricKey(key) {
12368
+ const spaced = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
12369
+ return spaced.length === 0 ? "Metric" : `${spaced[0]?.toUpperCase() ?? ""}${spaced.slice(1)}`;
12370
+ }
12371
+ function metricValue(value) {
12372
+ if (typeof value === "number" && Number.isFinite(value)) return value.toLocaleString();
12373
+ if (typeof value === "string" && value.trim().length > 0) return value;
12374
+ if (typeof value === "boolean") return value ? "Yes" : "No";
12375
+ if (Array.isArray(value)) {
12376
+ const items = value.filter(
12377
+ (item) => typeof item === "string" || typeof item === "number" && Number.isFinite(item)
12378
+ ).slice(0, 6);
12379
+ return items.length > 0 ? items.join(", ") : null;
12380
+ }
12381
+ return null;
12382
+ }
12383
+ function objectMetricEntries(value) {
12384
+ return Object.getOwnPropertyNames(value).map((key) => [key, safeGetOwnProperty(value, key)]);
12385
+ }
12386
+ function metricViews(value) {
12387
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return [];
12388
+ const entries = [];
12389
+ for (const [key, rawValue] of objectMetricEntries(value)) {
12390
+ const directValue = metricValue(rawValue);
12391
+ if (directValue !== null) {
12392
+ entries.push({ key, label: humanizeMetricKey(key), value: directValue });
12393
+ if (entries.length >= MAX_METRICS) break;
12394
+ continue;
12395
+ }
12396
+ if (rawValue === null || typeof rawValue !== "object" || Array.isArray(rawValue)) continue;
12397
+ for (const [nestedKey, nestedValue] of objectMetricEntries(rawValue)) {
12398
+ const formatted = metricValue(nestedValue);
12399
+ if (formatted === null) continue;
12400
+ const metricKey = `${key}.${nestedKey}`;
12401
+ entries.push({
12402
+ key: metricKey,
12403
+ label: `${humanizeMetricKey(key)} ${humanizeMetricKey(nestedKey).toLowerCase()}`,
12404
+ value: formatted
12405
+ });
12406
+ if (entries.length >= MAX_METRICS) break;
12407
+ }
12408
+ if (entries.length >= MAX_METRICS) break;
12409
+ }
12410
+ return entries;
12411
+ }
12412
+ function normalizePiAgentResponse(value) {
12413
+ const answer = readString(value, "answer");
12414
+ const providerId = readString(value, "providerId");
12415
+ const providerName = readString(value, "providerName");
12416
+ const model = readString(value, "model");
12417
+ const protocol = readString(value, "protocol");
12418
+ const logCount = readNumber(value, "logCount");
12419
+ if (answer === null || providerId === null || providerName === null || model === null || protocol === null || logCount === null) {
12420
+ return null;
12421
+ }
12422
+ const rawEvidence = safeGetOwnProperty(value, "evidence");
12423
+ const evidence = Array.isArray(rawEvidence) ? rawEvidence.map(evidenceView).filter((item) => item !== null).slice(0, 12) : [];
12424
+ return {
12425
+ answer,
12426
+ providerId,
12427
+ providerName,
12428
+ model,
12429
+ protocol,
12430
+ logCount,
12431
+ evidence,
12432
+ summaryMetrics: metricViews(safeGetOwnProperty(value, "summary")),
12433
+ queryMetrics: metricViews(safeGetOwnProperty(value, "queryStats"))
12434
+ };
12435
+ }
12436
+ const LazyReactMarkdown = reactExports.lazy(() => import("../_libs/react-markdown.mjs"));
12437
+ 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]";
12438
+ function AnswerMarkdown({ text }) {
12439
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ANSWER_MARKDOWN_CLASS, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
12440
+ reactExports.Suspense,
12441
+ {
12442
+ fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Loading Markdown..." }),
12443
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyReactMarkdown, { children: text })
12444
+ }
12445
+ ) });
12446
+ }
12204
12447
  const DEFAULT_QUESTION = "Analyze the current Inspector session. What looks abnormal, slow, or likely to hang?";
12205
12448
  function providerSupportsPiAgent(provider) {
12206
12449
  return provider.openaiResponsesBaseUrl !== void 0 || provider.openaiBaseUrl !== void 0 || provider.anthropicBaseUrl !== void 0;
@@ -12222,39 +12465,130 @@ function sortProviderBySource(providers) {
12222
12465
  return left.name.localeCompare(right.name);
12223
12466
  });
12224
12467
  }
12468
+ function nextMessageId(role) {
12469
+ return `${role}-${String(Date.now())}-${String(Math.random()).slice(2)}`;
12470
+ }
12471
+ function MetricStrip({ metrics }) {
12472
+ if (metrics.length === 0) return null;
12473
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid grid-cols-2 gap-1.5", children: metrics.slice(0, 8).map((metric) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-sm bg-black/20 px-2 py-1", children: [
12474
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-[9px] uppercase text-muted-foreground", children: metric.label }),
12475
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate font-mono text-[11px] text-cyan-50", children: metric.value })
12476
+ ] }, metric.key)) });
12477
+ }
12478
+ function EvidenceCard({ evidence }) {
12479
+ const openLog = () => {
12480
+ if (evidence.logId === null) return;
12481
+ dispatchLogFocusRequest({ logId: evidence.logId, tab: "anatomy" });
12482
+ };
12483
+ const title = evidence.logId === null ? `${evidence.source}:${evidence.id}` : `${evidence.source}:log #${String(evidence.logId)}`;
12484
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
12485
+ "button",
12486
+ {
12487
+ type: "button",
12488
+ onClick: openLog,
12489
+ disabled: evidence.logId === null,
12490
+ className: "w-full rounded-sm bg-black/20 px-2 py-2 text-left shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)] transition-colors hover:bg-black/30 disabled:cursor-default disabled:hover:bg-black/20",
12491
+ children: [
12492
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2", children: [
12493
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-mono text-[10px] text-cyan-100", children: title }),
12494
+ evidence.score !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-mono text-[9px] text-muted-foreground", children: evidence.score.toFixed(1) })
12495
+ ] }),
12496
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap gap-x-2 gap-y-1 text-[10px] text-muted-foreground", children: [
12497
+ evidence.providerName !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: evidence.providerName }),
12498
+ evidence.model !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: evidence.model }),
12499
+ evidence.status !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
12500
+ "status ",
12501
+ String(evidence.status)
12502
+ ] }),
12503
+ evidence.elapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
12504
+ String(evidence.elapsedMs),
12505
+ " ms"
12506
+ ] })
12507
+ ] }),
12508
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 line-clamp-3 text-[11px] leading-4 text-foreground/85", children: evidence.excerpt })
12509
+ ]
12510
+ }
12511
+ );
12512
+ }
12513
+ function AssistantMessage({ response }) {
12514
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md bg-black/25 p-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)]", children: [
12515
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text: response.answer }),
12516
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 break-words font-mono text-[10px] text-cyan-100/70", children: [
12517
+ response.providerName,
12518
+ " / ",
12519
+ response.model,
12520
+ " / ",
12521
+ response.protocol,
12522
+ " /",
12523
+ " ",
12524
+ String(response.logCount),
12525
+ " matched logs"
12526
+ ] }),
12527
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricStrip, { metrics: response.summaryMetrics }),
12528
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricStrip, { metrics: response.queryMetrics }),
12529
+ response.evidence.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 space-y-1.5", children: response.evidence.slice(0, 6).map((evidence) => /* @__PURE__ */ jsxRuntimeExports.jsx(EvidenceCard, { evidence }, `${evidence.source}-${evidence.id}`)) })
12530
+ ] });
12531
+ }
12532
+ function ConversationMessage({ message }) {
12533
+ if (message.role === "assistant" && message.response !== null) {
12534
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AssistantMessage, { response: message.response });
12535
+ }
12536
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-cyan-400/10 px-3 py-2 text-xs leading-5 text-cyan-50", children: message.content });
12537
+ }
12225
12538
  function PiAgentPanel({ currentSessionId, logCount }) {
12226
12539
  const { providers } = useProviders();
12227
12540
  const piProviders = reactExports.useMemo(
12228
12541
  () => sortProviderBySource(providers.filter(providerSupportsPiAgent)),
12229
12542
  [providers]
12230
12543
  );
12231
- const [question, setQuestion] = reactExports.useState(DEFAULT_QUESTION);
12544
+ const [conversation, setConversation] = reactExports.useState(() => ({
12545
+ ...createEmptyPiAgentConversation(),
12546
+ question: DEFAULT_QUESTION
12547
+ }));
12232
12548
  const [providerId, setProviderId] = reactExports.useState("__auto__");
12233
12549
  const [model, setModel] = reactExports.useState("__auto__");
12234
- const [answer, setAnswer] = reactExports.useState("");
12235
- const [status, setStatus] = reactExports.useState("");
12236
12550
  const [loading, setLoading] = reactExports.useState(false);
12237
12551
  const selectedProvider = piProviders.find((provider) => provider.id === providerId);
12238
12552
  const modelOptions = selectedProvider?.models ?? [];
12553
+ const question = conversation.question;
12239
12554
  const canAsk = question.trim() !== "" && piProviders.length > 0 && !loading;
12240
12555
  const handleQuestionChange = (event) => {
12241
- setQuestion(event.currentTarget.value);
12556
+ setConversation((current) => ({ ...current, question: event.currentTarget.value }));
12242
12557
  };
12243
12558
  const handleProviderChange = (value) => {
12244
12559
  setProviderId(value);
12245
12560
  setModel("__auto__");
12246
12561
  };
12562
+ const resetConversation = () => {
12563
+ setConversation({ ...createEmptyPiAgentConversation(), question: DEFAULT_QUESTION });
12564
+ };
12565
+ const setStarter = (questionText) => {
12566
+ setConversation((current) => ({ ...current, question: questionText, error: null }));
12567
+ };
12247
12568
  const askPiAgent = () => {
12248
12569
  if (!canAsk) return;
12570
+ const trimmedQuestion = question.trim();
12571
+ const history = buildPiAgentHistory(conversation.messages);
12572
+ const userMessage = {
12573
+ id: nextMessageId("user"),
12574
+ role: "user",
12575
+ content: trimmedQuestion,
12576
+ response: null
12577
+ };
12249
12578
  setLoading(true);
12250
- setStatus("");
12251
- setAnswer("");
12579
+ setConversation((current) => ({
12580
+ ...current,
12581
+ messages: [...current.messages, userMessage],
12582
+ question: "",
12583
+ error: null
12584
+ }));
12252
12585
  const body = {
12253
- question: question.trim(),
12586
+ question: trimmedQuestion,
12587
+ history,
12254
12588
  ...currentSessionId !== null ? { sessionId: currentSessionId } : {},
12255
12589
  ...providerId !== "__auto__" ? { providerId } : {},
12256
12590
  ...model !== "__auto__" ? { model } : {},
12257
- logLimit: 24
12591
+ logLimit: 16
12258
12592
  };
12259
12593
  void fetch("/api/pi-agent", {
12260
12594
  method: "POST",
@@ -12266,25 +12600,38 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12266
12600
  }).then(async (response) => {
12267
12601
  const raw = await response.text();
12268
12602
  if (!response.ok) {
12269
- setStatus(`Pi Agent failed: HTTP ${String(response.status)}`);
12270
- setAnswer(raw);
12603
+ setConversation((current) => ({
12604
+ ...current,
12605
+ error: `Pi Agent failed: HTTP ${String(response.status)} ${raw}`
12606
+ }));
12271
12607
  return;
12272
12608
  }
12273
12609
  const parsedJson = JSON.parse(raw);
12274
- const parsed = PiAgentResponseSchema.safeParse(parsedJson);
12275
- if (!parsed.success) {
12276
- setStatus("Pi Agent returned an unexpected response.");
12277
- setAnswer(raw);
12610
+ const normalized = normalizePiAgentResponse(parsedJson);
12611
+ if (normalized === null) {
12612
+ setConversation((current) => ({
12613
+ ...current,
12614
+ error: "Pi Agent returned an unexpected response."
12615
+ }));
12278
12616
  return;
12279
12617
  }
12280
- setStatus(
12281
- `${parsed.data.providerName} / ${parsed.data.model} / ${parsed.data.protocol} / ${String(
12282
- parsed.data.logCount
12283
- )} logs`
12284
- );
12285
- setAnswer(parsed.data.answer);
12618
+ setConversation((current) => ({
12619
+ ...current,
12620
+ messages: [
12621
+ ...current.messages,
12622
+ {
12623
+ id: nextMessageId("assistant"),
12624
+ role: "assistant",
12625
+ content: normalized.answer,
12626
+ response: normalized
12627
+ }
12628
+ ]
12629
+ }));
12286
12630
  }).catch((err) => {
12287
- setStatus(err instanceof Error ? err.message : "Pi Agent request failed.");
12631
+ setConversation((current) => ({
12632
+ ...current,
12633
+ error: err instanceof Error ? err.message : "Pi Agent request failed."
12634
+ }));
12288
12635
  }).finally(() => {
12289
12636
  setLoading(false);
12290
12637
  });
@@ -12294,8 +12641,18 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12294
12641
  /* @__PURE__ */ jsxRuntimeExports.jsx(BrainCircuit, { className: "size-4 text-cyan-200" }),
12295
12642
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
12296
12643
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-semibold text-foreground", children: "Pi Agent" }),
12297
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] text-muted-foreground", children: currentSessionId === null ? "Inspector-wide analysis" : "Session analysis" })
12298
- ] })
12644
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] text-muted-foreground", children: currentSessionId === null ? "Inspector-wide ChatBI" : "Session ChatBI" })
12645
+ ] }),
12646
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
12647
+ "button",
12648
+ {
12649
+ type: "button",
12650
+ onClick: resetConversation,
12651
+ className: "inline-flex size-7 items-center justify-center rounded-md bg-black/25 text-muted-foreground transition-colors hover:text-foreground",
12652
+ title: "Reset conversation",
12653
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-3.5" })
12654
+ }
12655
+ )
12299
12656
  ] }),
12300
12657
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 grid grid-cols-2 gap-2", children: [
12301
12658
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: providerId, onValueChange: handleProviderChange, children: [
@@ -12317,13 +12674,35 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12317
12674
  ] })
12318
12675
  ] })
12319
12676
  ] }),
12677
+ conversation.messages.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 flex flex-wrap gap-1.5", children: PI_AGENT_STARTERS.map((starter) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
12678
+ "button",
12679
+ {
12680
+ type: "button",
12681
+ onClick: () => {
12682
+ setStarter(starter.question);
12683
+ },
12684
+ className: "inline-flex h-7 items-center gap-1.5 rounded-sm bg-black/25 px-2 text-[11px] text-cyan-50 transition-colors hover:bg-cyan-400/12",
12685
+ children: [
12686
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "size-3" }),
12687
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: starter.label })
12688
+ ]
12689
+ },
12690
+ starter.id
12691
+ )) }),
12692
+ conversation.messages.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 max-h-96 space-y-2 overflow-y-auto pr-1", children: [
12693
+ conversation.messages.map((message) => /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationMessage, { message }, message.id)),
12694
+ loading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-2 rounded-md bg-black/25 px-3 py-2 text-xs text-muted-foreground", children: [
12695
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
12696
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Searching Inspector..." })
12697
+ ] })
12698
+ ] }),
12320
12699
  /* @__PURE__ */ jsxRuntimeExports.jsx(
12321
12700
  "textarea",
12322
12701
  {
12323
12702
  value: question,
12324
12703
  onChange: handleQuestionChange,
12325
- className: "mt-2 min-h-24 w-full resize-y rounded-md bg-black/25 px-3 py-2 text-xs leading-5 text-foreground outline-none shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring",
12326
- placeholder: "Ask Pi Agent about this session..."
12704
+ className: "mt-3 min-h-20 w-full resize-y rounded-md bg-black/25 px-3 py-2 text-xs leading-5 text-foreground outline-none shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring",
12705
+ placeholder: "Ask Pi Agent across saved Inspector data..."
12327
12706
  }
12328
12707
  ),
12329
12708
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -12339,9 +12718,8 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12339
12718
  ]
12340
12719
  }
12341
12720
  ),
12721
+ conversation.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 break-words text-[11px] leading-5 text-red-200", children: conversation.error }),
12342
12722
  piProviders.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "Configure a Provider with Responses, Chat, or Anthropic URL to enable Pi Agent." }),
12343
- status !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 break-words font-mono text-[10px] text-cyan-100/70", children: status }),
12344
- answer !== "" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 max-h-64 overflow-y-auto whitespace-pre-wrap rounded-md bg-black/25 p-3 text-xs leading-5 text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)]", children: answer }),
12345
12723
  logCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-[11px] leading-5 text-muted-foreground", children: "No logs are visible in this scope yet; Pi Agent can still answer Provider setup questions." })
12346
12724
  ] });
12347
12725
  }
@@ -16976,13 +17354,14 @@ export {
16976
17354
  dispatchLogFocusRequest as n,
16977
17355
  analyzeContextIntelligence as o,
16978
17356
  ANATOMY_ROLE_LABELS as p,
16979
- Collapsible as q,
17357
+ AnswerMarkdown as q,
16980
17358
  resolveLogFormat as r,
16981
- CollapsibleTrigger as s,
16982
- CollapsibleContent as t,
17359
+ Collapsible as s,
17360
+ CollapsibleTrigger as t,
16983
17361
  useProviders as u,
16984
- ScrollArea as v,
16985
- LazyJsonViewer as w,
16986
- safeJsonValue as x,
16987
- parseJsonText as y
17362
+ CollapsibleContent as v,
17363
+ ScrollArea as w,
17364
+ LazyJsonViewer as x,
17365
+ safeJsonValue as y,
17366
+ parseJsonText as z
16988
17367
  };
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useProviders, f as fetchJsonWithTimeout, D as Dialog, b as DialogContent, c as DialogHeader, d as DialogTitle, T as Tabs, e as TabsList, h as TabsTrigger, i as TabsContent, j as TooltipProvider, k as Tooltip, l as TooltipTrigger, m as TooltipContent, n as dispatchLogFocusRequest, A as ApiTimeoutError } from "./ProxyViewerContainer-CvsUmbJ3.mjs";
3
- import { B as Button, C as CapturedLogSchema } from "./router-GKvrwifJ.mjs";
4
- import { ResponseView } from "./ResponseView-BLXW73eq.mjs";
2
+ import { u as useProviders, f as fetchJsonWithTimeout, D as Dialog, b as DialogContent, c as DialogHeader, d as DialogTitle, T as Tabs, e as TabsList, h as TabsTrigger, i as TabsContent, j as TooltipProvider, k as Tooltip, l as TooltipTrigger, m as TooltipContent, n as dispatchLogFocusRequest, A as ApiTimeoutError } from "./ProxyViewerContainer-DlAl0uF-.mjs";
3
+ import { B as Button, C as CapturedLogSchema } from "./router-CgsqLnk5.mjs";
4
+ import { ResponseView } from "./ResponseView-CgbqS8sr.mjs";
5
5
  import "node:crypto";
6
6
  import "node:path";
7
7
  import "node:fs";
@@ -14,7 +14,7 @@ import "node:net";
14
14
  import "../_libs/modelcontextprotocol__server.mjs";
15
15
  import "../_libs/jszip.mjs";
16
16
  import "node:os";
17
- import { av as RotateCcw, aJ as Braces, aK as Minimize2 } from "../_libs/lucide-react.mjs";
17
+ import { o as RotateCcw, aJ as Braces, aK as Minimize2 } from "../_libs/lucide-react.mjs";
18
18
  import { o as object, n as number, e as array, d as boolean, b as string } from "../_libs/zod.mjs";
19
19
  import "../_libs/swr.mjs";
20
20
  import "../_libs/use-sync-external-store.mjs";