@datalayer/agent-runtimes 1.0.4 → 1.0.5

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 (267) hide show
  1. package/README.md +34 -0
  2. package/lib/App.js +1 -1
  3. package/lib/agents/AgentDetails.d.ts +22 -1
  4. package/lib/agents/AgentDetails.js +34 -47
  5. package/lib/api/index.d.ts +0 -1
  6. package/lib/api/index.js +4 -2
  7. package/lib/chat/Chat.d.ts +5 -106
  8. package/lib/chat/Chat.js +4 -4
  9. package/lib/chat/ChatFloating.d.ts +7 -140
  10. package/lib/chat/ChatFloating.js +2 -2
  11. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  12. package/lib/chat/ChatPopupStandalone.js +3 -3
  13. package/lib/chat/ChatSidebar.d.ts +4 -69
  14. package/lib/chat/ChatSidebar.js +2 -2
  15. package/lib/chat/ChatStandalone.d.ts +4 -54
  16. package/lib/chat/ChatStandalone.js +3 -3
  17. package/lib/chat/base/ChatBase.js +1083 -157
  18. package/lib/chat/header/ChatHeaderBase.d.ts +11 -6
  19. package/lib/chat/header/ChatHeaderBase.js +18 -16
  20. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  21. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  22. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  23. package/lib/chat/indicators/SandboxStatusIndicator.js +9 -9
  24. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  25. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  26. package/lib/chat/indicators/index.d.ts +1 -0
  27. package/lib/chat/indicators/index.js +1 -0
  28. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  29. package/lib/chat/messages/ChatMessageList.js +108 -113
  30. package/lib/chat/prompt/InputFooter.d.ts +19 -6
  31. package/lib/chat/prompt/InputFooter.js +71 -18
  32. package/lib/chat/prompt/InputPrompt.d.ts +3 -1
  33. package/lib/chat/prompt/InputPrompt.js +4 -4
  34. package/lib/chat/prompt/InputPromptFooter.js +1 -1
  35. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  36. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  37. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  38. package/lib/chat/prompt/InputPromptText.js +2 -2
  39. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  40. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  41. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  42. package/lib/chat/usage/TokenUsageBar.js +20 -2
  43. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  44. package/lib/client/AgentRuntimesClientContext.js +55 -0
  45. package/lib/client/AgentsMixin.d.ts +0 -18
  46. package/lib/client/AgentsMixin.js +6 -30
  47. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  48. package/lib/client/IAgentRuntimesClient.js +5 -0
  49. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  50. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  51. package/lib/client/index.d.ts +4 -1
  52. package/lib/client/index.js +3 -1
  53. package/lib/components/NotificationEventCard.js +5 -1
  54. package/lib/config/AgentConfiguration.js +3 -3
  55. package/lib/context/ContextDistribution.d.ts +3 -1
  56. package/lib/context/ContextDistribution.js +8 -27
  57. package/lib/context/ContextInspector.d.ts +3 -1
  58. package/lib/context/ContextInspector.js +19 -67
  59. package/lib/context/ContextPanel.d.ts +3 -1
  60. package/lib/context/ContextPanel.js +104 -64
  61. package/lib/context/ContextUsage.d.ts +3 -1
  62. package/lib/context/ContextUsage.js +3 -3
  63. package/lib/context/CostTracker.d.ts +9 -3
  64. package/lib/context/CostTracker.js +26 -47
  65. package/lib/context/CostUsageChart.d.ts +12 -0
  66. package/lib/context/CostUsageChart.js +378 -0
  67. package/lib/context/GraphFlowChart.d.ts +16 -0
  68. package/lib/context/GraphFlowChart.js +182 -0
  69. package/lib/context/TokenUsageChart.d.ts +8 -1
  70. package/lib/context/TokenUsageChart.js +349 -211
  71. package/lib/context/TurnGraphChart.d.ts +39 -0
  72. package/lib/context/TurnGraphChart.js +538 -0
  73. package/lib/context/otelWsPool.d.ts +20 -0
  74. package/lib/context/otelWsPool.js +69 -0
  75. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  76. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  77. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  78. package/lib/examples/A2UiContactCardExample.js +154 -411
  79. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  80. package/lib/examples/A2UiRestaurantExample.js +114 -212
  81. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  82. package/lib/examples/A2UiViewerExample.js +283 -532
  83. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  84. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  85. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  86. package/lib/examples/AgentCheckpointsExample.js +13 -27
  87. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  88. package/lib/examples/AgentCodemodeExample.js +591 -169
  89. package/lib/examples/AgentEvalsExample.js +12 -16
  90. package/lib/examples/AgentGuardrailsExample.js +370 -64
  91. package/lib/examples/AgentHooksExample.d.ts +3 -0
  92. package/lib/examples/AgentHooksExample.js +104 -0
  93. package/lib/examples/AgentMCPExample.d.ts +3 -0
  94. package/lib/examples/AgentMCPExample.js +480 -0
  95. package/lib/examples/AgentMemoryExample.js +13 -17
  96. package/lib/examples/AgentMonitoringExample.js +260 -199
  97. package/lib/examples/AgentNotificationsExample.js +49 -17
  98. package/lib/examples/AgentOtelExample.js +2 -3
  99. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  100. package/lib/examples/AgentOutputsExample.js +382 -81
  101. package/lib/examples/AgentParametersExample.d.ts +3 -0
  102. package/lib/examples/AgentParametersExample.js +246 -0
  103. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  104. package/lib/examples/AgentSandboxExample.js +68 -40
  105. package/lib/examples/AgentSkillsExample.js +91 -99
  106. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  107. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  108. package/lib/examples/AgentSubagentsExample.js +228 -0
  109. package/lib/examples/AgentToolApprovalsExample.js +29 -557
  110. package/lib/examples/AgentTriggersExample.js +819 -565
  111. package/lib/examples/ChatCustomExample.js +11 -24
  112. package/lib/examples/ChatExample.js +7 -24
  113. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  114. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  115. package/lib/examples/HomeExample.d.ts +15 -0
  116. package/lib/examples/HomeExample.js +77 -0
  117. package/lib/examples/Lexical2Example.js +4 -2
  118. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  119. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  120. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  121. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  122. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  123. package/lib/examples/NotebookAgentExample.js +192 -0
  124. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  125. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  126. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  127. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  128. package/lib/examples/NotebookExample.d.ts +4 -7
  129. package/lib/examples/NotebookExample.js +14 -146
  130. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  131. package/lib/examples/components/AuthRequiredView.js +33 -0
  132. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  133. package/lib/examples/components/ExampleWrapper.js +25 -6
  134. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  135. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  136. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  137. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  138. package/lib/examples/components/index.d.ts +3 -0
  139. package/lib/examples/components/index.js +4 -0
  140. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  142. package/lib/examples/example-selector.d.ts +17 -4
  143. package/lib/examples/example-selector.js +107 -41
  144. package/lib/examples/index.d.ts +9 -6
  145. package/lib/examples/index.js +9 -6
  146. package/lib/examples/main.js +217 -27
  147. package/lib/examples/utils/a2ui.d.ts +18 -0
  148. package/lib/examples/utils/a2ui.js +69 -0
  149. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  150. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  151. package/lib/examples/utils/agentId.d.ts +18 -0
  152. package/lib/examples/utils/agentId.js +54 -0
  153. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  154. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  155. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  156. package/lib/examples/utils/agents/stock-market.json +11 -11
  157. package/lib/examples/utils/examplesStore.js +82 -27
  158. package/lib/hooks/index.d.ts +8 -8
  159. package/lib/hooks/index.js +7 -7
  160. package/lib/hooks/useA2A.d.ts +2 -3
  161. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  162. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  163. package/lib/hooks/useAcp.d.ts +1 -2
  164. package/lib/hooks/useAgUi.d.ts +1 -1
  165. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  166. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  167. package/lib/hooks/useAgentsCatalog.js +1 -1
  168. package/lib/hooks/useAgentsService.d.ts +2 -2
  169. package/lib/hooks/useAgentsService.js +7 -7
  170. package/lib/hooks/useCheckpoints.js +1 -1
  171. package/lib/hooks/useConfig.d.ts +4 -1
  172. package/lib/hooks/useConfig.js +10 -3
  173. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  174. package/lib/hooks/useContextSnapshot.js +9 -37
  175. package/lib/hooks/useMonitoring.js +3 -0
  176. package/lib/hooks/useSandbox.d.ts +20 -8
  177. package/lib/hooks/useSandbox.js +105 -40
  178. package/lib/hooks/useSkills.d.ts +23 -5
  179. package/lib/hooks/useSkills.js +94 -39
  180. package/lib/hooks/useToolApprovals.d.ts +60 -36
  181. package/lib/hooks/useToolApprovals.js +318 -69
  182. package/lib/hooks/useVercelAI.d.ts +1 -1
  183. package/lib/index.d.ts +2 -1
  184. package/lib/index.js +1 -0
  185. package/lib/inference/index.d.ts +0 -1
  186. package/lib/middleware/index.d.ts +0 -1
  187. package/lib/protocols/AGUIAdapter.js +6 -0
  188. package/lib/protocols/VercelAIAdapter.d.ts +7 -0
  189. package/lib/protocols/VercelAIAdapter.js +59 -7
  190. package/lib/specs/agents/agents.d.ts +10 -0
  191. package/lib/specs/agents/agents.js +2139 -262
  192. package/lib/specs/agents/index.js +3 -1
  193. package/lib/specs/envvars.d.ts +1 -0
  194. package/lib/specs/envvars.js +38 -20
  195. package/lib/specs/evals.js +6 -6
  196. package/lib/specs/events.d.ts +3 -10
  197. package/lib/specs/events.js +127 -84
  198. package/lib/specs/frontendTools.js +2 -2
  199. package/lib/specs/guardrails.d.ts +0 -7
  200. package/lib/specs/guardrails.js +240 -159
  201. package/lib/specs/index.d.ts +1 -0
  202. package/lib/specs/index.js +1 -0
  203. package/lib/specs/mcpServers.js +35 -6
  204. package/lib/specs/memory.d.ts +0 -2
  205. package/lib/specs/memory.js +4 -17
  206. package/lib/specs/models.js +25 -5
  207. package/lib/specs/notifications.js +102 -18
  208. package/lib/specs/outputs.js +15 -9
  209. package/lib/specs/personas.d.ts +41 -0
  210. package/lib/specs/personas.js +168 -0
  211. package/lib/specs/skills.d.ts +2 -1
  212. package/lib/specs/skills.js +41 -23
  213. package/lib/specs/teams/index.js +3 -1
  214. package/lib/specs/teams/teams.js +468 -348
  215. package/lib/specs/tools.js +4 -4
  216. package/lib/specs/triggers.js +61 -11
  217. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  218. package/lib/stores/agentRuntimeStore.js +636 -0
  219. package/lib/stores/index.d.ts +1 -1
  220. package/lib/stores/index.js +1 -1
  221. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  222. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  223. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  224. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  225. package/lib/tools/index.d.ts +0 -2
  226. package/lib/tools/index.js +0 -1
  227. package/lib/types/agentspecs.d.ts +50 -1
  228. package/lib/types/chat.d.ts +309 -8
  229. package/lib/types/context.d.ts +27 -0
  230. package/lib/types/cost.d.ts +2 -2
  231. package/lib/types/index.d.ts +2 -0
  232. package/lib/types/index.js +2 -0
  233. package/lib/types/mcp.d.ts +8 -0
  234. package/lib/types/models.d.ts +2 -2
  235. package/lib/types/personas.d.ts +25 -0
  236. package/lib/types/personas.js +5 -0
  237. package/lib/types/skills.d.ts +43 -1
  238. package/lib/types/stream.d.ts +110 -0
  239. package/lib/types/stream.js +36 -0
  240. package/lib/utils/utils.d.ts +9 -5
  241. package/lib/utils/utils.js +9 -5
  242. package/package.json +13 -9
  243. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  244. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  245. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  246. package/scripts/codegen/generate_agents.py +102 -6
  247. package/scripts/codegen/generate_events.py +35 -13
  248. package/scripts/codegen/generate_personas.py +319 -0
  249. package/scripts/codegen/generate_skills.py +9 -9
  250. package/scripts/sync-jupyter.sh +26 -7
  251. package/lib/api/tool-approvals.d.ts +0 -62
  252. package/lib/api/tool-approvals.js +0 -145
  253. package/lib/examples/LexicalSidebarExample.js +0 -163
  254. package/lib/examples/NotebookSidebarExample.js +0 -119
  255. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  256. package/lib/examples/NotebookSimpleExample.js +0 -22
  257. package/lib/examples/ag-ui/index.d.ts +0 -10
  258. package/lib/examples/ag-ui/index.js +0 -16
  259. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  260. package/lib/hooks/useAgentsRegistry.js +0 -20
  261. package/lib/stores/agentsStore.d.ts +0 -123
  262. package/lib/stores/agentsStore.js +0 -270
  263. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  264. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  265. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  266. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  267. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -18,28 +18,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
