@datalayer/agent-runtimes 1.0.4 → 1.0.6

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 (299) hide show
  1. package/README.md +182 -1
  2. package/lib/AgentNode.d.ts +3 -0
  3. package/lib/AgentNode.js +676 -0
  4. package/lib/App.js +1 -1
  5. package/lib/agent-node/themeStore.d.ts +3 -0
  6. package/lib/agent-node/themeStore.js +156 -0
  7. package/lib/agent-node-main.d.ts +1 -0
  8. package/lib/agent-node-main.js +14 -0
  9. package/lib/agents/AgentDetails.d.ts +22 -1
  10. package/lib/agents/AgentDetails.js +34 -47
  11. package/lib/api/index.d.ts +0 -1
  12. package/lib/api/index.js +4 -2
  13. package/lib/chat/Chat.d.ts +5 -106
  14. package/lib/chat/Chat.js +20 -14
  15. package/lib/chat/ChatFloating.d.ts +7 -140
  16. package/lib/chat/ChatFloating.js +3 -3
  17. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  18. package/lib/chat/ChatPopupStandalone.js +3 -3
  19. package/lib/chat/ChatSidebar.d.ts +4 -69
  20. package/lib/chat/ChatSidebar.js +83 -51
  21. package/lib/chat/ChatStandalone.d.ts +4 -54
  22. package/lib/chat/ChatStandalone.js +3 -3
  23. package/lib/chat/base/ChatBase.js +1414 -174
  24. package/lib/chat/display/FloatingBrandButton.js +8 -1
  25. package/lib/chat/header/ChatHeader.d.ts +3 -1
  26. package/lib/chat/header/ChatHeader.js +15 -12
  27. package/lib/chat/header/ChatHeaderBase.d.ts +30 -5
  28. package/lib/chat/header/ChatHeaderBase.js +41 -16
  29. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  30. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  31. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  32. package/lib/chat/indicators/SandboxStatusIndicator.js +91 -56
  33. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  34. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  35. package/lib/chat/indicators/index.d.ts +1 -0
  36. package/lib/chat/indicators/index.js +1 -0
  37. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  38. package/lib/chat/messages/ChatMessageList.js +154 -114
  39. package/lib/chat/messages/ChatMessages.js +6 -2
  40. package/lib/chat/prompt/InputFooter.d.ts +21 -6
  41. package/lib/chat/prompt/InputFooter.js +76 -20
  42. package/lib/chat/prompt/InputPrompt.d.ts +5 -1
  43. package/lib/chat/prompt/InputPrompt.js +4 -4
  44. package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
  45. package/lib/chat/prompt/InputPromptFooter.js +3 -3
  46. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  47. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  48. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  49. package/lib/chat/prompt/InputPromptText.js +2 -2
  50. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  51. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  52. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  53. package/lib/chat/usage/TokenUsageBar.js +20 -2
  54. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  55. package/lib/client/AgentRuntimesClientContext.js +55 -0
  56. package/lib/client/AgentsMixin.d.ts +0 -18
  57. package/lib/client/AgentsMixin.js +20 -30
  58. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  59. package/lib/client/IAgentRuntimesClient.js +5 -0
  60. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  61. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  62. package/lib/client/index.d.ts +4 -1
  63. package/lib/client/index.js +3 -1
  64. package/lib/components/NotificationEventCard.js +5 -1
  65. package/lib/config/AgentConfiguration.d.ts +22 -0
  66. package/lib/config/AgentConfiguration.js +319 -64
  67. package/lib/context/ContextDistribution.d.ts +3 -1
  68. package/lib/context/ContextDistribution.js +8 -27
  69. package/lib/context/ContextInspector.d.ts +3 -1
  70. package/lib/context/ContextInspector.js +19 -67
  71. package/lib/context/ContextPanel.d.ts +3 -1
  72. package/lib/context/ContextPanel.js +104 -64
  73. package/lib/context/ContextUsage.d.ts +3 -1
  74. package/lib/context/ContextUsage.js +3 -3
  75. package/lib/context/CostTracker.d.ts +9 -3
  76. package/lib/context/CostTracker.js +26 -47
  77. package/lib/context/CostUsageChart.d.ts +12 -0
  78. package/lib/context/CostUsageChart.js +378 -0
  79. package/lib/context/GraphFlowChart.d.ts +16 -0
  80. package/lib/context/GraphFlowChart.js +182 -0
  81. package/lib/context/TokenUsageChart.d.ts +8 -1
  82. package/lib/context/TokenUsageChart.js +349 -211
  83. package/lib/context/TurnGraphChart.d.ts +39 -0
  84. package/lib/context/TurnGraphChart.js +538 -0
  85. package/lib/context/otelWsPool.d.ts +20 -0
  86. package/lib/context/otelWsPool.js +69 -0
  87. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  88. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  89. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  90. package/lib/examples/A2UiContactCardExample.js +154 -411
  91. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  92. package/lib/examples/A2UiRestaurantExample.js +114 -212
  93. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  94. package/lib/examples/A2UiViewerExample.js +283 -532
  95. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  96. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  97. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  98. package/lib/examples/AgUiSharedStateExample.js +2 -1
  99. package/lib/examples/AgentCheckpointsExample.js +14 -28
  100. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  101. package/lib/examples/AgentCodemodeExample.js +603 -169
  102. package/lib/examples/AgentEvalsExample.js +339 -53
  103. package/lib/examples/AgentGuardrailsExample.js +383 -66
  104. package/lib/examples/AgentHooksExample.d.ts +3 -0
  105. package/lib/examples/AgentHooksExample.js +122 -0
  106. package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
  107. package/lib/examples/AgentInferenceProviderExample.js +329 -0
  108. package/lib/examples/AgentMCPExample.d.ts +3 -0
  109. package/lib/examples/AgentMCPExample.js +481 -0
  110. package/lib/examples/AgentMemoryExample.d.ts +1 -2
  111. package/lib/examples/AgentMemoryExample.js +78 -33
  112. package/lib/examples/AgentMonitoringExample.js +261 -200
  113. package/lib/examples/AgentNotificationsExample.d.ts +1 -2
  114. package/lib/examples/AgentNotificationsExample.js +114 -33
  115. package/lib/examples/AgentOtelExample.js +32 -42
  116. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  117. package/lib/examples/AgentOutputsExample.js +433 -81
  118. package/lib/examples/AgentParametersExample.d.ts +3 -0
  119. package/lib/examples/AgentParametersExample.js +248 -0
  120. package/lib/examples/AgentSandboxExample.d.ts +3 -3
  121. package/lib/examples/AgentSandboxExample.js +74 -45
  122. package/lib/examples/AgentSkillsExample.js +95 -103
  123. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  124. package/lib/examples/AgentSubagentsExample.js +228 -0
  125. package/lib/examples/AgentToolApprovalsExample.js +49 -561
  126. package/lib/examples/AgentTriggersExample.js +823 -569
  127. package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
  128. package/lib/examples/AgentspecsExample.js +1096 -0
  129. package/lib/examples/ChatCustomExample.js +16 -28
  130. package/lib/examples/ChatExample.js +13 -29
  131. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  132. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  133. package/lib/examples/HomeExample.d.ts +15 -0
  134. package/lib/examples/HomeExample.js +77 -0
  135. package/lib/examples/Lexical2Example.js +4 -2
  136. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  137. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +66 -17
  138. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  139. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  140. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  141. package/lib/examples/NotebookAgentExample.js +192 -0
  142. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  143. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  144. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  145. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  146. package/lib/examples/NotebookExample.d.ts +4 -7
  147. package/lib/examples/NotebookExample.js +14 -146
  148. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  149. package/lib/examples/components/AuthRequiredView.js +33 -0
  150. package/lib/examples/components/ExampleWrapper.d.ts +9 -3
  151. package/lib/examples/components/ExampleWrapper.js +45 -9
  152. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  153. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  154. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  155. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  156. package/lib/examples/components/index.d.ts +3 -0
  157. package/lib/examples/components/index.js +4 -0
  158. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  159. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  160. package/lib/examples/example-selector.d.ts +17 -4
  161. package/lib/examples/example-selector.js +108 -41
  162. package/lib/examples/index.d.ts +10 -6
  163. package/lib/examples/index.js +10 -6
  164. package/lib/examples/lexical/initial-content.json +6 -6
  165. package/lib/examples/main.js +257 -27
  166. package/lib/examples/utils/a2ui.d.ts +18 -0
  167. package/lib/examples/utils/a2ui.js +69 -0
  168. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  169. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  170. package/lib/examples/utils/agentId.d.ts +18 -0
  171. package/lib/examples/utils/agentId.js +54 -0
  172. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  173. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  174. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  175. package/lib/examples/utils/agents/stock-market.json +11 -11
  176. package/lib/examples/utils/examplesStore.js +82 -27
  177. package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
  178. package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
  179. package/lib/hooks/index.d.ts +8 -8
  180. package/lib/hooks/index.js +7 -7
  181. package/lib/hooks/useA2A.d.ts +2 -3
  182. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  183. package/lib/hooks/useAIAgentsWebSocket.js +153 -12
  184. package/lib/hooks/useAcp.d.ts +1 -2
  185. package/lib/hooks/useAgUi.d.ts +1 -1
  186. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +70 -4
  187. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
  188. package/lib/hooks/useAgentsCatalog.js +1 -1
  189. package/lib/hooks/useAgentsService.d.ts +2 -2
  190. package/lib/hooks/useAgentsService.js +7 -7
  191. package/lib/hooks/useCheckpoints.js +1 -1
  192. package/lib/hooks/useConfig.d.ts +4 -1
  193. package/lib/hooks/useConfig.js +10 -3
  194. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  195. package/lib/hooks/useContextSnapshot.js +9 -37
  196. package/lib/hooks/useMonitoring.js +3 -0
  197. package/lib/hooks/useSandbox.d.ts +20 -8
  198. package/lib/hooks/useSandbox.js +105 -40
  199. package/lib/hooks/useSkills.d.ts +23 -5
  200. package/lib/hooks/useSkills.js +94 -39
  201. package/lib/hooks/useToolApprovals.d.ts +60 -36
  202. package/lib/hooks/useToolApprovals.js +318 -69
  203. package/lib/hooks/useVercelAI.d.ts +1 -1
  204. package/lib/index.d.ts +2 -1
  205. package/lib/index.js +1 -0
  206. package/lib/inference/index.d.ts +0 -1
  207. package/lib/middleware/index.d.ts +0 -1
  208. package/lib/protocols/AGUIAdapter.js +6 -0
  209. package/lib/protocols/VercelAIAdapter.d.ts +7 -0
  210. package/lib/protocols/VercelAIAdapter.js +59 -7
  211. package/lib/specs/agents/agents.d.ts +21 -4
  212. package/lib/specs/agents/agents.js +2879 -316
  213. package/lib/specs/agents/index.js +3 -1
  214. package/lib/specs/benchmarks.d.ts +20 -0
  215. package/lib/specs/benchmarks.js +205 -0
  216. package/lib/specs/envvars.js +27 -20
  217. package/lib/specs/evals.d.ts +10 -9
  218. package/lib/specs/evals.js +128 -88
  219. package/lib/specs/events.d.ts +3 -10
  220. package/lib/specs/events.js +127 -84
  221. package/lib/specs/frontendTools.js +2 -2
  222. package/lib/specs/guardrails.d.ts +0 -7
  223. package/lib/specs/guardrails.js +240 -159
  224. package/lib/specs/mcpServers.js +35 -6
  225. package/lib/specs/memory.d.ts +0 -2
  226. package/lib/specs/memory.js +4 -17
  227. package/lib/specs/models.d.ts +0 -2
  228. package/lib/specs/models.js +20 -15
  229. package/lib/specs/notifications.js +102 -18
  230. package/lib/specs/outputs.js +15 -9
  231. package/lib/specs/personas.d.ts +41 -0
  232. package/lib/specs/personas.js +168 -0
  233. package/lib/specs/skills.d.ts +1 -1
  234. package/lib/specs/skills.js +23 -23
  235. package/lib/specs/teams/index.js +3 -1
  236. package/lib/specs/teams/teams.js +468 -348
  237. package/lib/specs/tools.js +4 -4
  238. package/lib/specs/triggers.js +61 -11
  239. package/lib/stores/agentRuntimeStore.d.ts +208 -0
  240. package/lib/stores/agentRuntimeStore.js +650 -0
  241. package/lib/stores/conversationStore.js +2 -2
  242. package/lib/stores/index.d.ts +1 -1
  243. package/lib/stores/index.js +1 -1
  244. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  245. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  246. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  247. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  248. package/lib/tools/index.d.ts +0 -2
  249. package/lib/tools/index.js +0 -1
  250. package/lib/types/agents-lifecycle.d.ts +18 -0
  251. package/lib/types/agents.d.ts +6 -0
  252. package/lib/types/agentspecs.d.ts +54 -1
  253. package/lib/types/benchmarks.d.ts +43 -0
  254. package/lib/types/benchmarks.js +5 -0
  255. package/lib/types/chat.d.ts +325 -8
  256. package/lib/types/context.d.ts +27 -0
  257. package/lib/types/cost.d.ts +2 -2
  258. package/lib/types/evals.d.ts +26 -17
  259. package/lib/types/index.d.ts +3 -0
  260. package/lib/types/index.js +3 -0
  261. package/lib/types/mcp.d.ts +8 -0
  262. package/lib/types/models.d.ts +2 -2
  263. package/lib/types/personas.d.ts +25 -0
  264. package/lib/types/personas.js +5 -0
  265. package/lib/types/skills.d.ts +43 -1
  266. package/lib/types/stream.d.ts +110 -0
  267. package/lib/types/stream.js +36 -0
  268. package/lib/utils/utils.d.ts +9 -5
  269. package/lib/utils/utils.js +9 -5
  270. package/package.json +19 -11
  271. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  272. package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
  273. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  274. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  275. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  276. package/scripts/codegen/generate_agents.py +187 -45
  277. package/scripts/codegen/generate_benchmarks.py +441 -0
  278. package/scripts/codegen/generate_evals.py +94 -16
  279. package/scripts/codegen/generate_events.py +35 -14
  280. package/scripts/codegen/generate_personas.py +319 -0
  281. package/scripts/codegen/generate_skills.py +9 -9
  282. package/scripts/sync-jupyter.sh +26 -7
  283. package/lib/api/tool-approvals.d.ts +0 -62
  284. package/lib/api/tool-approvals.js +0 -145
  285. package/lib/examples/AgentspecExample.js +0 -705
  286. package/lib/examples/LexicalSidebarExample.js +0 -163
  287. package/lib/examples/NotebookSidebarExample.js +0 -119
  288. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  289. package/lib/examples/NotebookSimpleExample.js +0 -22
  290. package/lib/examples/ag-ui/index.d.ts +0 -10
  291. package/lib/examples/ag-ui/index.js +0 -16
  292. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  293. package/lib/hooks/useAgentsRegistry.js +0 -20
  294. package/lib/stores/agentsStore.d.ts +0 -123
  295. package/lib/stores/agentsStore.js +0 -270
  296. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  297. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  298. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  299. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -6,18 +6,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  */
