@datalayer/agent-runtimes 1.0.3 → 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 (275) hide show
  1. package/README.md +35 -119
  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 -104
  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 +1118 -141
  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 +110 -102
  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 +48 -19
  46. package/lib/client/AgentsMixin.js +115 -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 +55 -26
  54. package/lib/components/OutputCard.js +21 -7
  55. package/lib/components/ToolApprovalCard.js +20 -2
  56. package/lib/config/AgentConfiguration.js +3 -3
  57. package/lib/context/ContextDistribution.d.ts +3 -1
  58. package/lib/context/ContextDistribution.js +8 -27
  59. package/lib/context/ContextInspector.d.ts +3 -1
  60. package/lib/context/ContextInspector.js +19 -67
  61. package/lib/context/ContextPanel.d.ts +3 -1
  62. package/lib/context/ContextPanel.js +104 -64
  63. package/lib/context/ContextUsage.d.ts +3 -1
  64. package/lib/context/ContextUsage.js +3 -3
  65. package/lib/context/CostTracker.d.ts +9 -3
  66. package/lib/context/CostTracker.js +26 -47
  67. package/lib/context/CostUsageChart.d.ts +12 -0
  68. package/lib/context/CostUsageChart.js +378 -0
  69. package/lib/context/GraphFlowChart.d.ts +16 -0
  70. package/lib/context/GraphFlowChart.js +182 -0
  71. package/lib/context/TokenUsageChart.d.ts +8 -1
  72. package/lib/context/TokenUsageChart.js +349 -211
  73. package/lib/context/TurnGraphChart.d.ts +39 -0
  74. package/lib/context/TurnGraphChart.js +538 -0
  75. package/lib/context/otelWsPool.d.ts +20 -0
  76. package/lib/context/otelWsPool.js +69 -0
  77. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  78. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  79. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  80. package/lib/examples/A2UiContactCardExample.js +154 -411
  81. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  82. package/lib/examples/A2UiRestaurantExample.js +114 -212
  83. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  84. package/lib/examples/A2UiViewerExample.js +283 -532
  85. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  86. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  87. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  88. package/lib/examples/AgentCheckpointsExample.js +14 -34
  89. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  90. package/lib/examples/AgentCodemodeExample.js +591 -175
  91. package/lib/examples/AgentEvalsExample.js +13 -23
  92. package/lib/examples/AgentGuardrailsExample.js +371 -71
  93. package/lib/examples/AgentHooksExample.d.ts +3 -0
  94. package/lib/examples/AgentHooksExample.js +104 -0
  95. package/lib/examples/AgentMCPExample.d.ts +3 -0
  96. package/lib/examples/AgentMCPExample.js +480 -0
  97. package/lib/examples/AgentMemoryExample.js +14 -24
  98. package/lib/examples/AgentMonitoringExample.js +261 -206
  99. package/lib/examples/AgentNotificationsExample.js +50 -24
  100. package/lib/examples/AgentOtelExample.js +2 -3
  101. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  102. package/lib/examples/AgentOutputsExample.js +383 -88
  103. package/lib/examples/AgentParametersExample.d.ts +3 -0
  104. package/lib/examples/AgentParametersExample.js +246 -0
  105. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  106. package/lib/examples/AgentSandboxExample.js +69 -47
  107. package/lib/examples/AgentSkillsExample.js +92 -106
  108. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  109. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  110. package/lib/examples/AgentSubagentsExample.js +228 -0
  111. package/lib/examples/AgentToolApprovalsExample.js +30 -493
  112. package/lib/examples/AgentTriggersExample.js +1067 -246
  113. package/lib/examples/ChatCustomExample.js +11 -24
  114. package/lib/examples/ChatExample.js +9 -34
  115. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  116. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  117. package/lib/examples/HomeExample.d.ts +15 -0
  118. package/lib/examples/HomeExample.js +77 -0
  119. package/lib/examples/Lexical2Example.js +4 -2
  120. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  121. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  122. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  123. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  124. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  125. package/lib/examples/NotebookAgentExample.js +192 -0
  126. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  127. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  128. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  129. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  130. package/lib/examples/NotebookExample.d.ts +4 -7
  131. package/lib/examples/NotebookExample.js +14 -146
  132. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  133. package/lib/examples/components/AuthRequiredView.js +33 -0
  134. package/lib/examples/components/ErrorView.d.ts +14 -0
  135. package/lib/examples/components/ErrorView.js +20 -0
  136. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  137. package/lib/examples/components/ExampleWrapper.js +25 -6
  138. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  139. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  140. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  142. package/lib/examples/components/index.d.ts +5 -0
  143. package/lib/examples/components/index.js +5 -0
  144. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  145. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  146. package/lib/examples/example-selector.d.ts +17 -4
  147. package/lib/examples/example-selector.js +107 -41
  148. package/lib/examples/index.d.ts +9 -6
  149. package/lib/examples/index.js +9 -6
  150. package/lib/examples/main.d.ts +1 -0
  151. package/lib/examples/main.js +218 -27
  152. package/lib/examples/utils/a2ui.d.ts +18 -0
  153. package/lib/examples/utils/a2ui.js +69 -0
  154. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  155. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  156. package/lib/examples/utils/agentId.d.ts +18 -0
  157. package/lib/examples/utils/agentId.js +54 -0
  158. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  159. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  160. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  161. package/lib/examples/utils/agents/stock-market.json +11 -11
  162. package/lib/examples/utils/examplesStore.js +82 -27
  163. package/lib/hooks/index.d.ts +8 -8
  164. package/lib/hooks/index.js +7 -7
  165. package/lib/hooks/useA2A.d.ts +2 -3
  166. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  167. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  168. package/lib/hooks/useAcp.d.ts +1 -2
  169. package/lib/hooks/useAgUi.d.ts +1 -1
  170. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  171. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  172. package/lib/hooks/useAgentsCatalog.js +1 -1
  173. package/lib/hooks/useAgentsService.d.ts +2 -2
  174. package/lib/hooks/useAgentsService.js +7 -7
  175. package/lib/hooks/useCheckpoints.js +1 -1
  176. package/lib/hooks/useConfig.d.ts +4 -1
  177. package/lib/hooks/useConfig.js +10 -3
  178. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  179. package/lib/hooks/useContextSnapshot.js +9 -37
  180. package/lib/hooks/useMonitoring.js +3 -0
  181. package/lib/hooks/useSandbox.d.ts +20 -8
  182. package/lib/hooks/useSandbox.js +105 -40
  183. package/lib/hooks/useSkills.d.ts +23 -5
  184. package/lib/hooks/useSkills.js +94 -39
  185. package/lib/hooks/useToolApprovals.d.ts +60 -36
  186. package/lib/hooks/useToolApprovals.js +318 -69
  187. package/lib/hooks/useVercelAI.d.ts +1 -1
  188. package/lib/index.d.ts +2 -1
  189. package/lib/index.js +1 -0
  190. package/lib/inference/index.d.ts +0 -1
  191. package/lib/middleware/index.d.ts +0 -1
  192. package/lib/protocols/AGUIAdapter.js +6 -0
  193. package/lib/protocols/VercelAIAdapter.d.ts +9 -0
  194. package/lib/protocols/VercelAIAdapter.js +144 -26
  195. package/lib/shims/json5.d.ts +4 -0
  196. package/lib/shims/json5.js +8 -0
  197. package/lib/specs/agents/agents.d.ts +10 -0
  198. package/lib/specs/agents/agents.js +752 -24
  199. package/lib/specs/envvars.d.ts +1 -0
  200. package/lib/specs/envvars.js +11 -0
  201. package/lib/specs/events.d.ts +1 -0
  202. package/lib/specs/events.js +1 -0
  203. package/lib/specs/index.d.ts +1 -0
  204. package/lib/specs/index.js +1 -0
  205. package/lib/specs/personas.d.ts +41 -0
  206. package/lib/specs/personas.js +168 -0
  207. package/lib/specs/skills.d.ts +2 -1
  208. package/lib/specs/skills.js +23 -5
  209. package/lib/specs/tools.js +3 -0
  210. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  211. package/lib/stores/agentRuntimeStore.js +636 -0
  212. package/lib/stores/index.d.ts +1 -1
  213. package/lib/stores/index.js +1 -1
  214. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  215. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  216. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  217. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  218. package/lib/tools/index.d.ts +0 -2
  219. package/lib/tools/index.js +0 -1
  220. package/lib/types/agentspecs.d.ts +50 -1
  221. package/lib/types/chat.d.ts +309 -8
  222. package/lib/types/context.d.ts +27 -0
  223. package/lib/types/cost.d.ts +2 -2
  224. package/lib/types/index.d.ts +2 -0
  225. package/lib/types/index.js +2 -0
  226. package/lib/types/mcp.d.ts +8 -0
  227. package/lib/types/models.d.ts +2 -2
  228. package/lib/types/personas.d.ts +25 -0
  229. package/lib/types/personas.js +5 -0
  230. package/lib/types/skills.d.ts +43 -1
  231. package/lib/types/stream.d.ts +110 -0
  232. package/lib/types/stream.js +36 -0
  233. package/lib/types/tools.d.ts +2 -0
  234. package/lib/utils/utils.d.ts +9 -5
  235. package/lib/utils/utils.js +9 -5
  236. package/package.json +13 -9
  237. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  238. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  239. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  240. package/scripts/codegen/generate_agents.py +106 -7
  241. package/scripts/codegen/generate_events.py +47 -17
  242. package/scripts/codegen/generate_personas.py +319 -0
  243. package/scripts/codegen/generate_skills.py +9 -9
  244. package/scripts/codegen/generate_tools.py +20 -0
  245. package/scripts/sync-jupyter.sh +26 -7
  246. package/style/primer-primitives.css +1 -6
  247. package/lib/api/tool-approvals.d.ts +0 -62
  248. package/lib/api/tool-approvals.js +0 -145
  249. package/lib/examples/LexicalSidebarExample.js +0 -163
  250. package/lib/examples/NotebookSidebarExample.js +0 -119
  251. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  252. package/lib/examples/NotebookSimpleExample.js +0 -22
  253. package/lib/examples/ag-ui/index.d.ts +0 -10
  254. package/lib/examples/ag-ui/index.js +0 -16
  255. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  256. package/lib/hooks/useAgentsRegistry.js +0 -20
  257. package/lib/stores/agentsStore.d.ts +0 -123
  258. package/lib/stores/agentsStore.js +0 -270
  259. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  260. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  261. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  262. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  263. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  264. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  265. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  266. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  267. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  268. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  269. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  270. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
  271. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  272. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  273. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  274. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  275. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -3,34 +3,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  * Copyright (c) 2025-2026 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