18
  import { useEffect, useState, useCallback, useRef } from 'react';
19
19
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
20
20
  import { Text, Button, Spinner, TextInput, Heading, Label, Flash, } from '@primer/react';
21
- import { SearchIcon, DatabaseIcon, SignOutIcon, } from '@primer/octicons-react';
21
+ import { SearchIcon, DatabaseIcon } from '@primer/octicons-react';
22
22
  import { Box } from '@datalayer/primer-addons';
23
- import { ErrorView } from './components';
23
+ import { AuthRequiredView, ErrorView } from './components';
24
24
  import { ThemedProvider } from './utils/themedProvider';
25
+ import { uniqueAgentId } from './utils/agentId';
25
26
  const queryClient = new QueryClient();
26
27
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
27
- import { SignInSimple } from '@datalayer/core/lib/views/iam';
28
- import { UserBadge } from '@datalayer/core/lib/views/profile';
29
28
  import { Chat } from '../chat';
30
- import { useAgents } from '../hooks/useAgents';
29
+ import { useAgentRuntimes } from '../hooks/useAgentRuntimes';
31
30
  // ─── Constants ─────────────────────────────────────────────────────────────
32
31
  const AGENT_NAME = 'memory-demo-agent';
33
32
  const AGENT_SPEC_ID = 'monitor-sales-kpis'; // uses mem0 memory
