@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
|
@@ -20,8 +20,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
20
20
|
* @module stories/loop/ReferenceScreens
|
|
21
21
|
*/
|
|
22
22
|
import { useEffect, useRef, useState } from 'react';
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
23
|
+
import { Button, Heading, Text } from '@primer/react';
|
|
24
|
+
import { Box, DatalayerThemeProvider, setupPrimerPortals, themeAccentVars, themeConfigs, } from '@datalayer/primer-addons';
|
|
25
25
|
import { ChatBaseHeader } from '../../chat/header/ChatHeaderBase';
|
|
26
26
|
import { ChatMessageList } from '../../chat/messages/ChatMessageList';
|
|
27
27
|
import { InputPrompt } from '../../chat/prompt/InputPrompt';
|
|
@@ -84,29 +84,12 @@ export function ReferenceTheme({ theme, mode, children, }) {
|
|
|
84
84
|
document.documentElement.setAttribute('data-reference-mode', mode);
|
|
85
85
|
}, [theme, mode]);
|
|
86
86
|
return (_jsx(DatalayerThemeProvider, { colorMode: mode, theme: config.primerTheme, themeStyles: config.themeStyles, baseStyles: theme === 'loop'
|
|
87
|
-
?
|
|
88
|
-
: undefined, children: _jsx(Box, { "data-reference-stage": "",
|
|
89
|
-
position: 'fixed',
|
|
90
|
-
inset: 0,
|
|
91
|
-
p: 4,
|
|
92
|
-
bg: 'var(--loop-stage, var(--bgColor-muted))',
|
|
93
|
-
color: 'fg.default',
|
|
94
|
-
display: 'flex',
|
|
95
|
-
}, children: children }) }));
|
|
87
|
+
? themeAccentVars('green', mode)
|
|
88
|
+
: undefined, children: _jsx(Box, { "data-reference-stage": "", position: "fixed", inset: 0, p: 4, bg: theme === 'loop' ? 'var(--theme-stage)' : 'var(--bgColor-muted)', color: "fg.default", display: "flex", children: children }) }));
|
|
96
89
|
}
|
|
97
90
|
/** One rounded surface on the stage: the theme's frame. */
|
|
98
91
|
function Frame({ children }) {
|
|
99
|
-
return (_jsx(Box, {
|
|
100
|
-
flex: 1,
|
|
101
|
-
minWidth: 0,
|
|
102
|
-
display: 'flex',
|
|
103
|
-
overflow: 'hidden',
|
|
104
|
-
bg: 'canvas.default',
|
|
105
|
-
borderRadius: 'var(--theme-radius-frame, 12px)',
|
|
106
|
-
border: 'var(--theme-hairline, 1px) solid',
|
|
107
|
-
borderColor: 'border.muted',
|
|
108
|
-
boxShadow: 'var(--theme-shadow, none)',
|
|
109
|
-
}, children: children }));
|
|
92
|
+
return (_jsx(Box, { flex: 1, minWidth: 0, display: "flex", overflow: "hidden", bg: "canvas.default", borderRadius: "var(--theme-radius-frame, 12px)", border: "var(--theme-hairline, 1px) solid", borderColor: "border.muted", boxShadow: "var(--theme-shadow, none)", children: children }));
|
|
110
93
|
}
|
|
111
94
|
// ---------------------------------------------------------------------------
|
|
112
95
|
// Fixed data
|
|
@@ -188,47 +171,30 @@ const AVATARS = {
|
|
|
188
171
|
function Conversation({ name, face, presence, items, composer = true, mcpServers, }) {
|
|
189
172
|
const endRef = useRef(null);
|
|
190
173
|
const [input, setInput] = useState('');
|
|
191
|
-
return (_jsxs(Box, {
|
|
192
|
-
flex: 1,
|
|
193
|
-
minWidth: 0,
|
|
194
|
-
display: 'flex',
|
|
195
|
-
flexDirection: 'column',
|
|
196
|
-
height: '100%',
|
|
197
|
-
}, children: [_jsx(ChatBaseHeader, { title: name, brandIcon: _jsx(PresenceFace, { face: face, size: 20, state: presence }), headerContent: _jsx(PresenceLine, { state: presence }), padding: 3, messageCount: items.length, onNewChat: () => undefined, onClear: () => undefined }), _jsx(Box, { sx: { flex: 1, minHeight: 0, overflow: 'hidden' }, children: _jsx(ChatMessageList, { displayItems: items, isLoading: false, isStreaming: false, showLoadingIndicator: false, hideMessagesAfterToolUI: false, avatarConfig: AVATARS, padding: 3, emptyContent: null, messagesEndRef: endRef, onRespond: async () => undefined, mcpServers: mcpServers }) }), composer && (_jsx(InputPrompt, { input: input, setInput: setInput, isLoading: false, connectionConfirmed: true, placeholder: "Send a message", autoFocus: false, padding: 3, onSend: () => undefined, onStop: () => undefined, showTokenUsage: false, showModelSelector: false, showToolsMenu: false, showSkillsMenu: false, codemodeEnabled: false, hasConfigData: false, hasSkillsData: false, isA2AProtocol: false }))] }));
|
|
174
|
+
return (_jsxs(Box, { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", height: "100%", children: [_jsx(ChatBaseHeader, { title: name, brandIcon: _jsx(PresenceFace, { face: face, size: 20, state: presence }), headerContent: _jsx(PresenceLine, { state: presence }), padding: 3, messageCount: items.length, onNewChat: () => undefined, onClear: () => undefined }), _jsx(Box, { flex: 1, minHeight: 0, overflow: "hidden", children: _jsx(ChatMessageList, { displayItems: items, isLoading: false, isStreaming: false, showLoadingIndicator: false, hideMessagesAfterToolUI: false, avatarConfig: AVATARS, padding: 3, emptyContent: null, messagesEndRef: endRef, onRespond: async () => undefined, mcpServers: mcpServers }) }), composer && (_jsx(InputPrompt, { input: input, setInput: setInput, isLoading: false, connectionConfirmed: true, placeholder: "Send a message", autoFocus: false, padding: 3, onSend: () => undefined, onStop: () => undefined, showTokenUsage: false, showModelSelector: false, showToolsMenu: false, showSkillsMenu: false, codemodeEnabled: false, hasConfigData: false, hasSkillsData: false, isA2AProtocol: false }))] }));
|
|
198
175
|
}
|
|
199
176
|
// ---------------------------------------------------------------------------
|
|
200
177
|
// The four screens
|
|
201
178
|
// ---------------------------------------------------------------------------
|
|
202
179
|
/** A conversation. */
|
|
203
180
|
export function ConversationScreen() {
|
|
204
|
-
return (_jsx(Frame, { children: _jsx(Box, {
|
|
181
|
+
return (_jsx(Frame, { children: _jsx(Box, { flex: 1, display: "flex", justifyContent: "center", children: _jsx(Box, { width: "100%", maxWidth: 640, display: "flex", children: _jsx(Conversation, { name: "Support desk", face: "\uD83E\uDD8A", presence: "idle", items: CONVERSATION }) }) }) }));
|
|
205
182
|
}
|
|
206
183
|
/** A conversation beside its work: the split, one hairline between them. */
|
|
207
184
|
export function BesideWorkScreen() {
|
|
208
|
-
return (_jsxs(Frame, { children: [_jsx(Box, {
|
|
209
|
-
width: 'var(--theme-hairline, 1px)',
|
|
210
|
-
bg: 'border.muted',
|
|
211
|
-
flexShrink: 0,
|
|
212
|
-
} }), _jsxs(Box, { "data-reference-work": "", sx: {
|
|
213
|
-
flex: 1,
|
|
214
|
-
minWidth: 0,
|
|
215
|
-
p: 4,
|
|
216
|
-
display: 'flex',
|
|
217
|
-
flexDirection: 'column',
|
|
218
|
-
gap: 3,
|
|
219
|
-
}, children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Draft \u00B7 reply" }), _jsx(Heading, { as: "h2", sx: { fontSize: 3, fontWeight: 600 }, children: "Your order 1042" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "To ada@example.com" }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(Text, { as: "p", sx: { m: 0 }, children: "Dear Ada," }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "We are sorry your order arrived four days late. It left our warehouse on Monday and is with you by Thursday, 8 October." }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "Your next order ships free, with no code to enter." }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "The support desk" })] }), _jsxs(Box, { sx: { display: 'flex', gap: 2, mt: 'auto' }, children: [_jsx(Button, { variant: "primary", children: "Send" }), _jsx(Button, { children: "Edit" })] })] })] }));
|
|
185
|
+
return (_jsxs(Frame, { children: [_jsx(Box, { width: 400, flexShrink: 0, display: "flex", children: _jsx(Conversation, { name: "Support desk", face: "\uD83E\uDD8A", presence: "idle", items: BESIDE_WORK }) }), _jsx(Box, { width: "var(--theme-hairline, 1px)", bg: "border.muted", flexShrink: 0 }), _jsxs(Box, { "data-reference-work": "", flex: 1, minWidth: 0, p: 4, display: "flex", flexDirection: "column", gap: 3, children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Draft \u00B7 reply" }), _jsx(Heading, { as: "h2", sx: { fontSize: 3, fontWeight: 600 }, children: "Your order 1042" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "To ada@example.com" }), _jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsx(Text, { as: "p", sx: { m: 0 }, children: "Dear Ada," }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "We are sorry your order arrived four days late. It left our warehouse on Monday and is with you by Thursday, 8 October." }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "Your next order ships free, with no code to enter." }), _jsx(Text, { as: "p", sx: { m: 0 }, children: "The support desk" })] }), _jsxs(Box, { display: "flex", gap: 2, mt: "auto", children: [_jsx(Button, { variant: "primary", children: "Send" }), _jsx(Button, { children: "Edit" })] })] })] }));
|
|
220
186
|
}
|
|
221
187
|
/** The activity of a worker: what it did on its own, as it did it. */
|
|
222
188
|
export function WorkerActivityScreen() {
|
|
223
|
-
return (_jsx(Frame, { children: _jsx(Box, {
|
|
189
|
+
return (_jsx(Frame, { children: _jsx(Box, { flex: 1, display: "flex", justifyContent: "center", children: _jsx(Box, { width: "100%", maxWidth: 680, display: "flex", children: _jsx(Conversation, { name: "Inbox triage", face: "\uD83D\uDCEC", presence: "working", items: WORKER_ACTIVITY, composer: false }) }) }) }));
|
|
224
190
|
}
|
|
225
191
|
/** An approval: the action, the rule that asks, and the one decision. */
|
|
226
192
|
export function ApprovalScreen() {
|
|
227
|
-
return (_jsx(Frame, { children: _jsx(Box, {
|
|
193
|
+
return (_jsx(Frame, { children: _jsx(Box, { flex: 1, display: "flex", justifyContent: "center", children: _jsx(Box, { width: "100%", maxWidth: 640, display: "flex", children: _jsx(Conversation, { name: "Support desk", face: "\uD83E\uDD8A", presence: "waiting", items: APPROVAL }) }) }) }));
|
|
228
194
|
}
|
|
229
195
|
/** Tool calls, each led by the mark of whoever the tool belongs to. */
|
|
230
196
|
export function ToolMarksScreen() {
|
|
231
|
-
return (_jsx(Frame, { children: _jsx(Box, {
|
|
197
|
+
return (_jsx(Frame, { children: _jsx(Box, { flex: 1, display: "flex", justifyContent: "center", children: _jsx(Box, { width: "100%", maxWidth: 680, display: "flex", children: _jsx(Conversation, { name: "Bookkeeper", face: "\uD83E\uDDEE", presence: "idle", items: TOOL_MARKS, composer: false, mcpServers: TOOL_MARKS_SERVERS }) }) }) }));
|
|
232
198
|
}
|
|
233
199
|
export const REFERENCE_SCREEN_COMPONENTS = {
|
|
234
200
|
conversation: ConversationScreen,
|
|
@@ -284,20 +250,7 @@ export function AssistantScreen({ picture, }) {
|
|
|
284
250
|
? 'working'
|
|
285
251
|
: picture;
|
|
286
252
|
const balloon = BALLOONS[picture];
|
|
287
|
-
return (_jsxs(Box, {
|
|
288
|
-
position: 'fixed',
|
|
289
|
-
right: 24,
|
|
290
|
-
bottom: 24,
|
|
291
|
-
width: 280,
|
|
292
|
-
height: 160,
|
|
293
|
-
p: 3,
|
|
294
|
-
zIndex: 2000,
|
|
295
|
-
bg: 'canvas.overlay',
|
|
296
|
-
border: 'var(--theme-hairline, 1px) solid',
|
|
297
|
-
borderColor: 'border.default',
|
|
298
|
-
borderRadius: 'var(--theme-radius-card, 6px)',
|
|
299
|
-
boxShadow: 'var(--theme-shadow, none)',
|
|
300
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "A dialog" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1 }, children: "The assistant steps aside while this is open." })] })), _jsx(AssistantStage, { character: "paperclip", state: state, place: { right: 48, bottom: 48 }, stageRef: stageRef, onDragStart: () => undefined, open: picture === 'open', onToggle: () => undefined, balloon: balloon, balloonDisplay: picture === 'current' ? 'current' : 'history', insist: !!balloon, onDismiss: () => undefined })] }));
|
|
253
|
+
return (_jsxs(Box, { flex: 1, position: "relative", children: [picture === 'open' && _jsx(OpenConversation, {}), picture === 'aside' && (_jsxs(Box, { role: "dialog", "aria-label": "A dialog over the assistant", position: "fixed", right: 24, bottom: 24, width: 280, height: 160, p: 3, zIndex: 2000, bg: "canvas.overlay", border: "var(--theme-hairline, 1px) solid", borderColor: "border.default", borderRadius: "var(--theme-radius-card, 6px)", boxShadow: "var(--theme-shadow, none)", children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "A dialog" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1 }, children: "The assistant steps aside while this is open." })] })), _jsx(AssistantStage, { character: "paperclip", state: state, place: { right: 48, bottom: 48 }, stageRef: stageRef, onDragStart: () => undefined, open: picture === 'open', onToggle: () => undefined, balloon: balloon, balloonDisplay: picture === 'current' ? 'current' : 'history', insist: !!balloon, onDismiss: () => undefined })] }));
|
|
301
254
|
}
|
|
302
255
|
/** What the open picture's conversation holds. */
|
|
303
256
|
const OPEN_CONVERSATION = [
|
|
@@ -316,37 +269,10 @@ function OpenConversation() {
|
|
|
316
269
|
const [input, setInput] = useState('');
|
|
317
270
|
const height = conversationBalloonHeight(window.innerHeight);
|
|
318
271
|
const left = window.innerWidth - 48 - CONVERSATION_BALLOON_WIDTH;
|
|
319
|
-
return (_jsxs(Box, { "data-conversation-balloon": "", sx: {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
width: `${CONVERSATION_BALLOON_WIDTH}px`,
|
|
324
|
-
height: `${height}px`,
|
|
325
|
-
zIndex: 1001,
|
|
326
|
-
display: 'flex',
|
|
327
|
-
flexDirection: 'column',
|
|
328
|
-
bg: 'canvas.default',
|
|
329
|
-
border: '1px solid',
|
|
330
|
-
borderColor: 'border.default',
|
|
331
|
-
boxShadow: 'shadow.extra-large',
|
|
332
|
-
...conversationBalloonSx({
|
|
333
|
-
edge: 'bottom',
|
|
334
|
-
at: balloonTailAt(window.innerWidth - 48 - 44, left),
|
|
335
|
-
}, 'canvas.subtle'),
|
|
336
|
-
}, children: [_jsx(ConversationBalloonClose, { onClose: () => undefined }), _jsx(ConversationBalloonHeader, { count: OPEN_CONVERSATION.length - 1 }), _jsxs(Box, { sx: {
|
|
337
|
-
flex: 1,
|
|
338
|
-
minHeight: 0,
|
|
339
|
-
display: 'flex',
|
|
340
|
-
flexDirection: 'column',
|
|
341
|
-
borderRadius: 'var(--theme-radius-bubble, 16px)',
|
|
342
|
-
overflow: 'hidden',
|
|
343
|
-
}, children: [_jsx(Box, { sx: { flex: 1, minHeight: 0, overflow: 'auto' }, children: _jsx(ChatMessageList, { displayItems: OPEN_CONVERSATION, isLoading: false, isStreaming: false, showLoadingIndicator: false, hideMessagesAfterToolUI: false, avatarConfig: { ...AVATARS, showAvatars: true }, padding: 2, emptyContent: null, messagesEndRef: endRef, onRespond: async () => undefined }) }), _jsx(Box, { sx: {
|
|
344
|
-
px: 3,
|
|
345
|
-
pb: 1,
|
|
346
|
-
display: 'flex',
|
|
347
|
-
justifyContent: 'flex-end',
|
|
348
|
-
fontSize: 0,
|
|
349
|
-
}, children: _jsx(DecisionAsk, { ask: async () => ({}) }) }), _jsx(InputPrompt, { input: input, setInput: setInput, isLoading: false, connectionConfirmed: true, placeholder: "Type a message...", autoFocus: false, padding: 2, promptVariant: "lexical", onSend: () => undefined, onStop: () => undefined, showTokenUsage: false, showModelSelector: false, showToolsMenu: false, showSkillsMenu: false, showAgentsMenu: false, codemodeEnabled: false, hasConfigData: false, hasSkillsData: false, isA2AProtocol: false })] })] }));
|
|
272
|
+
return (_jsxs(Box, { "data-conversation-balloon": "", position: "fixed", right: "48px", bottom: `${48 + 88 + 16}px`, width: `${CONVERSATION_BALLOON_WIDTH}px`, height: `${height}px`, zIndex: 1001, display: "flex", flexDirection: "column", bg: "canvas.default", border: "1px solid", borderColor: "border.default", boxShadow: "shadow.extra-large", sx: conversationBalloonSx({
|
|
273
|
+
edge: 'bottom',
|
|
274
|
+
at: balloonTailAt(window.innerWidth - 48 - 44, left),
|
|
275
|
+
}, 'canvas.subtle'), children: [_jsx(ConversationBalloonClose, { onClose: () => undefined }), _jsx(ConversationBalloonHeader, { count: OPEN_CONVERSATION.length - 1 }), _jsxs(Box, { flex: 1, minHeight: 0, display: "flex", flexDirection: "column", borderRadius: "var(--theme-radius-bubble, 16px)", overflow: "hidden", children: [_jsx(Box, { flex: 1, minHeight: 0, overflow: "auto", children: _jsx(ChatMessageList, { displayItems: OPEN_CONVERSATION, isLoading: false, isStreaming: false, showLoadingIndicator: false, hideMessagesAfterToolUI: false, avatarConfig: { ...AVATARS, showAvatars: true }, padding: 2, emptyContent: null, messagesEndRef: endRef, onRespond: async () => undefined }) }), _jsx(Box, { px: 3, pb: 1, display: "flex", justifyContent: "flex-end", fontSize: 0, children: _jsx(DecisionAsk, { ask: async () => ({}) }) }), _jsx(InputPrompt, { input: input, setInput: setInput, isLoading: false, connectionConfirmed: true, placeholder: "Type a message...", autoFocus: false, padding: 2, promptVariant: "lexical", onSend: () => undefined, onStop: () => undefined, showTokenUsage: false, showModelSelector: false, showToolsMenu: false, showSkillsMenu: false, showAgentsMenu: false, codemodeEnabled: false, hasConfigData: false, hasSkillsData: false, isA2AProtocol: false })] })] }));
|
|
350
276
|
}
|
|
351
277
|
// ---------------------------------------------------------------------------
|
|
352
278
|
// The characters (T-25, T-24)
|
|
@@ -364,5 +290,5 @@ characterReactor.start();
|
|
|
364
290
|
export function CharacterScreen({ character, ready, }) {
|
|
365
291
|
const stageRef = useRef(null);
|
|
366
292
|
const drawn = assistantCharacterNamed(characterReactor, character);
|
|
367
|
-
return (_jsxs(Box, {
|
|
293
|
+
return (_jsxs(Box, { flex: 1, position: "relative", children: [_jsx(AssistantStage, { character: drawn, state: "idle", place: { right: 48, bottom: 48 }, stageRef: stageRef, onDragStart: () => undefined, open: false, onToggle: () => undefined, onDismiss: () => undefined }), ready] }));
|
|
368
294
|
}
|
|
@@ -68,7 +68,7 @@ function Ready() {
|
|
|
68
68
|
*/
|
|
69
69
|
function GalleryScreen() {
|
|
70
70
|
const { characters, ready } = useGalleryCharacters();
|
|
71
|
-
return (_jsxs(Box, {
|
|
71
|
+
return (_jsxs(Box, { flex: 1, bg: "canvas.default", p: 2, overflow: "hidden", children: [_jsx(AssistantGalleryGrid, { characters: characters }), ready && _jsx(Ready, {})] }));
|
|
72
72
|
}
|
|
73
73
|
function Page() {
|
|
74
74
|
if (gallery) {
|
|
@@ -670,8 +670,11 @@ export interface AppUploadsSpec {
|
|
|
670
670
|
/** What the user of an application sees. */
|
|
671
671
|
export interface AppInterfaceSpec {
|
|
672
672
|
layout: AppLayout;
|
|
673
|
-
/**
|
|
674
|
-
|
|
673
|
+
/**
|
|
674
|
+
* Its one colour, over whichever theme it runs in; unsaid, it wears the
|
|
675
|
+
* theme's own colours (decided 2026-10-07).
|
|
676
|
+
*/
|
|
677
|
+
accent?: AppAccent;
|
|
675
678
|
/** The theme it runs in by default; the person's own when unsaid (T-30). */
|
|
676
679
|
theme?: AppThemeSpec;
|
|
677
680
|
welcome: string;
|
package/lib/types/protocol.d.ts
CHANGED
|
@@ -67,6 +67,8 @@ export interface ProtocolAdapterConfig {
|
|
|
67
67
|
maxReconnectAttempts?: number;
|
|
68
68
|
/** Request timeout in milliseconds */
|
|
69
69
|
timeout?: number;
|
|
70
|
+
/** The fetch to use; a phone passes one whose response body streams (e.g. `expo/fetch`). Default: the global `fetch`. */
|
|
71
|
+
fetch?: typeof fetch;
|
|
70
72
|
/** Additional protocol-specific options */
|
|
71
73
|
options?: Record<string, unknown>;
|
|
72
74
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalised approval record. Both snake_case (server-native) and
|
|
3
|
+
* camelCase (TypeScript-idiomatic) keys are present so existing UI
|
|
4
|
+
* consumers keep working regardless of which naming they read.
|
|
5
|
+
*/
|
|
6
|
+
export type ApprovalRecord = {
|
|
7
|
+
id: string;
|
|
8
|
+
agent_id: string;
|
|
9
|
+
agentId: string;
|
|
10
|
+
runtime_name: string;
|
|
11
|
+
runtimeName: string;
|
|
12
|
+
tool_name: string;
|
|
13
|
+
toolName: string;
|
|
14
|
+
tool_call_id?: string;
|
|
15
|
+
toolCallId?: string;
|
|
16
|
+
tool_args: Record<string, unknown>;
|
|
17
|
+
toolArgs: Record<string, unknown>;
|
|
18
|
+
status: string;
|
|
19
|
+
note?: string | null;
|
|
20
|
+
requester_uid?: string;
|
|
21
|
+
requesterUid?: string;
|
|
22
|
+
requested_by?: string;
|
|
23
|
+
requestedBy?: string;
|
|
24
|
+
resolved_by?: string;
|
|
25
|
+
resolvedBy?: string;
|
|
26
|
+
resolved_at?: string;
|
|
27
|
+
resolvedAt?: string;
|
|
28
|
+
created_at: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
updated_at?: string;
|
|
31
|
+
updatedAt?: string;
|
|
32
|
+
read?: boolean;
|
|
33
|
+
};
|
|
34
|
+
/** An approval as the server or the `/ws` stream sends it; null without an id. */
|
|
35
|
+
export declare function normalizeApproval(raw: unknown): ApprovalRecord | null;
|
|
36
|
+
/** An approval's arguments, under either key: the web reads `tool_args`, mobile `toolArgs`. */
|
|
37
|
+
export type ApprovalArgs = {
|
|
38
|
+
tool_args?: Record<string, unknown>;
|
|
39
|
+
toolArgs?: Record<string, unknown>;
|
|
40
|
+
};
|
|
41
|
+
/** A message it asks to send, as the approval carries it, whole (LOOP W-05). */
|
|
42
|
+
export type MessageAsked = {
|
|
43
|
+
to: string;
|
|
44
|
+
cc: string;
|
|
45
|
+
bcc: string;
|
|
46
|
+
subject: string;
|
|
47
|
+
body: string;
|
|
48
|
+
/** It forwards a message received, named by its id. */
|
|
49
|
+
forwards: boolean;
|
|
50
|
+
/** A reply, in the conversation it names. */
|
|
51
|
+
replies: boolean;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The message a send asks for, to show whole before *Approve* (LOOP W-05):
|
|
55
|
+
* an approval whose arguments say to whom and what. `null` for anything else.
|
|
56
|
+
*/
|
|
57
|
+
export declare function messageOfApproval(approval: ApprovalArgs): MessageAsked | null;
|
|
58
|
+
/** Why it was asked: the rule (`_rule`) or the check (`_check`). */
|
|
59
|
+
export declare const whyAsked: (approval: ApprovalArgs) => string;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
function str(value) {
|
|
6
|
+
return typeof value === 'string' ? value : value == null ? '' : String(value);
|
|
7
|
+
}
|
|
8
|
+
/** An approval as the server or the `/ws` stream sends it; null without an id. */
|
|
9
|
+
export function normalizeApproval(raw) {
|
|
10
|
+
if (!raw || typeof raw !== 'object')
|
|
11
|
+
return null;
|
|
12
|
+
const rec = raw;
|
|
13
|
+
const idSource = rec.id ?? rec.approval_id ?? rec.approvalId;
|
|
14
|
+
const id = typeof idSource === 'string' ? idSource : undefined;
|
|
15
|
+
if (!id)
|
|
16
|
+
return null;
|
|
17
|
+
const agent = str(rec.agent_id ?? rec.agentId);
|
|
18
|
+
const pod = str(rec.runtime_name ?? rec.runtimeName);
|
|
19
|
+
const tool = str(rec.tool_name ?? rec.toolName ?? 'unknown');
|
|
20
|
+
const toolCall = rec.tool_call_id ?? rec.toolCallId;
|
|
21
|
+
const args = rec.tool_args ??
|
|
22
|
+
rec.toolArgs ??
|
|
23
|
+
{};
|
|
24
|
+
const created = str(rec.created_at ?? rec.createdAt);
|
|
25
|
+
const updated = str(rec.updated_at ?? rec.updatedAt);
|
|
26
|
+
const resolvedBy = str(rec.resolved_by ?? rec.resolvedBy);
|
|
27
|
+
const requesterUid = str(rec.requester_uid ?? rec.requesterUid);
|
|
28
|
+
const requestedBy = str(rec.requested_by ?? rec.requestedBy);
|
|
29
|
+
const resolvedAtRaw = str(rec.resolved_at ?? rec.resolvedAt);
|
|
30
|
+
const status = str(rec.status ?? 'pending');
|
|
31
|
+
// Keep reviewer metadata from WS payloads. If this is dropped during
|
|
32
|
+
// normalization, downstream pages receive status=approved/rejected but no
|
|
33
|
+
// reviewer/timestamp context and can incorrectly render "review pending".
|
|
34
|
+
// Some producers only set updated_at on decision; for non-pending statuses,
|
|
35
|
+
// fall back to updated_at so UI can still show a decision time.
|
|
36
|
+
const resolvedAt = resolvedAtRaw || (status !== 'pending' ? updated || undefined : undefined);
|
|
37
|
+
return {
|
|
38
|
+
id,
|
|
39
|
+
agent_id: agent,
|
|
40
|
+
agentId: agent,
|
|
41
|
+
runtime_name: pod,
|
|
42
|
+
runtimeName: pod,
|
|
43
|
+
tool_name: tool,
|
|
44
|
+
toolName: tool,
|
|
45
|
+
tool_call_id: typeof toolCall === 'string' ? toolCall : undefined,
|
|
46
|
+
toolCallId: typeof toolCall === 'string' ? toolCall : undefined,
|
|
47
|
+
tool_args: args,
|
|
48
|
+
toolArgs: args,
|
|
49
|
+
status,
|
|
50
|
+
note: typeof rec.note === 'string'
|
|
51
|
+
? rec.note
|
|
52
|
+
: rec.note === null
|
|
53
|
+
? null
|
|
54
|
+
: undefined,
|
|
55
|
+
requester_uid: requesterUid || undefined,
|
|
56
|
+
requesterUid: requesterUid || undefined,
|
|
57
|
+
requested_by: requestedBy || undefined,
|
|
58
|
+
requestedBy: requestedBy || undefined,
|
|
59
|
+
resolved_by: resolvedBy || undefined,
|
|
60
|
+
resolvedBy: resolvedBy || undefined,
|
|
61
|
+
resolved_at: resolvedAt,
|
|
62
|
+
resolvedAt: resolvedAt,
|
|
63
|
+
created_at: created,
|
|
64
|
+
createdAt: created,
|
|
65
|
+
updated_at: updated || undefined,
|
|
66
|
+
updatedAt: updated || undefined,
|
|
67
|
+
read: typeof rec.read === 'boolean' ? rec.read : undefined,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const argsOf = (approval) => approval.tool_args ?? approval.toolArgs ?? {};
|
|
71
|
+
const said = (approval, key) => {
|
|
72
|
+
const value = argsOf(approval)[key];
|
|
73
|
+
return typeof value === 'string' ? value : '';
|
|
74
|
+
};
|
|
75
|
+
const addressed = (value) => Array.isArray(value)
|
|
76
|
+
? value.filter(item => typeof item === 'string').join(', ')
|
|
77
|
+
: typeof value === 'string'
|
|
78
|
+
? value
|
|
79
|
+
: '';
|
|
80
|
+
/**
|
|
81
|
+
* The message a send asks for, to show whole before *Approve* (LOOP W-05):
|
|
82
|
+
* an approval whose arguments say to whom and what. `null` for anything else.
|
|
83
|
+
*/
|
|
84
|
+
export function messageOfApproval(approval) {
|
|
85
|
+
const args = argsOf(approval);
|
|
86
|
+
const to = addressed(args.to);
|
|
87
|
+
if (!to || typeof args.body !== 'string') {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
to,
|
|
92
|
+
cc: addressed(args.cc),
|
|
93
|
+
bcc: addressed(args.bcc),
|
|
94
|
+
subject: said(approval, 'subject'),
|
|
95
|
+
body: args.body,
|
|
96
|
+
forwards: Boolean(said(approval, 'forward_message_id')),
|
|
97
|
+
replies: Boolean(said(approval, 'thread_id') || said(approval, 'in_reply_to')),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Why it was asked: the rule (`_rule`) or the check (`_check`). */
|
|
101
|
+
export const whyAsked = (approval) => said(approval, '_rule') || said(approval, '_check');
|
package/lib/voice/VoiceInput.js
CHANGED
|
@@ -158,24 +158,7 @@ export function VoiceInput({ hearing, language, onTranscript, onListen, consentK
|
|
|
158
158
|
const label = listening
|
|
159
159
|
? 'Listening — let go to stop'
|
|
160
160
|
: 'Hold to talk (Ctrl+Space)';
|
|
161
|
-
return (_jsxs(Box, { "data-voice-input": state, sx: {
|
|
162
|
-
display: 'inline-flex',
|
|
163
|
-
alignItems: 'center',
|
|
164
|
-
gap: 1,
|
|
165
|
-
position: 'relative',
|
|
166
|
-
}, children: [speaking && onStopSpeaking && (_jsx(Tooltip, { text: "Stop speaking (Esc)", direction: "n", children: _jsx(IconButton, { icon: MuteIcon, "aria-label": "Stop speaking", size: "small", variant: "invisible", "data-voice-stop": "", onClick: onStopSpeaking }) })), listening && (_jsx(Box, { "aria-hidden": "true", sx: {
|
|
167
|
-
width: 40,
|
|
168
|
-
height: 4,
|
|
169
|
-
borderRadius: 2,
|
|
170
|
-
bg: 'neutral.muted',
|
|
171
|
-
overflow: 'hidden',
|
|
172
|
-
}, children: _jsx(Box, { ref: meter, sx: {
|
|
173
|
-
width: '100%',
|
|
174
|
-
height: '100%',
|
|
175
|
-
bg: 'danger.emphasis',
|
|
176
|
-
transformOrigin: 'left',
|
|
177
|
-
transform: prefersStill() ? 'scaleX(1)' : 'scaleX(0.04)',
|
|
178
|
-
} }) })), (state === 'loading' || state === 'hearing') && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, "data-voice-progress": "", children: state === 'loading' && progress !== undefined ? `${progress}%` : '…' })), _jsx(Tooltip, { text: label, direction: "n", children: _jsx(IconButton, { icon: () => _jsx(MicrophoneIcon, { size: 16 }), "aria-label": label, "aria-pressed": listening, size: "small", variant: listening ? 'danger' : 'invisible', disabled: disabled || state === 'hearing', "data-voice-mic": "", onPointerDown: event => {
|
|
161
|
+
return (_jsxs(Box, { "data-voice-input": state, display: "inline-flex", alignItems: "center", gap: 1, position: "relative", children: [speaking && onStopSpeaking && (_jsx(Tooltip, { text: "Stop speaking (Esc)", direction: "n", children: _jsx(IconButton, { icon: MuteIcon, "aria-label": "Stop speaking", size: "small", variant: "invisible", "data-voice-stop": "", onClick: onStopSpeaking }) })), listening && (_jsx(Box, { "aria-hidden": "true", width: 40, height: 4, borderRadius: 2, bg: "neutral.muted", overflow: "hidden", children: _jsx(Box, { ref: meter, width: "100%", height: "100%", bg: "danger.emphasis", transformOrigin: "left", transform: prefersStill() ? 'scaleX(1)' : 'scaleX(0.04)' }) })), (state === 'loading' || state === 'hearing') && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, "data-voice-progress": "", children: state === 'loading' && progress !== undefined ? `${progress}%` : '…' })), _jsx(Tooltip, { text: label, direction: "n", children: _jsx(IconButton, { icon: () => _jsx(MicrophoneIcon, { size: 16 }), "aria-label": label, "aria-pressed": listening, size: "small", variant: listening ? 'danger' : 'invisible', disabled: disabled || state === 'hearing', "data-voice-mic": "", onPointerDown: event => {
|
|
179
162
|
if (event.button !== 0) {
|
|
180
163
|
return;
|
|
181
164
|
}
|
|
@@ -203,31 +186,12 @@ export function VoiceInput({ hearing, language, onTranscript, onListen, consentK
|
|
|
203
186
|
void start();
|
|
204
187
|
}
|
|
205
188
|
}
|
|
206
|
-
} }) }), state === 'asking' && (_jsxs(Box, { role: "dialog", "aria-label": "Talk instead of typing", "data-voice-consent": "", sx: {
|
|
207
|
-
position: 'absolute',
|
|
208
|
-
bottom: '100%',
|
|
209
|
-
right: 0,
|
|
210
|
-
mb: 2,
|
|
211
|
-
width: 280,
|
|
212
|
-
p: 3,
|
|
213
|
-
bg: 'canvas.overlay',
|
|
214
|
-
border: '1px solid',
|
|
215
|
-
borderColor: 'border.default',
|
|
216
|
-
borderRadius: 2,
|
|
217
|
-
boxShadow: 'shadow.large',
|
|
218
|
-
zIndex: 10,
|
|
219
|
-
}, children: [_jsx(Text, { as: "p", sx: { fontSize: 1, mb: 2 }, children: CONSENT_SENTENCE }), _jsxs(Box, { sx: { display: 'flex', gap: 2, justifyContent: 'flex-end' }, children: [_jsx(Button, { size: "small", onClick: () => setState('idle'), children: "Not now" }), _jsx(Button, { size: "small", variant: "primary", "data-voice-consent-yes": "", onClick: () => {
|
|
189
|
+
} }) }), state === 'asking' && (_jsxs(Box, { role: "dialog", "aria-label": "Talk instead of typing", "data-voice-consent": "", position: "absolute", bottom: "100%", right: 0, mb: 2, width: 280, p: 3, bg: "canvas.overlay", border: "1px solid", borderColor: "border.default", borderRadius: 2, boxShadow: "shadow.large", zIndex: 10, children: [_jsx(Text, { as: "p", sx: { fontSize: 1, mb: 2 }, children: CONSENT_SENTENCE }), _jsxs(Box, { display: "flex", gap: 2, justifyContent: "flex-end", children: [_jsx(Button, { size: "small", onClick: () => setState('idle'), children: "Not now" }), _jsx(Button, { size: "small", variant: "primary", "data-voice-consent-yes": "", onClick: () => {
|
|
220
190
|
consent(consentKey);
|
|
221
191
|
// Asked, and said yes: listen now, without another press.
|
|
222
192
|
stateRef.current = 'idle';
|
|
223
193
|
setState('idle');
|
|
224
194
|
void start();
|
|
225
|
-
}, children: "Use the microphone" })] })] })), _jsx(Box, { as: "span", role: "status", "aria-live": "polite", sx: {
|
|
226
|
-
position: 'absolute',
|
|
227
|
-
width: 1,
|
|
228
|
-
height: 1,
|
|
229
|
-
overflow: 'hidden',
|
|
230
|
-
clip: 'rect(0 0 0 0)',
|
|
231
|
-
}, children: WORDS[state] || said }), problem && (_jsx(Text, { role: "alert", sx: { fontSize: 0, color: 'danger.fg', maxWidth: 220 }, "data-voice-problem": "", children: problem }))] }));
|
|
195
|
+
}, children: "Use the microphone" })] })] })), _jsx(Box, { as: "span", role: "status", "aria-live": "polite", position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", children: WORDS[state] || said }), problem && (_jsx(Text, { role: "alert", sx: { fontSize: 0, color: 'danger.fg', maxWidth: 220 }, "data-voice-problem": "", children: problem }))] }));
|
|
232
196
|
}
|
|
233
197
|
export default VoiceInput;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/agent-runtimes",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.90",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
"@datalayer/jupyter-react": "^2.0.20",
|
|
155
155
|
"@datalayer/jupyter-server-nbmodel": "^0.2.8",
|
|
156
156
|
"@datalayer/lexical-loro": "^1.0.6",
|
|
157
|
-
"@datalayer/primer-addons": "^1.0.
|
|
157
|
+
"@datalayer/primer-addons": "^1.0.39",
|
|
158
158
|
"@datalayer/primer-rjsf": "^1.0.3",
|
|
159
159
|
"@datalayer/reactor": "^1.0.4",
|
|
160
160
|
"@datalayer/reactor-commands": "^1.0.4",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Box as default, Box } from '@primer/react';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
// Runtime shim: force the primer-addons Box export to use Primer's Box.
|
|
6
|
-
// This prevents `sx` from being forwarded to raw DOM nodes as an attribute.
|
|
7
|
-
export { Box as default, Box } from '@primer/react';
|