- /**
7
- * A2UiRestaurantExample
8
- *
9
- * Demonstrates A2UI (Agent-to-UI) protocol integration with a pydantic-ai
10
- * restaurant finder agent using the official @a2ui/react renderer.
11
- *
12
- * The agent generates A2UI JSON messages that are rendered into
13
- * interactive React components via A2UIProvider + A2UIRenderer.
14
- *
15
- * Features:
16
- * - A2UI protocol message processing via @a2ui/react
17
- * - Dynamic UI generation from agent responses
18
- * - Restaurant search and booking interface
19
- * - Action handling for interactive components (buttons, forms)
20
- * - Dark/light theme support
21
- *
22
- * Backend: /api/v1/a2ui/restaurant/
23
- */
24
- import { useState, useCallback, useEffect, useRef } from 'react';
6
+ import { useCallback, useEffect, useRef, useState } from 'react';
25
7
  import { Box, getCardGradient } from '@datalayer/primer-addons';
8
+ import { Text, Spinner, TextInput, Button } from '@primer/react';
9
+ import { A2uiSurface } from '@a2ui/react/v0_9';
26
10
  import { ThemedProvider } from './utils/themedProvider';
11
+ import { A2uiMarkdownProvider } from './utils/a2uiMarkdownProvider';
27
12
  import { useExampleThemeStore } from './utils/themeStore';