34
33
  // ─── Inner component (rendered after auth) ─────────────────────────────────
35
34
  const AgentMemoryInner = ({ onLogout }) => {
36
35
  const { token } = useSimpleAuthStore();
37
- const { runtime, status: runtimeStatus, isReady, error: hookError, } = useAgents({
36
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
37
+ const { runtime, status: runtimeStatus, isReady, error: hookError, } = useAgentRuntimes({
38
38
  agentSpecId: AGENT_SPEC_ID,
39
39
  autoStart: true,
40
40
  agentConfig: {
41
- name: AGENT_NAME,
42
- protocol: 'ag-ui',
41
+ name: agentName,
42
+ model: 'bedrock:us.anthropic.claude-3-5-haiku-20241022-v1:0',
43
+ protocol: 'vercel-ai',
43
44
  description: 'Agent with Mem0 persistent memory',
44
45
  },
45
46
  });
@@ -133,12 +134,12 @@ const AgentMemoryInner = ({ onLogout }) => {
133
134
  borderBottom: '1px solid',
134
135
  borderColor: 'border.default',
135
136
  flexShrink: 0,
136
- }, children: [_jsx(DatabaseIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Durable Memory \u2014 ", podName] }), token && _jsx(UserBadge, { token: token, variant: "small" }), _jsx(Button, { size: "small", variant: "invisible", onClick: onLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] }), _jsxs(Box, { sx: { display: 'flex', flex: 1, minHeight: 0 }, children: [_jsx(Box, { sx: {
137
+ }, children: [_jsx(DatabaseIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Durable Memory \u2014 ", podName] })] }), _jsxs(Box, { sx: { display: 'flex', flex: 1, minHeight: 0 }, children: [_jsx(Box, { sx: {
137
138
  flex: 1,
138
139
  minWidth: 0,
139
140
  borderRight: '1px solid',
140
141
  borderColor: 'border.default',
141
- }, children: _jsx(Chat, { protocol: "ag-ui", baseUrl: agentBaseUrl, agentId: agentId, title: "Memory Agent", placeholder: "Chat \u2014 the agent remembers you across sessions\u2026", description: "Agent with Mem0 persistent memory", showHeader: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
142
+ }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Memory Agent", placeholder: "Chat \u2014 the agent remembers you across sessions\u2026", description: "Agent with Mem0 persistent memory", showHeader: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
142
143
  {
143
144
  title: 'Remember',
144
145
  message: 'My favourite colour is midnight blue.',
@@ -200,7 +201,7 @@ const syncTokenToIamStore = (token) => {
200
201
  };
201
202
  // ─── Main component with auth gate ─────────────────────────────────────────
202
203
  const AgentMemoryExample = () => {
203
- const { token, setAuth, clearAuth } = useSimpleAuthStore();
204
+ const { token, clearAuth } = useSimpleAuthStore();
204
205
  const hasSynced = useRef(false);
205
206
  useEffect(() => {
206
207
  if (token && !hasSynced.current) {
@@ -208,11 +209,6 @@ const AgentMemoryExample = () => {
208
209
  syncTokenToIamStore(token);
209
210
  }
210
211
  }, [token]);
211
- const handleSignIn = useCallback((newToken, handle) => {
212
- setAuth(newToken, handle);
213
- hasSynced.current = true;
214
- syncTokenToIamStore(newToken);
215
- }, [setAuth]);
216
212
  const handleLogout = useCallback(() => {
217
213
  clearAuth();
218
214
  hasSynced.current = false;
@@ -221,7 +217,7 @@ const AgentMemoryExample = () => {
221
217
  });
222
218
  }, [clearAuth]);
223
219
  if (!token) {
224
- return (_jsx(ThemedProvider, { children: _jsx(SignInSimple, { onSignIn: handleSignIn, onApiKeySignIn: apiKey => handleSignIn(apiKey, 'api-key-user'), title: "Memory Agent", description: "Sign in to use agents with persistent memory.", leadingIcon: _jsx(DatabaseIcon, { size: 24 }) }) }));
220
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
225
221
  }
226
222
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentMemoryInner, { onLogout: handleLogout }) }) }));
227
223
  };
@@ -16,142 +16,57 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
16
  /// <reference types="vite/client" />
17
17
  import { useEffect, useState, useCallback, useRef } from 'react';
18
18
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
19
- import { Text, Button, Spinner, Heading, Label } from '@primer/react';
20
- import { CheckCircleIcon, GraphIcon, SignOutIcon, } from '@primer/octicons-react';
19
+ import { Text, Spinner, Heading, Label } from '@primer/react';
20
+ import { GraphIcon } from '@primer/octicons-react';
21
21
  import { Box } from '@datalayer/primer-addons';
22
- import { ErrorView } from './components';
22
+ import { AuthRequiredView, ErrorView } from './components';
23
23
  import { ThemedProvider } from './utils/themedProvider';
24
+ import { uniqueAgentId } from './utils/agentId';
25
+ import { ContextPanel, } from '../context/ContextPanel';
26
+ import { CostTracker } from '../context/CostTracker';
27
+ import { CostUsageChart } from '../context/CostUsageChart';
28
+ import { TokenUsageChart } from '../context/TokenUsageChart';
29
+ import { GraphFlowChart } from '../context/GraphFlowChart';
30
+ import { TurnGraphChart } from '../context/TurnGraphChart';
31
+ import { useAIAgentsWebSocket } from '../hooks';
32
+ import { parseAgentStreamMessage } from '../types/stream';
33
+ import { useCoreStore } from '@datalayer/core/lib/state';
24
34
  const queryClient = new QueryClient();
25
35
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
26
- import { SignInSimple } from '@datalayer/core/lib/views/iam';
27
- import { UserBadge } from '@datalayer/core/lib/views/profile';
28
36
  import { Chat } from '../chat';
29
- import { useAgents } from '../hooks/useAgents';
30
37
  const AGENT_NAME = 'monitoring-demo-agent';
31
- const AGENT_SPEC_ID = 'monitor-sales-kpis';
32
- const clampPercent = (value) => Math.max(0, Math.min(100, value));
33
- const toNumber = (value, fallback) => {
34
- const n = Number(value);
35
- return Number.isFinite(n) ? n : fallback;
36
- };
37
- const randomOffset = (range) => (Math.random() - 0.5) * range;
38
- const createSyntheticSnapshot = (previous) => {
39
- const baseCpu = previous?.cpuPercent ?? 42;
40
- const baseMemory = previous?.memoryPercent ?? 57;
41
- const baseLatency = previous?.latencyMs ?? 320;
42
- const baseErrorRate = previous?.errorRatePercent ?? 1.6;
43
- const baseQueueDepth = previous?.queueDepth ?? 12;
44
- const cpuPercent = clampPercent(baseCpu + randomOffset(10));
45
- const memoryPercent = clampPercent(baseMemory + randomOffset(8));
46
- const latencyMs = Math.max(30, baseLatency + randomOffset(120));
47
- const errorRatePercent = clampPercent(baseErrorRate + randomOffset(0.8));
48
- const queueDepth = Math.max(0, Math.round(baseQueueDepth + randomOffset(8)));
49
- let status = 'healthy';
50
- if (errorRatePercent > 4 || latencyMs > 1200 || cpuPercent > 90) {
51
- status = 'critical';
52
- }
53
- else if (errorRatePercent > 2 || latencyMs > 700 || cpuPercent > 80) {
54
- status = 'degraded';
55
- }
56
- return {
57
- timestamp: new Date().toISOString(),
58
- cpuPercent,
59
- memoryPercent,
60
- latencyMs,
61
- errorRatePercent,
62
- queueDepth,
63
- status,
64
- };
65
- };
66
- const normalizeSnapshot = (raw, previous) => {
67
- if (!raw || typeof raw !== 'object') {
68
- return createSyntheticSnapshot(previous);
69
- }
70
- const data = raw;
71
- const snapshot = createSyntheticSnapshot(previous);
72
- const statusValue = String(data.status ?? snapshot.status).toLowerCase();
73
- const status = statusValue === 'healthy' ||
74
- statusValue === 'degraded' ||
75
- statusValue === 'critical'
76
- ? statusValue
77
- : 'unknown';
78
- return {
79
- timestamp: String(data.timestamp ?? new Date().toISOString()),
80
- cpuPercent: clampPercent(toNumber(data.cpuPercent ?? data.cpu, snapshot.cpuPercent)),
81
- memoryPercent: clampPercent(toNumber(data.memoryPercent ?? data.memory, snapshot.memoryPercent)),
82
- latencyMs: Math.max(0, toNumber(data.latencyMs ?? data.latency, snapshot.latencyMs)),
83
- errorRatePercent: clampPercent(toNumber(data.errorRatePercent ?? data.errorRate, snapshot.errorRatePercent)),
84
- queueDepth: Math.max(0, Math.round(toNumber(data.queueDepth, snapshot.queueDepth))),
85
- status,
86
- };
87
- };
88
- const normalizeAlert = (raw, index) => {
89
- if (!raw || typeof raw !== 'object') {
90
- return null;
91
- }
92
- const data = raw;
93
- const severityValue = String(data.severity ?? 'info').toLowerCase();
94
- const severity = severityValue === 'warning' || severityValue === 'critical'
95
- ? severityValue
96
- : 'info';
97
- return {
98
- id: String(data.id ?? `alert-${Date.now()}-${index}`),
99
- title: String(data.title ?? 'Agent alert detected'),
100
- severity,
101
- timestamp: String(data.timestamp ?? new Date().toISOString()),
102
- };
103
- };
104
- const statusVariant = (status) => {
105
- if (status === 'healthy')
106
- return 'success';
107
- if (status === 'degraded')
108
- return 'attention';
109
- if (status === 'critical')
110
- return 'danger';
111
- return 'secondary';
112
- };
113
- const alertVariant = (severity) => {
114
- if (severity === 'critical')
115
- return 'danger';
116
- if (severity === 'warning')
117
- return 'attention';
118
- return 'secondary';
119
- };
120
- const MetricRow = ({ label, value, percent }) => {
121
- return (_jsxs(Box, { sx: { mb: 2 }, children: [_jsxs(Box, { sx: {
122
- display: 'flex',
123
- justifyContent: 'space-between',
124
- alignItems: 'center',
125
- mb: 1,
126
- }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: label }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold' }, children: value })] }), _jsx(Box, { sx: {
127
- width: '100%',
128
- height: 8,
129
- bg: 'canvas.subtle',
130
- borderRadius: 6,
131
- overflow: 'hidden',
132
- }, children: _jsx(Box, { sx: {
133
- width: `${clampPercent(percent)}%`,
134
- height: '100%',
135
- bg: percent >= 85 ? 'danger.emphasis' : 'accent.emphasis',
136
- transition: 'width 300ms ease-out',
137
- } }) })] }));
138
- };
38
+ const AGENT_SPEC_ID = 'demo-monitoring';
39
+ const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
40
+ const OTEL_BASE_URL_ENV = import.meta.env.VITE_OTEL_BASE_URL;
41
+ const DATALAYER_RUN_URL_ENV = import.meta.env.DATALAYER_RUN_URL;
139
42
  const AgentMonitoringInner = ({ onLogout, }) => {
140
43
  const { token } = useSimpleAuthStore();
141
- const { runtime, status: runtimeStatus, isReady, error: hookError, } = useAgents({
142
- agentSpecId: AGENT_SPEC_ID,
143
- autoStart: true,
144
- agentConfig: {
145
- name: AGENT_NAME,
146
- protocol: 'ag-ui',
147
- description: 'Agent with runtime and alert monitoring signals',
148
- },
149
- });
150
- const [snapshots, setSnapshots] = useState([]);
44
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
45
+ const { configuration } = useCoreStore();
46
+ const [runtimeStatus, setRuntimeStatus] = useState('launching');
47
+ const [isReady, setIsReady] = useState(false);
48
+ const [hookError, setHookError] = useState(null);
49
+ const [agentId, setAgentId] = useState(agentName);
50
+ const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
151
51
  const [alerts, setAlerts] = useState([]);
152
- const agentBaseUrl = runtime?.agentBaseUrl || '';
153
- const agentId = runtime?.agentId || AGENT_NAME;
154
- const podName = runtime?.podName || '(launching…)';
52
+ const [liveContext, setLiveContext] = useState(undefined);
53
+ const [liveContextSnapshot, setLiveContextSnapshot] = useState(undefined);
54
+ const [liveCost, setLiveCost] = useState(undefined);
55
+ const [liveMcpStatus, setLiveMcpStatus] = useState(undefined);
56
+ const [monitorLastSnapshotAt, setMonitorLastSnapshotAt] = useState(null);
57
+ const [liveGraphTelemetry, setLiveGraphTelemetry] = useState(undefined);
58
+ const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
59
+ const otelBaseUrl = configuration?.otelRunUrl ||
60
+ configuration?.runUrl ||
61
+ OTEL_BASE_URL_ENV ||
62
+ DATALAYER_RUN_URL_ENV ||
63
+ 'https://prod1.datalayer.run';
64
+ const podName = agentId;
65
+ // The OTEL service_name resource attribute is 'agent-runtimes' (the
66
+ // application name), NOT the individual agent ID. Use the correct value
67
+ // so the TokenUsageChart WS filter and HTTP query match actual rows.
68
+ const otelServiceName = 'agent-runtimes';
69
+ const chatAuthToken = token === null ? undefined : token;
155
70
  const authFetch = useCallback((url, opts = {}) => fetch(url, {
156
71
  ...opts,
157
72
  headers: {
@@ -161,46 +76,137 @@ const AgentMonitoringInner = ({ onLogout, }) => {
161
76
  },
162
77
  }), [token]);
163
78
  useEffect(() => {
164
- if (!isReady || !agentBaseUrl)
165
- return;
166
- const poll = async () => {
167
- let nextSnapshot = null;
168
- let nextAlerts = null;
79
+ let isCancelled = false;
80
+ const createLocalAgent = async () => {
81
+ setRuntimeStatus('launching');
82
+ setIsReady(false);
83
+ setHookError(null);
84
+ setIsReconnectedAgent(false);
169
85
  try {
170
- const res = await authFetch(`${agentBaseUrl}/api/v1/agents/${agentId}/monitoring`);
171
- if (res.ok) {
172
- const data = await res.json();
173
- const rawSnapshot = data?.snapshot ?? data?.metrics ?? data;
174
- nextAlerts = Array.isArray(data?.alerts)
175
- ? data.alerts
176
- .map((a, i) => normalizeAlert(a, i))
177
- .filter((a) => !!a)
178
- .slice(0, 25)
179
- : [];
180
- setSnapshots(prev => {
181
- nextSnapshot = normalizeSnapshot(rawSnapshot, prev[0]);
182
- return [nextSnapshot, ...prev].slice(0, 40);
183
- });
184
- if (nextAlerts) {
185
- setAlerts(nextAlerts);
86
+ const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
87
+ method: 'POST',
88
+ body: JSON.stringify({
89
+ name: agentName,
90
+ description: 'MCP monitoring demo – web crawling via Tavily with live cost/token metrics',
91
+ agent_library: 'pydantic-ai',
92
+ transport: 'vercel-ai',
93
+ agent_spec_id: AGENT_SPEC_ID,
94
+ enable_skills: true,
95
+ tools: [],
96
+ }),
97
+ });
98
+ let resolvedAgentId = agentName;
99
+ let isAlreadyRunning = false;
100
+ if (response.ok) {
101
+ const data = await response.json();
102
+ resolvedAgentId = data?.id || agentName;
103
+ }
104
+ else {
105
+ const contentType = response.headers.get('content-type') || '';
106
+ let detail = '';
107
+ if (contentType.includes('application/json')) {
108
+ const data = await response.json().catch(() => null);
109
+ detail =
110
+ (typeof data?.detail === 'string' && data.detail) ||
111
+ (typeof data?.message === 'string' && data.message) ||
112
+ '';
113
+ }
114
+ else {
115
+ detail = await response.text();
116
+ }
117
+ if (response.status === 409 || /already exists/i.test(detail || '')) {
118
+ isAlreadyRunning = true;
119
+ }
120
+ else {
121
+ throw new Error(detail || `Failed to create local agent: ${response.status}`);
186
122
  }
187
- return;
123
+ }
124
+ if (!isCancelled) {
125
+ setAgentId(resolvedAgentId);
126
+ setIsReconnectedAgent(isAlreadyRunning);
127
+ setIsReady(true);
128
+ setRuntimeStatus('ready');
188
129
  }
189
130
  }
190
- catch {
191
- // Keep UI responsive with synthetic values when endpoint is unavailable.
192
- }
193
- setSnapshots(prev => {
194
- if (prev.length > 0) {
195
- return prev;
131
+ catch (error) {
132
+ if (!isCancelled) {
133
+ setHookError(error instanceof Error ? error.message : 'Agent failed to start');
134
+ setRuntimeStatus('error');
196
135
  }
197
- return [createSyntheticSnapshot()];
198
- });
136
+ }
199
137
  };
200
- poll();
201
- const interval = window.setInterval(poll, 10_000);
202
- return () => window.clearInterval(interval);
203
- }, [isReady, agentBaseUrl, agentId, authFetch]);
138
+ void createLocalAgent();
139
+ return () => {
140
+ isCancelled = true;
141
+ };
142
+ }, [agentBaseUrl, authFetch]);
143
+ const handleMonitoringStreamMessage = useCallback((message) => {
144
+ try {
145
+ const stream = parseAgentStreamMessage(message?.raw ?? message);
146
+ if (!stream || stream.type !== 'agent.snapshot') {
147
+ return;
148
+ }
149
+ const payload = stream.payload;
150
+ if (payload.contextSnapshot) {
151
+ setLiveContext(payload.contextSnapshot);
152
+ setLiveContextSnapshot(payload.contextSnapshot);
153
+ setMonitorLastSnapshotAt(Date.now());
154
+ }
155
+ if (payload.mcpStatus !== undefined) {
156
+ setLiveMcpStatus(payload.mcpStatus ?? undefined);
157
+ }
158
+ if (payload.graphTelemetry) {
159
+ setLiveGraphTelemetry(payload.graphTelemetry);
160
+ }
161
+ const snapshotCost = payload.contextSnapshot?.costUsage ?? payload.costUsage;
162
+ if (!snapshotCost) {
163
+ return;
164
+ }
165
+ setLiveCost({
166
+ agentId,
167
+ lastTurnCostUsd: Number(snapshotCost.lastTurnCostUsd ?? 0),
168
+ cumulativeCostUsd: Number(snapshotCost.cumulativeCostUsd ?? 0),
169
+ perRunBudgetUsd: snapshotCost.perRunBudgetUsd == null
170
+ ? null
171
+ : Number(snapshotCost.perRunBudgetUsd),
172
+ cumulativeBudgetUsd: snapshotCost.cumulativeBudgetUsd == null
173
+ ? null
174
+ : Number(snapshotCost.cumulativeBudgetUsd),
175
+ requestCount: Number(snapshotCost.requestCount ?? 0),
176
+ totalTokensUsed: Number(snapshotCost.totalTokensUsed ?? 0),
177
+ modelBreakdown: Array.isArray(snapshotCost.modelBreakdown)
178
+ ? snapshotCost.modelBreakdown.map(item => ({
179
+ model: String(item.model ?? 'unknown'),
180
+ inputTokens: Number(item.inputTokens ?? 0),
181
+ outputTokens: Number(item.outputTokens ?? 0),
182
+ costUsd: Number(item.costUsd ?? 0),
183
+ requests: Number(item.requests ?? 0),
184
+ }))
185
+ : [],
186
+ runs: Array.isArray(snapshotCost.runs)
187
+ ? snapshotCost.runs.map(item => ({
188
+ pricingResolved: Boolean(item.pricingResolved),
189
+ }))
190
+ : undefined,
191
+ });
192
+ }
193
+ catch {
194
+ // Ignore malformed stream payloads.
195
+ }
196
+ }, [agentId]);
197
+ const monitorSocket = useAIAgentsWebSocket({
198
+ enabled: isReady && Boolean(agentBaseUrl),
199
+ baseUrl: agentBaseUrl,
200
+ path: '/api/v1/tool-approvals/ws',
201
+ queryParams: { agent_id: agentId },
202
+ onMessage: handleMonitoringStreamMessage,
203
+ reconnectDelayMs: attempt => Math.min(1000 * 2 ** Math.max(0, attempt - 1), 10000),
204
+ });
205
+ useEffect(() => {
206
+ // Monitoring alerts endpoint is optional and may return 404 in local mode.
207
+ // Keep the UI quiet and rely on stream snapshots for now.
208
+ setAlerts([]);
209
+ }, [isReady, agentId]);
204
210
  if (!isReady && runtimeStatus !== 'error') {
205
211
  return (_jsxs(Box, { sx: {
206
212
  display: 'flex',
@@ -209,14 +215,11 @@ const AgentMonitoringInner = ({ onLogout, }) => {
209
215
  justifyContent: 'center',
210
216
  height: '100vh',
211
217
  gap: 3,
212
- }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: runtimeStatus === 'launching'
213
- ? 'Launching runtime for monitoring agent…'
214
- : 'Creating monitoring demo agent…' })] }));
218
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching local monitoring demo agent..." })] }));
215
219
  }
