@tonyclaw/agent-inspector 3.0.30 → 3.0.32

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-CONqySRK.js} +1 -1
  3. package/.output/public/assets/{InspectorPet-mAzeGmEE.js → InspectorPet-B6oMiG2V.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-Ce_WtVu2.js +126 -0
  5. package/.output/public/assets/{ReplayDialog-DodiTL6E.js → ReplayDialog-BauSX4Hj.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-B3IauToI.js → RequestAnatomy-gyMOB2oK.js} +1 -1
  7. package/.output/public/assets/ResponseView-CUQvY1eb.js +2 -0
  8. package/.output/public/assets/{StreamingChunkSequence-vLDOVQM_.js → StreamingChunkSequence-CE6R5CKU.js} +1 -1
  9. package/.output/public/assets/{_sessionId-BFH4TOaI.js → _sessionId-BW1YYf5W.js} +1 -1
  10. package/.output/public/assets/{_sessionId-Cj_HIFZx.js → _sessionId-DRRig28i.js} +1 -1
  11. package/.output/public/assets/{index-DkDdKvLl.js → index-BTor51ZC.js} +3 -3
  12. package/.output/public/assets/{index-Ch7uqnCT.js → index-BzL-q9eN.js} +1 -1
  13. package/.output/public/assets/{index-Bmj2lcWE.js → index-CbFGlzA-.js} +1 -1
  14. package/.output/public/assets/index-D17dU-mX.css +1 -0
  15. package/.output/public/assets/{index-ZlhqCrSg.js → index-iN9QtGKF.js} +1 -1
  16. package/.output/public/assets/{json-viewer-BdrnVQu-.js → json-viewer-cR8mD7Tl.js} +1 -1
  17. package/.output/public/assets/{jszip.min-CS_nt_o1.js → jszip.min-aHTREmPV.js} +1 -1
  18. package/.output/server/_libs/lucide-react.mjs +55 -55
  19. package/.output/server/{_sessionId-C5S3pGZd.mjs → _sessionId-CuTfM9Wy.mjs} +2 -2
  20. package/.output/server/{_sessionId-g6D69lKq.mjs → _sessionId-RGCARWul.mjs} +1 -1
  21. package/.output/server/_ssr/{CompareDrawer-CqUmGHal.mjs → CompareDrawer-mUnxKFwp.mjs} +3 -3
  22. package/.output/server/_ssr/{InspectorPet-DI0UJd01.mjs → InspectorPet-J0mv5NOp.mjs} +1 -1
  23. package/.output/server/_ssr/{ProxyViewerContainer-CvsUmbJ3.mjs → ProxyViewerContainer-C7Wx7SjJ.mjs} +457 -47
  24. package/.output/server/_ssr/{ReplayDialog-DS48dpFG.mjs → ReplayDialog-C_zNrriu.mjs} +4 -4
  25. package/.output/server/_ssr/{RequestAnatomy-DxYVQU1C.mjs → RequestAnatomy-lvR2Uz9j.mjs} +3 -3
  26. package/.output/server/_ssr/{ResponseView-BLXW73eq.mjs → ResponseView-CRcqekgn.mjs} +3 -14
  27. package/.output/server/_ssr/{StreamingChunkSequence-DD0iFuy0.mjs → StreamingChunkSequence-CJLR-ZYV.mjs} +3 -3
  28. package/.output/server/_ssr/{index-RHVJnU2p.mjs → index-BhL5Yn1J.mjs} +1 -1
  29. package/.output/server/_ssr/{index-B10LIaK0.mjs → index-urTy0DU2.mjs} +2 -2
  30. package/.output/server/_ssr/index.mjs +2 -2
  31. package/.output/server/_ssr/{json-viewer-LDu2XBaK.mjs → json-viewer-BcooIEu5.mjs} +3 -3
  32. package/.output/server/_ssr/{router-GKvrwifJ.mjs → router-D-PJYphE.mjs} +5382 -4524
  33. package/.output/server/{_tanstack-start-manifest_v-Df2n4mbT.mjs → _tanstack-start-manifest_v-DhxDbp_1.mjs} +1 -1
  34. package/.output/server/index.mjs +92 -92
  35. package/package.json +1 -1
  36. package/src/components/pi-agent/PiAgentPanel.tsx +229 -34
  37. package/src/components/pi-agent/piAgentChatLogic.ts +287 -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-D-PJYphE.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-mUnxKFwp.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-J0mv5NOp.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-C_zNrriu.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-lvR2Uz9j.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-CRcqekgn.mjs").then((m) => ({ default: m.ResponseView }))
2447
2520
  );
