@datalayer/agent-runtimes 1.0.0 → 1.0.2
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 +1 -2
- package/lib/AgentLexical.js +1 -2
- package/lib/AgentNotebook.js +1 -2
- package/lib/components/McpServerManager.d.ts +1 -1
- package/lib/components/McpServerManager.js +1 -1
- package/lib/components/chat/components/Chat.d.ts +1 -1
- package/lib/components/chat/components/ChatFloating.d.ts +4 -2
- package/lib/components/chat/components/ChatFloating.js +1 -1
- package/lib/components/chat/components/base/ChatBase.d.ts +1 -1
- package/lib/components/chat/components/base/ChatBase.js +4 -2
- package/lib/components/chat/store/conversationStore.d.ts +1 -1
- package/lib/components/chat/store/conversationStore.js +2 -2
- package/lib/examples/A2UiRestaurantExample.js +2 -2
- package/lib/examples/AgUiAgenticExample.js +3 -3
- package/lib/examples/AgUiBackendToolRenderingExample.js +4 -3
- package/lib/examples/AgUiHaikuGenUIExample.js +4 -3
- package/lib/examples/AgUiHumanInTheLoopExample.js +4 -3
- package/lib/examples/AgUiSharedStateExample.js +4 -3
- package/lib/examples/AgUiToolsBasedGenUIExample.js +4 -3
- package/lib/examples/AgentRuntimeChatExample.js +3 -3
- package/lib/examples/AgentRuntimeCustomExample.js +2 -2
- package/lib/examples/AgentRuntimeFormExample.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.js +3 -2
- package/lib/examples/AgentRuntimeLexicalExample.js +4 -3
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +3 -2
- package/lib/examples/AgentRuntimeNotebookExample.js +4 -3
- package/lib/examples/AgentRuntimeNotebookSidebarExample.js +3 -2
- package/lib/examples/AgentRuntimeStandaloneExample.js +3 -3
- package/lib/examples/CopilotKitLexicalExample.js +3 -2
- package/lib/examples/CopilotKitNotebookExample.js +3 -2
- package/lib/examples/DatalayerNotebookExample.js +3 -2
- package/lib/examples/JupyterCellExample.js +3 -2
- package/lib/examples/JupyterNotebookExample.js +3 -2
- package/lib/examples/main.js +68 -18
- package/lib/examples/stores/themeStore.d.ts +33 -0
- package/lib/examples/stores/themeStore.js +38 -0
- package/lib/examples/stores/themedProvider.d.ts +45 -0
- package/lib/examples/stores/themedProvider.js +54 -0
- package/lib/hooks/index.d.ts +8 -0
- package/lib/hooks/index.js +8 -0
- package/lib/hooks/useAgentRuntimes.d.ts +350 -0
- package/lib/hooks/useAgentRuntimes.js +78 -0
- package/lib/hooks/useAgentStore.d.ts +30 -0
- package/lib/hooks/useAgentStore.js +22 -0
- package/lib/specs/agents/codeai/agents.d.ts +1 -1
- package/lib/specs/agents/codeai/agents.js +28 -0
- package/lib/specs/agents/codemode-paper/agents.d.ts +1 -1
- package/lib/specs/agents/codemode-paper/agents.js +71 -1
- package/lib/specs/agents/datalayer-ai/agents.d.ts +1 -1
- package/lib/specs/agents/datalayer-ai/agents.js +70 -0
- package/lib/specs/agents/index.js +2 -0
- package/lib/specs/agents/mocks/agents.d.ts +43 -0
- package/lib/specs/agents/mocks/agents.js +2293 -0
- package/lib/specs/agents/mocks/index.d.ts +1 -0
- package/lib/specs/agents/mocks/index.js +5 -0
- package/lib/specs/mcpServers.d.ts +1 -0
- package/lib/specs/mcpServers.js +16 -0
- package/lib/specs/models.d.ts +2 -2
- package/lib/specs/models.js +5 -5
- package/lib/types/Types.d.ts +29 -1
- package/package.json +4 -3
- package/scripts/codegen/generate_agents.py +95 -2
|
@@ -18,7 +18,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
18
18
|
import { useCallback } from 'react';
|
|
19
19
|
import { Text } from '@primer/react';
|
|
20
20
|
import { Box } from '@datalayer/primer-addons';
|
|
21
|
-
import {
|
|
21
|
+
import { ThemedProvider } from './stores/themedProvider';
|
|
22
22
|
import { ChatStandalone } from '../components/chat';
|
|
23
23
|
/**
|
|
24
24
|
* Simulated AI responses for demo purposes.
|
|
@@ -97,7 +97,7 @@ const AgentRuntimePopupStandaloneExample = () => {
|
|
|
97
97
|
throw err;
|
|
98
98
|
}
|
|
99
99
|
}, []);
|
|
100
|
-
return (_jsx(
|
|
100
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
101
101
|
minHeight: '100vh',
|
|
102
102
|
backgroundColor: 'canvas.default',
|
|
103
103
|
padding: 4,
|
|
@@ -153,6 +153,6 @@ const AgentRuntimePopupStandaloneExample = () => {
|
|
|
153
153
|
borderRadius: 2,
|
|
154
154
|
border: '1px solid',
|
|
155
155
|
borderColor: 'attention.muted',
|
|
156
|
-
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "When to Use" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, marginBottom: 2 }, children: ["Use ", _jsx("strong", { children: "ChatStandalone" }), " when:"] }), _jsxs(Box, { as: "ul", sx: { paddingLeft: 3, fontSize: 1 }, children: [_jsx("li", { children: "You have a custom AI backend that does not use AG-UI/ACP" }), _jsx("li", { children: "You want full control over the message handling logic" }), _jsx("li", { children: "You need to integrate with a specific API (OpenAI, etc.)" }), _jsx("li", { children: "You want a quick demo without setting up a backend server" })] }), _jsxs(Text, { as: "p", sx: { fontSize: 1, marginTop: 2 }, children: ["Use ", _jsx("strong", { children: "ChatFloating" }), " instead when:"] }), _jsxs(Box, { as: "ul", sx: { paddingLeft: 3, fontSize: 1 }, children: [_jsx("li", { children: "You have an AG-UI compatible backend" }), _jsx("li", { children: "You need built-in tool rendering support" }), _jsx("li", { children: "You want automatic protocol handling" })] })] })] }), _jsx(ChatStandalone, { title: "Demo Assistant", onSendMessage: handleSendMessage, position: "bottom-right",
|
|
156
|
+
}, children: [_jsx(Text, { as: "h2", sx: { fontSize: 2, fontWeight: 'semibold', marginBottom: 2 }, children: "When to Use" }), _jsxs(Text, { as: "p", sx: { fontSize: 1, marginBottom: 2 }, children: ["Use ", _jsx("strong", { children: "ChatStandalone" }), " when:"] }), _jsxs(Box, { as: "ul", sx: { paddingLeft: 3, fontSize: 1 }, children: [_jsx("li", { children: "You have a custom AI backend that does not use AG-UI/ACP" }), _jsx("li", { children: "You want full control over the message handling logic" }), _jsx("li", { children: "You need to integrate with a specific API (OpenAI, etc.)" }), _jsx("li", { children: "You want a quick demo without setting up a backend server" })] }), _jsxs(Text, { as: "p", sx: { fontSize: 1, marginTop: 2 }, children: ["Use ", _jsx("strong", { children: "ChatFloating" }), " instead when:"] }), _jsxs(Box, { as: "ul", sx: { paddingLeft: 3, fontSize: 1 }, children: [_jsx("li", { children: "You have an AG-UI compatible backend" }), _jsx("li", { children: "You need built-in tool rendering support" }), _jsx("li", { children: "You want automatic protocol handling" })] })] })] }), _jsx(ChatStandalone, { title: "Demo Assistant", onSendMessage: handleSendMessage, position: "bottom-right", enableStreaming: true, emptyStateMessage: "Hi! I'm a demo assistant. Try asking me for the time, a joke, or what I can do!", buttonTooltip: "Chat with Demo Assistant", showPoweredBy: true })] }) }));
|
|
157
157
|
};
|
|
158
158
|
export default AgentRuntimePopupStandaloneExample;
|
|
@@ -47,7 +47,8 @@ import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
|
47
47
|
import { CopilotKit, useFrontendTool } from '@copilotkit/react-core';
|
|
48
48
|
import { CopilotSidebar } from '@copilotkit/react-ui';
|
|
49
49
|
import { Box } from '@datalayer/primer-addons';
|
|
50
|
-
import {
|
|
50
|
+
import { useJupyter } from '@datalayer/jupyter-react';
|
|
51
|
+
import { ThemedJupyterProvider } from './stores/themedProvider';
|
|
51
52
|
import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, TableCellResizerPlugin, TablePlugin, } from '@datalayer/jupyter-lexical';
|
|
52
53
|
import { ActionRegistrar, useLexicalToolActions, } from '../tools/adapters/copilotkit/lexicalHooks';
|
|
53
54
|
import { editorConfig } from './lexical/editorConfig';
|
|
@@ -146,7 +147,7 @@ const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, ser
|
|
|
146
147
|
padding: 3,
|
|
147
148
|
backgroundColor: 'canvas.default',
|
|
148
149
|
minHeight: '600px',
|
|
149
|
-
}, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(
|
|
150
|
+
}, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(ThemedJupyterProvider, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }) }) })] }) }));
|
|
150
151
|
});
|
|
151
152
|
function LexicalWithTools({ content, serviceManager, }) {
|
|
152
153
|
// Get all actions for this lexical document
|
|
@@ -16,7 +16,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
16
16
|
*/
|
|
17
17
|
import React from 'react';
|
|
18
18
|
import { Box } from '@datalayer/primer-addons';
|
|
19
|
-
import {
|
|
19
|
+
import { Notebook } from '@datalayer/jupyter-react';
|
|
20
|
+
import { ThemedJupyterProvider } from './stores/themedProvider';
|
|
20
21
|
// CopilotKit imports
|
|
21
22
|
import { CopilotKit, useFrontendTool } from '@copilotkit/react-core';
|
|
22
23
|
import { CopilotSidebar } from '@copilotkit/react-ui';
|
|
@@ -50,7 +51,7 @@ const NotebookUI = React.memo(function NotebookUI({ serviceManager, }) {
|
|
|
50
51
|
borderRadius: 8,
|
|
51
52
|
padding: 24,
|
|
52
53
|
backgroundColor: 'var(--bgColor-default)',
|
|
53
|
-
}, children: serviceManager ? (_jsx(
|
|
54
|
+
}, children: serviceManager ? (_jsx(ThemedJupyterProvider, { children: _jsx(Notebook, { nbformat: NOTEBOOK_CONTENT, id: NOTEBOOK_ID, serviceManager: serviceManager, height: "600px", cellSidebarMargin: 120, startDefaultKernel: true }) })) : (_jsx(Box, { style: { padding: 24 }, children: _jsx("p", { children: "Loading service manager..." }) })) })] }) }));
|
|
54
55
|
});
|
|
55
56
|
/**
|
|
56
57
|
* Component to register actions with CopilotKit.
|
|
@@ -7,7 +7,8 @@ import { useState, useEffect, useMemo } from 'react';
|
|
|
7
7
|
import { Checkbox, FormControl, Heading } from '@primer/react';
|
|
8
8
|
import { Box } from '@datalayer/primer-addons';
|
|
9
9
|
import { useCoreStore, createDatalayerServiceManager, DatalayerCollaborationProvider, } from '@datalayer/core';
|
|
10
|
-
import { loadJupyterConfig,
|
|
10
|
+
import { loadJupyterConfig, Notebook } from '@datalayer/jupyter-react';
|
|
11
|
+
import { ThemedJupyterProvider } from './stores/themedProvider';
|
|
11
12
|
import nbformatExample from './stores/notebooks/NotebookExample1.ipynb.json';
|
|
12
13
|
// This corresponds to the notebook ID in the URL when you open an existing notbook in your library
|
|
13
14
|
const NOTEBOOK_ID = '01JZQRQ35GG871QQCZW9TB1A8J';
|
|
@@ -64,7 +65,7 @@ const DatalayerNotebookExample = (props) => {
|
|
|
64
65
|
token,
|
|
65
66
|
});
|
|
66
67
|
}, [enableCollaboration, configuration]);
|
|
67
|
-
return (_jsx(
|
|
68
|
+
return (_jsx(ThemedJupyterProvider, { children: _jsxs(Box, { p: 3, children: [_jsx(Heading, { as: "h2", sx: { mb: 3 }, children: "Datalayer Notebook Collaboration Example" }), _jsx(Box, { sx: { mb: 3 }, children: _jsxs(FormControl, { children: [_jsx(Checkbox, { checked: enableCollaboration, onChange: e => setEnableCollaboration(e.target.checked) }), _jsx(FormControl.Label, { children: "Enable Datalayer Collaboration" })] }) }), (!configuration?.runUrl || !configuration?.token) && (_jsx(Box, { sx: { mb: 2, p: 2, bg: 'danger.subtle' }, children: "Warning: Datalayer configuration is missing. Please configure runUrl and token to use DatalayerServiceManager and collaboration features." })), !serviceManager && (_jsx(Box, { sx: { mb: 2, p: 2, bg: 'attention.subtle' }, children: "Note: DatalayerServiceManager is not available. Notebook functionality will be limited." })), enableCollaboration ? (_jsxs(Box, { sx: {
|
|
68
69
|
display: 'flex',
|
|
69
70
|
gap: 2,
|
|
70
71
|
flexDirection: 'row',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Cell, KernelIndicator, useJupyter, useKernelsStore, useCellsStore, } from '@datalayer/jupyter-react';
|
|
3
|
+
import { ThemedJupyterProvider } from './stores/themedProvider';
|
|
3
4
|
import { Button, Label } from '@primer/react';
|
|
4
5
|
import { Box } from '@datalayer/primer-addons';
|
|
5
6
|
const CELL_ID = 'cell-example-1';
|
|
@@ -14,6 +15,6 @@ const JupyterCellExampleContent = () => {
|
|
|
14
15
|
return (_jsxs(Box, { p: 4, children: [_jsx(Box, { as: "h1", children: "Jupyter Cell Example" }), _jsxs(Box, { children: ["Source: ", cellsStore.getSource(CELL_ID)] }), _jsxs(Box, { children: ["Outputs Count: ", cellsStore.getOutputsCount(CELL_ID)] }), _jsxs(Box, { children: ["Kernel State:", ' ', _jsx(Label, { children: defaultKernel && kernelsStore.getExecutionState(defaultKernel.id) })] }), _jsxs(Box, { children: ["Kernel Phase:", ' ', _jsx(Label, { children: defaultKernel && kernelsStore.getExecutionPhase(defaultKernel.id) })] }), _jsxs(Box, { display: "flex", children: [_jsx(Box, { children: "Kernel Indicator:" }), _jsx(Box, { ml: 3, children: _jsx(KernelIndicator, { kernel: defaultKernel && defaultKernel.connection }) })] }), _jsx(Box, { children: _jsx(Button, { onClick: () => cellsStore.execute(CELL_ID), children: "Run cell" }) }), _jsx(Cell, { source: DEFAULT_SOURCE, id: CELL_ID, kernel: defaultKernel })] }));
|
|
15
16
|
};
|
|
16
17
|
export const JupyterCellExample = (props) => {
|
|
17
|
-
return (_jsx(
|
|
18
|
+
return (_jsx(ThemedJupyterProvider, { children: _jsx(JupyterCellExampleContent, {}) }));
|
|
18
19
|
};
|
|
19
20
|
export default JupyterCellExample;
|
|
@@ -10,12 +10,13 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
10
10
|
*/
|
|
11
11
|
import { useMemo } from 'react';
|
|
12
12
|
import { Box } from '@datalayer/primer-addons';
|
|
13
|
-
import {
|
|
13
|
+
import { Notebook, NotebookToolbar, CellSidebarExtension, CellSidebarButton, } from '@datalayer/jupyter-react';
|
|
14
|
+
import { ThemedJupyterProvider } from './stores/themedProvider';
|
|
14
15
|
import nbformatExample from './stores/notebooks/NotebookExample1.ipynb.json';
|
|
15
16
|
const NOTEBOOK_ID = 'notebook-example-1';
|
|
16
17
|
export const JupyterNotebookExample = (props) => {
|
|
17
18
|
const { serviceManager } = props;
|
|
18
19
|
const extensions = useMemo(() => [new CellSidebarExtension({ factory: CellSidebarButton })], []);
|
|
19
|
-
return (_jsxs(_Fragment, { children: [_jsx(Box, { as: "h1", children: "Jupyter Notebook Example" }), serviceManager && (_jsx(
|
|
20
|
+
return (_jsxs(_Fragment, { children: [_jsx(Box, { as: "h1", children: "Jupyter Notebook Example" }), serviceManager && (_jsx(ThemedJupyterProvider, { children: _jsx(Notebook, { id: NOTEBOOK_ID, nbformat: nbformatExample, serviceManager: serviceManager, startDefaultKernel: true, extensions: extensions, Toolbar: NotebookToolbar }) }))] }));
|
|
20
21
|
};
|
|
21
22
|
export default JupyterNotebookExample;
|
package/lib/examples/main.js
CHANGED
|
@@ -8,10 +8,15 @@ import { useEffect, useState } from 'react';
|
|
|
8
8
|
import { createRoot } from 'react-dom/client';
|
|
9
9
|
import { loadJupyterConfig, JupyterReactTheme, createServerSettings, setJupyterServerUrl, setJupyterServerToken, getJupyterServerUrl, getJupyterServerToken, } from '@datalayer/jupyter-react';
|
|
10
10
|
import { ServiceManager } from '@jupyterlab/services';
|
|
11
|
-
import {
|
|
11
|
+
import { DatalayerThemeProvider, themeConfigs, themeVariants, } from '@datalayer/primer-addons';
|
|
12
|
+
import { SegmentedControl } from '@primer/react';
|
|
13
|
+
import { Box } from '@datalayer/primer-addons';
|
|
14
|
+
import { MoonIcon, SunIcon, DeviceDesktopIcon } from '@primer/octicons-react';
|
|
15
|
+
import { coreStore, iamStore, createDatalayerServiceManager, } from '@datalayer/core';
|
|
12
16
|
import { useChatStore } from '../components/chat/store';
|
|
13
17
|
import { OAuthCallback } from '../identity';
|
|
14
18
|
import { EXAMPLES } from './example-selector';
|
|
19
|
+
import { useExampleThemeStore } from './stores/themeStore';
|
|
15
20
|
import nbformatExample from './stores/notebooks/NotebookExample1.ipynb.json';
|
|
16
21
|
// Load configurations from DOM
|
|
17
22
|
const loadConfigurations = () => {
|
|
@@ -292,39 +297,84 @@ export const ExampleApp = () => {
|
|
|
292
297
|
if (serviceManager) {
|
|
293
298
|
exampleProps.serviceManager = serviceManager;
|
|
294
299
|
}
|
|
295
|
-
return (_jsx(
|
|
300
|
+
return (_jsx(ExampleAppThemed, { selectedExample: selectedExample, isChangingExample: isChangingExample, error: error, ExampleComponent: ExampleComponent, exampleProps: exampleProps, onExampleChange: handleExampleChange }));
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Inner shell that reads from the theme store and wires
|
|
304
|
+
* DatalayerThemeProvider + the header bar with selectors.
|
|
305
|
+
*/
|
|
306
|
+
const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleComponent, exampleProps, onExampleChange, }) => {
|
|
307
|
+
const { colorMode, theme: themeVariant } = useExampleThemeStore();
|
|
308
|
+
const cfg = themeConfigs[themeVariant];
|
|
309
|
+
return (_jsx(DatalayerThemeProvider, { colorMode: colorMode, theme: cfg.primerTheme, themeStyles: cfg.themeStyles, children: _jsxs(Box, { sx: {
|
|
310
|
+
width: '100vw',
|
|
311
|
+
height: '100vh',
|
|
312
|
+
overflow: 'hidden',
|
|
313
|
+
bg: 'canvas.default',
|
|
314
|
+
color: 'fg.default',
|
|
315
|
+
}, children: [_jsxs(Box, { sx: {
|
|
296
316
|
position: 'fixed',
|
|
297
317
|
top: 0,
|
|
298
318
|
left: 0,
|
|
299
319
|
right: 0,
|
|
300
320
|
zIndex: 100,
|
|
301
|
-
|
|
302
|
-
background: '#f0f0f0',
|
|
303
|
-
borderBottom: '1px solid #ccc',
|
|
321
|
+
px: 3,
|
|
304
322
|
display: 'flex',
|
|
305
323
|
alignItems: 'center',
|
|
306
324
|
justifyContent: 'space-between',
|
|
307
|
-
gap:
|
|
308
|
-
fontSize: '14px',
|
|
309
|
-
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
325
|
+
gap: 3,
|
|
310
326
|
height: '50px',
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
327
|
+
bg: 'canvas.subtle',
|
|
328
|
+
borderBottom: '1px solid',
|
|
329
|
+
borderColor: 'border.default',
|
|
330
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { as: "select", value: selectedExample, onChange: (e) => onExampleChange(e.target.value), disabled: isChangingExample, sx: {
|
|
331
|
+
px: 2,
|
|
332
|
+
py: '6px',
|
|
333
|
+
fontSize: 1,
|
|
334
|
+
fontFamily: 'mono',
|
|
335
|
+
border: '1px solid',
|
|
336
|
+
borderColor: 'border.default',
|
|
337
|
+
borderRadius: 2,
|
|
338
|
+
bg: 'canvas.default',
|
|
339
|
+
color: 'fg.default',
|
|
318
340
|
cursor: isChangingExample ? 'not-allowed' : 'pointer',
|
|
319
|
-
fontFamily: 'monospace',
|
|
320
341
|
minWidth: '250px',
|
|
342
|
+
outline: 'none',
|
|
343
|
+
'&:focus-visible': {
|
|
344
|
+
boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))',
|
|
345
|
+
},
|
|
321
346
|
}, children: getExampleNames()
|
|
322
347
|
.sort()
|
|
323
|
-
.map(name => (_jsx("option", { value: name, children: name }, name))) }), isChangingExample && (_jsx("span",
|
|
348
|
+
.map(name => (_jsx("option", { value: name, children: name }, name))) }), isChangingExample && (_jsx(Box, { as: "span", sx: { color: 'fg.muted', fontSize: 0 }, children: "Loading\u2026" })), error && (_jsxs(Box, { as: "span", sx: { color: 'danger.fg', fontSize: 0 }, children: ["Error: ", error] }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 3 }, children: [_jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: themeVariants.map(variant => {
|
|
349
|
+
const tcfg = themeConfigs[variant];
|
|
350
|
+
const isSelected = themeVariant === variant;
|
|
351
|
+
return (_jsx(Box, { as: "button", "aria-label": tcfg.label, "aria-pressed": isSelected, onClick: () => useExampleThemeStore.getState().setTheme(variant, false), sx: {
|
|
352
|
+
width: 24,
|
|
353
|
+
height: 24,
|
|
354
|
+
borderRadius: '50%',
|
|
355
|
+
backgroundColor: tcfg.brandColor,
|
|
356
|
+
border: '2px solid',
|
|
357
|
+
borderColor: isSelected ? 'accent.fg' : 'border.default',
|
|
358
|
+
cursor: 'pointer',
|
|
359
|
+
padding: 0,
|
|
360
|
+
outline: 'none',
|
|
361
|
+
transition: 'border-color 0.15s ease',
|
|
362
|
+
boxShadow: isSelected
|
|
363
|
+
? '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))'
|
|
364
|
+
: 'none',
|
|
365
|
+
'&:hover': { borderColor: 'accent.fg' },
|
|
366
|
+
'&:focus-visible': {
|
|
367
|
+
boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))',
|
|
368
|
+
},
|
|
369
|
+
} }, variant));
|
|
370
|
+
}) }), _jsxs(SegmentedControl, { "aria-label": "Color mode", size: "small", onChange: (index) => {
|
|
371
|
+
const modes = ['light', 'dark', 'auto'];
|
|
372
|
+
useExampleThemeStore.getState().setColorMode(modes[index]);
|
|
373
|
+
}, children: [_jsx(SegmentedControl.IconButton, { selected: colorMode === 'light', icon: SunIcon, "aria-label": "Light" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'dark', icon: MoonIcon, "aria-label": "Dark" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'auto', icon: DeviceDesktopIcon, "aria-label": "Auto" })] }), _jsx("img", { src: "https://assets.datalayer.tech/datalayer-25.svg", alt: "Datalayer", style: { height: '24px' } })] })] }), _jsx(Box, { sx: {
|
|
324
374
|
marginTop: '50px',
|
|
325
375
|
height: 'calc(100vh - 50px)',
|
|
326
376
|
overflow: 'auto',
|
|
327
|
-
}, children: isChangingExample ? (_jsxs(
|
|
377
|
+
}, children: isChangingExample ? (_jsxs(Box, { sx: { p: 5, textAlign: 'center', color: 'fg.muted' }, children: [_jsxs("h3", { children: ["Loading ", selectedExample, "\u2026"] }), _jsx("p", { children: "Please wait while the example loads." })] })) : ExampleComponent ? (_jsx(ExampleComponent, { ...exampleProps })) : null })] }) }));
|
|
328
378
|
};
|
|
329
379
|
// Mount the app - check route to determine which app to render
|
|
330
380
|
const root = document.getElementById('root');
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ThemeVariant, type ColorMode } from '@datalayer/primer-addons';
|
|
2
|
+
export type { ThemeVariant, ColorMode };
|
|
3
|
+
export interface ThemeState {
|
|
4
|
+
/** Current color mode (light, dark, or auto = follow OS). */
|
|
5
|
+
colorMode: ColorMode;
|
|
6
|
+
/** Current theme variant. */
|
|
7
|
+
theme: ThemeVariant;
|
|
8
|
+
/** Cycle through light → dark → auto. */
|
|
9
|
+
toggleColorMode: () => void;
|
|
10
|
+
/** Set a specific color mode. */
|
|
11
|
+
setColorMode: (mode: ColorMode) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Set the active theme variant.
|
|
14
|
+
* @param applyDefaultColorMode When true (default), also switches the
|
|
15
|
+
* color mode to the theme's configured default.
|
|
16
|
+
*/
|
|
17
|
+
setTheme: (theme: ThemeVariant, applyDefaultColorMode?: boolean) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Zustand store for theme preferences in the examples app.
|
|
21
|
+
* Persisted to localStorage under 'agent-runtimes-theme' key.
|
|
22
|
+
*/
|
|
23
|
+
export declare const useExampleThemeStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<ThemeState>, "persist"> & {
|
|
24
|
+
persist: {
|
|
25
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown>>) => void;
|
|
26
|
+
clearStorage: () => void;
|
|
27
|
+
rehydrate: () => Promise<void> | void;
|
|
28
|
+
hasHydrated: () => boolean;
|
|
29
|
+
onHydrate: (fn: (state: ThemeState) => void) => () => void;
|
|
30
|
+
onFinishHydration: (fn: (state: ThemeState) => void) => () => void;
|
|
31
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<ThemeState, unknown>>;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { create } from 'zustand';
|
|
6
|
+
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
7
|
+
import { themeConfigs, } from '@datalayer/primer-addons';
|
|
8
|
+
/**
|
|
9
|
+
* Zustand store for theme preferences in the examples app.
|
|
10
|
+
* Persisted to localStorage under 'agent-runtimes-theme' key.
|
|
11
|
+
*/
|
|
12
|
+
export const useExampleThemeStore = create()(persist(set => ({
|
|
13
|
+
colorMode: 'light',
|
|
14
|
+
theme: 'datalayer',
|
|
15
|
+
toggleColorMode: () => set(state => {
|
|
16
|
+
const cycle = {
|
|
17
|
+
light: 'dark',
|
|
18
|
+
dark: 'auto',
|
|
19
|
+
auto: 'light',
|
|
20
|
+
};
|
|
21
|
+
return { colorMode: cycle[state.colorMode] };
|
|
22
|
+
}),
|
|
23
|
+
setColorMode: (mode) => set({ colorMode: mode }),
|
|
24
|
+
setTheme: (theme, applyDefaultColorMode = true) => set(() => {
|
|
25
|
+
const next = { theme };
|
|
26
|
+
if (applyDefaultColorMode) {
|
|
27
|
+
next.colorMode = themeConfigs[theme].defaultColorMode;
|
|
28
|
+
}
|
|
29
|
+
return next;
|
|
30
|
+
}),
|
|
31
|
+
}), {
|
|
32
|
+
name: 'agent-runtimes-theme',
|
|
33
|
+
storage: createJSONStorage(() => localStorage),
|
|
34
|
+
partialize: state => ({
|
|
35
|
+
colorMode: state.colorMode,
|
|
36
|
+
theme: state.theme,
|
|
37
|
+
}),
|
|
38
|
+
}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme-aware wrappers for example components.
|
|
3
|
+
*
|
|
4
|
+
* These are drop-in replacements for `DatalayerThemeProvider` and
|
|
5
|
+
* `JupyterReactTheme` that automatically read theme / color-mode
|
|
6
|
+
* from the shared `useExampleThemeStore`.
|
|
7
|
+
*
|
|
8
|
+
* Usage: replace
|
|
9
|
+
* import { DatalayerThemeProvider } from '@datalayer/primer-addons';
|
|
10
|
+
* with
|
|
11
|
+
* import { ThemedProvider } from './stores/themedProvider';
|
|
12
|
+
*
|
|
13
|
+
* and swap `<DatalayerThemeProvider>` → `<ThemedProvider>`.
|
|
14
|
+
*/
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import { type IDatalayerThemeProviderProps } from '@datalayer/primer-addons';
|
|
17
|
+
/**
|
|
18
|
+
* Drop-in replacement for `<DatalayerThemeProvider>`.
|
|
19
|
+
* Reads theme/colorMode from the example theme store and
|
|
20
|
+
* forwards them to the real provider. Any explicit props
|
|
21
|
+
* (colorMode, theme, themeStyles) are still respected as overrides.
|
|
22
|
+
*/
|
|
23
|
+
export declare const ThemedProvider: React.FC<React.PropsWithChildren<Omit<IDatalayerThemeProviderProps, 'ref'>>>;
|
|
24
|
+
/**
|
|
25
|
+
* Drop-in replacement for `<JupyterReactTheme>`.
|
|
26
|
+
* Wraps children in `ThemedProvider` so Jupyter components also
|
|
27
|
+
* pick up the selected theme/color-mode.
|
|
28
|
+
*
|
|
29
|
+
* The wrapper automatically derives `colormode` and `backgroundColor`
|
|
30
|
+
* from the shared theme store so every Jupyter component inherits
|
|
31
|
+
* the correct palette — mirroring the pattern used by
|
|
32
|
+
* `ProjectNotebookEditor`.
|
|
33
|
+
*
|
|
34
|
+
* @param useJupyterReactTheme - When `true`, wraps children in
|
|
35
|
+
* `<JupyterReactTheme>` inside the themed provider. Defaults to `true`.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Hook that returns the `brandColor` for the currently selected theme.
|
|
39
|
+
* Use this in example components to pass a dynamic brand color to
|
|
40
|
+
* `<ChatFloating>` or any other component that accepts a `brandColor` prop.
|
|
41
|
+
*/
|
|
42
|
+
export declare const useThemeBrandColor: () => string;
|
|
43
|
+
export declare const ThemedJupyterProvider: React.FC<React.PropsWithChildren<{
|
|
44
|
+
useJupyterReactTheme?: boolean;
|
|
45
|
+
}>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DatalayerThemeProvider, themeConfigs, } from '@datalayer/primer-addons';
|
|
3
|
+
import { JupyterReactTheme } from '@datalayer/jupyter-react';
|
|
4
|
+
import { useExampleThemeStore } from './themeStore';
|
|
5
|
+
/**
|
|
6
|
+
* Drop-in replacement for `<DatalayerThemeProvider>`.
|
|
7
|
+
* Reads theme/colorMode from the example theme store and
|
|
8
|
+
* forwards them to the real provider. Any explicit props
|
|
9
|
+
* (colorMode, theme, themeStyles) are still respected as overrides.
|
|
10
|
+
*/
|
|
11
|
+
export const ThemedProvider = ({ children, ...rest }) => {
|
|
12
|
+
const { colorMode, theme: themeVariant } = useExampleThemeStore();
|
|
13
|
+
const cfg = themeConfigs[themeVariant];
|
|
14
|
+
return (_jsx(DatalayerThemeProvider, { colorMode: rest.colorMode ?? colorMode, theme: rest.theme ?? cfg.primerTheme, themeStyles: rest.themeStyles ?? cfg.themeStyles, ...rest, children: children }));
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Drop-in replacement for `<JupyterReactTheme>`.
|
|
18
|
+
* Wraps children in `ThemedProvider` so Jupyter components also
|
|
19
|
+
* pick up the selected theme/color-mode.
|
|
20
|
+
*
|
|
21
|
+
* The wrapper automatically derives `colormode` and `backgroundColor`
|
|
22
|
+
* from the shared theme store so every Jupyter component inherits
|
|
23
|
+
* the correct palette — mirroring the pattern used by
|
|
24
|
+
* `ProjectNotebookEditor`.
|
|
25
|
+
*
|
|
26
|
+
* @param useJupyterReactTheme - When `true`, wraps children in
|
|
27
|
+
* `<JupyterReactTheme>` inside the themed provider. Defaults to `true`.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Hook that returns the `brandColor` for the currently selected theme.
|
|
31
|
+
* Use this in example components to pass a dynamic brand color to
|
|
32
|
+
* `<ChatFloating>` or any other component that accepts a `brandColor` prop.
|
|
33
|
+
*/
|
|
34
|
+
export const useThemeBrandColor = () => {
|
|
35
|
+
const { theme: themeVariant } = useExampleThemeStore();
|
|
36
|
+
return themeConfigs[themeVariant].brandColor;
|
|
37
|
+
};
|
|
38
|
+
export const ThemedJupyterProvider = ({ children, useJupyterReactTheme = true }) => {
|
|
39
|
+
const { colorMode, theme: themeVariant } = useExampleThemeStore();
|
|
40
|
+
const cfg = themeConfigs[themeVariant];
|
|
41
|
+
// Resolve 'auto' to an actual mode so we can pick the right style set.
|
|
42
|
+
const resolvedMode = colorMode === 'auto'
|
|
43
|
+
? typeof window !== 'undefined' &&
|
|
44
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
45
|
+
? 'dark'
|
|
46
|
+
: 'light'
|
|
47
|
+
: colorMode === 'dark'
|
|
48
|
+
? 'dark'
|
|
49
|
+
: 'light';
|
|
50
|
+
// Extract the canvas background from the theme's CSS-var overrides.
|
|
51
|
+
const modeStyles = resolvedMode === 'dark' ? cfg.themeStyles.dark : cfg.themeStyles.light;
|
|
52
|
+
const backgroundColor = modeStyles['--bgColor-default'];
|
|
53
|
+
return (_jsx(ThemedProvider, { children: useJupyterReactTheme ? (_jsx(JupyterReactTheme, { colormode: colorMode, backgroundColor: backgroundColor, children: children })) : (children) }));
|
|
54
|
+
};
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -65,4 +65,12 @@ export { useVercelChat } from './useVercelChat';
|
|
|
65
65
|
* Datalayer AI Agents REST API hook.
|
|
66
66
|
*/
|
|
67
67
|
export * from './useAgents';
|
|
68
|
+
/**
|
|
69
|
+
* Agent runtimes service hooks for managing agent runtime instances.
|
|
70
|
+
*/
|
|
71
|
+
export * from './useAgentRuntimes';
|
|
72
|
+
/**
|
|
73
|
+
* Centralized agent catalog store for available agent specs and running agents.
|
|
74
|
+
*/
|
|
75
|
+
export * from './useAgentStore';
|
|
68
76
|
export * from './useNotebookAIAgent';
|
package/lib/hooks/index.js
CHANGED
|
@@ -78,4 +78,12 @@ export { useVercelChat } from './useVercelChat';
|
|
|
78
78
|
* Datalayer AI Agents REST API hook.
|
|
79
79
|
*/
|
|
80
80
|
export * from './useAgents';
|
|
81
|
+
/**
|
|
82
|
+
* Agent runtimes service hooks for managing agent runtime instances.
|
|
83
|
+
*/
|
|
84
|
+
export * from './useAgentRuntimes';
|
|
85
|
+
/**
|
|
86
|
+
* Centralized agent catalog store for available agent specs and running agents.
|
|
87
|
+
*/
|
|
88
|
+
export * from './useAgentStore';
|
|
81
89
|
export * from './useNotebookAIAgent';
|