216
220
  if (runtimeStatus === 'error' || hookError) {
217
221
  return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
218
222
  }
219
- const latest = snapshots[0] ?? createSyntheticSnapshot();
220
223
  return (_jsxs(Box, { sx: {
221
224
  height: 'calc(100vh - 60px)',
222
225
  display: 'flex',
@@ -230,46 +233,109 @@ const AgentMonitoringInner = ({ onLogout, }) => {
230
233
  borderBottom: '1px solid',
231
234
  borderColor: 'border.default',
232
235
  flexShrink: 0,
233
- }, children: [_jsx(GraphIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Monitoring \u2014 ", podName] }), _jsx(Label, { variant: statusVariant(latest.status), size: "small", children: latest.status }), token && _jsx(UserBadge, { token: token, variant: "small" }), _jsx(Button, { size: "small", variant: "invisible", onClick: onLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "ag-ui", baseUrl: agentBaseUrl, agentId: agentId, title: "Monitoring Agent", placeholder: "Ask about performance, latency, and alert trends\u2026", description: `${alerts.length} active alert${alerts.length !== 1 ? 's' : ''}`, showHeader: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
236
+ }, children: [_jsx(GraphIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Monitoring \u2014 ", podName] }), isReconnectedAgent && (_jsx(Label, { variant: "secondary", size: "small", children: "Reconnected" })), _jsxs(Label, { variant: monitorSocket.connectionState === 'connected'
237
+ ? 'success'
238
+ : 'secondary', children: ["WS: ", monitorSocket.connectionState] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsxs(Box, { sx: {
239
+ width: 320,
240
+ minWidth: 280,
241
+ borderRight: '1px solid',
242
+ borderColor: 'border.default',
243
+ display: 'flex',
244
+ flexDirection: 'column',
245
+ overflow: 'auto',
246
+ '@media (max-width: 1680px)': {
247
+ width: 300,
248
+ minWidth: 260,
249
+ },
250
+ '@media (max-width: 1400px)': {
251
+ display: 'none',
252
+ },
253
+ }, children: [_jsxs(Box, { sx: {
254
+ p: 3,
255
+ borderBottom: '1px solid',
256
+ borderColor: 'border.default',
257
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Token Usage" }), _jsx(TokenUsageChart, { serviceName: otelServiceName, agentId: agentId, apiKey: token ?? undefined, runUrl: otelBaseUrl, liveSystemPromptTokens: liveContextSnapshot?.systemPromptTokens, liveUserMessageTokens: liveContextSnapshot?.userMessageTokens, liveAgentMessageTokens: liveContextSnapshot?.assistantMessageTokens, liveToolsUsageTokens: liveContextSnapshot?.toolTokens, liveTimestampMs: monitorLastSnapshotAt, height: 180 })] }), _jsxs(Box, { sx: {
258
+ p: 3,
259
+ borderBottom: '1px solid',
260
+ borderColor: 'border.default',
261
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Cost" }), _jsx(CostUsageChart, { serviceName: otelServiceName, agentId: agentId, apiKey: token ?? undefined, runUrl: otelBaseUrl, liveCumulativeUsd: liveCost?.cumulativeCostUsd, liveTimestampMs: monitorLastSnapshotAt, height: 180 })] }), _jsxs(Box, { sx: {
262
+ p: 3,
263
+ borderBottom: '1px solid',
264
+ borderColor: 'border.default',
265
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "LLM Cost Monitoring" }), liveCost ? (_jsx(CostTracker, { agentId: agentId, compact: false, liveData: liveCost })) : (_jsxs(Box, { children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Waiting for first websocket snapshot..." }), monitorSocket.lastClose?.detail && (_jsxs(Text, { sx: {
266
+ color: 'danger.fg',
267
+ fontSize: 0,
268
+ mt: 1,
269
+ display: 'block',
270
+ }, children: ["Last close: ", monitorSocket.lastClose.detail] }))] }))] })] }), _jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Monitoring Agent", placeholder: "Ask for cost, token usage, and turn-level monitoring insights...", description: `${alerts.length} active alert${alerts.length !== 1 ? 's' : ''}`, showHeader: true, showTokenUsage: true, showToolsMenu: true, showSkillsMenu: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
271
+ {
272
+ title: '▶ No-tool turn',
273
+ message: 'Briefly introduce yourself without calling any tool or skill — produces a linear Start → Model → Decision → End graph.',
274
+ },
234
275
  {
235
- title: 'Health summary',
236
- message: 'Summarize current agent health and key bottlenecks',
276
+ title: '🔍 Single tool call',
277
+ message: 'Use the Tavily web search tool to find the latest news about pydantic-graph. Make a single search call.',
237
278
  },