2448
2521
  const LazyStreamingChunkSequence = reactExports.lazy(
2449
- () => import("./StreamingChunkSequence-DD0iFuy0.mjs").then((m) => ({
2522
+ () => import("./StreamingChunkSequence-CJLR-ZYV.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-BcooIEu5.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-BcooIEu5.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,190 @@ function AgentLabDialog({ currentSessionId, logCount }) {
12201
12277
  )
12202
12278
  ] });
12203
12279
  }
12280
+ const PI_AGENT_SCOPE_PILLS = [
12281
+ {
12282
+ id: "saved-data",
12283
+ label: "Saved Inspector data",
12284
+ description: "requests, responses, sessions, tools, alerts, runs, groups, and knowledge"
12285
+ },
12286
+ {
12287
+ id: "root-cause",
12288
+ label: "Root-cause hints",
12289
+ description: "failures, hangs, slow paths, token spikes, and provider drift"
12290
+ },
12291
+ {
12292
+ id: "evidence",
12293
+ label: "Evidence links",
12294
+ description: "matched logs and metrics you can jump back into"
12295
+ }
12296
+ ];
12297
+ const PI_AGENT_STARTERS = [
12298
+ {
12299
+ id: "reliability",
12300
+ label: "Reliability",
12301
+ question: "Which requests failed, stalled, or look most likely to hang, and why?"
12302
+ },
12303
+ {
12304
+ id: "performance",
12305
+ label: "Performance",
12306
+ question: "Summarize latency and identify the slowest requests with supporting evidence."
12307
+ },
12308
+ {
12309
+ id: "tokens",
12310
+ label: "Token usage",
12311
+ question: "Where are tokens being spent, and which requests have unusually high usage?"
12312
+ },
12313
+ {
12314
+ id: "providers",
12315
+ label: "Providers",
12316
+ question: "Compare Provider and model reliability, latency, and token usage in this scope."
12317
+ },
12318
+ {
12319
+ id: "tools",
12320
+ label: "Tool activity",
12321
+ question: "Which tools were used most, and where did tool calls fail or produce warnings?"
12322
+ }
12323
+ ];
12324
+ const MAX_HISTORY_CONTENT_CHARS = 4e3;
12325
+ const MAX_METRICS = 12;
12326
+ function createEmptyPiAgentConversation() {
12327
+ return { messages: [], question: "", error: null };
12328
+ }
12329
+ function buildPiAgentHistory(messages) {
12330
+ return messages.filter((message) => message.content.trim().length > 0).slice(-10).map((message) => ({
12331
+ role: message.role,
12332
+ content: message.content.trim().slice(0, MAX_HISTORY_CONTENT_CHARS)
12333
+ }));
12334
+ }
12335
+ function readString(value, ...keys) {
12336
+ for (const key of keys) {
12337
+ const candidate = safeGetOwnProperty(value, key);
12338
+ if (typeof candidate === "string" && candidate.trim().length > 0) return candidate;
12339
+ }
12340
+ return null;
12341
+ }
12342
+ function readNumber(value, ...keys) {
12343
+ for (const key of keys) {
12344
+ const candidate = safeGetOwnProperty(value, key);
12345
+ if (typeof candidate === "number" && Number.isFinite(candidate)) return candidate;
12346
+ }
12347
+ return null;
12348
+ }
12349
+ function readStringArray(value, key) {
12350
+ const candidate = safeGetOwnProperty(value, key);
12351
+ if (!Array.isArray(candidate)) return [];
12352
+ return candidate.filter((item) => typeof item === "string").slice(0, 8);
12353
+ }
12354
+ function evidenceView(value) {
12355
+ const source = readString(value, "source") ?? "log";
12356
+ const id = readString(value, "id") ?? "";
12357
+ const logId = readNumber(value, "logId", "id");
12358
+ if (id === "" && logId === null) return null;
12359
+ if (logId !== null && (!Number.isInteger(logId) || logId < 0)) return null;
12360
+ const inputTokens = readNumber(value, "inputTokens");
12361
+ const outputTokens = readNumber(value, "outputTokens");
12362
+ const explicitTotal = readNumber(value, "totalTokens", "tokenCount");
12363
+ const statusNumber = readNumber(value, "responseStatus", "status");
12364
+ const statusString = readString(value, "responseStatus", "status");
12365
+ return {
12366
+ source,
12367
+ id: id !== "" ? id : String(logId),
12368
+ logId,
12369
+ sessionId: readString(value, "sessionId"),
12370
+ timestamp: readString(value, "timestamp"),
12371
+ model: readString(value, "model"),
12372
+ providerName: readString(value, "providerName", "provider"),
12373
+ path: readString(value, "path"),
12374
+ status: statusNumber ?? statusString,
12375
+ elapsedMs: readNumber(value, "elapsedMs", "latencyMs"),
12376
+ inputTokens,
12377
+ outputTokens,
12378
+ totalTokens: explicitTotal ?? (inputTokens === null && outputTokens === null ? null : (inputTokens ?? 0) + (outputTokens ?? 0)),
12379
+ score: readNumber(value, "score", "relevanceScore"),
12380
+ matchedFields: readStringArray(value, "matchedFields"),
12381
+ excerpt: readString(value, "excerpt", "snippet") ?? "No excerpt available."
12382
+ };
12383
+ }
12384
+ function humanizeMetricKey(key) {
12385
+ const spaced = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
12386
+ return spaced.length === 0 ? "Metric" : `${spaced[0]?.toUpperCase() ?? ""}${spaced.slice(1)}`;
12387
+ }
12388
+ function metricValue(value) {
12389
+ if (typeof value === "number" && Number.isFinite(value)) return value.toLocaleString();
12390
+ if (typeof value === "string" && value.trim().length > 0) return value;
12391
+ if (typeof value === "boolean") return value ? "Yes" : "No";
12392
+ if (Array.isArray(value)) {
12393
+ const items = value.filter(
12394
+ (item) => typeof item === "string" || typeof item === "number" && Number.isFinite(item)
12395
+ ).slice(0, 6);
12396
+ return items.length > 0 ? items.join(", ") : null;
12397
+ }
12398
+ return null;
12399
+ }
12400
+ function objectMetricEntries(value) {
12401
+ return Object.getOwnPropertyNames(value).map((key) => [key, safeGetOwnProperty(value, key)]);
12402
+ }
12403
+ function metricViews(value) {
12404
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return [];
12405
+ const entries = [];
12406
+ for (const [key, rawValue] of objectMetricEntries(value)) {
12407
+ const directValue = metricValue(rawValue);
12408
+ if (directValue !== null) {
12409
+ entries.push({ key, label: humanizeMetricKey(key), value: directValue });
12410
+ if (entries.length >= MAX_METRICS) break;
12411
+ continue;
12412
+ }
12413
+ if (rawValue === null || typeof rawValue !== "object" || Array.isArray(rawValue)) continue;
12414
+ for (const [nestedKey, nestedValue] of objectMetricEntries(rawValue)) {
12415
+ const formatted = metricValue(nestedValue);
12416
+ if (formatted === null) continue;
12417
+ const metricKey = `${key}.${nestedKey}`;
12418
+ entries.push({
12419
+ key: metricKey,
12420
+ label: `${humanizeMetricKey(key)} ${humanizeMetricKey(nestedKey).toLowerCase()}`,
12421
+ value: formatted
12422
+ });
12423
+ if (entries.length >= MAX_METRICS) break;
12424
+ }
12425
+ if (entries.length >= MAX_METRICS) break;
12426
+ }
12427
+ return entries;
12428
+ }
12429
+ function normalizePiAgentResponse(value) {
12430
+ const answer = readString(value, "answer");
12431
+ const providerId = readString(value, "providerId");
12432
+ const providerName = readString(value, "providerName");
12433
+ const model = readString(value, "model");
12434
+ const protocol = readString(value, "protocol");
12435
+ const logCount = readNumber(value, "logCount");
12436
+ if (answer === null || providerId === null || providerName === null || model === null || protocol === null || logCount === null) {
12437
+ return null;
12438
+ }
12439
+ const rawEvidence = safeGetOwnProperty(value, "evidence");
12440
+ const evidence = Array.isArray(rawEvidence) ? rawEvidence.map(evidenceView).filter((item) => item !== null).slice(0, 12) : [];
12441
+ return {
12442
+ answer,
12443
+ providerId,
12444
+ providerName,
12445
+ model,
12446
+ protocol,
12447
+ logCount,
12448
+ evidence,
12449
+ summaryMetrics: metricViews(safeGetOwnProperty(value, "summary")),
12450
+ queryMetrics: metricViews(safeGetOwnProperty(value, "queryStats"))
12451
+ };
12452
+ }
12453
+ const LazyReactMarkdown = reactExports.lazy(() => import("../_libs/react-markdown.mjs"));
12454
+ 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]";
12455
+ function AnswerMarkdown({ text }) {
12456
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ANSWER_MARKDOWN_CLASS, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
12457
+ reactExports.Suspense,
12458
+ {
12459
+ fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Loading Markdown..." }),
12460
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyReactMarkdown, { children: text })
12461
+ }
12462
+ ) });
12463
+ }
12204
12464
  const DEFAULT_QUESTION = "Analyze the current Inspector session. What looks abnormal, slow, or likely to hang?";
