@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
|
@@ -4,7 +4,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import React, { useCallback } from 'react';
|
|
7
|
-
import { Box
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { Text, Button, Label, Flash, ActionList, ActionMenu, Avatar, } from '@primer/react';
|
|
8
9
|
import { MarkGithubIcon, LinkIcon, UnlinkIcon, CheckCircleFillIcon, AlertIcon, KeyIcon, } from '@primer/octicons-react';
|
|
9
10
|
import { useIdentity } from './useIdentity';
|
|
10
11
|
import { GITHUB_PROVIDER, GOOGLE_PROVIDER, KAGGLE_PROVIDER } from './types';
|
|
@@ -154,39 +155,21 @@ export const IdentityButton = ({ provider, clientId, providerConfig, scopes, dis
|
|
|
154
155
|
width: size === 'small' ? 28 : size === 'large' ? 44 : 36,
|
|
155
156
|
height: size === 'small' ? 28 : size === 'large' ? 44 : 36,
|
|
156
157
|
p: 0,
|
|
157
|
-
}, children: isPending ? (_jsx(Box, { as: "span", className: "anim-rotate",
|
|
158
|
+
}, children: isPending ? (_jsx(Box, { as: "span", className: "anim-rotate", display: "inline-block", children: "\u23F3" })) : (_jsx(display.icon, { size: size === 'small' ? 14 : 18 })) }));
|
|
158
159
|
}
|
|
159
160
|
if (variant === 'compact') {
|
|
160
161
|
return (_jsx(Button, { ...buttonProps, variant: isConnected ? 'primary' : 'default', leadingVisual: display.icon, trailingVisual: isConnected ? CheckCircleFillIcon : undefined, children: isPending ? 'Connecting...' : display.name }));
|
|
161
162
|
}
|
|
162
163
|
// Full variant
|
|
163
|
-
return (_jsxs(Box, { sx: {
|
|
164
|
-
display: 'flex',
|
|
165
|
-
flexDirection: 'column',
|
|
166
|
-
gap: 2,
|
|
167
|
-
p: 2,
|
|
168
|
-
border: '1px solid',
|
|
169
|
-
borderColor: isConnected ? 'success.muted' : 'border.default',
|
|
170
|
-
borderRadius: 2,
|
|
171
|
-
backgroundColor: isConnected ? 'success.subtle' : 'canvas.subtle',
|
|
172
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { sx: {
|
|
173
|
-
width: 40,
|
|
174
|
-
height: 40,
|
|
175
|
-
borderRadius: 2,
|
|
176
|
-
display: 'flex',
|
|
177
|
-
alignItems: 'center',
|
|
178
|
-
justifyContent: 'center',
|
|
179
|
-
backgroundColor: display.color,
|
|
180
|
-
color: 'white',
|
|
181
|
-
}, children: _jsx(display.icon, { size: 20 }) }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'bold', display: 'block' }, children: display.name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: isConnected && identity?.userInfo
|
|
164
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, p: 2, border: "1px solid", borderColor: isConnected ? 'success.muted' : 'border.default', borderRadius: 2, backgroundColor: isConnected ? 'success.subtle' : 'canvas.subtle', children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Box, { width: 40, height: 40, borderRadius: 2, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: display.color, color: "white", children: _jsx(display.icon, { size: 20 }) }), _jsxs(Box, { flex: 1, children: [_jsx(Text, { sx: { fontWeight: 'bold', display: 'block' }, children: display.name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: isConnected && identity?.userInfo
|
|
182
165
|
? `Connected as ${identity.userInfo.name || identity.userInfo.email}`
|
|
183
|
-
: display.description })] }), !isConnected && (_jsx(Button, { ...buttonProps, variant: "primary", leadingVisual: LinkIcon, children: isPending ? 'Working...' : 'Connect' }))] }), isConnected && identity && (_jsxs(Box, {
|
|
166
|
+
: display.description })] }), !isConnected && (_jsx(Button, { ...buttonProps, variant: "primary", leadingVisual: LinkIcon, children: isPending ? 'Working...' : 'Connect' }))] }), isConnected && identity && (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, pl: 1, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
184
167
|
`https://github.com/${identity.userInfo.username}`, target: "_blank", rel: "noopener noreferrer", style: { display: 'block', lineHeight: 0 }, children: _jsx("img", { src: identity.userInfo.avatarUrl, alt: identity.userInfo.name || 'User avatar', style: {
|
|
185
168
|
width: 32,
|
|
186
169
|
height: 32,
|
|
187
170
|
borderRadius: '50%',
|
|
188
171
|
cursor: 'pointer',
|
|
189
|
-
} }) })), _jsxs(Box, {
|
|
172
|
+
} }) })), _jsxs(Box, { flex: 1, children: [identity.userInfo?.username && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
190
173
|
`https://github.com/${identity.userInfo.username}`, target: "_blank", rel: "noopener noreferrer", style: { textDecoration: 'none' }, children: _jsxs(Text, { sx: {
|
|
191
174
|
fontSize: 1,
|
|
192
175
|
color: 'fg.muted',
|
|
@@ -194,7 +177,7 @@ export const IdentityButton = ({ provider, clientId, providerConfig, scopes, dis
|
|
|
194
177
|
':hover': { textDecoration: 'underline' },
|
|
195
178
|
}, children: ["@", identity.userInfo.username] }) })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: identity.token?.expiresAt
|
|
196
179
|
? `Expires ${new Date(identity.token.expiresAt).toLocaleDateString()}`
|
|
197
|
-
: 'Token does not expire' })] })] }), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, {
|
|
180
|
+
: 'Token does not expire' })] })] }), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 1, pl: 1, children: identity.scopes.map(scope => (_jsx(Text, { sx: {
|
|
198
181
|
fontSize: 0,
|
|
199
182
|
px: 2,
|
|
200
183
|
py: 1,
|
|
@@ -220,43 +203,14 @@ export const IdentityConnect = ({ providers, layout = 'list', showHeader = true,
|
|
|
220
203
|
onError?.(provider, err);
|
|
221
204
|
}, [onError]);
|
|
222
205
|
if (layout === 'inline') {
|
|
223
|
-
return (_jsxs(Box, {
|
|
206
|
+
return (_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [showHeader && (_jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted', mr: 2 }, children: [title, ":"] })), providerKeys.map(provider => {
|
|
224
207
|
const config = providers[provider];
|
|
225
208
|
return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: size, variant: "icon", disabled: disabled, onConnect: handleConnect, onDisconnect: handleDisconnect, onError: handleError(provider) }, provider));
|
|
226
|
-
}), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span",
|
|
227
|
-
mr: 1,
|
|
228
|
-
display: 'inline-flex',
|
|
229
|
-
verticalAlign: 'text-bottom',
|
|
230
|
-
}, children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] }));
|
|
209
|
+
}), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", mr: 1, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] }));
|
|
231
210
|
}
|
|
232
|
-
return (_jsxs(Box, { sx: {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
borderRadius: 2,
|
|
236
|
-
backgroundColor: 'canvas.default',
|
|
237
|
-
overflow: 'hidden',
|
|
238
|
-
}, children: [showHeader && (_jsxs(Box, { sx: {
|
|
239
|
-
px: 3,
|
|
240
|
-
py: 2,
|
|
241
|
-
borderBottom: '1px solid',
|
|
242
|
-
borderColor: 'border.default',
|
|
243
|
-
backgroundColor: 'canvas.subtle',
|
|
244
|
-
display: 'flex',
|
|
245
|
-
alignItems: 'center',
|
|
246
|
-
justifyContent: 'space-between',
|
|
247
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'bold' }, children: title }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", sx: {
|
|
248
|
-
mr: 1,
|
|
249
|
-
display: 'inline-flex',
|
|
250
|
-
verticalAlign: 'text-bottom',
|
|
251
|
-
}, children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] })), error && (_jsxs(Flash, { variant: "danger", sx: { m: 2, borderRadius: 1 }, children: [_jsx(Box, { as: "span", sx: { mr: 2, display: 'inline-flex', verticalAlign: 'text-bottom' }, children: _jsx(AlertIcon, { size: 16 }) }), error instanceof Error ? error.message : String(error)] })), _jsx(Box, { sx: {
|
|
252
|
-
p: 2,
|
|
253
|
-
display: layout === 'grid' ? 'grid' : 'flex',
|
|
254
|
-
flexDirection: layout === 'list' ? 'column' : undefined,
|
|
255
|
-
gridTemplateColumns: layout === 'grid'
|
|
256
|
-
? 'repeat(auto-fill, minmax(250px, 1fr))'
|
|
257
|
-
: undefined,
|
|
258
|
-
gap: 2,
|
|
259
|
-
}, children: providerKeys.map(provider => {
|
|
211
|
+
return (_jsxs(Box, { border: "1px solid", borderColor: "border.default", borderRadius: 2, backgroundColor: "canvas.default", overflow: "hidden", children: [showHeader && (_jsxs(Box, { px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.default", backgroundColor: "canvas.subtle", display: "flex", alignItems: "center", justifyContent: "space-between", children: [_jsx(Text, { sx: { fontWeight: 'bold' }, children: title }), connectedCount > 0 && (_jsxs(Label, { variant: "success", children: [_jsx(Box, { as: "span", mr: 1, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(CheckCircleFillIcon, { size: 12 }) }), connectedCount, " connected"] }))] })), error && (_jsxs(Flash, { variant: "danger", sx: { m: 2, borderRadius: 1 }, children: [_jsx(Box, { as: "span", mr: 2, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(AlertIcon, { size: 16 }) }), error instanceof Error ? error.message : String(error)] })), _jsx(Box, { p: 2, display: layout === 'grid' ? 'grid' : 'flex', flexDirection: layout === 'list' ? 'column' : undefined, gridTemplateColumns: layout === 'grid'
|
|
212
|
+
? 'repeat(auto-fill, minmax(250px, 1fr))'
|
|
213
|
+
: undefined, gap: 2, children: providerKeys.map(provider => {
|
|
260
214
|
const config = providers[provider];
|
|
261
215
|
return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: size, variant: showDescriptions ? 'full' : 'compact', disabled: disabled, onConnect: handleConnect, onDisconnect: handleDisconnect, onError: handleError(provider) }, provider));
|
|
262
216
|
}) })] }));
|
|
@@ -310,7 +264,7 @@ export const IdentityMenu = ({ providers, onConnect, onDisconnect, disabled = fa
|
|
|
310
264
|
const display = PROVIDER_DISPLAY[provider] || PROVIDER_DISPLAY.custom;
|
|
311
265
|
const identity = identities.find(id => id.provider === provider);
|
|
312
266
|
const isConnected = !!identity;
|
|
313
|
-
return (_jsxs(ActionList.Item, { onSelect: () => handleProviderClick(provider), disabled: isAuthorizing, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, {
|
|
267
|
+
return (_jsxs(ActionList.Item, { onSelect: () => handleProviderClick(provider), disabled: isAuthorizing, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Text, { children: display.name }), isConnected && (_jsxs(_Fragment, { children: [identity?.userInfo?.avatarUrl && (_jsx(Avatar, { src: identity.userInfo.avatarUrl, size: 16 })), _jsx(Label, { variant: "success", sx: { ml: 1 }, children: "Connected" })] }))] }), _jsx(ActionList.TrailingVisual, { children: isConnected ? (_jsx(UnlinkIcon, { size: 16 })) : (_jsx(LinkIcon, { size: 16 })) })] }, provider));
|
|
314
268
|
}) }) }) })] }));
|
|
315
269
|
};
|
|
316
270
|
export default IdentityConnect;
|
|
@@ -4,7 +4,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
|
-
import { Box
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { Text, Spinner, Flash, Button } from '@primer/react';
|
|
8
9
|
import { CheckCircleFillIcon, AlertIcon, XCircleIcon, } from '@primer/octicons-react';
|
|
9
10
|
import { useIdentityStore } from './identityStore';
|
|
10
11
|
/**
|
|
@@ -155,38 +156,12 @@ export const OAuthCallback = ({ successMessage = 'Account connected successfully
|
|
|
155
156
|
window.location.href = redirectUrl;
|
|
156
157
|
}
|
|
157
158
|
};
|
|
158
|
-
return (_jsx(Box, { sx: {
|
|
159
|
-
display: 'flex',
|
|
160
|
-
flexDirection: 'column',
|
|
161
|
-
alignItems: 'center',
|
|
162
|
-
justifyContent: 'center',
|
|
163
|
-
minHeight: '100vh',
|
|
164
|
-
padding: 4,
|
|
165
|
-
backgroundColor: 'canvas.default',
|
|
166
|
-
}, children: _jsxs(Box, { sx: {
|
|
167
|
-
maxWidth: 400,
|
|
168
|
-
width: '100%',
|
|
169
|
-
padding: 4,
|
|
170
|
-
borderRadius: 2,
|
|
171
|
-
border: '1px solid',
|
|
172
|
-
borderColor: 'border.default',
|
|
173
|
-
backgroundColor: 'canvas.subtle',
|
|
174
|
-
textAlign: 'center',
|
|
175
|
-
}, children: [status === 'processing' && (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: {
|
|
159
|
+
return (_jsx(Box, { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", minHeight: "100vh", padding: 4, backgroundColor: "canvas.default", children: _jsxs(Box, { maxWidth: 400, width: "100%", padding: 4, borderRadius: 2, border: "1px solid", borderColor: "border.default", backgroundColor: "canvas.subtle", textAlign: "center", children: [status === 'processing' && (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: {
|
|
176
160
|
display: 'block',
|
|
177
161
|
marginTop: 3,
|
|
178
162
|
fontSize: 2,
|
|
179
163
|
fontWeight: 'bold',
|
|
180
|
-
}, children: "Connecting your account..." }), _jsx(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: "Please wait while we complete the authorization." })] })), status === 'success' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
181
|
-
width: 64,
|
|
182
|
-
height: 64,
|
|
183
|
-
borderRadius: '50%',
|
|
184
|
-
backgroundColor: 'success.subtle',
|
|
185
|
-
display: 'flex',
|
|
186
|
-
alignItems: 'center',
|
|
187
|
-
justifyContent: 'center',
|
|
188
|
-
margin: '0 auto',
|
|
189
|
-
}, children: _jsx(Box, { sx: { color: 'success.fg' }, children: _jsx(CheckCircleFillIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
164
|
+
}, children: "Connecting your account..." }), _jsx(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: "Please wait while we complete the authorization." })] })), status === 'success' && (_jsxs(_Fragment, { children: [_jsx(Box, { width: 64, height: 64, borderRadius: "50%", backgroundColor: "success.subtle", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto", children: _jsx(Box, { color: "success.fg", children: _jsx(CheckCircleFillIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
190
165
|
display: 'block',
|
|
191
166
|
marginTop: 3,
|
|
192
167
|
fontSize: 2,
|
|
@@ -199,25 +174,12 @@ export const OAuthCallback = ({ successMessage = 'Account connected successfully
|
|
|
199
174
|
color: 'fg.muted',
|
|
200
175
|
}, children: isPopup
|
|
201
176
|
? 'This window will close automatically...'
|
|
202
|
-
: 'Redirecting...' })), showCloseButton && !shouldAutoClose && (_jsx(Button, { variant: "primary", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Continue' }))] })), status === 'error' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
203
|
-
width: 64,
|
|
204
|
-
height: 64,
|
|
205
|
-
borderRadius: '50%',
|
|
206
|
-
backgroundColor: 'danger.subtle',
|
|
207
|
-
display: 'flex',
|
|
208
|
-
alignItems: 'center',
|
|
209
|
-
justifyContent: 'center',
|
|
210
|
-
margin: '0 auto',
|
|
211
|
-
}, children: _jsx(Box, { sx: { color: 'danger.fg' }, children: _jsx(XCircleIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
177
|
+
: 'Redirecting...' })), showCloseButton && !shouldAutoClose && (_jsx(Button, { variant: "primary", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Continue' }))] })), status === 'error' && (_jsxs(_Fragment, { children: [_jsx(Box, { width: 64, height: 64, borderRadius: "50%", backgroundColor: "danger.subtle", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto", children: _jsx(Box, { color: "danger.fg", children: _jsx(XCircleIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
212
178
|
display: 'block',
|
|
213
179
|
marginTop: 3,
|
|
214
180
|
fontSize: 2,
|
|
215
181
|
fontWeight: 'bold',
|
|
216
182
|
color: 'danger.fg',
|
|
217
|
-
}, children: "Connection Failed" }), _jsxs(Flash, { variant: "danger", sx: { marginTop: 3, textAlign: 'left' }, children: [_jsx(Box, { as: "span", sx: {
|
|
218
|
-
mr: 2,
|
|
219
|
-
display: 'inline-flex',
|
|
220
|
-
verticalAlign: 'text-bottom',
|
|
221
|
-
}, children: _jsx(AlertIcon, { size: 16 }) }), errorMessagePrefix, ": ", error] }), showCloseButton && (_jsx(Button, { variant: "danger", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Go Back' }))] }))] }) }));
|
|
183
|
+
}, children: "Connection Failed" }), _jsxs(Flash, { variant: "danger", sx: { marginTop: 3, textAlign: 'left' }, children: [_jsx(Box, { as: "span", mr: 2, display: "inline-flex", verticalAlign: "text-bottom", children: _jsx(AlertIcon, { size: 16 }) }), errorMessagePrefix, ": ", error] }), showCloseButton && (_jsx(Button, { variant: "danger", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Go Back' }))] }))] }) }));
|
|
222
184
|
};
|
|
223
185
|
export default OAuthCallback;
|
|
@@ -4,7 +4,7 @@ import { createPortal } from 'react-dom';
|
|
|
4
4
|
import { $getSelection, $isRangeSelection, $createParagraphNode, $createTextNode, TextNode, COMMAND_PRIORITY_LOW, createCommand, } from 'lexical';
|
|
5
5
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
6
6
|
import { autoUpdate, hide, limitShift, offset, shift, size, useFloating, } from '@floating-ui/react-dom';
|
|
7
|
-
import { Box } from '@primer
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
8
|
import { ChatInline } from '../chat/ChatInline';
|
|
9
9
|
// Margin from editor edges
|
|
10
10
|
const MARGIN_X = 32;
|
|
@@ -209,18 +209,10 @@ export function ChatInlinePlugin({ protocol, isOpen, onClose, pendingPrompt, onP
|
|
|
209
209
|
return null;
|
|
210
210
|
}
|
|
211
211
|
const portalTarget = portalContainer || document.body;
|
|
212
|
-
return createPortal(_jsx(Box, { ref: setFloating,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
left: editor._rootElement
|
|
218
|
-
? editor._rootElement.getBoundingClientRect().left + MARGIN_X
|
|
219
|
-
: 0,
|
|
220
|
-
transform: `translate3d(0, ${Math.round(y)}px, 0)`,
|
|
221
|
-
width: editor._rootElement
|
|
222
|
-
? editor._rootElement.getBoundingClientRect().width - MARGIN_X * 2
|
|
223
|
-
: 'auto',
|
|
224
|
-
}, children: _jsx(ChatInline, { selectedText: effectiveText, protocol: protocol, onReplaceSelection: handleReplaceSelection, onInsertInline: handleInsertInline, onInsertBelow: handleInsertBelow, onClose: onClose, onSaveSelection: saveSelection, onRestoreSelection: restoreSelection, pendingPrompt: pendingPrompt, onPendingPromptConsumed: onPendingPromptConsumed }) }), portalTarget);
|
|
212
|
+
return createPortal(_jsx(Box, { ref: setFloating, pointerEvents: "auto", zIndex: 50, position: strategy, top: 0, left: editor._rootElement
|
|
213
|
+
? editor._rootElement.getBoundingClientRect().left + MARGIN_X
|
|
214
|
+
: 0, transform: `translate3d(0, ${Math.round(y)}px, 0)`, width: editor._rootElement
|
|
215
|
+
? editor._rootElement.getBoundingClientRect().width - MARGIN_X * 2
|
|
216
|
+
: 'auto', children: _jsx(ChatInline, { selectedText: effectiveText, protocol: protocol, onReplaceSelection: handleReplaceSelection, onInsertInline: handleInsertInline, onInsertBelow: handleInsertBelow, onClose: onClose, onSaveSelection: saveSelection, onRestoreSelection: restoreSelection, pendingPrompt: pendingPrompt, onPendingPromptConsumed: onPendingPromptConsumed }) }), portalTarget);
|
|
225
217
|
}
|
|
226
218
|
export default ChatInlinePlugin;
|
|
@@ -247,9 +247,10 @@ export declare const DATALAYER_BOOTSTRAP_AGENTSPEC = "example-simple";
|
|
|
247
247
|
* The application's accent over the theme its conversation wears, in both
|
|
248
248
|
* modes (LOOP T-05): its bubbles and its one button in its own colour, and
|
|
249
249
|
* not in the theme's default — the chat sets its theme again inside it, so
|
|
250
|
-
* what the page around it set does not reach in. The accents are
|
|
251
|
-
*
|
|
250
|
+
* what the page around it set does not reach in. The accents are the theme
|
|
251
|
+
* system's: laid over whatever theme it wears (T-30; decided 2026-10-07).
|
|
252
|
+
* Naming none, it wears the theme's own colours: nothing is laid.
|
|
252
253
|
*/
|
|
253
|
-
export declare function appThemeOverrides(app: AppSpec
|
|
254
|
+
export declare function appThemeOverrides(app: AppSpec): ThemeOverrides | undefined;
|
|
254
255
|
export declare function AppRenderer({ app, plugins, instance, onPresence, onSaying, paused, sidebar, computer, frame, page, pluginsOff, language, ...embed }: AppRendererProps): React.JSX.Element;
|
|
255
256
|
export default AppRenderer;
|
|
@@ -51,7 +51,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
51
51
|
*/
|
|
52
52
|
import { useMemo } from 'react';
|
|
53
53
|
import { defineExtension, } from '@datalayer/reactor';
|
|
54
|
-
import {
|
|
54
|
+
import { themeAccentVars, useSystemColorMode } from '@datalayer/primer-addons';
|
|
55
55
|
import { defineAgentCapacityPlugin } from '../plugins/agent-capacity';
|
|
56
56
|
import { APP_PAGE_SURFACE, defineAppHostPagePlugin, defineAppPagePlugin, hasAppPage, } from '../plugins/app-page';
|
|
57
57
|
import { CANVAS_BLOCK_PLUGINS, canvasBlocksPluginName, } from '../plugins/canvas-blocks';
|
|
@@ -316,15 +316,16 @@ const NO_PLUGINS = [];
|
|
|
316
316
|
* The application's accent over the theme its conversation wears, in both
|
|
317
317
|
* modes (LOOP T-05): its bubbles and its one button in its own colour, and
|
|
318
318
|
* not in the theme's default — the chat sets its theme again inside it, so
|
|
319
|
-
* what the page around it set does not reach in. The accents are
|
|
320
|
-
*
|
|
319
|
+
* what the page around it set does not reach in. The accents are the theme
|
|
320
|
+
* system's: laid over whatever theme it wears (T-30; decided 2026-10-07).
|
|
321
|
+
* Naming none, it wears the theme's own colours: nothing is laid.
|
|
321
322
|
*/
|
|
322
|
-
export function appThemeOverrides(app
|
|
323
|
+
export function appThemeOverrides(app) {
|
|
323
324
|
const accent = app.interface?.accent;
|
|
324
|
-
return accent
|
|
325
|
+
return accent
|
|
325
326
|
? {
|
|
326
|
-
light:
|
|
327
|
-
dark:
|
|
327
|
+
light: themeAccentVars(accent, 'light'),
|
|
328
|
+
dark: themeAccentVars(accent, 'dark'),
|
|
328
329
|
}
|
|
329
330
|
: undefined;
|
|
330
331
|
}
|
|
@@ -406,21 +407,19 @@ export function AppRenderer({ app, plugins = NO_PLUGINS, instance, onPresence, o
|
|
|
406
407
|
/*
|
|
407
408
|
* The theme it runs in (T-30): the one its host says, else the one its
|
|
408
409
|
* Appspec names, else the page's — the person's own. Its mode likewise;
|
|
409
|
-
* `auto` is the device's.
|
|
410
|
+
* `auto` is the device's. Its accent is laid over whichever it is.
|
|
410
411
|
*/
|
|
411
|
-
const pageTheme = useThemeStore(state => state.theme);
|
|
412
412
|
const system = useSystemColorMode();
|
|
413
413
|
const named = app.interface?.theme;
|
|
414
|
-
const worn = embed.themeVariant ?? named?.variant ?? pageTheme;
|
|
415
414
|
const namedMode = named?.mode === 'auto'
|
|
416
415
|
? system
|
|
417
416
|
: named?.mode === 'light' || named?.mode === 'dark'
|
|
418
417
|
? named.mode
|
|
419
418
|
: undefined;
|
|
420
419
|
const accent = app.interface?.accent;
|
|
421
|
-
const themeOverrides = useMemo(() => appThemeOverrides(app
|
|
420
|
+
const themeOverrides = useMemo(() => appThemeOverrides(app),
|
|
422
421
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
423
|
-
[accent
|
|
422
|
+
[accent]);
|
|
424
423
|
if ('problem' in preset) {
|
|
425
424
|
return (_jsx("div", { role: "status", style: { padding: 16 }, children: preset.problem }));
|
|
426
425
|
}
|
package/lib/loop/apps/appspec.js
CHANGED
|
@@ -122,7 +122,6 @@ export function emptyAppspec(kind = 'chat') {
|
|
|
122
122
|
},
|
|
123
123
|
interface: {
|
|
124
124
|
layout: DEFAULT_LAYOUTS[kind],
|
|
125
|
-
accent: 'green',
|
|
126
125
|
welcome: '',
|
|
127
126
|
starters: [],
|
|
128
127
|
commands: [],
|
|
@@ -463,7 +462,11 @@ function dumpPage(page) {
|
|
|
463
462
|
function parseInterface(data, kind) {
|
|
464
463
|
const parsed = {
|
|
465
464
|
layout: oneOf(data.layout, ['chat', 'page', 'split'], DEFAULT_LAYOUTS[kind]),
|
|
466
|
-
|
|
465
|
+
// Unsaid, the theme's own colours: no accent is assumed. A name that is
|
|
466
|
+
// not one of the six is refused by `checkAppspec`.
|
|
467
|
+
accent: APP_ACCENTS.includes(data.accent)
|
|
468
|
+
? data.accent
|
|
469
|
+
: undefined,
|
|
467
470
|
welcome: text(data.welcome),
|
|
468
471
|
starters: records(data.starters).map(parseStarter),
|
|
469
472
|
commands: records(data.commands).map(parseCommand),
|
|
@@ -814,7 +817,7 @@ function dumpInterface(spec, kind) {
|
|
|
814
817
|
const writer = new Writer()
|
|
815
818
|
// A layout is written when it is not the one its kind starts with.
|
|
816
819
|
.value('layout', spec.layout, DEFAULT_LAYOUTS[kind])
|
|
817
|
-
.value('accent', spec.accent,
|
|
820
|
+
.value('accent', spec.accent, undefined)
|
|
818
821
|
.text('welcome', spec.welcome)
|
|
819
822
|
.list('starters', spec.starters.map(dumpStarter))
|
|
820
823
|
.list('commands', spec.commands.map(command => ({
|
|
@@ -171,7 +171,7 @@ export type AppFloatingProps = {
|
|
|
171
171
|
export declare function AppFloating({ app, view, colorMode, themeVariant, themeOverrides, character, serverUrl, instance, embedToken, renderer, host, session, language, }: AppFloatingProps): JSX.Element;
|
|
172
172
|
/** The application's theme (`loop` unless it names one), with its (or the host's) accent and face. */
|
|
173
173
|
export declare function EmbedThemed({ accent, colorMode, font, variant, children, style, }: {
|
|
174
|
-
accent
|
|
174
|
+
accent?: AppAccent;
|
|
175
175
|
colorMode: 'light' | 'dark';
|
|
176
176
|
font?: string;
|
|
177
177
|
variant: AppThemeVariant;
|
|
@@ -29,7 +29,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
29
29
|
* it does inline; the chrome told by the workspace what it is doing and
|
|
30
30
|
* what it last said, for the balloon and the blink.
|
|
31
31
|
*
|
|
32
|
-
* In
|
|
32
|
+
* In its theme (`loop` unless it names one) with the application's accent
|
|
33
|
+
* over it, whichever theme (T-12, T-05), which the
|
|
33
34
|
* host may override with the face and the mode (D-11) — around the
|
|
34
35
|
* conversation and inside it, where the chat sets its theme again.
|
|
35
36
|
*
|
|
@@ -143,12 +143,6 @@ export function LoopEmbed({ agentId = '', showHeader = false, chatHeaderActions,
|
|
|
143
143
|
return (_jsx(QueryClientProvider, { client: internalQueryClient, children: frameTitle !== undefined ? (_jsx(WindowFrame, { title: frameTitle, height: frameHeight, children: shell })) : (
|
|
144
144
|
// Filling its host, whatever the host is: in a flex row it used to
|
|
145
145
|
// shrink to the chat's own width and leave the rest of the frame bare.
|
|
146
|
-
_jsx(Box, {
|
|
147
|
-
height: '100%',
|
|
148
|
-
minHeight: 0,
|
|
149
|
-
width: '100%',
|
|
150
|
-
flex: '1 1 auto',
|
|
151
|
-
minWidth: 0,
|
|
152
|
-
}, children: shell })) }));
|
|
146
|
+
_jsx(Box, { height: "100%", minHeight: 0, width: "100%", flex: "1 1 auto", minWidth: 0, children: shell })) }));
|
|
153
147
|
}
|
|
154
148
|
export default LoopEmbed;
|
|
@@ -27,7 +27,7 @@ export declare const EMBED_ATTRIBUTES: {
|
|
|
27
27
|
readonly token: "An embed token for an application that is not public, issued to your server for each visit.";
|
|
28
28
|
readonly spec: "The address of an Appspec (YAML or JSON) to run, in place of `app`.";
|
|
29
29
|
readonly mode: "inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.";
|
|
30
|
-
readonly accent: "green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default.";
|
|
30
|
+
readonly accent: "green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.";
|
|
31
31
|
readonly theme: "light, dark or auto (the visitor’s system); auto by default.";
|
|
32
32
|
readonly font: "A CSS font family for the application’s text; Inter, then the system’s sans-serif, by default.";
|
|
33
33
|
readonly server: "An agent-runtimes server the application’s agent runs on; a Datalayer runtime by default.";
|
|
@@ -84,8 +84,8 @@ export type EmbedInputs = {
|
|
|
84
84
|
/** How an application is shown and dressed in a host's page. */
|
|
85
85
|
export type EmbedLook = {
|
|
86
86
|
mode: AppEmbedMode;
|
|
87
|
-
/** The accent the host chose, or the application's own. */
|
|
88
|
-
accent
|
|
87
|
+
/** The accent the host chose, or the application's own; none: the theme's own colours. */
|
|
88
|
+
accent?: AppAccent;
|
|
89
89
|
colorMode: EmbedColorMode;
|
|
90
90
|
/** The host's face; empty for the theme's own. */
|
|
91
91
|
font: string;
|
|
@@ -19,7 +19,7 @@ export const EMBED_ATTRIBUTES = {
|
|
|
19
19
|
token: 'An embed token for an application that is not public, issued to your server for each visit.',
|
|
20
20
|
spec: 'The address of an Appspec (YAML or JSON) to run, in place of `app`.',
|
|
21
21
|
mode: 'inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.',
|
|
22
|
-
accent: 'green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default.',
|
|
22
|
+
accent: 'green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.',
|
|
23
23
|
theme: 'light, dark or auto (the visitor’s system); auto by default.',
|
|
24
24
|
font: 'A CSS font family for the application’s text; Inter, then the system’s sans-serif, by default.',
|
|
25
25
|
server: 'An agent-runtimes server the application’s agent runs on; a Datalayer runtime by default.',
|
|
@@ -105,8 +105,7 @@ export function embedLookOf(inputs, app) {
|
|
|
105
105
|
'inline';
|
|
106
106
|
const accent = oneOf(attributes.accent, APP_ACCENTS, 'an accent') ??
|
|
107
107
|
oneOf(variables.accent, APP_ACCENTS, 'an accent') ??
|
|
108
|
-
app?.interface?.accent
|
|
109
|
-
'green';
|
|
108
|
+
app?.interface?.accent;
|
|
110
109
|
const colorMode = oneOf(attributes.theme, EMBED_COLOR_MODES, 'a theme') ??
|
|
111
110
|
oneOf(variables.theme, EMBED_COLOR_MODES, 'a theme') ??
|
|
112
111
|
app?.interface?.theme?.mode ??
|
|
@@ -3,11 +3,11 @@ import type { AppAccent, AppThemeVariant } from '../../types/agentspecs';
|
|
|
3
3
|
import type { ThemeOverrides } from '../../types/chat';
|
|
4
4
|
/**
|
|
5
5
|
* The theme as the embed wears it — `loop`, or the one the application
|
|
6
|
-
* names (T-30) — with the application's accent over
|
|
6
|
+
* names (T-30) — with the application's accent over it in both modes
|
|
7
7
|
* (T-05), and the host's face when it named one.
|
|
8
8
|
*/
|
|
9
9
|
export declare function embedThemeStyles({ accent, font, variant, }: {
|
|
10
|
-
accent
|
|
10
|
+
accent?: AppAccent;
|
|
11
11
|
font?: string;
|
|
12
12
|
variant?: AppThemeVariant;
|
|
13
13
|
}): ThemeStyles;
|
|
@@ -15,11 +15,11 @@ export declare function embedThemeStyles({ accent, font, variant, }: {
|
|
|
15
15
|
* The same accent and face laid over the conversation's own theme (T-05,
|
|
16
16
|
* D-11): the chat sets its theme again inside it, which would put the
|
|
17
17
|
* theme's colours and face back over what the embed set around it. The
|
|
18
|
-
* accent's properties in each mode (over
|
|
18
|
+
* accent's properties in each mode (over any theme), and, when the host
|
|
19
19
|
* named a face, every property of the theme that names its own.
|
|
20
20
|
*/
|
|
21
21
|
export declare function embedThemeOverrides({ accent, font, variant, }: {
|
|
22
|
-
accent
|
|
22
|
+
accent?: AppAccent;
|
|
23
23
|
font?: string;
|
|
24
24
|
variant?: AppThemeVariant;
|
|
25
25
|
}): ThemeOverrides;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
import { getThemeConfig,
|
|
5
|
+
import { getThemeConfig, loopFontFamily, scopeThemeCss, THEME_SCOPE_ATTRIBUTE, themeAccentVars, } from '@datalayer/primer-addons';
|
|
6
6
|
/** One mode's properties, with the theme's face replaced by the host's. */
|
|
7
7
|
function withFace(styles, font, own) {
|
|
8
8
|
if (!font || !own) {
|
|
@@ -20,18 +20,22 @@ function faceOf(variant, styles) {
|
|
|
20
20
|
}
|
|
21
21
|
return typeof styles.fontFamily === 'string' ? styles.fontFamily : '';
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* The accent over a theme, whichever theme (T-05, T-30; every theme since
|
|
25
|
+
* 2026-10-07); none when neither the application nor the host names one —
|
|
26
|
+
* the theme's own colours.
|
|
27
|
+
*/
|
|
28
|
+
const accentOver = (accent, which) => (accent ? themeAccentVars(accent, which) : {});
|
|
25
29
|
/**
|
|
26
30
|
* The theme as the embed wears it — `loop`, or the one the application
|
|
27
|
-
* names (T-30) — with the application's accent over
|
|
31
|
+
* names (T-30) — with the application's accent over it in both modes
|
|
28
32
|
* (T-05), and the host's face when it named one.
|
|
29
33
|
*/
|
|
30
34
|
export function embedThemeStyles({ accent, font = '', variant = 'loop', }) {
|
|
31
35
|
const base = getThemeConfig(variant).themeStyles;
|
|
32
36
|
const mode = (which) => {
|
|
33
37
|
const theme = base[which];
|
|
34
|
-
return withFace({ ...theme, ...accentOver(
|
|
38
|
+
return withFace({ ...theme, ...accentOver(accent, which) }, font, faceOf(variant, theme));
|
|
35
39
|
};
|
|
36
40
|
return {
|
|
37
41
|
...base,
|
|
@@ -43,7 +47,7 @@ export function embedThemeStyles({ accent, font = '', variant = 'loop', }) {
|
|
|
43
47
|
* The same accent and face laid over the conversation's own theme (T-05,
|
|
44
48
|
* D-11): the chat sets its theme again inside it, which would put the
|
|
45
49
|
* theme's colours and face back over what the embed set around it. The
|
|
46
|
-
* accent's properties in each mode (over
|
|
50
|
+
* accent's properties in each mode (over any theme), and, when the host
|
|
47
51
|
* named a face, every property of the theme that names its own.
|
|
48
52
|
*/
|
|
49
53
|
export function embedThemeOverrides({ accent, font = '', variant = 'loop', }) {
|
|
@@ -51,7 +55,7 @@ export function embedThemeOverrides({ accent, font = '', variant = 'loop', }) {
|
|
|
51
55
|
const mode = (which) => {
|
|
52
56
|
const theme = base[which];
|
|
53
57
|
const faced = Object.fromEntries(Object.entries(withFace(theme, font, faceOf(variant, theme))).filter(([name, value]) => typeof value === 'string' && value !== theme[name]));
|
|
54
|
-
return { ...faced, ...accentOver(
|
|
58
|
+
return { ...faced, ...accentOver(accent, which) };
|
|
55
59
|
};
|
|
56
60
|
return { light: mode('light'), dark: mode('dark') };
|
|
57
61
|
}
|
|
@@ -100,14 +100,14 @@ const STATUS_LABEL = {
|
|
|
100
100
|
function StatusBadge({ status, }) {
|
|
101
101
|
switch (status) {
|
|
102
102
|
case 'done':
|
|
103
|
-
return (_jsx(Box, {
|
|
103
|
+
return (_jsx(Box, { color: "success.fg", display: "flex", children: _jsx(CheckCircleIcon, {}) }));
|
|
104
104
|
case 'stopped':
|
|
105
|
-
return (_jsx(Box, {
|
|
105
|
+
return (_jsx(Box, { color: "attention.fg", display: "flex", children: _jsx(AlertIcon, {}) }));
|
|
106
106
|
case 'failed':
|
|
107
|
-
return (_jsx(Box, {
|
|
107
|
+
return (_jsx(Box, { color: "danger.fg", display: "flex", children: _jsx(AlertIcon, {}) }));
|
|
108
108
|
case 'launching':
|
|
109
109
|
case 'working':
|
|
110
|
-
return (_jsx(Box, {
|
|
110
|
+
return (_jsx(Box, { color: "accent.fg", display: "flex", children: _jsx(DependabotIcon, {}) }));
|
|
111
111
|
default:
|
|
112
112
|
return _jsx(BroadcastIcon, {});
|
|
113
113
|
}
|
|
@@ -120,13 +120,7 @@ function LaunchChip({ launch, }) {
|
|
|
120
120
|
: launch === 'local'
|
|
121
121
|
? DeviceDesktopIcon
|
|
122
122
|
: BroadcastIcon;
|
|
123
|
-
return (_jsxs(Box, { sx: {
|
|
124
|
-
display: 'inline-flex',
|
|
125
|
-
alignItems: 'center',
|
|
126
|
-
gap: 1,
|
|
127
|
-
fontSize: 0,
|
|
128
|
-
color: 'fg.muted',
|
|
129
|
-
}, children: [_jsx(Icon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: launch })] }));
|
|
123
|
+
return (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 1, fontSize: 0, color: "fg.muted", children: [_jsx(Icon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: launch })] }));
|
|
130
124
|
}
|
|
131
125
|
function SectionHeading({ children }) {
|
|
132
126
|
return (_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: children }));
|
|
@@ -142,30 +136,9 @@ export function A2ASidebar(_props) {
|
|
|
142
136
|
const [shown, setShown] = useState(null);
|
|
143
137
|
const activeOverA2A = activeKey !== null &&
|
|
144
138
|
(activity[activeKey] ?? []).some(event => event.transport === 'a2a');
|
|
145
|
-
return (_jsxs(Box, { "data-a2a-sidebar": true,
|
|
146
|
-
height: A2A_ACTIVE_PANEL_HEIGHT,
|
|
147
|
-
display: 'flex',
|
|
148
|
-
alignItems: 'center',
|
|
149
|
-
justifyContent: 'center',
|
|
150
|
-
border: '1px solid',
|
|
151
|
-
borderColor: 'border.muted',
|
|
152
|
-
borderRadius: 2,
|
|
153
|
-
bg: 'canvas.default',
|
|
154
|
-
}, children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "No A2A agent running" }) }))] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Remote agents" }), agents.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "This agent declares no A2A agents." })) : (_jsx(Timeline, { children: agents.map(agent => {
|
|
139
|
+
return (_jsxs(Box, { "data-a2a-sidebar": true, display: "flex", flexDirection: "column", gap: 4, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(BroadcastIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0, flex: 1 }, children: "A2A agents" }), _jsx(Label, { variant: "accent", children: agents.length })] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Running now" }), activeKey && activeOverA2A ? (_jsx(SubagentChatPanel, { toolCallId: activeKey, height: A2A_ACTIVE_PANEL_HEIGHT })) : (_jsx(Box, { "data-a2a-sidebar-idle": true, height: A2A_ACTIVE_PANEL_HEIGHT, display: "flex", alignItems: "center", justifyContent: "center", border: "1px solid", borderColor: "border.muted", borderRadius: 2, bg: "canvas.default", children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "No A2A agent running" }) }))] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Remote agents" }), agents.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "This agent declares no A2A agents." })) : (_jsx(Timeline, { children: agents.map(agent => {
|
|
155
140
|
const status = STATUS_LABEL[agent.status];
|
|
156
|
-
return (_jsxs(Timeline.Item, { "data-a2a-agent": agent.name, children: [_jsx(Timeline.Badge, { children: _jsx(StatusBadge, { status: agent.status }) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { sx: {
|
|
157
|
-
display: 'flex',
|
|
158
|
-
alignItems: 'center',
|
|
159
|
-
gap: 2,
|
|
160
|
-
mb: 1,
|
|
161
|
-
flexWrap: 'wrap',
|
|
162
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: agent.name }), _jsx(Label, { variant: status.variant, size: "small", children: status.text }), _jsx(LaunchChip, { launch: agent.launch })] }), agent.description ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: agent.description })) : null, _jsxs(Box, { sx: {
|
|
163
|
-
display: 'flex',
|
|
164
|
-
flexDirection: 'column',
|
|
165
|
-
gap: '2px',
|
|
166
|
-
fontSize: 0,
|
|
167
|
-
color: 'fg.muted',
|
|
168
|
-
}, children: [agent.card?.name ? (_jsxs(Text, { sx: { fontSize: 0 }, children: ["Card: ", agent.card.name, agent.card.version ? ` v${agent.card.version}` : ''] })) : agent.ref ? (_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono' }, children: agent.ref })) : null, agent.url ? (_jsx(Link, { as: "button", type: "button", "data-a2a-card-button": agent.name, onClick: () => setShown(agent), sx: {
|
|
141
|
+
return (_jsxs(Timeline.Item, { "data-a2a-agent": agent.name, children: [_jsx(Timeline.Badge, { children: _jsx(StatusBadge, { status: agent.status }) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 1, flexWrap: "wrap", children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: agent.name }), _jsx(Label, { variant: status.variant, size: "small", children: status.text }), _jsx(LaunchChip, { launch: agent.launch })] }), agent.description ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: agent.description })) : null, _jsxs(Box, { display: "flex", flexDirection: "column", gap: "2px", fontSize: 0, color: "fg.muted", children: [agent.card?.name ? (_jsxs(Text, { sx: { fontSize: 0 }, children: ["Card: ", agent.card.name, agent.card.version ? ` v${agent.card.version}` : ''] })) : agent.ref ? (_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono' }, children: agent.ref })) : null, agent.url ? (_jsx(Link, { as: "button", type: "button", "data-a2a-card-button": agent.name, onClick: () => setShown(agent), sx: {
|
|
169
142
|
fontSize: 0,
|
|
170
143
|
fontFamily: 'mono',
|
|
171
144
|
overflow: 'hidden',
|