238
279
  {
239
- title: 'Alert triage',
240
- message: 'List critical alerts first and suggest immediate mitigations',
280
+ title: '🌀 Parallel tool fan-out',
281
+ message: 'Use Tavily to search the web in parallel for these three topics in the same turn: (1) OpenTelemetry traces, (2) agent observability, (3) LLM cost monitoring. Issue all three searches together so the turn graph fans out (Broadcast → Spread → Join).',
241
282
  },
242
- ], submitOnSuggestionClick: true }) }), _jsxs(Box, { sx: {
243
- width: 380,
283
+ {
284
+ title: '🧩 Skill call',
285
+ message: 'Use the datalayer-whoami skill to identify my profile, then summarize it.',
286
+ },
287
+ {
288
+ title: '😄 Joke skill',
289
+ message: 'Use the jokes skill to tell me a random dad joke, then wrap it in one-sentence commentary.',
290
+ },
291
+ {
292
+ title: '🧪 Mixed tools + skills',
293
+ message: 'In one turn: (a) use Tavily to search for "OTEL traces best practices", (b) call the datalayer-whoami skill, (c) call the jokes skill. Summarize all three results together. This should produce a Broadcast → three Spread nodes → Join in the Turn Execution Graph.',
294
+ },
295
+ {
296
+ title: 'Monitoring summary',
297
+ message: 'Summarize my current token usage, cost status, and recent turn activity.',
298
+ },
299
+ {
300
+ title: 'Turn usage analysis',
301
+ message: 'Analyze the last turn usage and explain which parts drove input and output tokens.',
302
+ },
303
+ ], submitOnSuggestionClick: true, contextSnapshot: liveContextSnapshot, mcpStatusData: liveMcpStatus }) }), _jsxs(Box, { sx: {
304
+ width: 360,
305
+ minWidth: 320,
244
306
  borderLeft: '1px solid',
245
307
  borderColor: 'border.default',
246
308
  display: 'flex',
247
309
  flexDirection: 'column',
248
310
  overflow: 'auto',
311
+ '@media (max-width: 1680px)': {
312
+ width: 340,
313
+ minWidth: 300,
314
+ },
315
+ '@media (max-width: 1100px)': {
316
+ width: 300,
317
+ minWidth: 260,
318
+ },
249
319
  }, children: [_jsxs(Box, { sx: {
250
320
  p: 3,
251
321
  borderBottom: '1px solid',
252
322
  borderColor: 'border.default',
253
- }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Live Metrics" }), _jsx(MetricRow, { label: "CPU", value: `${latest.cpuPercent.toFixed(1)}%`, percent: latest.cpuPercent }), _jsx(MetricRow, { label: "Memory", value: `${latest.memoryPercent.toFixed(1)}%`, percent: latest.memoryPercent }), _jsx(MetricRow, { label: "Latency", value: `${Math.round(latest.latencyMs)} ms`, percent: (latest.latencyMs / 2000) * 100 }), _jsx(MetricRow, { label: "Error Rate", value: `${latest.errorRatePercent.toFixed(2)}%`, percent: latest.errorRatePercent * 20 }), _jsx(MetricRow, { label: "Queue Depth", value: `${latest.queueDepth}`, percent: latest.queueDepth })] }), _jsxs(Box, { sx: { p: 3, flex: 1, overflow: 'auto' }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Recent Alerts" }), alerts.length === 0 ? (_jsxs(Box, { sx: {
254
- p: 2,
255
- border: '1px solid',
256
- borderColor: 'border.default',
257
- borderRadius: 2,
258
- display: 'flex',
259
- alignItems: 'center',
260
- gap: 2,
261
- }, children: [_jsx(CheckCircleIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No active alerts." })] })) : (alerts.map(alert => (_jsxs(Box, { sx: {
262
- p: 2,
263
- mb: 2,
264
- border: '1px solid',
265
- borderColor: 'border.default',
266
- borderRadius: 2,
267
- }, children: [_jsxs(Box, { sx: {
268
- display: 'flex',
269
- justifyContent: 'space-between',
270
- alignItems: 'center',
271
- mb: 1,
272
- }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: alert.title }), _jsx(Label, { size: "small", variant: alertVariant(alert.severity), children: alert.severity })] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: new Date(alert.timestamp).toLocaleString() })] }, alert.id))))] })] })] })] }));
323
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Turn and Session Usage" }), liveContext ? (_jsx(ContextPanel, { agentId: agentId, apiBase: agentBaseUrl, liveData: liveContext, defaultView: "overview", chartHeight: "160px" })) : (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Waiting for first websocket snapshot..." })), _jsxs(Text, { sx: { mt: 2, color: 'fg.muted', fontSize: 0 }, children: ["Live monitoring uses websocket snapshots only.", monitorLastSnapshotAt
324
+ ? ` Last snapshot ${new Date(monitorLastSnapshotAt).toLocaleTimeString()}.`
325
+ : '', monitorSocket.connectionState !== 'connected' &&
326
+ monitorSocket.reconnectAttempt > 0
327
+ ? ` Reconnect attempt ${monitorSocket.reconnectAttempt}.`
328
+ : ''] })] }), liveGraphTelemetry && (_jsxs(Box, { sx: {
329
+ p: 3,
330
+ borderBottom: '1px solid',
331
+ borderColor: 'border.default',
332
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Graph Execution (live)" }), _jsx(GraphFlowChart, { data: liveGraphTelemetry, height: 240 }), _jsxs(Text, { sx: { mt: 1, color: 'fg.muted', fontSize: 0 }, children: [liveGraphTelemetry.totalNodesExecuted, " node(s) executed across", ' ', liveGraphTelemetry.runCount, " run(s)", liveGraphTelemetry.totalDurationMs
333
+ ? ` — ${(liveGraphTelemetry.totalDurationMs / 1000).toFixed(2)}s total`
334
+ : ''] })] })), _jsxs(Box, { sx: {
335
+ p: 3,
336
+ borderBottom: '1px solid',
337
+ borderColor: 'border.default',
338
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Turn Execution Graph (OTEL traces)" }), _jsx(TurnGraphChart, { serviceName: otelServiceName, agentId: agentId, runUrl: otelBaseUrl, apiKey: token ?? undefined, autoRefreshMs: 10_000, height: 280 })] })] })] })] }));
273
339
  };
274
340
  const syncTokenToIamStore = (token) => {
275
341
  import('@datalayer/core/lib/state').then(({ iamStore }) => {
@@ -277,7 +343,7 @@ const syncTokenToIamStore = (token) => {
277
343
  });
278
344
  };
279
345
  const AgentMonitoringExample = () => {
280
- const { token, setAuth, clearAuth } = useSimpleAuthStore();
346
+ const { token, clearAuth } = useSimpleAuthStore();
281
347
  const hasSynced = useRef(false);
282
348
  useEffect(() => {
283
349
  if (token && !hasSynced.current) {
@@ -285,11 +351,6 @@ const AgentMonitoringExample = () => {
285
351
  syncTokenToIamStore(token);
286
352
  }
287
353
  }, [token]);
288
- const handleSignIn = useCallback((newToken, handle) => {
289
- setAuth(newToken, handle);
290
- hasSynced.current = true;
291
- syncTokenToIamStore(newToken);
292
- }, [setAuth]);
293
354
  const handleLogout = useCallback(() => {
294
355
  clearAuth();
295
356
  hasSynced.current = false;
@@ -298,7 +359,7 @@ const AgentMonitoringExample = () => {
298
359
  });
299
360
  }, [clearAuth]);
300
361
  if (!token) {
301
- return (_jsx(ThemedProvider, { children: _jsx(SignInSimple, { onSignIn: handleSignIn, onApiKeySignIn: apiKey => handleSignIn(apiKey, 'api-key-user'), title: "Agent Monitoring", description: "Sign in to monitor runtime health and alerts.", leadingIcon: _jsx(GraphIcon, { size: 24 }) }) }));
362
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
302
363
  }
303
364
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentMonitoringInner, { onLogout: handleLogout }) }) }));
304
365
  };