@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.
- package/README.md +182 -1
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/App.js +1 -1
- package/lib/agent-node/themeStore.d.ts +3 -0
- package/lib/agent-node/themeStore.js +156 -0
- package/lib/agent-node-main.d.ts +1 -0
- package/lib/agent-node-main.js +14 -0
- package/lib/agents/AgentDetails.d.ts +22 -1
- package/lib/agents/AgentDetails.js +34 -47
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +4 -2
- package/lib/chat/Chat.d.ts +5 -106
- package/lib/chat/Chat.js +20 -14
- package/lib/chat/ChatFloating.d.ts +7 -140
- package/lib/chat/ChatFloating.js +3 -3
- package/lib/chat/ChatPopupStandalone.d.ts +8 -47
- package/lib/chat/ChatPopupStandalone.js +3 -3
- package/lib/chat/ChatSidebar.d.ts +4 -69
- package/lib/chat/ChatSidebar.js +83 -51
- package/lib/chat/ChatStandalone.d.ts +4 -54
- package/lib/chat/ChatStandalone.js +3 -3
- package/lib/chat/base/ChatBase.js +1414 -174
- package/lib/chat/display/FloatingBrandButton.js +8 -1
- package/lib/chat/header/ChatHeader.d.ts +3 -1
- package/lib/chat/header/ChatHeader.js +15 -12
- package/lib/chat/header/ChatHeaderBase.d.ts +30 -5
- package/lib/chat/header/ChatHeaderBase.js +41 -16
- package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
- package/lib/chat/indicators/McpStatusIndicator.js +7 -32
- package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
- package/lib/chat/indicators/SandboxStatusIndicator.js +91 -56
- package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
- package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
- package/lib/chat/indicators/index.d.ts +1 -0
- package/lib/chat/indicators/index.js +1 -0
- package/lib/chat/messages/ChatMessageList.d.ts +1 -1
- package/lib/chat/messages/ChatMessageList.js +154 -114
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +21 -6
- package/lib/chat/prompt/InputFooter.js +76 -20
- package/lib/chat/prompt/InputPrompt.d.ts +5 -1
- package/lib/chat/prompt/InputPrompt.js +4 -4
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
- package/lib/chat/prompt/InputPromptLexical.js +12 -5
- package/lib/chat/prompt/InputPromptText.d.ts +3 -1
- package/lib/chat/prompt/InputPromptText.js +2 -2
- package/lib/chat/tools/ToolApprovalBanner.js +1 -1
- package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
- package/lib/chat/tools/ToolCallDisplay.js +2 -2
- package/lib/chat/usage/TokenUsageBar.js +20 -2
- package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
- package/lib/client/AgentRuntimesClientContext.js +55 -0
- package/lib/client/AgentsMixin.d.ts +0 -18
- package/lib/client/AgentsMixin.js +20 -30
- package/lib/client/IAgentRuntimesClient.d.ts +215 -0
- package/lib/client/IAgentRuntimesClient.js +5 -0
- package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
- package/lib/client/SdkAgentRuntimesClient.js +134 -0
- package/lib/client/index.d.ts +4 -1
- package/lib/client/index.js +3 -1
- package/lib/components/NotificationEventCard.js +5 -1
- package/lib/config/AgentConfiguration.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- package/lib/context/ContextDistribution.d.ts +3 -1
- package/lib/context/ContextDistribution.js +8 -27
- package/lib/context/ContextInspector.d.ts +3 -1
- package/lib/context/ContextInspector.js +19 -67
- package/lib/context/ContextPanel.d.ts +3 -1
- package/lib/context/ContextPanel.js +104 -64
- package/lib/context/ContextUsage.d.ts +3 -1
- package/lib/context/ContextUsage.js +3 -3
- package/lib/context/CostTracker.d.ts +9 -3
- package/lib/context/CostTracker.js +26 -47
- package/lib/context/CostUsageChart.d.ts +12 -0
- package/lib/context/CostUsageChart.js +378 -0
- package/lib/context/GraphFlowChart.d.ts +16 -0
- package/lib/context/GraphFlowChart.js +182 -0
- package/lib/context/TokenUsageChart.d.ts +8 -1
- package/lib/context/TokenUsageChart.js +349 -211
- package/lib/context/TurnGraphChart.d.ts +39 -0
- package/lib/context/TurnGraphChart.js +538 -0
- package/lib/context/otelWsPool.d.ts +20 -0
- package/lib/context/otelWsPool.js +69 -0
- package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
- package/lib/examples/A2UiComponentGalleryExample.js +315 -522
- package/lib/examples/A2UiContactCardExample.d.ts +0 -18
- package/lib/examples/A2UiContactCardExample.js +154 -411
- package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
- package/lib/examples/A2UiRestaurantExample.js +114 -212
- package/lib/examples/A2UiViewerExample.d.ts +0 -18
- package/lib/examples/A2UiViewerExample.js +283 -532
- package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
- package/lib/examples/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +14 -28
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +603 -169
- package/lib/examples/AgentEvalsExample.js +339 -53
- package/lib/examples/AgentGuardrailsExample.js +383 -66
- package/lib/examples/AgentHooksExample.d.ts +3 -0
- package/lib/examples/AgentHooksExample.js +122 -0
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.d.ts +3 -0
- package/lib/examples/AgentMCPExample.js +481 -0
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +78 -33
- package/lib/examples/AgentMonitoringExample.js +261 -200
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +114 -33
- package/lib/examples/AgentOtelExample.js +32 -42
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +433 -81
- package/lib/examples/AgentParametersExample.d.ts +3 -0
- package/lib/examples/AgentParametersExample.js +248 -0
- package/lib/examples/AgentSandboxExample.d.ts +3 -3
- package/lib/examples/AgentSandboxExample.js +74 -45
- package/lib/examples/AgentSkillsExample.js +95 -103
- package/lib/examples/AgentSubagentsExample.d.ts +14 -0
- package/lib/examples/AgentSubagentsExample.js +228 -0
- package/lib/examples/AgentToolApprovalsExample.js +49 -561
- package/lib/examples/AgentTriggersExample.js +823 -569
- package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +16 -28
- package/lib/examples/ChatExample.js +13 -29
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/CopilotKitNotebookExample.js +2 -1
- package/lib/examples/HomeExample.d.ts +15 -0
- package/lib/examples/HomeExample.js +77 -0
- package/lib/examples/Lexical2Example.js +4 -2
- package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
- package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +66 -17
- package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
- package/lib/examples/LexicalAgentSidebarExample.js +261 -0
- package/lib/examples/NotebookAgentExample.d.ts +9 -0
- package/lib/examples/NotebookAgentExample.js +192 -0
- package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
- package/lib/examples/NotebookAgentSidebarExample.js +221 -0
- package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
- package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
- package/lib/examples/NotebookExample.d.ts +4 -7
- package/lib/examples/NotebookExample.js +14 -146
- package/lib/examples/components/AuthRequiredView.d.ts +6 -0
- package/lib/examples/components/AuthRequiredView.js +33 -0
- package/lib/examples/components/ExampleWrapper.d.ts +9 -3
- package/lib/examples/components/ExampleWrapper.js +45 -9
- package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
- package/lib/examples/components/index.d.ts +3 -0
- package/lib/examples/components/index.js +4 -0
- package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
- package/lib/examples/example-selector.d.ts +17 -4
- package/lib/examples/example-selector.js +108 -41
- package/lib/examples/index.d.ts +10 -6
- package/lib/examples/index.js +10 -6
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +257 -27
- package/lib/examples/utils/a2ui.d.ts +18 -0
- package/lib/examples/utils/a2ui.js +69 -0
- package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
- package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
- package/lib/examples/utils/agentId.d.ts +18 -0
- package/lib/examples/utils/agentId.js +54 -0
- package/lib/examples/utils/agents/earthquake-detector.json +11 -11
- package/lib/examples/utils/agents/sales-forecaster.json +11 -11
- package/lib/examples/utils/agents/social-post-generator.json +11 -11
- package/lib/examples/utils/agents/stock-market.json +11 -11
- package/lib/examples/utils/examplesStore.js +82 -27
- package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- package/lib/hooks/index.d.ts +8 -8
- package/lib/hooks/index.js +7 -7
- package/lib/hooks/useA2A.d.ts +2 -3
- package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
- package/lib/hooks/useAIAgentsWebSocket.js +153 -12
- package/lib/hooks/useAcp.d.ts +1 -2
- package/lib/hooks/useAgUi.d.ts +1 -1
- package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +70 -4
- package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
- package/lib/hooks/useAgentsCatalog.js +1 -1
- package/lib/hooks/useAgentsService.d.ts +2 -2
- package/lib/hooks/useAgentsService.js +7 -7
- package/lib/hooks/useCheckpoints.js +1 -1
- package/lib/hooks/useConfig.d.ts +4 -1
- package/lib/hooks/useConfig.js +10 -3
- package/lib/hooks/useContextSnapshot.d.ts +9 -4
- package/lib/hooks/useContextSnapshot.js +9 -37
- package/lib/hooks/useMonitoring.js +3 -0
- package/lib/hooks/useSandbox.d.ts +20 -8
- package/lib/hooks/useSandbox.js +105 -40
- package/lib/hooks/useSkills.d.ts +23 -5
- package/lib/hooks/useSkills.js +94 -39
- package/lib/hooks/useToolApprovals.d.ts +60 -36
- package/lib/hooks/useToolApprovals.js +318 -69
- package/lib/hooks/useVercelAI.d.ts +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/inference/index.d.ts +0 -1
- package/lib/middleware/index.d.ts +0 -1
- package/lib/protocols/AGUIAdapter.js +6 -0
- package/lib/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/protocols/VercelAIAdapter.js +59 -7
- package/lib/specs/agents/agents.d.ts +21 -4
- package/lib/specs/agents/agents.js +2879 -316
- package/lib/specs/agents/index.js +3 -1
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.js +27 -20
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- package/lib/specs/events.d.ts +3 -10
- package/lib/specs/events.js +127 -84
- package/lib/specs/frontendTools.js +2 -2
- package/lib/specs/guardrails.d.ts +0 -7
- package/lib/specs/guardrails.js +240 -159
- package/lib/specs/mcpServers.js +35 -6
- package/lib/specs/memory.d.ts +0 -2
- package/lib/specs/memory.js +4 -17
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +20 -15
- package/lib/specs/notifications.js +102 -18
- package/lib/specs/outputs.js +15 -9
- package/lib/specs/personas.d.ts +41 -0
- package/lib/specs/personas.js +168 -0
- package/lib/specs/skills.d.ts +1 -1
- package/lib/specs/skills.js +23 -23
- package/lib/specs/teams/index.js +3 -1
- package/lib/specs/teams/teams.js +468 -348
- package/lib/specs/tools.js +4 -4
- package/lib/specs/triggers.js +61 -11
- package/lib/stores/agentRuntimeStore.d.ts +208 -0
- package/lib/stores/agentRuntimeStore.js +650 -0
- package/lib/stores/conversationStore.js +2 -2
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
- package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
- package/lib/tools/index.d.ts +0 -2
- package/lib/tools/index.js +0 -1
- package/lib/types/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +54 -1
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +325 -8
- package/lib/types/context.d.ts +27 -0
- package/lib/types/cost.d.ts +2 -2
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.js +3 -0
- package/lib/types/mcp.d.ts +8 -0
- package/lib/types/models.d.ts +2 -2
- package/lib/types/personas.d.ts +25 -0
- package/lib/types/personas.js +5 -0
- package/lib/types/skills.d.ts +43 -1
- package/lib/types/stream.d.ts +110 -0
- package/lib/types/stream.js +36 -0
- package/lib/utils/utils.d.ts +9 -5
- package/lib/utils/utils.js +9 -5
- package/package.json +19 -11
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +187 -45
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +35 -14
- package/scripts/codegen/generate_personas.py +319 -0
- package/scripts/codegen/generate_skills.py +9 -9
- package/scripts/sync-jupyter.sh +26 -7
- package/lib/api/tool-approvals.d.ts +0 -62
- package/lib/api/tool-approvals.js +0 -145
- package/lib/examples/AgentspecExample.js +0 -705
- package/lib/examples/LexicalSidebarExample.js +0 -163
- package/lib/examples/NotebookSidebarExample.js +0 -119
- package/lib/examples/NotebookSimpleExample.d.ts +0 -6
- package/lib/examples/NotebookSimpleExample.js +0 -22
- package/lib/examples/ag-ui/index.d.ts +0 -10
- package/lib/examples/ag-ui/index.js +0 -16
- package/lib/hooks/useAgentsRegistry.d.ts +0 -10
- package/lib/hooks/useAgentsRegistry.js +0 -20
- package/lib/stores/agentsStore.d.ts +0 -123
- package/lib/stores/agentsStore.js +0 -270
- /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
- /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 {
|
|
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
|
-
|
|
48
|
-
const part = item.root
|
|
49
|
-
if (part.kind
|
|
50
|
-
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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()
|
|
113
|
-
|
|
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
|
-
|
|
122
|
-
maxWidth:
|
|
123
|
-
|
|
51
|
+
p: 4,
|
|
52
|
+
maxWidth: 640,
|
|
53
|
+
mx: 'auto',
|
|
124
54
|
}, children: [_jsx(Box, { sx: {
|
|
125
55
|
width: '100%',
|
|
126
|
-
height:
|
|
127
|
-
borderRadius:
|
|
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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
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
|
-
|
|
82
|
+
if (!isLoading) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const interval = window.setInterval(() => {
|
|
148
86
|
setLoadingTextIndex(prev => (prev + 1) % LOADING_TEXT_LINES.length);
|
|
149
|
-
},
|
|
87
|
+
}, 1800);
|
|
150
88
|
return () => {
|
|
151
|
-
|
|
152
|
-
clearInterval(loadingIntervalRef.current);
|
|
153
|
-
}
|
|
89
|
+
clearInterval(interval);
|
|
154
90
|
};
|
|
155
|
-
}, []);
|
|
156
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
+
catch (requestError) {
|
|
119
|
+
const message = requestError instanceof Error
|
|
120
|
+
? requestError.message
|
|
121
|
+
: 'Unknown error';
|
|
122
|
+
setError(message);
|
|
200
123
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
setHasData(false);
|
|
204
|
-
}, []);
|
|
205
|
-
const handleRetry = useCallback(() => {
|
|
206
|
-
if (lastQuery) {
|
|
207
|
-
handleSearch(lastQuery);
|
|
124
|
+
finally {
|
|
125
|
+
setIsLoading(false);
|
|
208
126
|
}
|
|
209
|
-
}, [
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
258
|
-
|
|
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:
|
|
262
|
-
|
|
263
|
-
|
|
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;
|