7
7
  import { Box, Text, Spinner, Button } from '@primer/react';
8
8
  import { ListUnorderedIcon } from '@primer/octicons-react';
9
- import { useQuery } from '@tanstack/react-query';
10
9
  import ReactECharts from 'echarts-for-react';
11
10
  import { useState } from 'react';
12
- function getLocalApiBase() {
13
- if (typeof window === 'undefined') {
14
- return '';
15
- }
16
- const host = window.location.hostname;
17
- return host === 'localhost' || host === '127.0.0.1'
18
- ? 'http://127.0.0.1:8765'
19
- : '';
20
- }
21
11
  /**
22
12
  * Format token count for display
23
13
  */
@@ -33,23 +23,14 @@ function formatTokens(tokens) {
33
23
  /**
34
24
  * ContextDistribution component displays context distribution as a treemap.
35
25
  */
36
- export function ContextDistribution({ agentId, height = '250px', }) {
26
+ export function ContextDistribution({ agentId, height = '250px', liveData, }) {
37
27
  const [showDetails, setShowDetails] = useState(false);
38
- const { data: snapshotData, isLoading, error, } = useQuery({
39
- queryKey: ['context-snapshot', agentId],
40
- queryFn: async () => {
41
- const apiBase = getLocalApiBase();
42
- const response = await fetch(`${apiBase}/api/v1/configure/agents/${encodeURIComponent(agentId)}/context-snapshot`);
43
- if (!response.ok) {
44
- throw new Error('Failed to fetch context snapshot');
45
- }
46
- return response.json();
47
- },
48
- refetchInterval: 10000, // Refresh every 10 seconds
49
- refetchOnMount: 'always',
50
- staleTime: 0,
51
- });
52
- if (isLoading) {
28
+ const hasLiveData = liveData !== undefined;
29
+ // REST polling removed — data comes exclusively via WS `agent.snapshot`.
30
+ const snapshotData = liveData;
31
+ const showLoading = !hasLiveData;
32
+ const hasError = false;
33
+ if (showLoading) {
53
34
  return (_jsxs(Box, { sx: {
54
35
  p: 3,
55
36
  display: 'flex',
@@ -58,7 +39,7 @@ export function ContextDistribution({ agentId, height = '250px', }) {
58
39
  height,
59
40
  }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { ml: 2, fontSize: 1, color: 'fg.muted' }, children: "Loading context distribution..." })] }));
60
41
  }
61
- if (error || !snapshotData) {
42
+ if (hasError || !snapshotData) {
62
43
  return (_jsx(Box, { sx: {
63
44
  p: 3,
64
45
  bg: 'canvas.subtle',
@@ -73,9 +73,11 @@ export interface ContextInspectorProps {
73
73
  agentId: string;
74
74
  /** API base URL for fetching context data */
75
75
  apiBase?: string;
76
+ /** Live full-context data from WS — bypasses REST polling when provided */
77
+ liveData?: FullContextResponse | null;
76
78
  }
77
79
  /**
78
80
  * ContextInspector component displays full detailed context snapshot.
79
81
  */
80
- export declare function ContextInspector({ agentId, apiBase }: ContextInspectorProps): import("react/jsx-runtime").JSX.Element;
82
+ export declare function ContextInspector({ agentId, apiBase, liveData, }: ContextInspectorProps): import("react/jsx-runtime").JSX.Element;
81
83
  export default ContextInspector;
@@ -5,29 +5,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
5
5
  * ContextInspector component - Shows detailed context snapshot with full tool schemas,
6
6
  * message history with in_context flags, and model configuration.
7
7
  */
8
- import { Text, Spinner, Button, Label, ProgressBar } from '@primer/react';
8
+ import { Text, Button, Label, ProgressBar } from '@primer/react';
9
9
  import { Box } from '@datalayer/primer-addons';
10
10
  import { AiModelIcon, TerminalIcon, CommentDiscussionIcon, DatabaseIcon, KeyIcon, CodeIcon, CheckCircleIcon, XCircleIcon, ChevronDownIcon, ChevronRightIcon, InfoIcon, } from '@primer/octicons-react';
11
- import { useQuery } from '@tanstack/react-query';
12
- import React, { useState, useMemo, useEffect } from 'react';
13
- const RETRY_INTERVAL_SECONDS = 5;
11
+ import React, { useState, useMemo } from 'react';
14
12
  /**
15
13
  * Get the API base URL for fetching context data.
16
14
  * If apiBase prop is provided, use it.
17
15
  * Otherwise, fall back to localhost for local development.
18
16
  */
19
- function getApiBase(apiBase) {
20
- if (apiBase) {
21
- return apiBase;
22
- }
23
- if (typeof window === 'undefined') {
24
- return '';
25
- }
26
- const host = window.location.hostname;
27
- return host === 'localhost' || host === '127.0.0.1'
28
- ? 'http://127.0.0.1:8765'
29
- : '';
30
- }
31
17
  /**
32
18
  * Format token count for display
33
19
  */
@@ -143,34 +129,10 @@ function MessageDetailView({ message }) {
143
129
  /**
144
130
  * ContextInspector component displays full detailed context snapshot.
145
131
  */
146
- export function ContextInspector({ agentId, apiBase }) {
147
- const [retryCountdown, setRetryCountdown] = useState(RETRY_INTERVAL_SECONDS);
148
- const { data: contextData, isLoading, error, refetch, } = useQuery({
149
- queryKey: ['full-context', agentId, apiBase],
150
- queryFn: async () => {
151
- const base = getApiBase(apiBase);
152
- const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/full-context`);
153
- if (!response.ok) {
154
- throw new Error('Failed to fetch full context');
155
- }
156
- return response.json();
157
- },
158
- refetchInterval: RETRY_INTERVAL_SECONDS * 1000,
159
- refetchOnMount: 'always',
160
- staleTime: 0,
161
- });
162
- const hasRetryError = Boolean(error) || Boolean(contextData?.error);
163
- useEffect(() => {
164
- if (!hasRetryError) {
165
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
166
- return;
167
- }
168
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
169
- const timer = window.setInterval(() => {
170
- setRetryCountdown(prev => prev <= 1 ? RETRY_INTERVAL_SECONDS : prev - 1);
171
- }, 1000);
172
- return () => window.clearInterval(timer);
173
- }, [hasRetryError]);
132
+ export function ContextInspector({ agentId, apiBase, liveData, }) {
133
+ const hasLiveData = liveData !== undefined;
134
+ // REST polling removed data comes exclusively via WS `agent.snapshot`.
135
+ const contextData = liveData;
174
136
  // Separate messages by in_context status
175
137
  const { inContextMessages, outOfContextMessages } = useMemo(() => {
176
138
  if (!contextData?.messages) {
@@ -181,30 +143,28 @@ export function ContextInspector({ agentId, apiBase }) {
181
143
  outOfContextMessages: contextData.messages.filter(m => !m.inContext),
182
144
  };
183
145
  }, [contextData?.messages]);
184
- if (isLoading) {
185
- return (_jsxs(Box, { sx: {
146
+ const messageHistoryTokens = useMemo(() => {
147
+ if (!contextData?.messages) {
148
+ return 0;
149
+ }
150
+ return contextData.messages.reduce((sum, message) => sum + (message.estimatedTokens || 0), 0);
151
+ }, [contextData?.messages]);
152
+ if (!hasLiveData) {
153
+ return (_jsx(Box, { sx: {
186
154
  p: 3,
187
155
  display: 'flex',
188
156
  alignItems: 'center',
189
157
  justifyContent: 'center',
190
- }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { ml: 2, color: 'fg.muted' }, children: "Loading full context snapshot..." })] }));
158
+ }, children: _jsx(Text, { sx: { color: 'fg.muted' }, children: "Waiting for context data from WebSocket stream..." }) }));
191
159
  }
192
- if (error || !contextData) {
160
+ if (!contextData) {
193
161
  return (_jsx(Box, { sx: {
194
162
  p: 3,
195
163
  bg: 'attention.subtle',
196
164
  borderRadius: 2,
197
165
  border: '1px solid',
198
166
  borderColor: 'attention.muted',
199
- }, children: _jsxs(Box, { sx: {
200
- display: 'flex',
201
- alignItems: 'center',
202
- justifyContent: 'space-between',
203
- gap: 2,
204
- }, children: [_jsxs(Text, { sx: { color: 'attention.fg' }, children: ["Service not available for context snapshot. Retrying in", ' ', retryCountdown, " second", retryCountdown === 1 ? '' : 's', "..."] }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
205
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
206
- void refetch();
207
- }, children: "Retry now" })] }) }));
167
+ }, children: _jsx(Text, { sx: { color: 'attention.fg' }, children: "No context data available." }) }));
208
168
  }
209
169
  if (contextData.error) {
210
170
  return (_jsx(Box, { sx: {
@@ -213,15 +173,7 @@ export function ContextInspector({ agentId, apiBase }) {
213
173
  borderRadius: 2,
214
174
  border: '1px solid',
215
175
  borderColor: 'attention.muted',
216
- }, children: _jsxs(Box, { sx: {
217
- display: 'flex',
218
- alignItems: 'center',
219
- justifyContent: 'space-between',
220
- gap: 2,
221
- }, children: [_jsx(Text, { sx: { color: 'attention.fg' }, children: `${contextData.error} Retrying in ${retryCountdown} second${retryCountdown === 1 ? '' : 's'}...` }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
222
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
223
- void refetch();
224
- }, children: "Retry now" })] }) }));
176
+ }, children: _jsx(Text, { sx: { color: 'attention.fg' }, children: contextData.error }) }));
225
177
  }
226
178
  const { tokenSummary, modelConfiguration } = contextData;
227
179
  return (_jsxs(Box, { children: [_jsxs(Box, { sx: { mb: 3 }, children: [_jsxs(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: ["Total usage: ", formatTokens(tokenSummary.total), " /", ' ', formatTokens(tokenSummary.contextWindow), " (", Math.round(tokenSummary.usagePercent), "%)"] }), _jsx(ProgressBar, { progress: Math.min(tokenSummary.usagePercent, 100), sx: { mt: 2, height: 8 }, bg: tokenSummary.usagePercent > 90
@@ -258,7 +210,7 @@ export function ContextInspector({ agentId, apiBase }) {
258
210
  wordBreak: 'break-word',
259
211
  maxHeight: 200,
260
212
  overflow: 'auto',
261
- }, children: prompt.content })] }, idx)))) }), _jsx(CollapsibleSection, { title: "Tools", icon: TerminalIcon, count: contextData.tools.length, tokens: contextData.toolTokens, children: contextData.tools.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No tools configured" })) : (contextData.tools.map((tool, idx) => (_jsx(ToolDetailView, { tool: tool }, idx)))) }), _jsx(CollapsibleSection, { title: "Message History", icon: CommentDiscussionIcon, count: contextData.messages.length, children: contextData.messages.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No messages yet" })) : (_jsxs(_Fragment, { children: [outOfContextMessages.length > 0 && (_jsxs(Box, { sx: { mb: 3 }, children: [_jsxs(Text, { sx: {
213
+ }, children: prompt.content })] }, idx)))) }), _jsx(CollapsibleSection, { title: "Tool Definitions", icon: TerminalIcon, count: contextData.tools.length, tokens: contextData.toolTokens, children: contextData.tools.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No tools configured" })) : (contextData.tools.map((tool, idx) => (_jsx(ToolDetailView, { tool: tool }, idx)))) }), _jsx(CollapsibleSection, { title: "Message History", icon: CommentDiscussionIcon, count: contextData.messages.length, tokens: messageHistoryTokens, children: contextData.messages.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No messages yet" })) : (_jsxs(_Fragment, { children: [outOfContextMessages.length > 0 && (_jsxs(Box, { sx: { mb: 3 }, children: [_jsxs(Text, { sx: {
262
214
  fontWeight: 'semibold',
263
215
  fontSize: 1,
264
216
  color: 'fg.muted',
@@ -98,6 +98,8 @@ export interface ContextPanelProps {
98
98
  agentId: string;
99
99
  /** API base URL for fetching context data */
100
100
  apiBase?: string;
101
+ /** Live context snapshot pushed by websocket; skips internal polling when provided */
102
+ liveData?: ContextSnapshotResponse | null;
101
103
  /** Number of messages in conversation (from chat store) */
102
104
  messageCount?: number;
103
105
  /** Default view mode */
@@ -108,5 +110,5 @@ export interface ContextPanelProps {
108
110
  /**
109
111
  * ContextPanel component - unified context usage display.
110
112
  */
111
- export declare function ContextPanel({ agentId, apiBase, messageCount, defaultView, chartHeight, }: ContextPanelProps): import("react/jsx-runtime").JSX.Element;
113
+ export declare function ContextPanel({ agentId, apiBase, liveData, messageCount, defaultView, chartHeight, }: ContextPanelProps): import("react/jsx-runtime").JSX.Element;
112
114
  export default ContextPanel;
@@ -7,12 +7,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  * - Token distribution treemap
8
8
  * - Historic usage time-series chart
9
9
  */
10
- import { CommentDiscussionIcon, DatabaseIcon, FileIcon, ToolsIcon, ClockIcon, GraphIcon, ListUnorderedIcon, } from '@primer/octicons-react';
10
+ import { CommentDiscussionIcon, DatabaseIcon, FileIcon, ToolsIcon, ClockIcon, GraphIcon, AppsIcon, ListUnorderedIcon, DownloadIcon, } from '@primer/octicons-react';
11
11
  import { Heading, Text, ProgressBar, Spinner, Button, SegmentedControl, } from '@primer/react';
12
12
  import { Box } from '@datalayer/primer-addons';
13
- import { useQuery } from '@tanstack/react-query';
14
13
  import ReactECharts from 'echarts-for-react';
15
- import { useState, useMemo, useEffect } from 'react';
14
+ import { useState, useMemo } from 'react';
16
15
  /**
17
16
  * Format token count for display
18
17
  */
@@ -29,8 +28,11 @@ function formatTokens(tokens) {
29
28
  * Format duration
30
29
  */
31
30
  function formatDuration(seconds) {
31
+ if (!Number.isFinite(seconds) || Number.isNaN(seconds) || seconds < 0) {
32
+ return '0ms';
33
+ }
32
34
  if (seconds < 1) {
33
- return `${Math.round(seconds * 1000)}ms`;
35
+ return `${Math.max(0, Math.round(seconds * 1000))}ms`;
34
36
  }
35
37
  if (seconds < 60) {
36
38
  return `${seconds.toFixed(1)}s`;
@@ -39,6 +41,89 @@ function formatDuration(seconds) {
39
41
  const secs = Math.round(seconds % 60);
40
42
  return `${minutes}m ${secs}s`;
41
43
  }
44
+ function csvCell(value) {
45
+ const text = String(value ?? '');
46
+ if (/[",\n]/.test(text)) {
47
+ return `"${text.replace(/"/g, '""')}"`;
48
+ }
49
+ return text;
50
+ }
51
+ function downloadContextUsageAsCSV(data) {
52
+ const rows = [];
53
+ rows.push(['Context Usage Snapshot for Agent', data.agentId]);
54
+ rows.push(['Generated At', new Date().toISOString()]);
55
+ rows.push([]);
56
+ rows.push(['Summary']);
57
+ rows.push(['Total Tokens', data.totalTokens]);
58
+ rows.push(['Context Window', data.contextWindow]);
59
+ rows.push(['System Prompt Tokens', data.systemPromptTokens]);
60
+ rows.push(['Tool Tokens', data.toolTokens]);
61
+ rows.push(['History Tokens', data.historyTokens]);
62
+ rows.push(['Current Message Tokens', data.currentMessageTokens]);
63
+ rows.push(['User Message Tokens', data.userMessageTokens]);
64
+ rows.push(['Assistant Message Tokens', data.assistantMessageTokens]);
65
+ rows.push([]);
66
+ if (data.sessionUsage) {
67
+ rows.push(['Session Usage']);
68
+ rows.push(['Input Tokens', data.sessionUsage.inputTokens]);
69
+ rows.push(['Output Tokens', data.sessionUsage.outputTokens]);
70
+ rows.push(['Requests', data.sessionUsage.requests]);
71
+ rows.push(['Tool Calls', data.sessionUsage.toolCalls]);
72
+ rows.push(['Turns', data.sessionUsage.turns]);
73
+ rows.push(['Duration Seconds', data.sessionUsage.durationSeconds]);
74
+ rows.push([]);
75
+ }
76
+ if (data.turnUsage) {
77
+ rows.push(['Last Turn Usage']);
78
+ rows.push(['Input Tokens', data.turnUsage.inputTokens]);
79
+ rows.push(['Output Tokens', data.turnUsage.outputTokens]);
80
+ rows.push(['Requests', data.turnUsage.requests]);
81
+ rows.push(['Tool Calls', data.turnUsage.toolCalls]);
82
+ rows.push(['Duration Seconds', data.turnUsage.durationSeconds]);
83
+ rows.push([]);
84
+ }
85
+ rows.push(['Distribution']);
86
+ rows.push(['Category', 'Tokens']);
87
+ for (const category of data.distribution?.children ?? []) {
88
+ rows.push([category.name, category.value]);
89
+ }
90
+ rows.push([]);
91
+ if (data.perRequestUsage.length > 0) {
92
+ rows.push(['Per Request Usage']);
93
+ rows.push([
94
+ 'Request #',
95
+ 'Input Tokens',
96
+ 'Output Tokens',
97
+ 'Duration Ms',
98
+ 'Tool Names',
99
+ 'Timestamp',
100
+ 'Turn ID',
101
+ ]);
102
+ for (const request of data.perRequestUsage) {
103
+ rows.push([
104
+ request.requestNum,
105
+ request.inputTokens,
106
+ request.outputTokens,
107
+ request.durationMs,
108
+ request.toolNames.join('; '),
109
+ request.timestamp ?? '',
110
+ request.turnId ?? '',
111
+ ]);
112
+ }
113
+ }
114
+ const csv = rows.map(row => row.map(csvCell).join(',')).join('\n');
115
+ const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
116
+ const url = URL.createObjectURL(blob);
117
+ const link = document.createElement('a');
118
+ link.href = url;
119
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
120
+ link.download = `context-usage-${data.agentId}-${ts}.csv`;
121
+ link.style.display = 'none';
122
+ document.body.appendChild(link);
123
+ link.click();
124
+ document.body.removeChild(link);
125
+ URL.revokeObjectURL(url);
126
+ }
42
127
  /**
43
128
  * Get icon for context category
44
129
  */
@@ -59,56 +144,17 @@ function getCategoryIcon(name) {
59
144
  return ClockIcon;
60
145
  }
61
146
  }
62
- const RETRY_INTERVAL_SECONDS = 5;
63
- /**
64
- * Get the API base URL for fetching context data.
65
- * If apiBase prop is provided, use it.
66
- * Otherwise, fall back to localhost for local development.
67
- */
68
- function getApiBase(apiBase) {
69
- if (apiBase) {
70
- return apiBase;
71
- }
72
- if (typeof window === 'undefined') {
73
- return '';
74
- }
75
- const host = window.location.hostname;
76
- return host === 'localhost' || host === '127.0.0.1'
77
- ? 'http://127.0.0.1:8765'
78
- : '';
79
- }
80
147
  /**
81
148
  * ContextPanel component - unified context usage display.
82
149
  */
83
- export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView = 'overview', chartHeight = '200px', }) {
150
+ export function ContextPanel({ agentId, apiBase, liveData, messageCount = 0, defaultView = 'overview', chartHeight = '200px', }) {
84
151
  const [viewMode, setViewMode] = useState(defaultView);
85
152
  const [showDetails, setShowDetails] = useState(false);
86
- const [retryCountdown, setRetryCountdown] = useState(RETRY_INTERVAL_SECONDS);
87
- const { data: snapshotData, isLoading, error, refetch, } = useQuery({
88
- queryKey: ['context-snapshot', agentId, apiBase],
89
- queryFn: async () => {
90
- const base = getApiBase(apiBase);
91
- const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/context-snapshot`);
92
- if (!response.ok) {
93
- throw new Error('Failed to fetch context snapshot');
94
- }
95
- return response.json();
96
- },
97
- refetchInterval: RETRY_INTERVAL_SECONDS * 1000,
98
- refetchOnMount: 'always',
99
- staleTime: 0,
100
- });
101
- useEffect(() => {
102
- if (!error) {
103
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
104
- return;
105
- }
106
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
107
- const timer = window.setInterval(() => {
108
- setRetryCountdown(prev => prev <= 1 ? RETRY_INTERVAL_SECONDS : prev - 1);
109
- }, 1000);
110
- return () => window.clearInterval(timer);
111
- }, [error]);
153
+ const hasLiveData = liveData !== undefined;
154
+ // REST polling removed data comes exclusively via WS `agent.snapshot`.
155
+ const snapshotData = liveData;
156
+ const showLoading = !hasLiveData;
157
+ const hasError = false;
112
158
  // Build historic usage chart data from perRequestUsage
113
159
  const historyChartOption = useMemo(() => {
114
160
  if (!snapshotData?.perRequestUsage ||
@@ -251,7 +297,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
251
297
  };
252
298
  // eslint-disable-next-line react-hooks/exhaustive-deps
253
299
  }, [snapshotData?.distribution]);
254
- if (isLoading) {
300
+ if (showLoading) {
255
301
  return (_jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
256
302
  fontSize: 1,
257
303
  fontWeight: 'semibold',
@@ -268,7 +314,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
268
314
  gap: 2,
269
315
  }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading context details..." })] })] }));
270
316
  }
271
- if (error || !snapshotData) {
317
+ if (hasError || !snapshotData) {
272
318
  return (_jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
273
319
  fontSize: 1,
274
320
  fontWeight: 'semibold',
@@ -280,19 +326,13 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
280
326
  borderRadius: 2,
281
327
  border: '1px solid',
282
328
  borderColor: 'attention.muted',
283
- }, children: _jsxs(Box, { sx: {
284
- display: 'flex',
285
- alignItems: 'center',
286
- justifyContent: 'space-between',
287
- gap: 2,
288
- }, children: [_jsxs(Text, { sx: { fontSize: 1, color: 'attention.fg' }, children: ["Service not available for context usage. Retrying in", ' ', retryCountdown, " second", retryCountdown === 1 ? '' : 's', "..."] }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
289
- setRetryCountdown(RETRY_INTERVAL_SECONDS);
290
- void refetch();
291
- }, children: "Retry now" })] }) })] }));
329
+ }, children: _jsx(Text, { sx: { fontSize: 1, color: 'attention.fg' }, children: "Waiting for context data from WebSocket stream..." }) })] }));
292
330
  }
293
331
  const { totalTokens, contextWindow, sessionUsage, turnUsage, distribution } = snapshotData;
332
+ const sentMessageCount = messageCount > 0
333
+ ? messageCount
334
+ : Math.max(sessionUsage?.turns ?? 0, snapshotData.perRequestUsage?.length > 0 ? 1 : 0);
294
335
  const hasDistributionData = distribution?.children && distribution.children.length > 0;
295
- const hasHistoryData = snapshotData.perRequestUsage && snapshotData.perRequestUsage.length > 0;
296
336
  return (_jsxs(Box, { children: [_jsxs(Box, { sx: {
297
337
  display: 'flex',
298
338
  justifyContent: 'space-between',
@@ -302,7 +342,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
302
342
  fontSize: 1,
303
343
  fontWeight: 'semibold',
304
344
  color: 'fg.muted',
305
- }, children: "Context Usage" }), messageCount > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [messageCount, " ", messageCount === 1 ? 'message' : 'messages'] }))] }), _jsxs(Box, { sx: {
345
+ }, children: "Context Usage" }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [sentMessageCount > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [sentMessageCount, ' ', sentMessageCount === 1 ? 'message sent' : 'messages sent'] })), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => downloadContextUsageAsCSV(snapshotData), children: "Download" })] })] }), _jsxs(Box, { sx: {
306
346
  p: 3,
307
347
  bg: 'canvas.subtle',
308
348
  borderRadius: 2,
@@ -337,7 +377,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
337
377
  }, children: [_jsxs(SegmentedControl, { "aria-label": "View mode", size: "small", onChange: index => {
338
378
  const modes = ['overview', 'distribution', 'history'];
339
379
  setViewMode(modes[index]);
340
- }, children: [_jsx(SegmentedControl.Button, { selected: viewMode === 'overview', leadingIcon: ListUnorderedIcon, children: "Overview" }), _jsx(SegmentedControl.Button, { selected: viewMode === 'distribution', leadingIcon: GraphIcon, disabled: !hasDistributionData, children: "Distribution" }), _jsx(SegmentedControl.Button, { selected: viewMode === 'history', leadingIcon: ClockIcon, disabled: !hasHistoryData, children: "History" })] }), viewMode === 'overview' && (_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowDetails(!showDetails), children: showDetails ? 'Less' : 'More' }))] }), viewMode === 'overview' && (_jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [hasDistributionData &&
380
+ }, children: [_jsx(SegmentedControl.IconButton, { "aria-label": "Overview", selected: viewMode === 'overview', icon: ListUnorderedIcon }), _jsx(SegmentedControl.IconButton, { "aria-label": "Distribution", selected: viewMode === 'distribution', icon: AppsIcon, disabled: !hasDistributionData }), _jsx(SegmentedControl.IconButton, { "aria-label": "History", selected: viewMode === 'history', icon: GraphIcon })] }), viewMode === 'overview' && (_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowDetails(!showDetails), children: showDetails ? 'Less' : 'More' }))] }), viewMode === 'overview' && (_jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [hasDistributionData &&
341
381
  distribution.children.map(category => {
342
382
  const CategoryIcon = getCategoryIcon(category.name);
343
383
  const categoryPercent = (category.value / contextWindow) * 100;
@@ -384,6 +424,6 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
384
424
  py: 1,
385
425
  borderBottom: idx < 9 ? '1px solid' : 'none',
386
426
  borderColor: 'border.muted',
387
- }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', minWidth: 30 }, children: ["#", req.requestNum] }), _jsxs(Text, { sx: { color: '#3B82F6' }, children: ["\u2193", formatTokens(req.inputTokens)] }), _jsxs(Text, { sx: { color: '#10B981' }, children: ["\u2191", formatTokens(req.outputTokens)] }), req.toolNames.length > 0 && (_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["\uD83D\uDD27 ", req.toolNames.join(', ')] }))] }, req.requestNum))) }))] }))] })] }));
427
+ }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', minWidth: 30 }, children: ["#", req.requestNum] }), _jsxs(Text, { sx: { color: '#3B82F6' }, children: ["\u2193", formatTokens(req.inputTokens)] }), _jsxs(Text, { sx: { color: '#10B981' }, children: ["\u2191", formatTokens(req.outputTokens)] }), req.toolNames.length > 0 && (_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["\uD83D\uDD27 ", req.toolNames.join(', ')] }))] }, req.requestNum))) }))] })), viewMode === 'history' && !historyChartOption && (_jsx(Box, { sx: { py: 3 }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No history" }) }))] })] }));
388
428
  }
389
429
  export default ContextPanel;
@@ -25,9 +25,11 @@ export interface ContextDetailsResponse {
25
25
  export interface ContextUsageProps {
26
26
  /** Agent ID for fetching context details (required) */
27
27
  agentId: string;
28
+ /** Optional base URL override (defaults to local 8765 or same-origin) */
29
+ baseUrl?: string;
28
30
  }
29
31
  /**
30
32
  * ContextUsage component displays token usage breakdown by category.
31
33
  */
32
- export declare function ContextUsage({ agentId }: ContextUsageProps): import("react/jsx-runtime").JSX.Element;
34
+ export declare function ContextUsage({ agentId, baseUrl }: ContextUsageProps): import("react/jsx-runtime").JSX.Element;
33
35
  export default ContextUsage;
@@ -52,11 +52,11 @@ function getCategoryIcon(name) {
52
52
  /**
53
53
  * ContextUsage component displays token usage breakdown by category.
54
54
  */
55
- export function ContextUsage({ agentId }) {
55
+ export function ContextUsage({ agentId, baseUrl }) {
56
56
  const { data: contextData, isLoading, error, } = useQuery({
57
- queryKey: ['context-details', agentId],
57
+ queryKey: ['context-details', agentId, baseUrl],
58
58
  queryFn: async () => {
59
- const apiBase = getLocalApiBase();
59
+ const apiBase = baseUrl || getLocalApiBase();
60
60
  const response = await fetch(`${apiBase}/api/v1/configure/agents/${encodeURIComponent(agentId)}/context-details`);
61
61
  if (!response.ok) {
62
62
  throw new Error('Failed to fetch context details');
@@ -3,8 +3,8 @@
3
3
  */
4
4
  export interface CostUsageResponse {
5
5
  agentId: string;
6
- /** Cost for the current run in USD */
7
- currentRunCostUsd: number;
6
+ /** Cost for the last completed turn in USD */
7
+ lastTurnCostUsd: number;
8
8
  /** Total cumulative cost in USD */
9
9
  cumulativeCostUsd: number;
10
10
  /** Per-run budget limit (from guardrails) */
@@ -23,15 +23,21 @@ export interface CostUsageResponse {
23
23
  costUsd: number;
24
24
  requests: number;
25
25
  }>;
26
+ /** Optional run traces with pricing resolution info */
27
+ runs?: Array<{
28
+ pricingResolved: boolean;
29
+ }>;
26
30
  }
27
31
  export interface CostTrackerProps {
28
32
  /** Agent ID for fetching cost data */
29
33
  agentId: string;
30
34
  /** Compact mode — show only the summary bar */
31
35
  compact?: boolean;
36
+ /** Live cost data pushed by websocket (single source of truth). */
37
+ liveData?: CostUsageResponse | null;
32
38
  }
33
39
  /**
34
40
  * Displays running cost and budget utilization for an agent.
35
41
  */
36
- export declare function CostTracker({ agentId, compact }: CostTrackerProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function CostTracker({ agentId: _agentId, compact, liveData, }: CostTrackerProps): import("react/jsx-runtime").JSX.Element;
37
43
  export default CostTracker;