28
- import { Text, Spinner, TextInput, Button } from '@primer/react';
29
- import { A2UIProvider, A2UIRenderer, useA2UIActions, initializeDefaultCatalog, } from '@a2ui/react';
30
- // Initialize the A2UI default component catalog (buttons, cards, text, etc.)
31
- // This must be called once before any A2UI rendering occurs.
32
- initializeDefaultCatalog();
33
- // A2UI endpoint for pydantic-ai restaurant agent
13
+ import { useA2uiProcessor } from './utils/a2ui';
34
14
  const A2UI_RESTAURANT_ENDPOINT = 'http://localhost:8765/api/v1/a2ui/restaurant/';
35
15
  const LOADING_TEXT_LINES = [
36
16
  'Finding the best spots for you...',
@@ -38,229 +18,151 @@ const LOADING_TEXT_LINES = [
38
18
  'Looking for open tables...',
39
19
  'Almost there...',
40
20
  ];
41
- /**
42
- * Extract ServerToClientMessage[] from A2A server payload,
43
- * handling both Python SDK (root wrapper) and JS SDK (direct) formats.
44
- */
45
- function extractMessages(data) {
21
+ const extractV09Messages = (data) => {
46
22
  const messages = [];
47
- for (const item of data) {
48
- const part = item.root || item;
49
- if (part.kind === 'text')
50
- continue;
51
- if (part.data) {
52
- messages.push(part.data);
23
+ data.forEach(item => {
24
+ const part = item.root ?? item;
25
+ if (part.kind !== 'data' || !part.data) {
26
+ return;
53
27
  }
54
- }
55
- return messages;
56
- }
57
- /**
58
- * Custom hook for A2UI restaurant client communication.
59
- * Uses useA2UIActions() from @a2ui/react for message processing.
60
- */
61
- function useA2UIRestaurantClient() {
62
- const { processMessages, clearSurfaces, getSurfaces } = useA2UIActions();
63
- const [isLoading, setIsLoading] = useState(false);
64
- const [error, setError] = useState(null);
65
- const makeRequest = useCallback(async (message) => {
66
- try {
67
- setIsLoading(true);
68
- setError(null);
69
- const response = await fetch(A2UI_RESTAURANT_ENDPOINT, {
70
- method: 'POST',
71
- headers: { 'Content-Type': 'application/json' },
72
- body: JSON.stringify({ query: message }),
73
- });
74
- if (!response.ok) {
75
- const errorData = await response.json();
76
- throw new Error(errorData.error || 'Request failed');
77
- }
78
- const data = (await response.json());
79
- if ('error' in data)
80
- throw new Error(data.error);
81
- const messages = extractMessages(data);
82
- clearSurfaces();
83
- processMessages(messages);
84
- return messages;
28
+ const message = part.data;
29
+ if (message.version === 'v0.9') {
30
+ messages.push(message);
85
31
  }
86
- catch (err) {
87
- const errorMessage = err instanceof Error ? err.message : 'Unknown error';
88
- setError(errorMessage);
89
- console.error('A2UI request error:', err);
90
- throw err;
91
- }
92
- finally {
93
- setIsLoading(false);
94
- }
95
- }, [processMessages, clearSurfaces]);
96
- return {
97
- getSurfaces,
98
- isLoading,
99
- error,
100
- makeRequest,
101
- };
102
- }
103
- /**
104
- * Restaurant search interface component
105
- */
106
- function RestaurantSearch({ onSearch, isLoading, defaultValue = 'Top 5 Chinese restaurants in New York', }) {
107
- const [inputValue, setInputValue] = useState(defaultValue);
32
+ });
33
+ return messages;
34
+ };
35
+ function RestaurantSearch({ onSearch, isLoading, }) {
36
+ const [inputValue, setInputValue] = useState('Top 5 Chinese restaurants in New York');
108
37
  const { theme, colorMode } = useExampleThemeStore();
109
38
  const gradient = getCardGradient(theme, colorMode);
110
39
  const handleSubmit = useCallback((event) => {
111
40
  event.preventDefault();
112
- if (inputValue.trim() && !isLoading) {
113
- onSearch(inputValue.trim());
41
+ if (!inputValue.trim() || isLoading) {
42
+ return;
114
43
  }
44
+ onSearch(inputValue.trim());
115
45
  }, [inputValue, isLoading, onSearch]);
116
46
  return (_jsxs(Box, { sx: {
117
47
  display: 'flex',
118
48
  flexDirection: 'column',
119
49
  alignItems: 'center',
120
50
  gap: 4,
121
- padding: 4,
122
- maxWidth: '600px',
123
- margin: '0 auto',
51
+ p: 4,
52
+ maxWidth: 640,
53
+ mx: 'auto',
124
54
  }, children: [_jsx(Box, { sx: {
125
55
  width: '100%',
126
- height: '200px',
127
- borderRadius: '12px',
56
+ height: 200,
57
+ borderRadius: 2,
128
58
  background: `linear-gradient(135deg, ${gradient.from} 0%, ${gradient.to} 100%)`,
129
59
  display: 'flex',
130
60
  alignItems: 'center',
131
61
  justifyContent: 'center',
132
- marginBottom: 2,
133
- }, children: _jsx(Text, { sx: { fontSize: '4rem' }, children: "\uD83C\uDF7D\uFE0F" }) }), _jsx(Text, { as: "h1", sx: {
134
- fontSize: '2rem',
135
- fontWeight: 'bold',
136
- textAlign: 'center',
137
- marginBottom: 2,
138
- }, children: "Restaurant Finder" }), _jsx(Text, { sx: { color: 'fg.muted', textAlign: 'center', marginBottom: 3 }, children: "Powered by A2UI protocol and pydantic-ai" }), _jsx("form", { onSubmit: handleSubmit, style: { width: '100%' }, children: _jsxs(Box, { sx: { display: 'flex', gap: 2 }, children: [_jsx(TextInput, { value: inputValue, onChange: e => setInputValue(e.target.value), placeholder: "Search for restaurants...", disabled: isLoading, sx: { flex: 1 }, block: true }), _jsx(Button, { type: "submit", disabled: isLoading || !inputValue.trim(), children: isLoading ? _jsx(Spinner, { size: "small" }) : 'Search' })] }) })] }));
62
+ }, children: _jsx(Text, { sx: { fontSize: '4rem' }, children: "\uD83C\uDF7D\uFE0F" }) }), _jsx(Text, { as: "h1", sx: { fontSize: '2rem', fontWeight: 'bold', textAlign: 'center' }, children: "Restaurant Finder" }), _jsx(Text, { sx: { color: 'fg.muted', textAlign: 'center' }, children: "A2UI renderer connected to a live agent backend." }), _jsx("form", { onSubmit: handleSubmit, style: { width: '100%' }, children: _jsxs(Box, { sx: { display: 'flex', gap: 2 }, children: [_jsx(TextInput, { value: inputValue, onChange: e => setInputValue(e.target.value), placeholder: "Search for restaurants...", disabled: isLoading, sx: { flex: 1 }, block: true }), _jsx(Button, { type: "submit", disabled: isLoading || !inputValue.trim(), children: isLoading ? _jsx(Spinner, { size: "small" }) : 'Search' })] }) })] }));
139
63
  }