12205
12465
  function providerSupportsPiAgent(provider) {
12206
12466
  return provider.openaiResponsesBaseUrl !== void 0 || provider.openaiBaseUrl !== void 0 || provider.anthropicBaseUrl !== void 0;
@@ -12222,39 +12482,130 @@ function sortProviderBySource(providers) {
12222
12482
  return left.name.localeCompare(right.name);
12223
12483
  });
12224
12484
  }
12485
+ function nextMessageId(role) {
12486
+ return `${role}-${String(Date.now())}-${String(Math.random()).slice(2)}`;
12487
+ }
12488
+ function MetricStrip({ metrics }) {
12489
+ if (metrics.length === 0) return null;
12490
+ 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: [
12491
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate text-[9px] uppercase text-muted-foreground", children: metric.label }),
12492
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "truncate font-mono text-[11px] text-cyan-50", children: metric.value })
12493
+ ] }, metric.key)) });
12494
+ }
12495
+ function EvidenceCard({ evidence }) {
12496
+ const openLog = () => {
12497
+ if (evidence.logId === null) return;
12498
+ dispatchLogFocusRequest({ logId: evidence.logId, tab: "anatomy" });
12499
+ };
12500
+ const title = evidence.logId === null ? `${evidence.source}:${evidence.id}` : `${evidence.source}:log #${String(evidence.logId)}`;
12501
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
12502
+ "button",
12503
+ {
12504
+ type: "button",
12505
+ onClick: openLog,
12506
+ disabled: evidence.logId === null,
12507
+ 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",
12508
+ children: [
12509
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2", children: [
12510
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-mono text-[10px] text-cyan-100", children: title }),
12511
+ evidence.score !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 font-mono text-[9px] text-muted-foreground", children: evidence.score.toFixed(1) })
12512
+ ] }),
12513
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap gap-x-2 gap-y-1 text-[10px] text-muted-foreground", children: [
12514
+ evidence.providerName !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: evidence.providerName }),
12515
+ evidence.model !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: evidence.model }),
12516
+ evidence.status !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
12517
+ "status ",
12518
+ String(evidence.status)
12519
+ ] }),
12520
+ evidence.elapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
12521
+ String(evidence.elapsedMs),
12522
+ " ms"
12523
+ ] })
12524
+ ] }),
12525
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 line-clamp-3 text-[11px] leading-4 text-foreground/85", children: evidence.excerpt })
12526
+ ]
12527
+ }
12528
+ );
12529
+ }
12530
+ function AssistantMessage({ response }) {
12531
+ 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: [
12532
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AnswerMarkdown, { text: response.answer }),
12533
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 break-words font-mono text-[10px] text-cyan-100/70", children: [
12534
+ response.providerName,
12535
+ " / ",
12536
+ response.model,
12537
+ " / ",
12538
+ response.protocol,
12539
+ " /",
12540
+ " ",
12541
+ String(response.logCount),
12542
+ " matched logs"
12543
+ ] }),
12544
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricStrip, { metrics: response.summaryMetrics }),
12545
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricStrip, { metrics: response.queryMetrics }),
12546
+ 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}`)) })
12547
+ ] });
12548
+ }
12549
+ function ConversationMessage({ message }) {
12550
+ if (message.role === "assistant" && message.response !== null) {
12551
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AssistantMessage, { response: message.response });
12552
+ }
12553
+ 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 });
12554
+ }
12225
12555
  function PiAgentPanel({ currentSessionId, logCount }) {
12226
12556
  const { providers } = useProviders();
12227
12557
  const piProviders = reactExports.useMemo(
12228
12558
  () => sortProviderBySource(providers.filter(providerSupportsPiAgent)),
12229
12559
  [providers]
12230
12560
  );
12231
- const [question, setQuestion] = reactExports.useState(DEFAULT_QUESTION);
12561
+ const [conversation, setConversation] = reactExports.useState(() => ({
12562
+ ...createEmptyPiAgentConversation(),
12563
+ question: DEFAULT_QUESTION
12564
+ }));
12232
12565
  const [providerId, setProviderId] = reactExports.useState("__auto__");
12233
12566
  const [model, setModel] = reactExports.useState("__auto__");
12234
- const [answer, setAnswer] = reactExports.useState("");
12235
- const [status, setStatus] = reactExports.useState("");
12236
12567
  const [loading, setLoading] = reactExports.useState(false);
12237
12568
  const selectedProvider = piProviders.find((provider) => provider.id === providerId);
12238
12569
  const modelOptions = selectedProvider?.models ?? [];
12570
+ const question = conversation.question;
12239
12571
  const canAsk = question.trim() !== "" && piProviders.length > 0 && !loading;
12240
12572
  const handleQuestionChange = (event) => {
12241
- setQuestion(event.currentTarget.value);
12573
+ setConversation((current) => ({ ...current, question: event.currentTarget.value }));
12242
12574
  };
12243
12575
  const handleProviderChange = (value) => {
12244
12576
  setProviderId(value);
12245
12577
  setModel("__auto__");
12246
12578
  };
12579
+ const resetConversation = () => {
12580
+ setConversation({ ...createEmptyPiAgentConversation(), question: DEFAULT_QUESTION });
12581
+ };
12582
+ const setStarter = (questionText) => {
12583
+ setConversation((current) => ({ ...current, question: questionText, error: null }));
12584
+ };
12247
12585
  const askPiAgent = () => {
12248
12586
  if (!canAsk) return;
12587
+ const trimmedQuestion = question.trim();
12588
+ const history = buildPiAgentHistory(conversation.messages);
12589
+ const userMessage = {
12590
+ id: nextMessageId("user"),
12591
+ role: "user",
12592
+ content: trimmedQuestion,
12593
+ response: null
12594
+ };
12249
12595
  setLoading(true);
12250
- setStatus("");
12251
- setAnswer("");
12596
+ setConversation((current) => ({
12597
+ ...current,
12598
+ messages: [...current.messages, userMessage],
12599
+ question: "",
12600
+ error: null
12601
+ }));
12252
12602
  const body = {
12253
- question: question.trim(),
12603
+ question: trimmedQuestion,
12604
+ history,
12254
12605
  ...currentSessionId !== null ? { sessionId: currentSessionId } : {},
12255
12606
  ...providerId !== "__auto__" ? { providerId } : {},
12256
12607
  ...model !== "__auto__" ? { model } : {},
12257
- logLimit: 24
12608
+ logLimit: 16
12258
12609
  };
12259
12610
  void fetch("/api/pi-agent", {
12260
12611
  method: "POST",
@@ -12266,25 +12617,38 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12266
12617
  }).then(async (response) => {
12267
12618
  const raw = await response.text();
12268
12619
  if (!response.ok) {
12269
- setStatus(`Pi Agent failed: HTTP ${String(response.status)}`);
12270
- setAnswer(raw);
12620
+ setConversation((current) => ({
12621
+ ...current,
12622
+ error: `Pi Agent failed: HTTP ${String(response.status)} ${raw}`
12623
+ }));
12271
12624
  return;
12272
12625
  }
12273
12626
  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);
12627
+ const normalized = normalizePiAgentResponse(parsedJson);
12628
+ if (normalized === null) {
12629
+ setConversation((current) => ({
12630
+ ...current,
12631
+ error: "Pi Agent returned an unexpected response."
12632
+ }));
12278
12633
  return;
12279
12634
  }
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);
12635
+ setConversation((current) => ({
12636
+ ...current,
12637
+ messages: [
12638
+ ...current.messages,
12639
+ {
12640
+ id: nextMessageId("assistant"),
12641
+ role: "assistant",
12642
+ content: normalized.answer,
12643
+ response: normalized
12644
+ }
12645
+ ]
12646
+ }));
12286
12647
  }).catch((err) => {
12287
- setStatus(err instanceof Error ? err.message : "Pi Agent request failed.");
12648
+ setConversation((current) => ({
12649
+ ...current,
12650
+ error: err instanceof Error ? err.message : "Pi Agent request failed."
12651
+ }));
12288
12652
  }).finally(() => {
12289
12653
  setLoading(false);
12290
12654
  });
@@ -12294,8 +12658,32 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12294
12658
  /* @__PURE__ */ jsxRuntimeExports.jsx(BrainCircuit, { className: "size-4 text-cyan-200" }),
12295
12659
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [
12296
12660
  /* @__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
- ] })
12661
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] text-muted-foreground", children: currentSessionId === null ? "Ask saved Inspector data" : "Ask this session" })
12662
+ ] }),
12663
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
12664
+ "button",
12665
+ {
12666
+ type: "button",
12667
+ onClick: resetConversation,
12668
+ className: "inline-flex size-7 items-center justify-center rounded-md bg-black/25 text-muted-foreground transition-colors hover:text-foreground",
12669
+ title: "Reset conversation",
12670
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-3.5" })
12671
+ }
12672
+ )
12673
+ ] }),
12674
+ conversation.messages.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 rounded-md bg-black/[0.18] px-3 py-2 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.045)]", children: [
12675
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] leading-5 text-muted-foreground", children: "ChatBI for Inspector memory: Pi searches saved traffic, sessions, tools, Provider signals, alerts, runs, groups, and knowledge candidates, then answers with linked evidence." }),
12676
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5", children: PI_AGENT_SCOPE_PILLS.map((pill) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
12677
+ "div",
12678
+ {
12679
+ className: "rounded-sm bg-cyan-400/[0.06] px-2 py-1.5 shadow-[inset_0_0_0_1px_rgba(103,232,249,0.08)]",
12680
+ children: [
12681
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-cyan-50", children: pill.label }),
12682
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-0.5 text-[9px] leading-4 text-muted-foreground", children: pill.description })
12683
+ ]
12684
+ },
12685
+ pill.id
12686
+ )) })
12299
12687
  ] }),
12300
12688
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 grid grid-cols-2 gap-2", children: [
12301
12689
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: providerId, onValueChange: handleProviderChange, children: [
@@ -12317,13 +12705,35 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12317
12705
  ] })
12318
12706
  ] })
12319
12707
  ] }),
12708
+ 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(
12709
+ "button",
12710
+ {
12711
+ type: "button",
12712
+ onClick: () => {
12713
+ setStarter(starter.question);
12714
+ },
12715
+ 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",
12716
+ children: [
12717
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "size-3" }),
12718
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: starter.label })
12719
+ ]
12720
+ },
12721
+ starter.id
12722
+ )) }),
12723
+ conversation.messages.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 max-h-96 space-y-2 overflow-y-auto pr-1", children: [
12724
+ conversation.messages.map((message) => /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationMessage, { message }, message.id)),
12725
+ 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: [
12726
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
12727
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Searching Inspector..." })
12728
+ ] })
12729
+ ] }),
12320
12730
  /* @__PURE__ */ jsxRuntimeExports.jsx(
12321
12731
  "textarea",
12322
12732
  {
12323
12733
  value: question,
12324
12734
  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..."
12735
+ 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",
12736
+ placeholder: "Ask Pi Agent across saved Inspector data..."
12327
12737
  }
12328
12738
  ),
12329
12739
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -12339,9 +12749,8 @@ function PiAgentPanel({ currentSessionId, logCount }) {
12339
12749
  ]
12340
12750
  }
12341
12751
  ),
12752
+ conversation.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 break-words text-[11px] leading-5 text-red-200", children: conversation.error }),
12342
12753
  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
12754
  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
12755
  ] });
12347
12756
  }
@@ -16976,13 +17385,14 @@ export {
16976
17385
  dispatchLogFocusRequest as n,
16977
17386
  analyzeContextIntelligence as o,
16978
17387
  ANATOMY_ROLE_LABELS as p,
16979
- Collapsible as q,
17388
+ AnswerMarkdown as q,
16980
17389
  resolveLogFormat as r,
16981
- CollapsibleTrigger as s,
16982
- CollapsibleContent as t,
17390
+ Collapsible as s,
17391
+ CollapsibleTrigger as t,
16983
17392
  useProviders as u,
16984
- ScrollArea as v,
16985
- LazyJsonViewer as w,
16986
- safeJsonValue as x,
16987
- parseJsonText as y
17393
+ CollapsibleContent as v,
17394
+ ScrollArea as w,
17395
+ LazyJsonViewer as x,
17396
+ safeJsonValue as y,
17397
+ parseJsonText as z
16988
17398
  };