@datalayer/agent-runtimes 1.3.88 → 1.3.90
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/lib/Agent.js +2 -18
- package/lib/AgentDocument.js +5 -55
- package/lib/AgentNode.js +31 -208
- package/lib/AgentNotebook.js +5 -59
- package/lib/agent-node/AgentNodeGallery.js +23 -111
- package/lib/agents/AgentDetails.js +36 -274
- package/lib/agents/AgentRuntimeChat.js +1 -8
- package/lib/chat/Chat.js +7 -46
- package/lib/chat/ChatFloating.js +15 -100
- package/lib/chat/ChatInline.js +5 -47
- package/lib/chat/ChatPopupStandalone.js +5 -53
- package/lib/chat/ChatSidebar.js +4 -51
- package/lib/chat/ChatStandalone.js +4 -45
- package/lib/chat/EphemeralSurfaceControl.js +5 -25
- package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
- package/lib/chat/assistant/AssistantContextMenu.js +17 -1
- package/lib/chat/assistant/AssistantStage.js +6 -25
- package/lib/chat/assistant/BalloonParts.js +8 -40
- package/lib/chat/assistant/BalloonVisual.js +2 -2
- package/lib/chat/assistant/ConversationBalloon.js +2 -11
- package/lib/chat/assistant/DecisionAsk.js +3 -3
- package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
- package/lib/chat/assistant/SpeechBalloon.js +14 -78
- package/lib/chat/base/ChatBase.js +37 -172
- package/lib/chat/display/EmptyState.js +7 -35
- package/lib/chat/display/FloatingBrandButton.js +4 -34
- package/lib/chat/display/PoweredByTag.js +3 -14
- package/lib/chat/document/EphemeralDocument.js +3 -18
- package/lib/chat/header/ChatHeader.js +1 -17
- package/lib/chat/header/ChatHeaderBase.js +2 -24
- package/lib/chat/header/ChatViewModeToggle.js +7 -29
- package/lib/chat/indicators/McpStatusIndicator.js +3 -12
- package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
- package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
- package/lib/chat/indicators/TypingDots.js +1 -11
- package/lib/chat/messages/ChatMessageList.js +58 -185
- package/lib/chat/messages/ChatMessages.js +15 -79
- package/lib/chat/messages/FormSubmissionMessage.js +2 -33
- package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
- package/lib/chat/messages/TurnFooter.js +4 -10
- package/lib/chat/notebook/EphemeralNotebook.js +2 -10
- package/lib/chat/parts/ReasoningPart.js +2 -16
- package/lib/chat/parts/TextPart.js +2 -12
- package/lib/chat/parts/ToolPart.js +16 -90
- package/lib/chat/presence/Presence.js +5 -33
- package/lib/chat/prompt/FloatingCard.js +1 -13
- package/lib/chat/prompt/InputPrompt.js +1 -6
- package/lib/chat/prompt/InputPromptBase.js +4 -17
- package/lib/chat/prompt/InputPromptLexical.js +44 -45
- package/lib/chat/prompt/InputPromptText.js +1 -1
- package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
- package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/ModelSelector.js +1 -5
- package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
- package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
- package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
- package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
- package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
- package/lib/chat/prompt/plugins/MentionChip.js +1 -15
- package/lib/chat/prompt/stack.js +1 -19
- package/lib/chat/tools/A2AAgentDialog.js +9 -42
- package/lib/chat/tools/SubagentActivity.js +5 -22
- package/lib/chat/tools/ToolApprovalBanner.js +4 -34
- package/lib/chat/tools/ToolApprovalDialog.js +4 -19
- package/lib/chat/tools/ToolCallDisplay.js +12 -97
- package/lib/chat/usage/ContextPie.js +4 -45
- package/lib/components/a2ui/datalayer/Chart.js +4 -10
- package/lib/components/a2ui/datalayer/Chat.js +2 -10
- package/lib/components/a2ui/datalayer/Download.js +1 -1
- package/lib/components/a2ui/datalayer/Evidence.js +1 -15
- package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
- package/lib/components/a2ui/datalayer/Table.js +9 -17
- package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
- package/lib/components/a2ui/datalayer/parts.js +1 -16
- package/lib/components/agents/AgentSummary.js +1 -51
- package/lib/components/cards/NotificationEventCard.js +6 -72
- package/lib/components/cards/OutputCard.js +4 -48
- package/lib/components/cards/ToolApprovalCard.js +2 -35
- package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
- package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
- package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
- package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
- package/lib/components/scheduler/ScheduleMenu.js +5 -10
- package/lib/components/specs/SpecPayloadPreview.js +1 -26
- package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
- package/lib/components/teams/A2ATeamGraph.js +25 -71
- package/lib/components/teams/AnswerSurfacesView.js +2 -2
- package/lib/components/teams/NotebookPreview.js +1 -10
- package/lib/components/teams/NotebookPreviewView.js +2 -3
- package/lib/components/teams/SceneTranscript.js +3 -17
- package/lib/components/teams/SceneView.js +1 -8
- package/lib/components/teams/TeamNotebook.js +5 -13
- package/lib/components/teams/TeamNotebookView.js +2 -12
- package/lib/components/teams/index.d.ts +1 -0
- package/lib/components/teams/index.js +1 -0
- package/lib/components/teams/useBalloonRoom.d.ts +39 -0
- package/lib/components/teams/useBalloonRoom.js +89 -0
- package/lib/config/AgentConfiguration.js +22 -225
- package/lib/context/ContextDistribution.js +7 -41
- package/lib/context/ContextInspector.js +9 -107
- package/lib/context/ContextPanel.js +11 -86
- package/lib/context/ContextUsage.js +6 -34
- package/lib/context/CostTracker.js +7 -42
- package/lib/context/MessageHistory.js +3 -37
- package/lib/context/TurnGraphChart.js +9 -41
- package/lib/examples/A2UiAgentExample.js +6 -108
- package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
- package/lib/examples/A2UiContactCardExample.js +1 -1
- package/lib/examples/A2UiJupyterOutputExample.js +25 -125
- package/lib/examples/A2UiRestaurantExample.js +1 -1
- package/lib/examples/A2UiViewerExample.js +1 -1
- package/lib/examples/AgUiAgenticExample.js +3 -35
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
- package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
- package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
- package/lib/examples/AgUiSharedStateExample.js +6 -56
- package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
- package/lib/examples/AgentA2AExample.js +1 -15
- package/lib/examples/AgentA2ATeamExample.js +6 -30
- package/lib/examples/AgentCheckpointsExample.js +11 -145
- package/lib/examples/AgentCodeSandboxExample.js +5 -108
- package/lib/examples/AgentCodeSandboxesExample.js +3 -30
- package/lib/examples/AgentCodemodeExample.js +9 -85
- package/lib/examples/AgentCompactionExample.js +3 -64
- package/lib/examples/AgentDecideExample.js +1 -13
- package/lib/examples/AgentEvalsExample.js +5 -60
- package/lib/examples/AgentGuardrailsExample.js +4 -28
- package/lib/examples/AgentHooksExample.js +1 -1
- package/lib/examples/AgentInferenceProviderExample.js +5 -96
- package/lib/examples/AgentMCPExample.js +7 -105
- package/lib/examples/AgentMemoryExample.js +5 -74
- package/lib/examples/AgentMonitoringExample.js +7 -53
- package/lib/examples/AgentNotificationsExample.js +3 -61
- package/lib/examples/AgentOtelExample.js +3 -72
- package/lib/examples/AgentOutputsExample.js +6 -81
- package/lib/examples/AgentParametersExample.js +2 -37
- package/lib/examples/AgentSkillsExample.js +3 -45
- package/lib/examples/AgentSubagentsExample.js +6 -56
- package/lib/examples/AgentToolApprovalsExample.js +1 -11
- package/lib/examples/AgentTriggersExample.js +29 -239
- package/lib/examples/AgentspecsExample.js +6 -60
- package/lib/examples/AssistantExample.js +5 -5
- package/lib/examples/AssistantGalleryExample.js +8 -65
- package/lib/examples/CellExample.js +1 -6
- package/lib/examples/ChatCustomExample.js +2 -31
- package/lib/examples/ChatExample.js +1 -9
- package/lib/examples/ChatStandaloneExample.js +3 -37
- package/lib/examples/CopilotKitLexicalExample.js +1 -24
- package/lib/examples/DecksAgent.js +1 -1
- package/lib/examples/DocumentPageAgent.js +1 -1
- package/lib/examples/HomeExample.js +14 -62
- package/lib/examples/Lexical2Example.js +3 -32
- package/lib/examples/LexicalAgentExample.js +2 -34
- package/lib/examples/LexicalAgentSidebarExample.js +3 -34
- package/lib/examples/LoopAppComputerExample.js +1 -1
- package/lib/examples/LoopShellExample.js +2 -2
- package/lib/examples/LoopStrategyExample.js +15 -87
- package/lib/examples/LoopWorkspaceEmbed.js +2 -18
- package/lib/examples/LoopWorkspaceExample.js +2 -2
- package/lib/examples/NotebookAgentExample.js +2 -33
- package/lib/examples/NotebookAgentSidebarExample.js +3 -46
- package/lib/examples/NotebookCollaborationExample.js +1 -31
- package/lib/examples/NotebookExample.js +1 -18
- package/lib/examples/NotebookPageAgent.js +1 -1
- package/lib/examples/ScenesExample.js +5 -24
- package/lib/examples/VoiceChatExample.js +1 -1
- package/lib/examples/components/AuthRequiredView.js +1 -7
- package/lib/examples/components/ErrorView.js +1 -8
- package/lib/examples/components/ExampleErrorBoundary.js +1 -14
- package/lib/examples/components/FooterMetrics.js +1 -7
- package/lib/examples/components/Header.js +12 -51
- package/lib/examples/components/HeaderControls.js +1 -9
- package/lib/examples/components/LexicalEditor.js +1 -8
- package/lib/examples/components/MainContent.js +1 -13
- package/lib/examples/components/MockFileBrowser.js +4 -40
- package/lib/examples/components/SessionTabs.js +1 -1
- package/lib/examples/components/TimeTravel.js +1 -13
- package/lib/examples/main.js +13 -81
- package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
- package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
- package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
- package/lib/examples/scenes/A2UiViewerScene.js +3 -34
- package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
- package/lib/examples2/DatalayerNotebookExample.js +3 -33
- package/lib/examples2/NativeNavigationExample.js +4 -10
- package/lib/examples2/NotebookMutationsKernel.js +2 -1
- package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
- package/lib/examples2/ReactRouterExample.js +14 -42
- package/lib/hooks/useToolApprovals.d.ts +2 -34
- package/lib/hooks/useToolApprovals.js +1 -64
- package/lib/identity/AgentIdentity.js +17 -62
- package/lib/identity/IdentityConnect.js +13 -59
- package/lib/identity/OAuthCallback.js +6 -44
- package/lib/lexical/ChatInlinePlugin.js +6 -14
- package/lib/loop/apps/AppRenderer.d.ts +4 -3
- package/lib/loop/apps/AppRenderer.js +11 -12
- package/lib/loop/apps/appspec.js +6 -3
- package/lib/loop/embed/AppEmbed.d.ts +1 -1
- package/lib/loop/embed/AppEmbed.js +2 -1
- package/lib/loop/embed/LoopEmbed.js +1 -7
- package/lib/loop/embed/embedConfig.d.ts +3 -3
- package/lib/loop/embed/embedConfig.js +2 -3
- package/lib/loop/embed/embedTheme.d.ts +4 -4
- package/lib/loop/embed/embedTheme.js +11 -7
- package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
- package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
- package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
- package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
- package/lib/loop/plugins/agents/SandboxView.js +4 -27
- package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
- package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
- package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
- package/lib/loop/plugins/app-computer/AppComputer.js +5 -21
- package/lib/loop/plugins/app-elements/AppElements.js +2 -31
- package/lib/loop/plugins/app-page/AppPage.js +1 -1
- package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
- package/lib/loop/plugins/assistant/index.js +1 -13
- package/lib/loop/plugins/chat/ChatView.js +40 -106
- package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
- package/lib/loop/plugins/decks/DeckSurface.js +2 -2
- package/lib/loop/plugins/document/DocumentView.js +4 -12
- package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
- package/lib/loop/plugins/graph/GraphView.js +2 -2
- package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
- package/lib/loop/plugins/notebook/NotebookView.js +3 -11
- package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
- package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
- package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
- package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
- package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
- package/lib/loop/plugins/window-frame/index.js +1 -1
- package/lib/loop/shell/LoopWorkspace.js +34 -77
- package/lib/loop/shell/PluginToggles.js +4 -15
- package/lib/loop/shell/SidebarRail.js +8 -40
- package/lib/loop/shell/ViewSwitcher.js +4 -24
- package/lib/loop-main.js +2 -3
- package/lib/mcp/McpServerManager.js +6 -37
- package/lib/portable/index.d.ts +11 -0
- package/lib/portable/index.js +20 -0
- package/lib/protocols/AGUIAdapter.js +2 -2
- package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
- package/lib/protocols/BaseProtocolAdapter.js +4 -0
- package/lib/specs/apps.js +6 -0
- package/lib/specs/appspecSchema.js +11 -4
- package/lib/stories/loop/ReferenceScreens.js +17 -91
- package/lib/stories/loop/pictures-main.js +1 -1
- package/lib/types/agentspecs.d.ts +5 -2
- package/lib/types/protocol.d.ts +2 -0
- package/lib/utils/approvals.d.ts +59 -0
- package/lib/utils/approvals.js +101 -0
- package/lib/voice/VoiceInput.js +3 -39
- package/package.json +2 -2
- package/scripts/codegen/generate_envvars.py +0 -1
- package/lib/shims/primerAddonsBox.d.ts +0 -1
- package/lib/shims/primerAddonsBox.js +0 -7
|
@@ -110,14 +110,7 @@ const AgUiHaikuGenUiExample = () => {
|
|
|
110
110
|
}), []);
|
|
111
111
|
// Tool name to match and CSS file to load are read from the agent spec.
|
|
112
112
|
const renderToolResult = useSpecRenderToolResult(AGENTSPEC_ID, haikuRenderers);
|
|
113
|
-
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
114
|
-
minHeight: '100vh',
|
|
115
|
-
backgroundColor: 'canvas.default',
|
|
116
|
-
padding: 4,
|
|
117
|
-
}, children: [_jsxs(Box, { sx: {
|
|
118
|
-
maxWidth: '800px',
|
|
119
|
-
margin: '0 auto',
|
|
120
|
-
}, children: [_jsx(Text, { as: "h1", sx: {
|
|
113
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { minHeight: "100vh", backgroundColor: "canvas.default", padding: 4, children: [_jsxs(Box, { maxWidth: "800px", margin: "0 auto", children: [_jsx(Text, { as: "h1", sx: {
|
|
121
114
|
fontSize: 4,
|
|
122
115
|
fontWeight: 'bold',
|
|
123
116
|
marginBottom: 2,
|
|
@@ -125,30 +118,7 @@ const AgUiHaikuGenUiExample = () => {
|
|
|
125
118
|
fontSize: 2,
|
|
126
119
|
color: 'fg.muted',
|
|
127
120
|
marginBottom: 4,
|
|
128
|
-
}, children: "Ask the assistant to generate haiku poetry. Haikus appear both in the chat and in the display area below!" }), _jsx(Box, { sx: {
|
|
129
|
-
padding: 5,
|
|
130
|
-
backgroundColor: 'canvas.default',
|
|
131
|
-
borderRadius: 2,
|
|
132
|
-
border: '1px solid',
|
|
133
|
-
borderColor: 'border.default',
|
|
134
|
-
marginBottom: 4,
|
|
135
|
-
}, children: _jsx(HaikuDisplayWithRef, { ref: displayRef, title: "Your Haiku Collection" }) }), _jsxs(Box, { sx: {
|
|
136
|
-
padding: 4,
|
|
137
|
-
backgroundColor: 'canvas.default',
|
|
138
|
-
borderRadius: 2,
|
|
139
|
-
border: '1px solid',
|
|
140
|
-
borderColor: 'border.default',
|
|
141
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This demonstrates ", _jsx("strong", { children: "tool-based generative UI" }), " with AG-UI. When the agent generates a haiku using the", ' ', _jsx("code", { children: "generate_haiku" }), " tool, it's rendered as a beautiful card both in the chat and in the main display area above."] }), _jsxs(Box, { sx: { marginTop: 3 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Features:" }), _jsxs(Box, { as: "ul", sx: {
|
|
142
|
-
paddingLeft: 3,
|
|
143
|
-
marginTop: 1,
|
|
144
|
-
fontSize: 1,
|
|
145
|
-
color: 'fg.muted',
|
|
146
|
-
}, children: [_jsx("li", { children: "\uD83C\uDFA8 Beautiful gradient backgrounds matching mood" }), _jsx("li", { children: "\uD83C\uDDEF\uD83C\uDDF5 Japanese text with English translation" }), _jsx("li", { children: "\uD83D\uDCDA Carousel to browse your haiku collection" }), _jsx("li", { children: "\uD83D\uDD04 Real-time rendering as the tool executes" }), _jsx("li", { children: "\u2728 Synchronized display between chat and main view" })] })] }), _jsxs(Box, { sx: { marginTop: 3 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Try these prompts:" }), _jsxs(Box, { as: "ul", sx: {
|
|
147
|
-
paddingLeft: 3,
|
|
148
|
-
marginTop: 1,
|
|
149
|
-
fontSize: 1,
|
|
150
|
-
color: 'fg.muted',
|
|
151
|
-
}, children: [_jsx("li", { children: "\"Write me a haiku about cherry blossoms\"" }), _jsx("li", { children: "\"Create a haiku about coding late at night\"" }), _jsx("li", { children: "\"Generate a haiku about the ocean\"" }), _jsx("li", { children: "\"Write a haiku about autumn leaves\"" })] })] })] })] }), _jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: haikuGenUiEndpoint, launching: !haikuGenUiEndpoint, launchingMessage: "Starting the haiku agent runtime\u2026", title: "Haiku Generator", description: "Ask me to write haiku poetry about any topic!", position: "bottom-right", brandColor: brandColor, defaultOpen: true, renderToolResult: renderToolResult, hideMessagesAfterToolUI: true, suggestions: [
|
|
121
|
+
}, children: "Ask the assistant to generate haiku poetry. Haikus appear both in the chat and in the display area below!" }), _jsx(Box, { padding: 5, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", marginBottom: 4, children: _jsx(HaikuDisplayWithRef, { ref: displayRef, title: "Your Haiku Collection" }) }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This demonstrates ", _jsx("strong", { children: "tool-based generative UI" }), " with AG-UI. When the agent generates a haiku using the", ' ', _jsx("code", { children: "generate_haiku" }), " tool, it's rendered as a beautiful card both in the chat and in the main display area above."] }), _jsxs(Box, { marginTop: 3, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Features:" }), _jsxs(Box, { as: "ul", paddingLeft: 3, marginTop: 1, fontSize: 1, color: "fg.muted", children: [_jsx("li", { children: "\uD83C\uDFA8 Beautiful gradient backgrounds matching mood" }), _jsx("li", { children: "\uD83C\uDDEF\uD83C\uDDF5 Japanese text with English translation" }), _jsx("li", { children: "\uD83D\uDCDA Carousel to browse your haiku collection" }), _jsx("li", { children: "\uD83D\uDD04 Real-time rendering as the tool executes" }), _jsx("li", { children: "\u2728 Synchronized display between chat and main view" })] })] }), _jsxs(Box, { marginTop: 3, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Try these prompts:" }), _jsxs(Box, { as: "ul", paddingLeft: 3, marginTop: 1, fontSize: 1, color: "fg.muted", children: [_jsx("li", { children: "\"Write me a haiku about cherry blossoms\"" }), _jsx("li", { children: "\"Create a haiku about coding late at night\"" }), _jsx("li", { children: "\"Generate a haiku about the ocean\"" }), _jsx("li", { children: "\"Write a haiku about autumn leaves\"" })] })] })] })] }), _jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: haikuGenUiEndpoint, launching: !haikuGenUiEndpoint, launchingMessage: "Starting the haiku agent runtime\u2026", title: "Haiku Generator", description: "Ask me to write haiku poetry about any topic!", position: "bottom-right", brandColor: brandColor, defaultOpen: true, renderToolResult: renderToolResult, hideMessagesAfterToolUI: true, suggestions: [
|
|
152
122
|
{
|
|
153
123
|
title: 'Cherry blossoms',
|
|
154
124
|
message: 'Write me a haiku about cherry blossoms in spring.',
|
|
@@ -96,36 +96,12 @@ const StepsFeedback = ({ args, status, respond, result }) => {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
|
-
return (_jsxs(Box, { "data-testid": "select-steps", sx: {
|
|
100
|
-
width: '100%',
|
|
101
|
-
padding: 3,
|
|
102
|
-
backgroundColor: 'canvas.default',
|
|
103
|
-
borderRadius: 2,
|
|
104
|
-
border: '1px solid',
|
|
105
|
-
borderColor: 'border.default',
|
|
106
|
-
}, children: [_jsxs(Box, { sx: {
|
|
107
|
-
display: 'flex',
|
|
108
|
-
justifyContent: 'space-between',
|
|
109
|
-
alignItems: 'center',
|
|
110
|
-
marginBottom: 3,
|
|
111
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(TasklistIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: "Select Steps" })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [enabledCount, "/", displaySteps.length, " Selected"] }), _jsx(Label, { variant: status === 'executing' ? 'accent' : 'secondary', size: "small", children: status === 'executing' ? 'Ready' : 'Waiting' })] })] }), _jsx(ProgressBar, { progress: progress, barSize: "small", sx: { mb: 3 } }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2, mb: 3 }, children: displaySteps.map((step, index) => (_jsxs(Box, { "data-testid": "step-item", sx: {
|
|
112
|
-
display: 'flex',
|
|
113
|
-
alignItems: 'center',
|
|
114
|
-
gap: 2,
|
|
115
|
-
padding: 2,
|
|
116
|
-
borderRadius: 2,
|
|
117
|
-
backgroundColor: step.status === 'enabled' ? 'success.subtle' : 'canvas.default',
|
|
118
|
-
border: '1px solid',
|
|
119
|
-
borderColor: step.status === 'enabled' ? 'success.muted' : 'border.muted',
|
|
120
|
-
opacity: status !== 'executing' ? 0.7 : 1,
|
|
121
|
-
cursor: status === 'executing' ? 'pointer' : 'default',
|
|
122
|
-
transition: 'all 0.2s ease',
|
|
123
|
-
}, onClick: () => status === 'executing' && handleStepToggle(index), children: [_jsx(FormControl, { disabled: status !== 'executing', children: _jsx(Checkbox, { checked: step.status === 'enabled', onChange: () => handleStepToggle(index), disabled: status !== 'executing' }) }), _jsx(Text, { "data-testid": "step-text", sx: {
|
|
99
|
+
return (_jsxs(Box, { "data-testid": "select-steps", width: "100%", padding: 3, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(TasklistIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: "Select Steps" })] }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [enabledCount, "/", displaySteps.length, " Selected"] }), _jsx(Label, { variant: status === 'executing' ? 'accent' : 'secondary', size: "small", children: status === 'executing' ? 'Ready' : 'Waiting' })] })] }), _jsx(ProgressBar, { progress: progress, barSize: "small", sx: { mb: 3 } }), _jsx(Box, { display: "flex", flexDirection: "column", gap: 2, mb: 3, children: displaySteps.map((step, index) => (_jsxs(Box, { "data-testid": "step-item", display: "flex", alignItems: "center", gap: 2, padding: 2, borderRadius: 2, backgroundColor: step.status === 'enabled' ? 'success.subtle' : 'canvas.default', border: "1px solid", borderColor: step.status === 'enabled' ? 'success.muted' : 'border.muted', opacity: status !== 'executing' ? 0.7 : 1, cursor: status === 'executing' ? 'pointer' : 'default', transition: "all 0.2s ease", onClick: () => status === 'executing' && handleStepToggle(index), children: [_jsx(FormControl, { disabled: status !== 'executing', children: _jsx(Checkbox, { checked: step.status === 'enabled', onChange: () => handleStepToggle(index), disabled: status !== 'executing' }) }), _jsx(Text, { "data-testid": "step-text", sx: {
|
|
124
100
|
flex: 1,
|
|
125
101
|
fontSize: 1,
|
|
126
102
|
textDecoration: step.status === 'disabled' ? 'line-through' : 'none',
|
|
127
103
|
color: step.status === 'disabled' ? 'fg.muted' : 'fg.default',
|
|
128
|
-
}, children: step.description }), step.status === 'enabled' && (_jsx(CheckCircleFillIcon, { size: 16, className: "color-fg-success" }))] }, index))) }), accepted === null && (_jsxs(Box, {
|
|
104
|
+
}, children: step.description }), step.status === 'enabled' && (_jsx(CheckCircleFillIcon, { size: 16, className: "color-fg-success" }))] }, index))) }), accepted === null && (_jsxs(Box, { display: "flex", justifyContent: "center", gap: 3, mt: 3, children: [_jsxs(Button, { variant: "default", disabled: status !== 'executing', onClick: handleReject, sx: {
|
|
129
105
|
display: 'flex',
|
|
130
106
|
alignItems: 'center',
|
|
131
107
|
gap: 1,
|
|
@@ -137,17 +113,7 @@ const StepsFeedback = ({ args, status, respond, result }) => {
|
|
|
137
113
|
'&:hover': {
|
|
138
114
|
backgroundColor: 'success.emphasis',
|
|
139
115
|
},
|
|
140
|
-
}, children: [_jsx(CheckCircleFillIcon, { size: 14 }), "Confirm", _jsx(Label, { variant: "accent", size: "small", sx: { ml: 1, backgroundColor: 'rgba(255,255,255,0.2)' }, children: enabledCount })] })] })), accepted !== null && (_jsx(Box, {
|
|
141
|
-
display: 'flex',
|
|
142
|
-
alignItems: 'center',
|
|
143
|
-
gap: 2,
|
|
144
|
-
px: 4,
|
|
145
|
-
py: 2,
|
|
146
|
-
borderRadius: 2,
|
|
147
|
-
backgroundColor: accepted ? 'success.subtle' : 'danger.subtle',
|
|
148
|
-
border: '1px solid',
|
|
149
|
-
borderColor: accepted ? 'success.muted' : 'danger.muted',
|
|
150
|
-
}, children: accepted ? (_jsxs(_Fragment, { children: [_jsx(CheckCircleFillIcon, { size: 16, className: "color-fg-success" }), _jsx(Text, { sx: { fontWeight: 'semibold', color: 'success.fg' }, children: "Accepted" })] })) : (_jsxs(_Fragment, { children: [_jsx(XCircleFillIcon, { size: 16, className: "color-fg-danger" }), _jsx(Text, { sx: { fontWeight: 'semibold', color: 'danger.fg' }, children: "Rejected" })] })) }) }))] }));
|
|
116
|
+
}, children: [_jsx(CheckCircleFillIcon, { size: 14 }), "Confirm", _jsx(Label, { variant: "accent", size: "small", sx: { ml: 1, backgroundColor: 'rgba(255,255,255,0.2)' }, children: enabledCount })] })] })), accepted !== null && (_jsx(Box, { display: "flex", justifyContent: "center", mt: 3, children: _jsx(Box, { display: "flex", alignItems: "center", gap: 2, px: 4, py: 2, borderRadius: 2, backgroundColor: accepted ? 'success.subtle' : 'danger.subtle', border: "1px solid", borderColor: accepted ? 'success.muted' : 'danger.muted', children: accepted ? (_jsxs(_Fragment, { children: [_jsx(CheckCircleFillIcon, { size: 16, className: "color-fg-success" }), _jsx(Text, { sx: { fontWeight: 'semibold', color: 'success.fg' }, children: "Accepted" })] })) : (_jsxs(_Fragment, { children: [_jsx(XCircleFillIcon, { size: 16, className: "color-fg-danger" }), _jsx(Text, { sx: { fontWeight: 'semibold', color: 'danger.fg' }, children: "Rejected" })] })) }) }))] }));
|
|
151
117
|
};
|
|
152
118
|
/**
|
|
153
119
|
* Render function for the generate_task_steps tool
|
|
@@ -192,14 +158,7 @@ const AgUiHumanInTheLoopExample = () => {
|
|
|
192
158
|
},
|
|
193
159
|
});
|
|
194
160
|
const humanInTheLoopEndpoint = agentId != null ? `${baseUrl}/api/v1/ag-ui/${agentId}/` : undefined;
|
|
195
|
-
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
196
|
-
minHeight: '100vh',
|
|
197
|
-
backgroundColor: 'canvas.default',
|
|
198
|
-
padding: 4,
|
|
199
|
-
}, children: [_jsxs(Box, { sx: {
|
|
200
|
-
maxWidth: '800px',
|
|
201
|
-
margin: '0 auto',
|
|
202
|
-
}, children: [_jsx(Text, { as: "h1", sx: {
|
|
161
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { minHeight: "100vh", backgroundColor: "canvas.default", padding: 4, children: [_jsxs(Box, { maxWidth: "800px", margin: "0 auto", children: [_jsx(Text, { as: "h1", sx: {
|
|
203
162
|
fontSize: 4,
|
|
204
163
|
fontWeight: 'bold',
|
|
205
164
|
marginBottom: 2,
|
|
@@ -207,20 +166,7 @@ const AgUiHumanInTheLoopExample = () => {
|
|
|
207
166
|
fontSize: 2,
|
|
208
167
|
color: 'fg.muted',
|
|
209
168
|
marginBottom: 4,
|
|
210
|
-
}, children: "This example demonstrates human review workflows. Ask the AI to create a plan, then use the Reject/Confirm buttons to respond." }), _jsxs(Box, { sx: {
|
|
211
|
-
padding: 4,
|
|
212
|
-
backgroundColor: 'canvas.default',
|
|
213
|
-
borderRadius: 2,
|
|
214
|
-
border: '1px solid',
|
|
215
|
-
borderColor: 'border.default',
|
|
216
|
-
marginBottom: 4,
|
|
217
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: "This demonstrates the \"Human in the Loop\" pattern where AI-generated task plans require human approval before proceeding. The pattern follows CopilotKit's useHumanInTheLoop hook." }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', marginTop: 2 }, children: _jsx("strong", { children: "How it works:" }) }), _jsxs(Box, { as: "ul", sx: { fontSize: 1, color: 'fg.muted', mt: 1, pl: 3 }, children: [_jsx("li", { children: "The agent calls the generate_task_steps tool" }), _jsx("li", { children: "A custom UI renders with toggleable steps" }), _jsx("li", { children: "User clicks Reject or Confirm to send response back" }), _jsx("li", { children: "The UI updates to show Rejected or Accepted state" })] }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', marginTop: 2 }, children: [_jsx("strong", { children: "Try:" }), " \"Create a plan to learn machine learning\" or \"Plan a trip to Paris in 5 steps\""] })] }), _jsxs(Box, { sx: {
|
|
218
|
-
padding: 4,
|
|
219
|
-
backgroundColor: 'neutral.muted',
|
|
220
|
-
borderRadius: 2,
|
|
221
|
-
border: '1px solid',
|
|
222
|
-
borderColor: 'border.default',
|
|
223
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "Key Concept: respond() Callback" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.default' }, children: ["The ", _jsx("code", { children: "renderToolResult" }), " function receives a", ' ', _jsx("code", { children: "respond" }), " callback when the tool status is \"executing\". Calling ", _jsxs("code", { children: ["respond(", '{ accepted: true, steps: [...] }', ")"] }), ' ', "sends the user's decision back to the agent, completing the human-in-the-loop interaction."] })] })] }), humanInTheLoopEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: humanInTheLoopEndpoint, title: "Task Planner", description: "I can help you plan tasks. I'll generate steps for your review.", position: "bottom-right", brandColor: brandColor, renderToolResult: renderTaskStepsTool, hideMessagesAfterToolUI: true, suggestions: [
|
|
169
|
+
}, children: "This example demonstrates human review workflows. Ask the AI to create a plan, then use the Reject/Confirm buttons to respond." }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", marginBottom: 4, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: "This demonstrates the \"Human in the Loop\" pattern where AI-generated task plans require human approval before proceeding. The pattern follows CopilotKit's useHumanInTheLoop hook." }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', marginTop: 2 }, children: _jsx("strong", { children: "How it works:" }) }), _jsxs(Box, { as: "ul", fontSize: 1, color: "fg.muted", mt: 1, pl: 3, children: [_jsx("li", { children: "The agent calls the generate_task_steps tool" }), _jsx("li", { children: "A custom UI renders with toggleable steps" }), _jsx("li", { children: "User clicks Reject or Confirm to send response back" }), _jsx("li", { children: "The UI updates to show Rejected or Accepted state" })] }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', marginTop: 2 }, children: [_jsx("strong", { children: "Try:" }), " \"Create a plan to learn machine learning\" or \"Plan a trip to Paris in 5 steps\""] })] }), _jsxs(Box, { padding: 4, backgroundColor: "neutral.muted", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "Key Concept: respond() Callback" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.default' }, children: ["The ", _jsx("code", { children: "renderToolResult" }), " function receives a", ' ', _jsx("code", { children: "respond" }), " callback when the tool status is \"executing\". Calling ", _jsxs("code", { children: ["respond(", '{ accepted: true, steps: [...] }', ")"] }), ' ', "sends the user's decision back to the agent, completing the human-in-the-loop interaction."] })] })] }), humanInTheLoopEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: humanInTheLoopEndpoint, title: "Task Planner", description: "I can help you plan tasks. I'll generate steps for your review.", position: "bottom-right", brandColor: brandColor, renderToolResult: renderTaskStepsTool, hideMessagesAfterToolUI: true, suggestions: [
|
|
224
170
|
{
|
|
225
171
|
title: 'Plan a trip',
|
|
226
172
|
message: 'Plan a weekend trip to Paris.',
|
|
@@ -41,13 +41,8 @@ const IngredientsList = ({ ingredients, onAdd, onRemove }) => {
|
|
|
41
41
|
setNewIngredient('');
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
|
-
return (_jsxs(Box, { children: [_jsx(Text, { as: "h4", sx: { fontSize: 1, fontWeight: 'semibold', marginBottom: 2 }, children: "Ingredients" }), _jsxs(Box, {
|
|
45
|
-
display: 'flex',
|
|
46
|
-
justifyContent: 'space-between',
|
|
47
|
-
alignItems: 'center',
|
|
48
|
-
padding: 1,
|
|
44
|
+
return (_jsxs(Box, { children: [_jsx(Text, { as: "h4", sx: { fontSize: 1, fontWeight: 'semibold', marginBottom: 2 }, children: "Ingredients" }), _jsxs(Box, { display: "flex", gap: 2, marginBottom: 2, children: [_jsx(TextInput, { value: newIngredient, onChange: e => setNewIngredient(e.target.value), placeholder: "Add an ingredient...", onKeyDown: e => e.key === 'Enter' && handleAdd(), sx: { flex: 1 } }), _jsx(Button, { onClick: handleAdd, leadingVisual: PlusIcon, size: "small", children: "Add" })] }), ingredients.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontStyle: 'italic' }, children: "No ingredients yet" })) : (_jsx(Box, { as: "ul", listStyle: "none", padding: 0, margin: 0, children: ingredients.map((ingredient, index) => (_jsxs(Box, { as: "li", display: "flex", justifyContent: "space-between", alignItems: "center", padding: 1, borderColor: "border.default", sx: {
|
|
49
45
|
borderBottom: '1px solid',
|
|
50
|
-
borderColor: 'border.default',
|
|
51
46
|
'&:last-child': { borderBottom: 'none' },
|
|
52
47
|
}, children: [_jsx(Text, { sx: { fontSize: 1 }, children: ingredient }), _jsx(Button, { variant: "invisible", size: "small", onClick: () => onRemove(index), "aria-label": "Remove", children: _jsx(XIcon, { size: 12 }) })] }, index))) }))] }));
|
|
53
48
|
};
|
|
@@ -63,28 +58,19 @@ const InstructionsList = ({ instructions, onAdd, onRemove }) => {
|
|
|
63
58
|
setNewInstruction('');
|
|
64
59
|
}
|
|
65
60
|
};
|
|
66
|
-
return (_jsxs(Box, { children: [_jsx(Text, { as: "h4", sx: { fontSize: 1, fontWeight: 'semibold', marginBottom: 2 }, children: "Instructions" }), _jsxs(Box, {
|
|
67
|
-
display: 'flex',
|
|
68
|
-
justifyContent: 'space-between',
|
|
69
|
-
alignItems: 'flex-start',
|
|
70
|
-
marginBottom: 2,
|
|
71
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, flex: 1 }, children: instruction }), _jsx(Button, { variant: "invisible", size: "small", onClick: () => onRemove(index), "aria-label": "Remove", children: _jsx(XIcon, { size: 12 }) })] }, index))) }))] }));
|
|
61
|
+
return (_jsxs(Box, { children: [_jsx(Text, { as: "h4", sx: { fontSize: 1, fontWeight: 'semibold', marginBottom: 2 }, children: "Instructions" }), _jsxs(Box, { display: "flex", gap: 2, marginBottom: 2, children: [_jsx(TextInput, { value: newInstruction, onChange: e => setNewInstruction(e.target.value), placeholder: "Add an instruction...", onKeyDown: e => e.key === 'Enter' && handleAdd(), sx: { flex: 1 } }), _jsx(Button, { onClick: handleAdd, leadingVisual: PlusIcon, size: "small", children: "Add" })] }), instructions.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontStyle: 'italic' }, children: "No instructions yet" })) : (_jsx(Box, { as: "ol", paddingLeft: 3, margin: 0, children: instructions.map((instruction, index) => (_jsxs(Box, { as: "li", display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 2, children: [_jsx(Text, { sx: { fontSize: 1, flex: 1 }, children: instruction }), _jsx(Button, { variant: "invisible", size: "small", onClick: () => onRemove(index), "aria-label": "Remove", children: _jsx(XIcon, { size: 12 }) })] }, index))) }))] }));
|
|
72
62
|
};
|
|
73
63
|
/**
|
|
74
64
|
* RecipeDisplay Component
|
|
75
65
|
* Main recipe editor/display
|
|
76
66
|
*/
|
|
77
67
|
const RecipeDisplay = ({ recipe, onUpdate }) => {
|
|
78
|
-
return (_jsxs(Box, {
|
|
68
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 4, children: [_jsxs(Box, { children: [_jsx(TextInput, { value: recipe.title, onChange: e => onUpdate({ title: e.target.value }), placeholder: "Recipe title...", sx: {
|
|
79
69
|
fontSize: 2,
|
|
80
70
|
fontWeight: 'bold',
|
|
81
71
|
marginBottom: 2,
|
|
82
72
|
width: '100%',
|
|
83
|
-
} }), _jsx(TextInput, { as: "textarea", value: recipe.description, onChange: e => onUpdate({ description: e.target.value }), placeholder: "Recipe description...", sx: { width: '100%', minHeight: '60px', resize: 'vertical' } })] }), _jsxs(Box, {
|
|
84
|
-
display: 'grid',
|
|
85
|
-
gridTemplateColumns: ['1fr', '1fr 1fr'],
|
|
86
|
-
gap: 4,
|
|
87
|
-
}, children: [_jsx(IngredientsList, { ingredients: recipe.ingredients, onAdd: ingredient => onUpdate({ ingredients: [...recipe.ingredients, ingredient] }), onRemove: index => onUpdate({
|
|
73
|
+
} }), _jsx(TextInput, { as: "textarea", value: recipe.description, onChange: e => onUpdate({ description: e.target.value }), placeholder: "Recipe description...", sx: { width: '100%', minHeight: '60px', resize: 'vertical' } })] }), _jsxs(Box, { display: "flex", gap: 4, flexWrap: "wrap", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(PersonIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Servings:" }), _jsx(TextInput, { type: "number", value: recipe.servings, onChange: e => onUpdate({ servings: parseInt(e.target.value) || 0 }), sx: { width: '60px' }, min: 1 })] }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(ClockIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Prep:" }), _jsx(TextInput, { value: recipe.prepTime, onChange: e => onUpdate({ prepTime: e.target.value }), placeholder: "30 min", sx: { width: '80px' } })] }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(BeakerIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Cook:" }), _jsx(TextInput, { value: recipe.cookTime, onChange: e => onUpdate({ cookTime: e.target.value }), placeholder: "1 hour", sx: { width: '80px' } })] })] }), _jsxs(Box, { display: "grid", gridTemplateColumns: ['1fr', '1fr 1fr'], gap: 4, children: [_jsx(IngredientsList, { ingredients: recipe.ingredients, onAdd: ingredient => onUpdate({ ingredients: [...recipe.ingredients, ingredient] }), onRemove: index => onUpdate({
|
|
88
74
|
ingredients: recipe.ingredients.filter((_, i) => i !== index),
|
|
89
75
|
}) }), _jsx(InstructionsList, { instructions: recipe.instructions, onAdd: instruction => onUpdate({ instructions: [...recipe.instructions, instruction] }), onRemove: index => onUpdate({
|
|
90
76
|
instructions: recipe.instructions.filter((_, i) => i !== index),
|
|
@@ -139,50 +125,14 @@ const AgUiSharedStateExample = () => {
|
|
|
139
125
|
const handleClear = useCallback(() => {
|
|
140
126
|
setRecipe(DEFAULT_RECIPE);
|
|
141
127
|
}, []);
|
|
142
|
-
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
143
|
-
height: '100%',
|
|
144
|
-
overflow: 'auto',
|
|
145
|
-
backgroundColor: 'canvas.default',
|
|
146
|
-
padding: 4,
|
|
147
|
-
}, children: [_jsxs(Box, { sx: {
|
|
148
|
-
maxWidth: '900px',
|
|
149
|
-
margin: '0 auto',
|
|
150
|
-
}, children: [_jsxs(Box, { sx: {
|
|
151
|
-
display: 'flex',
|
|
152
|
-
justifyContent: 'space-between',
|
|
153
|
-
alignItems: 'flex-start',
|
|
154
|
-
marginBottom: 4,
|
|
155
|
-
}, children: [_jsxs(Box, { children: [_jsx(Text, { as: "h1", sx: {
|
|
128
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { height: "100%", overflow: "auto", backgroundColor: "canvas.default", padding: 4, children: [_jsxs(Box, { maxWidth: "900px", margin: "0 auto", children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 4, children: [_jsxs(Box, { children: [_jsx(Text, { as: "h1", sx: {
|
|
156
129
|
fontSize: 4,
|
|
157
130
|
fontWeight: 'bold',
|
|
158
131
|
marginBottom: 2,
|
|
159
132
|
}, children: "AG-UI Shared State Example" }), _jsx(Text, { as: "p", sx: {
|
|
160
133
|
fontSize: 2,
|
|
161
134
|
color: 'fg.muted',
|
|
162
|
-
}, children: "Build a recipe together with AI. Both you and the agent can edit the recipe." })] }), _jsx(Button, { variant: "danger", onClick: handleClear, children: "Clear Recipe" })] }), _jsxs(Box, { sx: {
|
|
163
|
-
padding: 4,
|
|
164
|
-
backgroundColor: 'canvas.default',
|
|
165
|
-
borderRadius: 2,
|
|
166
|
-
border: '1px solid',
|
|
167
|
-
borderColor: 'border.default',
|
|
168
|
-
marginBottom: 4,
|
|
169
|
-
}, children: [_jsxs(Box, { sx: {
|
|
170
|
-
display: 'flex',
|
|
171
|
-
justifyContent: 'space-between',
|
|
172
|
-
alignItems: 'center',
|
|
173
|
-
marginBottom: 3,
|
|
174
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold' }, children: "Recipe Builder" }), _jsx(Label, { variant: "accent", children: "Shared State" })] }), _jsx(RecipeDisplay, { recipe: recipe, onUpdate: handleLocalUpdate })] }), _jsxs(Box, { sx: {
|
|
175
|
-
padding: 4,
|
|
176
|
-
backgroundColor: 'canvas.default',
|
|
177
|
-
borderRadius: 2,
|
|
178
|
-
border: '1px solid',
|
|
179
|
-
borderColor: 'border.default',
|
|
180
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This demonstrates bidirectional shared state with AG-UI. The recipe state is shared between the frontend and the AI agent. When you make changes, they're available to the agent. When the agent updates the recipe (via", _jsx("code", { children: "display_recipe" }), " tool), it emits STATE_SNAPSHOT events that update the frontend."] }), _jsxs(Box, { sx: { marginTop: 3 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Try these prompts:" }), _jsxs(Box, { as: "ul", sx: {
|
|
181
|
-
paddingLeft: 3,
|
|
182
|
-
marginTop: 1,
|
|
183
|
-
fontSize: 1,
|
|
184
|
-
color: 'fg.muted',
|
|
185
|
-
}, children: [_jsx("li", { children: "\"Create a recipe for chocolate chip cookies\"" }), _jsx("li", { children: "\"Add butter and sugar to the ingredients\"" }), _jsx("li", { children: "\"Update the prep time to 20 minutes\"" }), _jsx("li", { children: "\"Suggest 3 more ingredients for my recipe\"" })] })] })] })] }), sharedStateEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: sharedStateEndpoint, title: "Recipe Assistant", description: "Let's build a recipe together! I can add ingredients, instructions, and more.", position: "bottom-right", brandColor: brandColor, onStateUpdate: handleStateUpdate, suggestions: [
|
|
135
|
+
}, children: "Build a recipe together with AI. Both you and the agent can edit the recipe." })] }), _jsx(Button, { variant: "danger", onClick: handleClear, children: "Clear Recipe" })] }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", marginBottom: 4, children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 3, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold' }, children: "Recipe Builder" }), _jsx(Label, { variant: "accent", children: "Shared State" })] }), _jsx(RecipeDisplay, { recipe: recipe, onUpdate: handleLocalUpdate })] }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This demonstrates bidirectional shared state with AG-UI. The recipe state is shared between the frontend and the AI agent. When you make changes, they're available to the agent. When the agent updates the recipe (via", _jsx("code", { children: "display_recipe" }), " tool), it emits STATE_SNAPSHOT events that update the frontend."] }), _jsxs(Box, { marginTop: 3, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "Try these prompts:" }), _jsxs(Box, { as: "ul", paddingLeft: 3, marginTop: 1, fontSize: 1, color: "fg.muted", children: [_jsx("li", { children: "\"Create a recipe for chocolate chip cookies\"" }), _jsx("li", { children: "\"Add butter and sugar to the ingredients\"" }), _jsx("li", { children: "\"Update the prep time to 20 minutes\"" }), _jsx("li", { children: "\"Suggest 3 more ingredients for my recipe\"" })] })] })] })] }), sharedStateEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: sharedStateEndpoint, title: "Recipe Assistant", description: "Let's build a recipe together! I can add ingredients, instructions, and more.", position: "bottom-right", brandColor: brandColor, onStateUpdate: handleStateUpdate, suggestions: [
|
|
186
136
|
{
|
|
187
137
|
title: 'Pasta recipe',
|
|
188
138
|
message: 'Help me create a simple pasta recipe.',
|
|
@@ -36,68 +36,31 @@ const PlanStepItem = ({ step, index, onClick, isInteractive = false }) => {
|
|
|
36
36
|
completed: 'success.fg',
|
|
37
37
|
};
|
|
38
38
|
const isEnabled = step.enabled !== false;
|
|
39
|
-
return (_jsxs(Box, { as: isInteractive ? 'button' : 'div', onClick: isInteractive ? onClick : undefined,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
return (_jsxs(Box, { as: isInteractive ? 'button' : 'div', onClick: isInteractive ? onClick : undefined, display: "flex", gap: 2, padding: 3, borderRadius: 2, backgroundColor: step.status === 'in_progress'
|
|
40
|
+
? 'attention.subtle'
|
|
41
|
+
: step.status === 'completed'
|
|
42
|
+
? 'success.subtle'
|
|
43
|
+
: isEnabled
|
|
44
|
+
? 'canvas.default'
|
|
45
|
+
: 'canvas.default', border: "1px solid", borderColor: step.status === 'in_progress'
|
|
46
|
+
? 'attention.muted'
|
|
47
|
+
: step.status === 'completed'
|
|
48
|
+
? 'success.muted'
|
|
49
|
+
: isEnabled
|
|
50
|
+
? 'border.default'
|
|
51
|
+
: 'border.muted', cursor: isInteractive ? 'pointer' : 'default', opacity: isEnabled ? 1 : 0.6, transition: "all 0.2s ease", textAlign: "left", width: "100%", hover: isInteractive
|
|
52
|
+
? {
|
|
53
|
+
backgroundColor: step.status === 'completed'
|
|
47
54
|
? 'success.subtle'
|
|
48
|
-
:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
border:
|
|
52
|
-
borderColor: step.status === 'in_progress'
|
|
53
|
-
? 'attention.muted'
|
|
54
|
-
: step.status === 'completed'
|
|
55
|
-
? 'success.muted'
|
|
56
|
-
: isEnabled
|
|
57
|
-
? 'border.default'
|
|
58
|
-
: 'border.muted',
|
|
59
|
-
cursor: isInteractive ? 'pointer' : 'default',
|
|
60
|
-
opacity: isEnabled ? 1 : 0.6,
|
|
61
|
-
transition: 'all 0.2s ease',
|
|
62
|
-
textAlign: 'left',
|
|
63
|
-
width: '100%',
|
|
64
|
-
'&:hover': isInteractive
|
|
65
|
-
? {
|
|
66
|
-
backgroundColor: step.status === 'completed'
|
|
67
|
-
? 'success.subtle'
|
|
68
|
-
: 'canvas.default',
|
|
69
|
-
borderColor: 'accent.muted',
|
|
70
|
-
}
|
|
71
|
-
: {},
|
|
72
|
-
}, children: [_jsx(Box, { sx: {
|
|
73
|
-
color: statusColor[step.status],
|
|
74
|
-
flexShrink: 0,
|
|
75
|
-
marginTop: '2px',
|
|
76
|
-
display: 'flex',
|
|
77
|
-
alignItems: 'center',
|
|
78
|
-
justifyContent: 'center',
|
|
79
|
-
width: 20,
|
|
80
|
-
height: 20,
|
|
81
|
-
}, children: isInteractive ? (_jsx(Box, { sx: {
|
|
82
|
-
width: 18,
|
|
83
|
-
height: 18,
|
|
84
|
-
borderRadius: 1,
|
|
85
|
-
border: '2px solid',
|
|
86
|
-
borderColor: isEnabled ? 'accent.fg' : 'border.muted',
|
|
87
|
-
backgroundColor: isEnabled ? 'accent.fg' : 'transparent',
|
|
88
|
-
display: 'flex',
|
|
89
|
-
alignItems: 'center',
|
|
90
|
-
justifyContent: 'center',
|
|
91
|
-
}, children: isEnabled && _jsx(CheckIcon, { size: 12, fill: "white" }) })) : (statusIcon[step.status]) }), _jsx(Box, { sx: { flex: 1 }, children: _jsxs(Text, { sx: {
|
|
55
|
+
: 'canvas.default',
|
|
56
|
+
borderColor: 'accent.muted',
|
|
57
|
+
}
|
|
58
|
+
: {}, children: [_jsx(Box, { color: statusColor[step.status], flexShrink: 0, marginTop: "2px", display: "flex", alignItems: "center", justifyContent: "center", width: 20, height: 20, children: isInteractive ? (_jsx(Box, { width: 18, height: 18, borderRadius: 1, border: "2px solid", borderColor: isEnabled ? 'accent.fg' : 'border.muted', backgroundColor: isEnabled ? 'accent.fg' : 'transparent', display: "flex", alignItems: "center", justifyContent: "center", children: isEnabled && _jsx(CheckIcon, { size: 12, fill: "white" }) })) : (statusIcon[step.status]) }), _jsx(Box, { flex: 1, children: _jsxs(Text, { sx: {
|
|
92
59
|
fontWeight: 'medium',
|
|
93
60
|
fontSize: 1,
|
|
94
61
|
textDecoration: !isEnabled ? 'line-through' : 'none',
|
|
95
62
|
color: !isEnabled ? 'fg.muted' : 'fg.default',
|
|
96
|
-
}, children: [index + 1, ". ", step.description] }) }), step.status !== 'pending' && (_jsx(Box, {
|
|
97
|
-
fontSize: 0,
|
|
98
|
-
color: step.status === 'completed' ? 'success.fg' : 'attention.fg',
|
|
99
|
-
textTransform: 'capitalize',
|
|
100
|
-
}, children: step.status === 'in_progress' ? 'In Progress' : step.status }))] }));
|
|
63
|
+
}, children: [index + 1, ". ", step.description] }) }), step.status !== 'pending' && (_jsx(Box, { fontSize: 0, color: step.status === 'completed' ? 'success.fg' : 'attention.fg', textTransform: "capitalize", children: step.status === 'in_progress' ? 'In Progress' : step.status }))] }));
|
|
101
64
|
};
|
|
102
65
|
/**
|
|
103
66
|
* PlanDisplay Component
|
|
@@ -105,14 +68,7 @@ const PlanStepItem = ({ step, index, onClick, isInteractive = false }) => {
|
|
|
105
68
|
*/
|
|
106
69
|
const PlanDisplay = ({ plan, isInteractive = true, onStepToggle, onConfirm, onReject, decision, }) => {
|
|
107
70
|
if (!plan) {
|
|
108
|
-
return (_jsxs(Box, { sx: {
|
|
109
|
-
textAlign: 'center',
|
|
110
|
-
padding: 5,
|
|
111
|
-
color: 'fg.muted',
|
|
112
|
-
border: '2px dashed',
|
|
113
|
-
borderColor: 'border.muted',
|
|
114
|
-
borderRadius: 2,
|
|
115
|
-
}, children: [_jsx(Text, { sx: { fontSize: 2, display: 'block', marginBottom: 2 }, children: "\uD83D\uDCCB No plan created yet" }), _jsx(Text, { sx: { fontSize: 1, display: 'block' }, children: "Ask the AI to create a plan for you." }), _jsx(Text, { sx: {
|
|
71
|
+
return (_jsxs(Box, { textAlign: "center", padding: 5, color: "fg.muted", border: "2px dashed", borderColor: "border.muted", borderRadius: 2, children: [_jsx(Text, { sx: { fontSize: 2, display: 'block', marginBottom: 2 }, children: "\uD83D\uDCCB No plan created yet" }), _jsx(Text, { sx: { fontSize: 1, display: 'block' }, children: "Ask the AI to create a plan for you." }), _jsx(Text, { sx: {
|
|
116
72
|
fontSize: 0,
|
|
117
73
|
display: 'block',
|
|
118
74
|
marginTop: 2,
|
|
@@ -123,34 +79,9 @@ const PlanDisplay = ({ plan, isInteractive = true, onStepToggle, onConfirm, onRe
|
|
|
123
79
|
const completedSteps = plan.steps.filter(s => s.status === 'completed').length;
|
|
124
80
|
const totalSteps = plan.steps.length;
|
|
125
81
|
const progress = totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0;
|
|
126
|
-
return (_jsxs(Box, { children: [_jsxs(Box, {
|
|
127
|
-
display: 'flex',
|
|
128
|
-
justifyContent: 'space-between',
|
|
129
|
-
alignItems: 'center',
|
|
130
|
-
marginBottom: 2,
|
|
131
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.default' }, children: "Select Steps" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: isInteractive
|
|
82
|
+
return (_jsxs(Box, { children: [_jsxs(Box, { marginBottom: 4, children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 2, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.default' }, children: "Select Steps" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: isInteractive
|
|
132
83
|
? `${enabledSteps}/${totalSteps} selected`
|
|
133
|
-
: `${completedSteps}/${totalSteps} completed` })] }), _jsx(ProgressBar, { progress: progress })] }), _jsx(Box, { sx: {
|
|
134
|
-
display: 'flex',
|
|
135
|
-
flexDirection: 'column',
|
|
136
|
-
gap: 2,
|
|
137
|
-
marginBottom: 4,
|
|
138
|
-
}, children: plan.steps.map((step, index) => (_jsx(PlanStepItem, { step: step, index: index, isInteractive: isInteractive && !decision, onClick: () => onStepToggle?.(index) }, index))) }), isInteractive && !decision && (_jsxs(Box, { sx: {
|
|
139
|
-
display: 'flex',
|
|
140
|
-
justifyContent: 'center',
|
|
141
|
-
gap: 3,
|
|
142
|
-
paddingTop: 3,
|
|
143
|
-
borderTop: '1px solid',
|
|
144
|
-
borderColor: 'border.default',
|
|
145
|
-
}, children: [_jsxs(Button, { variant: "danger", onClick: onReject, size: "large", children: [_jsx(XIcon, { size: 16 }), _jsx(Text, { sx: { marginLeft: 1 }, children: "Reject" })] }), _jsxs(Button, { variant: "primary", onClick: onConfirm, size: "large", children: [_jsx(CheckIcon, { size: 16 }), _jsxs(Text, { sx: { marginLeft: 1 }, children: ["Confirm (", enabledSteps, ")"] })] })] })), decision && (_jsx(Box, { sx: {
|
|
146
|
-
display: 'flex',
|
|
147
|
-
justifyContent: 'center',
|
|
148
|
-
padding: 3,
|
|
149
|
-
backgroundColor: decision === 'confirmed' ? 'success.subtle' : 'danger.subtle',
|
|
150
|
-
borderRadius: 2,
|
|
151
|
-
border: '1px solid',
|
|
152
|
-
borderColor: decision === 'confirmed' ? 'success.muted' : 'danger.muted',
|
|
153
|
-
}, children: _jsx(Text, { sx: {
|
|
84
|
+
: `${completedSteps}/${totalSteps} completed` })] }), _jsx(ProgressBar, { progress: progress })] }), _jsx(Box, { display: "flex", flexDirection: "column", gap: 2, marginBottom: 4, children: plan.steps.map((step, index) => (_jsx(PlanStepItem, { step: step, index: index, isInteractive: isInteractive && !decision, onClick: () => onStepToggle?.(index) }, index))) }), isInteractive && !decision && (_jsxs(Box, { display: "flex", justifyContent: "center", gap: 3, paddingTop: 3, borderTop: "1px solid", borderColor: "border.default", children: [_jsxs(Button, { variant: "danger", onClick: onReject, size: "large", children: [_jsx(XIcon, { size: 16 }), _jsx(Text, { sx: { marginLeft: 1 }, children: "Reject" })] }), _jsxs(Button, { variant: "primary", onClick: onConfirm, size: "large", children: [_jsx(CheckIcon, { size: 16 }), _jsxs(Text, { sx: { marginLeft: 1 }, children: ["Confirm (", enabledSteps, ")"] })] })] })), decision && (_jsx(Box, { display: "flex", justifyContent: "center", padding: 3, backgroundColor: decision === 'confirmed' ? 'success.subtle' : 'danger.subtle', borderRadius: 2, border: "1px solid", borderColor: decision === 'confirmed' ? 'success.muted' : 'danger.muted', children: _jsx(Text, { sx: {
|
|
154
85
|
fontWeight: 'semibold',
|
|
155
86
|
color: decision === 'confirmed' ? 'success.fg' : 'danger.fg',
|
|
156
87
|
}, children: decision === 'confirmed'
|
|
@@ -225,14 +156,7 @@ const AgUiToolsBasedGenUiExample = () => {
|
|
|
225
156
|
setDecision('rejected');
|
|
226
157
|
console.log('Plan rejected');
|
|
227
158
|
}, []);
|
|
228
|
-
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
229
|
-
minHeight: '100vh',
|
|
230
|
-
backgroundColor: 'canvas.default',
|
|
231
|
-
padding: 4,
|
|
232
|
-
}, children: [_jsxs(Box, { sx: {
|
|
233
|
-
maxWidth: '800px',
|
|
234
|
-
margin: '0 auto',
|
|
235
|
-
}, children: [_jsx(Text, { as: "h1", sx: {
|
|
159
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { minHeight: "100vh", backgroundColor: "canvas.default", padding: 4, children: [_jsxs(Box, { maxWidth: "800px", margin: "0 auto", children: [_jsx(Text, { as: "h1", sx: {
|
|
236
160
|
fontSize: 4,
|
|
237
161
|
fontWeight: 'bold',
|
|
238
162
|
marginBottom: 2,
|
|
@@ -240,26 +164,7 @@ const AgUiToolsBasedGenUiExample = () => {
|
|
|
240
164
|
fontSize: 2,
|
|
241
165
|
color: 'fg.muted',
|
|
242
166
|
marginBottom: 4,
|
|
243
|
-
}, children: "Watch the AI create and update a plan in real-time using STATE_SNAPSHOT and STATE_DELTA events." }), _jsxs(Box, { sx: {
|
|
244
|
-
padding: 4,
|
|
245
|
-
backgroundColor: 'canvas.default',
|
|
246
|
-
borderRadius: 2,
|
|
247
|
-
border: '1px solid',
|
|
248
|
-
borderColor: 'border.default',
|
|
249
|
-
marginBottom: 4,
|
|
250
|
-
minHeight: '300px',
|
|
251
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 3 }, children: "Generated Plan" }), _jsx(PlanDisplay, { plan: plan, isInteractive: true, onStepToggle: handleStepToggle, onConfirm: handleConfirm, onReject: handleReject, decision: decision })] }), _jsxs(Box, { sx: {
|
|
252
|
-
padding: 4,
|
|
253
|
-
backgroundColor: 'canvas.default',
|
|
254
|
-
borderRadius: 2,
|
|
255
|
-
border: '1px solid',
|
|
256
|
-
borderColor: 'border.default',
|
|
257
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This example shows how AG-UI enables tool-based generative UI. The agent has two tools: ", _jsx("code", { children: "create_plan" }), " emits a STATE_SNAPSHOT with the full plan, and", ' ', _jsx("code", { children: "update_plan_step" }), " emits STATE_DELTA events with JSON Patch operations for efficient incremental updates."] }), _jsxs(Box, { sx: { marginTop: 3 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "AG-UI Events Used:" }), _jsxs(Box, { as: "ul", sx: {
|
|
258
|
-
paddingLeft: 3,
|
|
259
|
-
marginTop: 1,
|
|
260
|
-
fontSize: 1,
|
|
261
|
-
color: 'fg.muted',
|
|
262
|
-
}, children: [_jsx("li", { children: "STATE_SNAPSHOT - Full state replacement" }), _jsx("li", { children: "STATE_DELTA - Incremental JSON Patch updates (RFC 6902)" }), _jsx("li", { children: "TOOL_CALL_START / TOOL_CALL_END - Tool execution tracking" })] })] })] })] }), agenticGenerativeUiEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: agenticGenerativeUiEndpoint, title: "Plan Generator", description: "I can create detailed plans and update them in real-time.", position: "bottom-right", brandColor: brandColor, onStateUpdate: handleStateUpdate, suggestions: [
|
|
167
|
+
}, children: "Watch the AI create and update a plan in real-time using STATE_SNAPSHOT and STATE_DELTA events." }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", marginBottom: 4, minHeight: "300px", children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 3 }, children: "Generated Plan" }), _jsx(PlanDisplay, { plan: plan, isInteractive: true, onStepToggle: handleStepToggle, onConfirm: handleConfirm, onReject: handleReject, decision: decision })] }), _jsxs(Box, { padding: 4, backgroundColor: "canvas.default", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "About This Example" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted' }, children: ["This example shows how AG-UI enables tool-based generative UI. The agent has two tools: ", _jsx("code", { children: "create_plan" }), " emits a STATE_SNAPSHOT with the full plan, and", ' ', _jsx("code", { children: "update_plan_step" }), " emits STATE_DELTA events with JSON Patch operations for efficient incremental updates."] }), _jsxs(Box, { marginTop: 3, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'medium' }, children: "AG-UI Events Used:" }), _jsxs(Box, { as: "ul", paddingLeft: 3, marginTop: 1, fontSize: 1, color: "fg.muted", children: [_jsx("li", { children: "STATE_SNAPSHOT - Full state replacement" }), _jsx("li", { children: "STATE_DELTA - Incremental JSON Patch updates (RFC 6902)" }), _jsx("li", { children: "TOOL_CALL_START / TOOL_CALL_END - Tool execution tracking" })] })] })] })] }), agenticGenerativeUiEndpoint && (_jsx(ChatFloating, { kernelIndicatorPlacement: "right", protocol: "ag-ui", endpoint: agenticGenerativeUiEndpoint, title: "Plan Generator", description: "I can create detailed plans and update them in real-time.", position: "bottom-right", brandColor: brandColor, onStateUpdate: handleStateUpdate, suggestions: [
|
|
263
168
|
{
|
|
264
169
|
title: 'Project plan',
|
|
265
170
|
message: 'Create a project plan for building a mobile app.',
|
|
@@ -37,20 +37,6 @@ const AgentA2AExample = () => {
|
|
|
37
37
|
const agentName = useMemo(() => uniqueAgentId(AGENT_NAME), []);
|
|
38
38
|
const plugins = useMemo(() => [AgentA2APlugin, A2ASidebarPlugin], []);
|
|
39
39
|
const remoteAgents = remoteAgentCount();
|
|
40
|
-
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
41
|
-
height: '100%',
|
|
42
|
-
display: 'flex',
|
|
43
|
-
flexDirection: 'column',
|
|
44
|
-
bg: 'canvas.default',
|
|
45
|
-
}, children: [_jsxs(Box, { sx: {
|
|
46
|
-
display: 'flex',
|
|
47
|
-
alignItems: 'center',
|
|
48
|
-
gap: 2,
|
|
49
|
-
px: 3,
|
|
50
|
-
py: 2,
|
|
51
|
-
borderBottom: '1px solid',
|
|
52
|
-
borderColor: 'border.default',
|
|
53
|
-
flexShrink: 0,
|
|
54
|
-
}, children: [_jsx(BroadcastIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: "A2A Demo" }), _jsx(Label, { variant: "accent", children: "local" }), _jsxs(Label, { variant: "accent", children: [remoteAgents, " A2A agent", remoteAgents === 1 ? '' : 's'] })] }), _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(LoopEmbed, { serverUrl: resolveExampleAgentRuntimesUrl('local'), target: "local", showAgentVariants: true, agentId: agentName, defaultEditor: "none", showHeader: true, plugins: plugins }) })] }) }));
|
|
40
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { height: "100%", display: "flex", flexDirection: "column", bg: "canvas.default", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.default", flexShrink: 0, children: [_jsx(BroadcastIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: "A2A Demo" }), _jsx(Label, { variant: "accent", children: "local" }), _jsxs(Label, { variant: "accent", children: [remoteAgents, " A2A agent", remoteAgents === 1 ? '' : 's'] })] }), _jsx(Box, { flex: 1, minHeight: 0, children: _jsx(LoopEmbed, { serverUrl: resolveExampleAgentRuntimesUrl('local'), target: "local", showAgentVariants: true, agentId: agentName, defaultEditor: "none", showHeader: true, plugins: plugins }) })] }) }));
|
|
55
41
|
};
|
|
56
42
|
export default AgentA2AExample;
|
|
@@ -114,19 +114,11 @@ function AgentA2ATeam() {
|
|
|
114
114
|
const accountingWhere = accountingKey
|
|
115
115
|
? `on a runtime, ${new URL(accountingUrl).host}, with a temporary key`
|
|
116
116
|
: `on a runtime, ${new URL(accountingUrl).host}`;
|
|
117
|
-
return (_jsxs(Box, {
|
|
118
|
-
(accountingKeyClock && !accountingKeyEnded)) && (_jsxs(Box, {
|
|
117
|
+
return (_jsxs(Box, { p: 4, maxWidth: 1080, mx: "auto", children: [_jsx(Heading, { as: "h2", sx: { fontSize: 4, mb: 1 }, children: "Agents A2A Team" }), _jsxs(Text, { as: "p", sx: { color: 'fg.muted', mt: 0 }, children: [TEAM.emoji, " ", _jsx("strong", { children: TEAM.name }), ": ", TEAM.description] }), ((anonymous.status === 'active' && anonymous.expiresAt) ||
|
|
118
|
+
(accountingKeyClock && !accountingKeyEnded)) && (_jsxs(Box, { display: "flex", gap: 4, flexWrap: "wrap", mb: 3, children: [anonymous.status === 'active' && anonymous.expiresAt && (_jsx(AnonymousKeyTimer, { expiresAt: anonymous.expiresAt, grantedMs: anonymous.grantedMs, label: `${SALES.name}'s trial key`, onExpire: () => useAnonymousSessionStore.getState().expire() })), accountingKeyClock && !accountingKeyEnded && (_jsx(AnonymousKeyTimer, { expiresAt: accountingKeyClock.expiresAt, grantedMs: accountingKeyClock.grantedMs, label: `${ACCOUNTING.name}'s temporary key`, onExpire: () => setAccountingKeyEnded(true) }))] })), anonymous.status === 'expired' && (_jsx(Box, { mb: 3, children: _jsx(AnonymousKeyExpired, { agentName: SALES.name,
|
|
119
119
|
// Sales runs in this page: what ended is its model's key, and
|
|
120
120
|
// signing in gives it the person's own.
|
|
121
|
-
onSignedIn: () => useAnonymousSessionStore.getState().clear() }) })), accountingKeyEnded && (_jsxs(Flash, { variant: "danger", sx: { mb: 3 }, children: [ACCOUNTING.name, "\u2019s temporary key has ended: it no longer answers. Make a new one with", ' ', _jsx("code", { children: "examples/sales-accounting-a2a/make_temp_key.py" }), " and reload."] })), needsSignIn && (_jsx(Flash, { variant: "warning", sx: { mb: 3 }, children: "Sales asks its model through the Datalayer inference service: sign in, or wait for a visitor's trial key." })), peerError && (_jsxs(Flash, { variant: "danger", sx: { mb: 3 }, children: ["Accounting is not reachable at ", accountingUrl, ": ", peerError, " Serve it with", ' ', _jsx("code", { children: "python examples/sales-accounting-a2a/serve_accounting.py" }), ' ', "on the local server, or", ' ', _jsx("code", { children: "loop apps run accounting.yaml --cloud --a2a" }), " and set", ' ', _jsx("code", { children: "VITE_A2A_ACCOUNTING_URL" }), "."] })), _jsx(Box, {
|
|
122
|
-
border: '1px solid',
|
|
123
|
-
borderColor: 'border.default',
|
|
124
|
-
borderRadius: 2,
|
|
125
|
-
bg: 'canvas.subtle',
|
|
126
|
-
px: 2,
|
|
127
|
-
pt: 2,
|
|
128
|
-
mb: 3,
|
|
129
|
-
}, children: _jsx(SceneView, { members: sceneMembers, tracer: inspector, emptyText: "Ask Sales: what it says to Accounting, what Accounting reads in Odoo and answers, line by line, shows here.", children: _jsx(A2ATeamGraph, { entry: {
|
|
121
|
+
onSignedIn: () => useAnonymousSessionStore.getState().clear() }) })), accountingKeyEnded && (_jsxs(Flash, { variant: "danger", sx: { mb: 3 }, children: [ACCOUNTING.name, "\u2019s temporary key has ended: it no longer answers. Make a new one with", ' ', _jsx("code", { children: "examples/sales-accounting-a2a/make_temp_key.py" }), " and reload."] })), needsSignIn && (_jsx(Flash, { variant: "warning", sx: { mb: 3 }, children: "Sales asks its model through the Datalayer inference service: sign in, or wait for a visitor's trial key." })), peerError && (_jsxs(Flash, { variant: "danger", sx: { mb: 3 }, children: ["Accounting is not reachable at ", accountingUrl, ": ", peerError, " Serve it with", ' ', _jsx("code", { children: "python examples/sales-accounting-a2a/serve_accounting.py" }), ' ', "on the local server, or", ' ', _jsx("code", { children: "loop apps run accounting.yaml --cloud --a2a" }), " and set", ' ', _jsx("code", { children: "VITE_A2A_ACCOUNTING_URL" }), "."] })), _jsx(Box, { border: "1px solid", borderColor: "border.default", borderRadius: 2, bg: "canvas.subtle", px: 2, pt: 2, mb: 3, children: _jsx(SceneView, { members: sceneMembers, tracer: inspector, emptyText: "Ask Sales: what it says to Accounting, what Accounting reads in Odoo and answers, line by line, shows here.", children: _jsx(A2ATeamGraph, { entry: {
|
|
130
122
|
id: SALES.id,
|
|
131
123
|
name: SALES.name,
|
|
132
124
|
emoji: SALES.emoji,
|
|
@@ -178,30 +170,14 @@ function AgentA2ATeam() {
|
|
|
178
170
|
},
|
|
179
171
|
}, flow: team.flow, calls: team.calls,
|
|
180
172
|
// Room for the balloons: suggestions, *more* and a notebook.
|
|
181
|
-
balloonRoom: 320, connected: peer !== null, label: peer ? `A2A · ${peer.skill.name}` : 'A2A · not connected' }) }) }), _jsx(Box, { ref: notebookArea,
|
|
182
|
-
display: 'grid',
|
|
183
|
-
gridTemplateColumns: ['1fr', '1fr', '1fr 1fr'],
|
|
184
|
-
gap: 3,
|
|
185
|
-
mb: 3,
|
|
186
|
-
}, "data-team-inspectors": "", children: [SALES, ACCOUNTING].map(member => (_jsxs(Box, { sx: { minWidth: 0 }, "data-team-inspector": member.id, children: [_jsxs(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: [member.emoji, " ", member.name, "\u2019s Agent Inspector"] }), _jsx(AgentInspector, { tracer: inspector, agent: member.name, compact: true, maxHeight: 360, exportName: `agent-inspector-${member.id}`, emptyText: member === SALES
|
|
173
|
+
balloonRoom: 320, connected: peer !== null, label: peer ? `A2A · ${peer.skill.name}` : 'A2A · not connected' }) }) }), _jsx(Box, { ref: notebookArea, mb: team.notebook ? 3 : 0, "data-team-notebook-placement": "under-graph" }), _jsx(Box, { display: "grid", gridTemplateColumns: ['1fr', '1fr', '1fr 1fr'], gap: 3, mb: 3, "data-team-inspectors": "", children: [SALES, ACCOUNTING].map(member => (_jsxs(Box, { minWidth: 0, "data-team-inspector": member.id, children: [_jsxs(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: [member.emoji, " ", member.name, "\u2019s Agent Inspector"] }), _jsx(AgentInspector, { tracer: inspector, agent: member.name, compact: true, maxHeight: 360, exportName: `agent-inspector-${member.id}`, emptyText: member === SALES
|
|
187
174
|
? 'Its model turns, its call to Accounting and the A2A requests it sends, with what came back, show here.'
|
|
188
|
-
: 'The A2A requests sent to it, its Odoo MCP calls and what it sends back show here.' })] }, member.id))) }), _jsxs(Box, {
|
|
175
|
+
: 'The A2A requests sent to it, its Odoo MCP calls and what it sends back show here.' })] }, member.id))) }), _jsxs(Box, { display: "flex", gap: 3, flexWrap: "wrap", children: [_jsxs(Box, { flex: "1 1 420px", minWidth: 0, children: [_jsxs(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: ["Ask ", SALES.name] }), _jsxs(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, mt: 0 }, children: ["Or choose one of ", SALES.name, "\u2019s suggestions in its balloon."] }), _jsx(Textarea, { ref: composer, block: true, rows: 3, value: draft, placeholder: "Ask for a financial report\u2026", onChange: event => setDraft(event.target.value), onKeyDown: event => {
|
|
189
176
|
if (event.key === 'Enter' && !event.shiftKey) {
|
|
190
177
|
event.preventDefault();
|
|
191
178
|
send(draft);
|
|
192
179
|
}
|
|
193
|
-
} }), _jsxs(Box, {
|
|
194
|
-
p: 2,
|
|
195
|
-
mb: 2,
|
|
196
|
-
borderRadius: 2,
|
|
197
|
-
bg: turn.role === 'user' ? 'accent.subtle' : 'canvas.subtle',
|
|
198
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: turn.role === 'user' ? 'You' : SALES.name }), _jsx(Streamdown, { children: turn.text })] }, index))) })] }), _jsx(Box, { sx: { flex: '1 1 360px', minWidth: 0 }, children: !team.notebook && (_jsxs(_Fragment, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: "The report" }), _jsx(Box, { sx: {
|
|
199
|
-
p: 3,
|
|
200
|
-
border: '1px solid',
|
|
201
|
-
borderColor: 'border.default',
|
|
202
|
-
borderRadius: 2,
|
|
203
|
-
minHeight: 120,
|
|
204
|
-
}, "data-team-report": "", children: team.report ? (_jsx(Streamdown, { children: team.report })) : (_jsx(Text, { sx: { color: 'fg.muted' }, children: "The report Accounting returns appears here, as it returned it, or as a notebook to run when it gives one." })) })] })) })] })] }));
|
|
180
|
+
} }), _jsxs(Box, { display: "flex", gap: 2, mt: 2, children: [_jsx(Button, { variant: "primary", disabled: !team.ready || team.busy || !draft.trim(), onClick: () => send(draft), children: "Ask" }), team.busy && _jsx(Button, { onClick: team.stop, children: "Stop" })] }), _jsx(Box, { mt: 3, "data-team-conversation": "", children: team.turns.map((turn, index) => (_jsxs(Box, { p: 2, mb: 2, borderRadius: 2, bg: turn.role === 'user' ? 'accent.subtle' : 'canvas.subtle', children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: turn.role === 'user' ? 'You' : SALES.name }), _jsx(Streamdown, { children: turn.text })] }, index))) })] }), _jsx(Box, { flex: "1 1 360px", minWidth: 0, children: !team.notebook && (_jsxs(_Fragment, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: "The report" }), _jsx(Box, { p: 3, border: "1px solid", borderColor: "border.default", borderRadius: 2, minHeight: 120, "data-team-report": "", children: team.report ? (_jsx(Streamdown, { children: team.report })) : (_jsx(Text, { sx: { color: 'fg.muted' }, children: "The report Accounting returns appears here, as it returned it, or as a notebook to run when it gives one." })) })] })) })] })] }));
|
|
205
181
|
}
|
|
206
182
|
export function AgentA2ATeamExample() {
|
|
207
183
|
return (_jsx(ThemedProvider, { children: _jsx(AgentA2ATeam, {}) }));
|