140
- /**
141
- * Loading state component with animated text
142
- */
143
- function LoadingState() {
64
+ const A2UiRestaurantExample = () => {
65
+ const [isLoading, setIsLoading] = useState(false);
66
+ const [error, setError] = useState(null);
67
+ const [hasData, setHasData] = useState(false);
68
+ const [lastQuery, setLastQuery] = useState('');
144
69
  const [loadingTextIndex, setLoadingTextIndex] = useState(0);
145
- const loadingIntervalRef = useRef(null);
70
+ const sendPayloadRef = useRef(null);
71
+ const handleAction = useCallback(async (action) => {
72
+ if (!sendPayloadRef.current) {
73
+ return;
74
+ }
75
+ await sendPayloadRef.current({
76
+ action: action.name,
77
+ context: action.context,
78
+ });
79
+ }, []);
80
+ const { surfaces, processMessages, resetSurfaces } = useA2uiProcessor(handleAction);
146
81
  useEffect(() => {
147
- loadingIntervalRef.current = window.setInterval(() => {
82
+ if (!isLoading) {
83
+ return;
84
+ }
85
+ const interval = window.setInterval(() => {
148
86
  setLoadingTextIndex(prev => (prev + 1) % LOADING_TEXT_LINES.length);
149
- }, 2000);
87
+ }, 1800);
150
88
  return () => {
151
- if (loadingIntervalRef.current) {
152
- clearInterval(loadingIntervalRef.current);
153
- }
89
+ clearInterval(interval);
154
90
  };
155
- }, []);
156
- return (_jsxs(Box, { sx: {
157
- display: 'flex',
158
- flexDirection: 'column',
159
- alignItems: 'center',
160
- justifyContent: 'center',
161
- height: '300px',
162
- gap: 3,
163
- }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: '1.1rem' }, children: LOADING_TEXT_LINES[loadingTextIndex] })] }));
164
- }
165
- /**
166
- * Results display component with A2UI renderer
167
- */
168
- function ResultsDisplay({ surfaceEntries, onBack, }) {
169
- return (_jsxs(Box, { sx: { padding: 3 }, children: [_jsx(Box, { sx: { display: 'flex', justifyContent: 'flex-start', marginBottom: 3 }, children: _jsx(Button, { variant: "invisible", onClick: onBack, children: "\u2190 New Search" }) }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: surfaceEntries.map(([surfaceId]) => (_jsx(A2UIRenderer, { surfaceId: surfaceId }, surfaceId))) })] }));
170
- }
171
- /**
172
- * Error display component
173
- */
174
- function ErrorDisplay({ error, onRetry, }) {
175
- return (_jsxs(Box, { sx: {
176
- display: 'flex',
177
- flexDirection: 'column',
178
- alignItems: 'center',
179
- justifyContent: 'center',
180
- padding: 4,
181
- gap: 3,
182
- }, children: [_jsxs(Text, { sx: { color: 'danger.fg', fontSize: '1.2rem' }, children: ["\u26A0\uFE0F ", error] }), _jsx(Button, { onClick: onRetry, children: "Try Again" })] }));
183
- }
184
- /**
185
- * Main A2UI Restaurant content component.
186
- * Must be rendered inside A2UIProvider to access hooks.
187
- */
188
- function A2UIRestaurantContent() {
189
- const { getSurfaces, isLoading, error, makeRequest } = useA2UIRestaurantClient();
190
- const [hasData, setHasData] = useState(false);
191
- const [lastQuery, setLastQuery] = useState('');
192
- const handleSearch = useCallback(async (query) => {
193
- setLastQuery(query);
91
+ }, [isLoading]);
92
+ const sendPayload = useCallback(async (payload) => {
194
93
  try {
195
- await makeRequest(query);
94
+ setIsLoading(true);
95
+ setError(null);
96
+ setLoadingTextIndex(0);
97
+ const response = await fetch(A2UI_RESTAURANT_ENDPOINT, {
98
+ method: 'POST',
99
+ headers: { 'Content-Type': 'application/json' },
100
+ body: JSON.stringify(payload),
101
+ });
102
+ if (!response.ok) {
103
+ const errorData = (await response.json());
104
+ throw new Error(errorData.detail || 'Request failed');
105
+ }
106
+ const data = (await response.json());
107
+ if (!Array.isArray(data)) {
108
+ throw new Error(data.error || 'Invalid server payload');
109
+ }
110
+ const v09Messages = extractV09Messages(data);
111
+ if (v09Messages.length === 0) {
112
+ throw new Error('No A2UI messages returned by backend');
113
+ }
114
+ resetSurfaces();
115
+ processMessages(v09Messages);
196
116
  setHasData(true);
197
117
  }
198
- catch {
199
- // Error is already set in the hook
118
+ catch (requestError) {
119
+ const message = requestError instanceof Error
120
+ ? requestError.message
121
+ : 'Unknown error';
122
+ setError(message);
200
123
  }
201
- }, [makeRequest]);
202
- const handleBack = useCallback(() => {
203
- setHasData(false);
204
- }, []);
205
- const handleRetry = useCallback(() => {
206
- if (lastQuery) {
207
- handleSearch(lastQuery);
124
+ finally {
125
+ setIsLoading(false);
208
126
  }
209
- }, [lastQuery, handleSearch]);
210
- if (error && !isLoading) {
211
- return _jsx(ErrorDisplay, { error: error, onRetry: handleRetry });
212
- }
213
- if (isLoading) {
214
- return _jsx(LoadingState, {});
215
- }
216
- if (!hasData) {
217
- return _jsx(RestaurantSearch, { onSearch: handleSearch, isLoading: isLoading });
218
- }
219
- const surfaces = getSurfaces();
220
- const surfaceEntries = Array.from(surfaces.entries());
221
- return _jsx(ResultsDisplay, { surfaceEntries: surfaceEntries, onBack: handleBack });
222
- }
223
- /**
224
- * A2UiRestaurantExample - Main example component
225
- *
226
- * Demonstrates A2UI protocol integration with pydantic-ai.
227
- * The agent generates A2UI JSON messages for restaurant search,
228
- * display, and booking functionality.
229
- *
230
- * Uses @a2ui/react's two-context architecture:
231
- * - A2UIProvider wraps the app, receives an onAction callback
232
- * - useA2UIActions() provides processMessages/clearSurfaces/getSurfaces
233
- * - A2UIRenderer renders surfaces by ID
234
- */
235
- const A2UiRestaurantExample = () => {
236
- // Handle A2UI actions (button clicks, form submissions, etc.)
237
- const handleAction = useCallback((actionMessage) => {
238
- console.log('A2UI Action:', actionMessage);
239
- // Send action back to the agent for processing
240
- fetch(A2UI_RESTAURANT_ENDPOINT, {
241
- method: 'POST',
242
- headers: { 'Content-Type': 'application/json' },
243
- body: JSON.stringify(actionMessage),
244
- }).catch(err => console.error('Action send error:', err));
245
- }, []);
246
- return (_jsx(ThemedProvider, { children: _jsx(A2UIProvider, { onAction: handleAction, children: _jsxs(Box, { sx: {
247
- display: 'flex',
248
- flexDirection: 'column',
249
- minHeight: '100vh',
250
- backgroundColor: 'canvas.default',
251
- }, children: [_jsxs(Box, { sx: {
252
- padding: 3,
127
+ }, [processMessages, resetSurfaces]);
128
+ useEffect(() => {
129
+ sendPayloadRef.current = sendPayload;
130
+ }, [sendPayload]);
131
+ const handleSearch = useCallback(async (query) => {
132
+ setLastQuery(query);
133
+ await sendPayload({ query });
134
+ }, [sendPayload]);
135
+ const handleRetry = useCallback(async () => {
136
+ if (!lastQuery) {
137
+ return;
138
+ }
139
+ await sendPayload({ query: lastQuery });
140
+ }, [lastQuery, sendPayload]);
141
+ return (_jsx(ThemedProvider, { children: _jsx(A2uiMarkdownProvider, { children: _jsxs(Box, { sx: { minHeight: '100vh', display: 'flex', flexDirection: 'column' }, children: [_jsxs(Box, { sx: {
142
+ p: 3,
253
143
  borderBottom: '1px solid',
254
144
  borderColor: 'border.default',
255
145
  backgroundColor: 'canvas.subtle',
256
- }, children: [_jsx(Text, { as: "h1", sx: {
257
- fontSize: '1.25rem',
258
- fontWeight: 'bold',
146
+ }, children: [_jsx(Text, { as: "h1", sx: { fontSize: '1.25rem', fontWeight: 'bold' }, children: "\uD83E\uDD16 A2UI Restaurant Example" }), _jsx(Text, { sx: { fontSize: '0.875rem', color: 'fg.muted' }, children: "Uses MessageProcessor and A2uiSurface with native A2UI backend messages." })] }), _jsxs(Box, { sx: { flex: 1, p: 3 }, children: [!hasData && !isLoading && !error && (_jsx(RestaurantSearch, { onSearch: handleSearch, isLoading: isLoading })), isLoading && (_jsxs(Box, { sx: {
147
+ display: 'flex',
148
+ flexDirection: 'column',
149
+ alignItems: 'center',
150
+ justifyContent: 'center',
151
+ height: 280,
152
+ gap: 3,
153
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: LOADING_TEXT_LINES[loadingTextIndex] })] })), error && !isLoading && (_jsxs(Box, { sx: {
259
154
  display: 'flex',
155
+ flexDirection: 'column',
260
156
  alignItems: 'center',
261
- gap: 2,
262
- }, children: "\uD83E\uDD16 A2UI Restaurant Example" }), _jsx(Text, { sx: { fontSize: '0.875rem', color: 'fg.muted' }, children: "pydantic-ai agent with A2UI protocol rendering (@a2ui/react)" })] }), _jsx(Box, { sx: { flex: 1, padding: 3 }, children: _jsx(A2UIRestaurantContent, {}) }), _jsx(Box, { sx: {
263
- padding: 2,
157
+ gap: 3,
158
+ p: 4,
159
+ }, children: [_jsxs(Text, { sx: { color: 'danger.fg' }, children: ["\u26A0\uFE0F ", error] }), _jsx(Button, { onClick: handleRetry, disabled: !lastQuery, children: "Retry" })] })), !isLoading && hasData && !error && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsx(Button, { variant: "invisible", sx: { alignSelf: 'flex-start' }, onClick: () => setHasData(false), children: "\u2190 New Search" }), surfaces.map(surface => (_jsx(Box, { sx: {
160
+ border: '1px solid',
161
+ borderColor: 'border.default',
162
+ borderRadius: 1,
163
+ p: 3,
164
+ }, children: _jsx(A2uiSurface, { surface: surface }) }, surface.id)))] }))] }), _jsx(Box, { sx: {
165
+ p: 2,
264
166
  borderTop: '1px solid',
265
167
  borderColor: 'border.default',
266
168
  backgroundColor: 'canvas.subtle',
@@ -1,21 +1,3 @@
1
- /**
2
- * A2UiViewerExample
3
- *
4
- * Demonstrates the standalone A2UIViewer component from @a2ui/react.
5
- * Unlike A2UIProvider + A2UIRenderer (which require context), A2UIViewer
6
- * is a self-contained component that takes component definitions directly.
7
- *
8
- * Features:
9
- * - Standalone rendering — no A2UIProvider needed
10
- * - Multiple pre-built A2UI scenes (recipe card, booking form, dashboard)
11
- * - Shows how to use A2UIViewer for embedding A2UI in any React context
12
- *
13
- * No backend required — uses static ComponentInstance[] arrays.
14
- */
15
1
  import React from 'react';
16
- /**
17
- * A2UiViewerExample — Standalone A2UIViewer with multiple scenes.
18
- * Demonstrates embedding A2UI components without a Provider context.
19
- */
20
2
  declare const A2UiViewerExample: React.FC;
21
3
  export default A2UiViewerExample;