@datalayer/agent-runtimes 1.3.11 → 1.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/lib/AgentNode.js +3 -3
- package/lib/api/runtimes/healthz.js +4 -2
- package/lib/api/spacer/healthz.js +4 -2
- package/lib/chat/base/ChatBase.js +39 -25
- package/lib/chat/base/modelChoice.d.ts +62 -0
- package/lib/chat/base/modelChoice.js +56 -0
- package/lib/chat/messages/ChatMessageList.js +13 -5
- package/lib/chat/messages/FormSubmissionMessage.d.ts +17 -0
- package/lib/chat/messages/FormSubmissionMessage.js +49 -0
- package/lib/chat/messages/formSubmission.d.ts +41 -0
- package/lib/chat/messages/formSubmission.js +90 -0
- package/lib/chat/prompt/menus/ModelSelector.js +11 -4
- package/lib/chat/styles/streamdownStyles.js +40 -0
- package/lib/client/mixins/RuntimesMixin.js +1 -1
- package/lib/client/mixins/SpacerMixin.js +3 -3
- package/lib/components/a2ui/A2uiMarkdownProvider.d.ts +11 -0
- package/lib/components/a2ui/A2uiMarkdownProvider.js +13 -0
- package/lib/components/a2ui/index.d.ts +1 -0
- package/lib/components/a2ui/index.js +1 -0
- package/lib/examples/A2UiAgentExample.js +36 -223
- package/lib/examples/A2UiJupyterOutputExample.js +11 -1
- package/lib/examples/A2UiViewerExample.d.ts +9 -2
- package/lib/examples/A2UiViewerExample.js +33 -3
- package/lib/examples/main.js +37 -35
- package/lib/examples/utils/a2uiMarkdownProvider.d.ts +1 -7
- package/lib/examples/utils/a2uiMarkdownProvider.js +6 -8
- package/lib/loop/core/index.d.ts +33 -2
- package/lib/loop/core/index.js +29 -2
- package/lib/loop/embed/LoopEmbed.js +1 -0
- package/lib/loop/index.d.ts +1 -1
- package/lib/loop/index.js +4 -1
- package/lib/loop/plugins/a2ui-surface/InlineSurface.d.ts +22 -0
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +64 -0
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.d.ts +38 -0
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +64 -0
- package/lib/loop/plugins/a2ui-surface/index.d.ts +34 -0
- package/lib/loop/plugins/a2ui-surface/index.js +91 -0
- package/lib/loop/plugins/a2ui-surface/toolResult.d.ts +52 -0
- package/lib/loop/plugins/a2ui-surface/toolResult.js +106 -0
- package/lib/loop/plugins/chat/ChatView.js +81 -10
- package/lib/loop/plugins/chat/index.d.ts +14 -0
- package/lib/loop/plugins/chat/index.js +1 -0
- package/lib/loop/plugins/document/index.js +4 -0
- package/lib/loop/plugins/notebook/index.js +4 -0
- package/lib/loop/plugins/shell/useEditorPreviews.js +7 -0
- package/lib/loop/presets.d.ts +5 -0
- package/lib/loop/presets.js +7 -1
- package/lib/models/environments.generated.d.ts +7 -1
- package/lib/models/environments.generated.js +1 -1
- package/lib/specs/agents/agents.d.ts +1 -0
- package/lib/specs/agents/agents.js +112 -0
- package/lib/specs/models.js +3 -3
- package/lib/tools/adapters/copilotkit/CopilotKitToolAdapter.js +1 -1
- package/package.json +10 -4
- package/patches/@primer+react+37.31.0.patch +390 -0
- package/patches/eslint-plugin-react+7.37.5.patch +65 -0
- package/scripts/apply-patches.sh +15 -1
- package/scripts/codegen/compose.py +4 -4
- package/scripts/codegen/generate_agents.py +1 -2
- package/scripts/codegen/generate_frontend_tools.py +1 -1
- package/scripts/codegen/generate_models.py +33 -8
|
@@ -3,11 +3,12 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { Box, IconButton, SegmentedControl, Text, Truncate, } from '@primer/react';
|
|
4
4
|
import { useColorPalette } from '@datalayer/primer-addons';
|
|
5
5
|
import { ScreenFullIcon, ScreenNormalIcon } from '@primer/octicons-react';
|
|
6
|
-
import { signal } from '@datalayer/reactor';
|
|
6
|
+
import { computed, signal } from '@datalayer/reactor';
|
|
7
7
|
/* A signal to read when the layout publishes no live stance: the hook needs one. */
|
|
8
8
|
const NO_STANCE = signal(undefined);
|
|
9
9
|
import { useContributions, useSignalValue, useGate, useReactorPlatform, ReactorLazy, ReactorSlot, useSlotComponents, } from '@datalayer/reactor/react';
|
|
10
10
|
import { ChatBase } from '../../../chat/base/ChatBase';
|
|
11
|
+
import { readServerCatalogue } from '../../../chat/base/modelChoice';
|
|
11
12
|
import { SUGGESTION_CHIP_WIDTH } from '../../../chat/display/EmptyState';
|
|
12
13
|
import { AnonymousKeyExpired } from '@datalayer/core/lib/components/anonymous/AnonymousKeyExpired';
|
|
13
14
|
import { useAnonymousSessionStore } from '../../../runtimes/browser/anonymousToken';
|
|
@@ -143,7 +144,16 @@ export default function ChatView({ workspace }) {
|
|
|
143
144
|
handler memoised with empty deps. Set once the spec is resolved below. */
|
|
144
145
|
const agentNameRef = useRef('');
|
|
145
146
|
const extrasEntries = useContributions(LoopChatExtras);
|
|
146
|
-
|
|
147
|
+
/*
|
|
148
|
+
* Every contribution, merged, a later one winning a key both set.
|
|
149
|
+
*
|
|
150
|
+
* Only the first used to be read, which made the extras the property of
|
|
151
|
+
* whichever plugin registered first: the loop's own surface plugin
|
|
152
|
+
* contributes a tool-result renderer, and a host example contributing a
|
|
153
|
+
* banner beside it would have silenced one or the other.
|
|
154
|
+
*/
|
|
155
|
+
const mergedExtras = useMemo(() => computed(() => extrasEntries.reduce((merged, entry) => ({ ...merged, ...entry.value.extras.value }), {})), [extrasEntries]);
|
|
156
|
+
const chatExtras = useSignalValue(extrasEntries.length > 0 ? mergedExtras : EMPTY_CHAT_EXTRAS);
|
|
147
157
|
/* Which editors have ever been mounted; they are never unmounted after —
|
|
148
158
|
see the render below. A ref, not state: adding to it during render is
|
|
149
159
|
idempotent and must not schedule another one. */
|
|
@@ -308,18 +318,43 @@ export default function ChatView({ workspace }) {
|
|
|
308
318
|
busy,
|
|
309
319
|
stop: controlsRef.current?.stop,
|
|
310
320
|
newChat: controlsRef.current?.newChat,
|
|
321
|
+
send: controlsRef.current?.send,
|
|
311
322
|
}
|
|
312
323
|
: null);
|
|
313
324
|
}, [busy, sendReady, setViewControls]);
|
|
314
325
|
// Stop reporting when the view goes away, or the shell would keep a stop
|
|
315
326
|
// button for something that is no longer there.
|
|
316
327
|
useEffect(() => () => setViewControls(null), [setViewControls]);
|
|
328
|
+
/*
|
|
329
|
+
* Said before the adapter could take it.
|
|
330
|
+
*
|
|
331
|
+
* The composer is live while the chat is still starting — the shell shows
|
|
332
|
+
* it as soon as the view mounts — and a message sent in that moment used
|
|
333
|
+
* to be dropped, on the grounds that sending it late and out of context
|
|
334
|
+
* would be worse. It was worse: the message stood in the conversation with
|
|
335
|
+
* no reply and no reason, and the only way to find out was to send it
|
|
336
|
+
* again. Held instead, and sent the moment the adapter is ready, which is
|
|
337
|
+
* the next second or two rather than minutes.
|
|
338
|
+
*/
|
|
339
|
+
const heldForAdapter = useRef([]);
|
|
317
340
|
useEffect(() => workspace.prompts.subscribe(message => {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
341
|
+
const send = controlsRef.current?.send;
|
|
342
|
+
if (!send) {
|
|
343
|
+
heldForAdapter.current.push(message);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
send(message);
|
|
322
347
|
}), [workspace.prompts]);
|
|
348
|
+
// The adapter arrived: whatever was said while it was starting goes now.
|
|
349
|
+
useEffect(() => {
|
|
350
|
+
if (!sendReady || heldForAdapter.current.length === 0) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const held = heldForAdapter.current.splice(0, heldForAdapter.current.length);
|
|
354
|
+
for (const message of held) {
|
|
355
|
+
controlsRef.current?.send(message);
|
|
356
|
+
}
|
|
357
|
+
}, [sendReady]);
|
|
323
358
|
/*
|
|
324
359
|
* Fired once, on the first real send, for the life of this mounted chat —
|
|
325
360
|
* a ref rather than a signal, because nothing here needs to re-render when
|
|
@@ -634,7 +669,11 @@ export default function ChatView({ workspace }) {
|
|
|
634
669
|
*/
|
|
635
670
|
const suggestionEntries = useContributions(LoopChatSuggestion);
|
|
636
671
|
const hiddenOpeners = chatExtras.hiddenOpeners;
|
|
672
|
+
const hideOpeners = chatExtras.hideOpeners;
|
|
637
673
|
const suggestions = useMemo(() => {
|
|
674
|
+
if (hideOpeners) {
|
|
675
|
+
return [];
|
|
676
|
+
}
|
|
638
677
|
// What the host took off this page, by the chip's words — the same key
|
|
639
678
|
// the two-group merge below uses to tell openers apart.
|
|
640
679
|
const hidden = new Set(hiddenOpeners ?? []);
|
|
@@ -659,7 +698,15 @@ export default function ChatView({ workspace }) {
|
|
|
659
698
|
.filter(item => !listed.has(item.text))
|
|
660
699
|
.map(item => ({ ...item, group: memberName })),
|
|
661
700
|
];
|
|
662
|
-
}, [
|
|
701
|
+
}, [
|
|
702
|
+
suggestionEntries,
|
|
703
|
+
team,
|
|
704
|
+
spec,
|
|
705
|
+
member,
|
|
706
|
+
agentId,
|
|
707
|
+
hiddenOpeners,
|
|
708
|
+
hideOpeners,
|
|
709
|
+
]);
|
|
663
710
|
/*
|
|
664
711
|
* The same openers in the shape the chat's empty state asks for.
|
|
665
712
|
*
|
|
@@ -743,13 +790,18 @@ export default function ChatView({ workspace }) {
|
|
|
743
790
|
}
|
|
744
791
|
// A host example's own frontend tools, folded in last (first name wins),
|
|
745
792
|
// so a bespoke client tool like A2UI's run_jupyter_output_demo joins the
|
|
746
|
-
// agent's toolset without a plugin of its own.
|
|
793
|
+
// agent's toolset without a plugin of its own. Vouched for in the chat
|
|
794
|
+
// view as well: the filter below keeps the tools that leave the editors
|
|
795
|
+
// alone, and a host's tool touches no editor — the Jupyter Output
|
|
796
|
+
// example's chat had lost its one tool to that filter and answered
|
|
797
|
+
// "use the demo button" instead of running the demonstration.
|
|
747
798
|
for (const tool of chatExtras.frontendTools ?? []) {
|
|
748
799
|
if (owners.has(tool.name)) {
|
|
749
800
|
continue;
|
|
750
801
|
}
|
|
751
802
|
owners.set(tool.name, 'chat-extras');
|
|
752
803
|
merged.push(tool);
|
|
804
|
+
keep.add(tool.name);
|
|
753
805
|
}
|
|
754
806
|
/*
|
|
755
807
|
* The view decides the toolset. With an editor on screen the agent has
|
|
@@ -1077,7 +1129,10 @@ export default function ChatView({ workspace }) {
|
|
|
1077
1129
|
.then(response => (response.ok ? response.json() : { models: [] }))
|
|
1078
1130
|
.then(payload => {
|
|
1079
1131
|
if (!cancelled) {
|
|
1080
|
-
|
|
1132
|
+
// In the chat's shape: the route says `available`, the menu and
|
|
1133
|
+
// the opening pick read `isAvailable`, and an unmapped row passes
|
|
1134
|
+
// for usable. See `readServerCatalogue`.
|
|
1135
|
+
setCatalogModels(readServerCatalogue(payload));
|
|
1081
1136
|
}
|
|
1082
1137
|
})
|
|
1083
1138
|
// No catalogue is not an error worth a banner: the menu simply has
|
|
@@ -1349,6 +1404,16 @@ export default function ChatView({ workspace }) {
|
|
|
1349
1404
|
// placeholder does: a dead control with no explanation is worse
|
|
1350
1405
|
// than an absent one.
|
|
1351
1406
|
disabled: chatDisabled, disableReason: disabledReason, protocol: protocol,
|
|
1407
|
+
/*
|
|
1408
|
+
The model this view is on, as the chat's opening pick.
|
|
1409
|
+
|
|
1410
|
+
`ChatBase` keeps the model it sends with, and opened on the
|
|
1411
|
+
first row of whatever catalogue it had before the server
|
|
1412
|
+
answered — Alibaba — while the footer, drawn from
|
|
1413
|
+
`activeModel`, said Claude. Told the same model, both agree
|
|
1414
|
+
from the first message.
|
|
1415
|
+
*/
|
|
1416
|
+
initialModel: activeModel || undefined,
|
|
1352
1417
|
/*
|
|
1353
1418
|
Who is answering, in the words its spec uses.
|
|
1354
1419
|
|
|
@@ -1417,7 +1482,13 @@ export default function ChatView({ workspace }) {
|
|
|
1417
1482
|
props through `renderHeader`. No contribution — or a host
|
|
1418
1483
|
that set `hideHeader` — means no bar.
|
|
1419
1484
|
*/
|
|
1420
|
-
showHeader: !config?.hideHeader && !!HeaderComponent,
|
|
1485
|
+
showHeader: !config?.hideHeader && !!HeaderComponent,
|
|
1486
|
+
// The `+` and the bin in the title bar, when the host asked for
|
|
1487
|
+
// them; the header draws whatever `ChatBase` assembles here.
|
|
1488
|
+
headerButtons: {
|
|
1489
|
+
showNewChat: config?.headerButtons?.newChat ?? false,
|
|
1490
|
+
showClear: config?.headerButtons?.clear ?? false,
|
|
1491
|
+
}, renderHeader: HeaderComponent
|
|
1421
1492
|
? headerProps => (_jsx(HeaderComponent, { workspace: workspace, header: headerProps }))
|
|
1422
1493
|
: undefined,
|
|
1423
1494
|
/*
|
|
@@ -44,6 +44,20 @@ export type ChatPluginConfig = {
|
|
|
44
44
|
* directly beneath repeats the point in a smaller font.
|
|
45
45
|
*/
|
|
46
46
|
hideHeader: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the title bar offers a way to start over.
|
|
49
|
+
*
|
|
50
|
+
* `newChat` is the `+`: a fresh thread, the transcript emptied. `clear`
|
|
51
|
+
* is the bin: the same emptying, behind a confirmation, and drawn only
|
|
52
|
+
* while there is something to empty. Both off by default — a workspace
|
|
53
|
+
* embedded in a page is usually one conversation — and on for an example
|
|
54
|
+
* whose reader will ask for one surface after another and want the last
|
|
55
|
+
* one gone.
|
|
56
|
+
*/
|
|
57
|
+
headerButtons: {
|
|
58
|
+
newChat: boolean;
|
|
59
|
+
clear: boolean;
|
|
60
|
+
};
|
|
47
61
|
/**
|
|
48
62
|
* Whether the chat renders a prompt at all.
|
|
49
63
|
*
|
|
@@ -79,6 +79,10 @@ export const DocumentPlugin = definePlugin({
|
|
|
79
79
|
id: 'document-tools',
|
|
80
80
|
tools: workspace => createLexicalTools(workspace.surfaceId),
|
|
81
81
|
}, { id: 'document-tools' });
|
|
82
|
+
}, error => {
|
|
83
|
+
// The chunk did not load, or the page went away while it did: the
|
|
84
|
+
// chat simply has no document tools.
|
|
85
|
+
console.warn('The document tools could not be loaded', error);
|
|
82
86
|
});
|
|
83
87
|
return {};
|
|
84
88
|
},
|
|
@@ -84,6 +84,10 @@ export const NotebookPlugin = definePlugin({
|
|
|
84
84
|
id: 'notebook-tools',
|
|
85
85
|
tools: workspace => createNotebookTools(workspace.surfaceId),
|
|
86
86
|
}, { id: 'notebook-tools' });
|
|
87
|
+
}, error => {
|
|
88
|
+
// The chunk did not load, or the page went away while it did: the
|
|
89
|
+
// chat simply has no notebook tools.
|
|
90
|
+
console.warn('The notebook tools could not be loaded', error);
|
|
87
91
|
});
|
|
88
92
|
return {};
|
|
89
93
|
},
|
|
@@ -179,6 +179,13 @@ function useDocumentRows(surfaceId, enabled) {
|
|
|
179
179
|
};
|
|
180
180
|
refresh();
|
|
181
181
|
unsubscribe = lexicalStore.subscribe(refresh);
|
|
182
|
+
})
|
|
183
|
+
.catch(() => {
|
|
184
|
+
// Lexical could not load (or the page went away while it did): the
|
|
185
|
+
// document offers no preview, which is all this hook was for.
|
|
186
|
+
if (!cancelled) {
|
|
187
|
+
setRows(null);
|
|
188
|
+
}
|
|
182
189
|
});
|
|
183
190
|
return () => {
|
|
184
191
|
cancelled = true;
|
package/lib/loop/presets.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export type LoopPresetOptions = {
|
|
|
40
40
|
showViewSelector?: boolean;
|
|
41
41
|
/** Whether the chat draws its own header. */
|
|
42
42
|
hideChatHeader?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the chat's header offers `+` (a new chat) and the bin (clear).
|
|
45
|
+
* Off by default; see `ChatPluginConfig.headerButtons`.
|
|
46
|
+
*/
|
|
47
|
+
chatHeaderButtons?: boolean;
|
|
43
48
|
/** Where the prompt sits. Passed through to the chat plugin. */
|
|
44
49
|
promptPlacement?: ChatPluginConfig['promptPlacement'];
|
|
45
50
|
/**
|
package/lib/loop/presets.js
CHANGED
|
@@ -33,6 +33,7 @@ import { AgentspecsPlugin } from './plugins/agentspecs';
|
|
|
33
33
|
import { AgentsPlugin, } from './plugins/agents';
|
|
34
34
|
import { ChatPlugin } from './plugins/chat';
|
|
35
35
|
import { ChatHeaderPlugin } from './plugins/chat-header';
|
|
36
|
+
import { A2uiSurfacePlugin } from './plugins/a2ui-surface';
|
|
36
37
|
import { ChatViewPlugin } from './plugins/chat-view';
|
|
37
38
|
import { DocumentViewPlugin } from './plugins/document-view';
|
|
38
39
|
import { InputPromptPlugin } from './plugins/input-prompt';
|
|
@@ -51,7 +52,7 @@ import { LoopPageLayoutPlugin } from './plugins/page-layout';
|
|
|
51
52
|
* be installed or signed into, and the switches a demonstration wants are off.
|
|
52
53
|
*/
|
|
53
54
|
export function loopPlugins(options = {}) {
|
|
54
|
-
const { serverUrl, target = 'browser', defaultEditor = 'notebook', showViewSelector = true, hideChatHeader = false, promptPlacement, autoFocusPrompt = true, fullScreenTopOffset = 0, showAgentVariants = false, agentSummary = true, teamId, teamPicker = true, pageLayout = false, pageLayoutTurnPanel = 'below', pageLayoutPrompt = 'docked', pageLayoutPromptAnchor = 'top', pageLayoutSize, pageLayoutTurnPanelFooter = 'full', localAgent, localAgentSpec, floatingPrompt = false, editorSelector = false, editors = true, graph = false, commandPalette = false, pluginsPanel = false, windowFrame = false, firstPromptHook, } = options;
|
|
55
|
+
const { serverUrl, target = 'browser', defaultEditor = 'notebook', showViewSelector = true, hideChatHeader = false, chatHeaderButtons = false, promptPlacement, autoFocusPrompt = true, fullScreenTopOffset = 0, showAgentVariants = false, agentSummary = true, teamId, teamPicker = true, pageLayout = false, pageLayoutTurnPanel = 'below', pageLayoutPrompt = 'docked', pageLayoutPromptAnchor = 'top', pageLayoutSize, pageLayoutTurnPanelFooter = 'full', localAgent, localAgentSpec, floatingPrompt = false, editorSelector = false, editors = true, graph = false, commandPalette = false, pluginsPanel = false, windowFrame = false, firstPromptHook, } = options;
|
|
55
56
|
return [
|
|
56
57
|
// The chat owns the editor beside it, so which one opens is its
|
|
57
58
|
// configuration rather than the workspace's.
|
|
@@ -62,6 +63,7 @@ export function loopPlugins(options = {}) {
|
|
|
62
63
|
// to choose.
|
|
63
64
|
showSurfaceSelector: editors && showViewSelector && !editorSelector,
|
|
64
65
|
hideHeader: hideChatHeader,
|
|
66
|
+
headerButtons: { newChat: chatHeaderButtons, clear: chatHeaderButtons },
|
|
65
67
|
promptPlacement: floatingPrompt ? 'floating' : promptPlacement,
|
|
66
68
|
autoFocusPrompt,
|
|
67
69
|
fullScreenTopOffset,
|
|
@@ -72,6 +74,10 @@ export function loopPlugins(options = {}) {
|
|
|
72
74
|
// still switched individually in the plugins panel.
|
|
73
75
|
configurePlugin(InputPromptPlugin, { firstPromptHook }),
|
|
74
76
|
ChatHeaderPlugin,
|
|
77
|
+
// An agent whose spec binds a tool to the `a2ui-surface` renderer gets
|
|
78
|
+
// its surfaces drawn and submitted without a line of host code. Idle
|
|
79
|
+
// for every other agent: it answers only for tools some spec bound.
|
|
80
|
+
A2uiSurfacePlugin,
|
|
75
81
|
// One footer icon per view, in the composer where the writing hand
|
|
76
82
|
// already is. Each editor's icon withdraws while its editor is not
|
|
77
83
|
// contributed, so mounting these unconditionally costs an absent editor
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** The `$id` of the JSON Schema these types are generated from. */
|
|
2
2
|
export declare const ENVIRONMENT_SCHEMA_ID = "https://datalayer.io/schemas/environments/v1alpha1/environment.json";
|
|
3
3
|
/** The sha256 of the schema text these types are generated from. */
|
|
4
|
-
export declare const ENVIRONMENT_SCHEMA_SHA256 = "
|
|
4
|
+
export declare const ENVIRONMENT_SCHEMA_SHA256 = "3aa1a84206afd2d5d04d3a2eab28abca1d60e1a6a6ab8c14a94ace62b39e6015";
|
|
5
5
|
/** The `apiVersion` an Environment document carries. */
|
|
6
6
|
export declare const ENVIRONMENT_API_VERSION = "environments.datalayer.io/v1alpha1";
|
|
7
7
|
/** The `kind` an Environment document carries. */
|
|
@@ -26,6 +26,7 @@ export interface BuildSecret {
|
|
|
26
26
|
}
|
|
27
27
|
export interface BuildSpec {
|
|
28
28
|
dependencyFile?: DependencyFileSpec | null;
|
|
29
|
+
dockerfile?: DockerfileSpec | null;
|
|
29
30
|
image?: ImageSourceSpec | null;
|
|
30
31
|
/** Default: `"packages"`. */
|
|
31
32
|
source?: 'packages' | 'dependencyFile' | 'dockerfile' | 'image';
|
|
@@ -55,6 +56,11 @@ export interface DependencyFileSpec {
|
|
|
55
56
|
/** Default: `"requirements"`. */
|
|
56
57
|
sourceFormat?: 'requirements' | 'pyproject' | 'conda';
|
|
57
58
|
}
|
|
59
|
+
/** The Dockerfile a `dockerfile`-sourced version builds from (E3-03). */
|
|
60
|
+
export interface DockerfileSpec {
|
|
61
|
+
/** Default: `""`. */
|
|
62
|
+
content?: string;
|
|
63
|
+
}
|
|
58
64
|
export interface EnvironmentSpec {
|
|
59
65
|
base: Base;
|
|
60
66
|
build?: BuildSpec;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/** The `$id` of the JSON Schema these types are generated from. */
|
|
7
7
|
export const ENVIRONMENT_SCHEMA_ID = 'https://datalayer.io/schemas/environments/v1alpha1/environment.json';
|
|
8
8
|
/** The sha256 of the schema text these types are generated from. */
|
|
9
|
-
export const ENVIRONMENT_SCHEMA_SHA256 = '
|
|
9
|
+
export const ENVIRONMENT_SCHEMA_SHA256 = '3aa1a84206afd2d5d04d3a2eab28abca1d60e1a6a6ab8c14a94ace62b39e6015';
|
|
10
10
|
/** The `apiVersion` an Environment document carries. */
|
|
11
11
|
export const ENVIRONMENT_API_VERSION = 'environments.datalayer.io/v1alpha1';
|
|
12
12
|
/** The `kind` an Environment document carries. */
|
|
@@ -11,6 +11,7 @@ export declare const EXAMPLE_A2A_WRITER_AGENTSPEC_0_0_1: Agentspec;
|
|
|
11
11
|
export declare const EXAMPLE_A2A_AGENTSPEC_0_0_1: Agentspec;
|
|
12
12
|
export declare const EXAMPLE_A2UI_AGENT_SPEC_0_0_1: Agentspec;
|
|
13
13
|
export declare const EXAMPLE_A2UI_JUPYTER_OUTPUT_AGENTSPEC_0_0_1: Agentspec;
|
|
14
|
+
export declare const EXAMPLE_A2UI_VIEWER_AGENTSPEC_0_0_1: Agentspec;
|
|
14
15
|
export declare const EXAMPLE_AGENT_CRITIC_LOOP_FOR_ANALYSIS_AGENTSPEC_0_0_1: Agentspec;
|
|
15
16
|
export declare const EXAMPLE_AGENTIC_CHAT_AGENTSPEC_0_0_1: Agentspec;
|
|
16
17
|
export declare const EXAMPLE_AGENTIC_GENERATIVE_UI_AGENTSPEC_0_0_1: Agentspec;
|
|
@@ -490,6 +490,117 @@ screen — do not apologise for it or offer to fix the code.
|
|
|
490
490
|
parameters: undefined,
|
|
491
491
|
subagents: undefined,
|
|
492
492
|
};
|
|
493
|
+
export const EXAMPLE_A2UI_VIEWER_AGENTSPEC_0_0_1 = {
|
|
494
|
+
id: 'example-a2ui-viewer',
|
|
495
|
+
version: '0.0.1',
|
|
496
|
+
name: 'A2UI Viewer Agent',
|
|
497
|
+
description: `Answers beside the A2UI Viewer, whose scenes — a recipe card, a booking form, a sales snapshot and a shipping status — it renders on request as live A2UI surfaces, and runs code in the sandbox to show its outputs.`,
|
|
498
|
+
tags: ['a2ui', 'viewer', 'loop'],
|
|
499
|
+
domain: undefined,
|
|
500
|
+
enabled: true,
|
|
501
|
+
model: 'bedrock:us.anthropic.claude-sonnet-4-6',
|
|
502
|
+
mcpServers: [],
|
|
503
|
+
skills: [].filter(Boolean),
|
|
504
|
+
tools: [TOOL_MAP['example-render-a2ui-surface:0.0.1']],
|
|
505
|
+
frontendTools: [],
|
|
506
|
+
frontendRenderTools: [
|
|
507
|
+
{ tool: 'render_a2ui_surface', renderer: 'a2ui-surface' },
|
|
508
|
+
],
|
|
509
|
+
environmentName: 'ai-agents-env',
|
|
510
|
+
icon: 'browser',
|
|
511
|
+
emoji: '🔍',
|
|
512
|
+
color: '#6366F1',
|
|
513
|
+
suggestions: [
|
|
514
|
+
{
|
|
515
|
+
text: 'Show a recipe card for a Mediterranean quinoa bowl, with a photo, its rating and review count, prep and cook time, and how many it serves.',
|
|
516
|
+
summary: 'Recipe Card',
|
|
517
|
+
emoji: '🍲',
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
text: 'Build a table booking form with party size, date and time, dietary requirements and a Submit Reservation button.',
|
|
521
|
+
summary: 'Booking Form',
|
|
522
|
+
emoji: '📅',
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
text: 'Show a Q2 sales snapshot by category — Apparel, Electronics, Home Goods and Health & Beauty — as KPI tiles under one headline.',
|
|
526
|
+
summary: 'Sales Snapshot',
|
|
527
|
+
emoji: '📈',
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
text: 'Show a package status card with the tracking number, the steps from placed to shipped to out for delivery, and the ETA.',
|
|
531
|
+
summary: 'Shipping Status',
|
|
532
|
+
emoji: '📦',
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
text: 'Plot a chart in the code sandbox and show me the image.',
|
|
536
|
+
summary: 'Plot a chart',
|
|
537
|
+
emoji: '📈',
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
text: 'Build a small DataFrame in the code sandbox and show it as a table.',
|
|
541
|
+
summary: 'DataFrame as a table',
|
|
542
|
+
emoji: '🧮',
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
text: 'Run something in the code sandbox that fails, so I can see the traceback.',
|
|
546
|
+
summary: 'Show a traceback',
|
|
547
|
+
emoji: '🐛',
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
text: 'Show me an interactive slider from the code sandbox.',
|
|
551
|
+
summary: 'Interactive slider',
|
|
552
|
+
emoji: '🎛️',
|
|
553
|
+
},
|
|
554
|
+
],
|
|
555
|
+
welcomeMessage: 'This is the A2UI Viewer. Pick a scene above to see a surface drawn from A2UI messages, ask me to render one of them here, or run something in the code sandbox and see its output.',
|
|
556
|
+
welcomeNotebook: undefined,
|
|
557
|
+
welcomeDocument: undefined,
|
|
558
|
+
sandboxVariant: 'browser',
|
|
559
|
+
harness: 'vercel-ai',
|
|
560
|
+
systemPrompt: `You answer beside the A2UI Viewer, an example that renders A2UI surfaces
|
|
561
|
+
from pasted protocol messages: a recipe card, a table booking form, a sales
|
|
562
|
+
snapshot of KPI tiles, and a shipping status timeline.
|
|
563
|
+
|
|
564
|
+
When asked for a surface — one of those, or anything like them:
|
|
565
|
+
1. ALWAYS call the \`render_a2ui_surface\` tool to produce it. Never describe
|
|
566
|
+
the surface in prose instead of rendering it.
|
|
567
|
+
2. Choose a concise \`title\` and a one-sentence \`intro\`.
|
|
568
|
+
3. Design a sensible ordered list of \`fields\`, picking the best \`type\` for
|
|
569
|
+
each: \`text\` / \`email\` for short input, \`longtext\` for notes, \`choice\`
|
|
570
|
+
or \`multichoice\` with \`options\` for pick-lists, \`checkbox\` for yes/no,
|
|
571
|
+
\`slider\` with \`min\`/\`max\` for ranges and ratings, \`date\` / \`datetime\`
|
|
572
|
+
for scheduling. A card that shows values rather than asking for them
|
|
573
|
+
still renders as a surface: put each value in a field with its label.
|
|
574
|
+
4. After the tool call, reply with ONE short sentence saying what you
|
|
575
|
+
rendered. Do not repeat the fields in text — the surface is shown.
|
|
576
|
+
|
|
577
|
+
When asked to run code, use \`execute_code\` in the sandbox and let the
|
|
578
|
+
outputs speak: a figure, a table, a traceback, a widget. Do not look for
|
|
579
|
+
helpers or skills in the sandbox; write the Python yourself.
|
|
580
|
+
`,
|
|
581
|
+
systemPromptCodemodeAddons: undefined,
|
|
582
|
+
goal: undefined,
|
|
583
|
+
delegable: [],
|
|
584
|
+
protocol: 'vercel-ai',
|
|
585
|
+
uiExtension: undefined,
|
|
586
|
+
trigger: undefined,
|
|
587
|
+
modelConfig: undefined,
|
|
588
|
+
mcpServerTools: undefined,
|
|
589
|
+
guardrails: undefined,
|
|
590
|
+
evals: undefined,
|
|
591
|
+
codemode: undefined,
|
|
592
|
+
output: undefined,
|
|
593
|
+
advanced: undefined,
|
|
594
|
+
checkpoints: undefined,
|
|
595
|
+
authorizationPolicy: undefined,
|
|
596
|
+
notifications: undefined,
|
|
597
|
+
memory: 'ephemeral',
|
|
598
|
+
preHooks: undefined,
|
|
599
|
+
postHooks: undefined,
|
|
600
|
+
toolHooks: undefined,
|
|
601
|
+
parameters: undefined,
|
|
602
|
+
subagents: undefined,
|
|
603
|
+
};
|
|
493
604
|
export const EXAMPLE_AGENT_CRITIC_LOOP_FOR_ANALYSIS_AGENTSPEC_0_0_1 = {
|
|
494
605
|
id: 'example-agent-critic-loop-for-analysis',
|
|
495
606
|
version: '0.0.1',
|
|
@@ -13098,6 +13209,7 @@ export const AGENTSPECS = {
|
|
|
13098
13209
|
'example-a2a': EXAMPLE_A2A_AGENTSPEC_0_0_1,
|
|
13099
13210
|
'example-a2ui-agent': EXAMPLE_A2UI_AGENT_SPEC_0_0_1,
|
|
13100
13211
|
'example-a2ui-jupyter-output': EXAMPLE_A2UI_JUPYTER_OUTPUT_AGENTSPEC_0_0_1,
|
|
13212
|
+
'example-a2ui-viewer': EXAMPLE_A2UI_VIEWER_AGENTSPEC_0_0_1,
|
|
13101
13213
|
'example-agent-critic-loop-for-analysis': EXAMPLE_AGENT_CRITIC_LOOP_FOR_ANALYSIS_AGENTSPEC_0_0_1,
|
|
13102
13214
|
'example-agentic-chat': EXAMPLE_AGENTIC_CHAT_AGENTSPEC_0_0_1,
|
|
13103
13215
|
'example-agentic-generative-ui': EXAMPLE_AGENTIC_GENERATIVE_UI_AGENTSPEC_0_0_1,
|
package/lib/specs/models.js
CHANGED
|
@@ -281,7 +281,7 @@ export const BEDROCK_US_ANTHROPIC_CLAUDE_SONNET_4_5_20250929_V1_0_0_0_1 = {
|
|
|
281
281
|
name: 'Bedrock Claude Sonnet 4.5',
|
|
282
282
|
description: 'Claude Sonnet 4.5 via AWS Bedrock - balanced performance',
|
|
283
283
|
provider: 'bedrock',
|
|
284
|
-
default:
|
|
284
|
+
default: false,
|
|
285
285
|
available: false,
|
|
286
286
|
requiredEnvVars: [
|
|
287
287
|
'AWS_ACCESS_KEY_ID',
|
|
@@ -461,5 +461,5 @@ export const AI_MODEL_CATALOGUE = {
|
|
|
461
461
|
'openai:gpt-4o': OPENAI_GPT_4O_0_0_1,
|
|
462
462
|
'openai:o3-mini': OPENAI_O3_MINI_0_0_1,
|
|
463
463
|
};
|
|
464
|
-
export const DEFAULT_MODEL = AIModels.
|
|
465
|
-
export const DEFAULT_MODEL_SPEC =
|
|
464
|
+
export const DEFAULT_MODEL = AIModels.BEDROCK_US_ANTHROPIC_CLAUDE_SONNET_4_6;
|
|
465
|
+
export const DEFAULT_MODEL_SPEC = BEDROCK_US_ANTHROPIC_CLAUDE_SONNET_4_6_0_0_1;
|
|
@@ -94,7 +94,7 @@ function jsonSchemaToParameters(jsonSchema) {
|
|
|
94
94
|
for (const [name, schema] of Object.entries(jsonSchema.properties || {})) {
|
|
95
95
|
const propSchema = schema;
|
|
96
96
|
// Map JSON Schema type to CopilotKit type
|
|
97
|
-
let copilotType
|
|
97
|
+
let copilotType;
|
|
98
98
|
if (propSchema.type === 'array') {
|
|
99
99
|
// Handle array types based on items type
|
|
100
100
|
const itemsType = propSchema.items?.type;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/agent-runtimes",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -145,8 +145,8 @@
|
|
|
145
145
|
"@datalayer/core": "^1.1.57",
|
|
146
146
|
"@datalayer/decks": "^1.0.0",
|
|
147
147
|
"@datalayer/icons-react": "^1.0.7",
|
|
148
|
-
"@datalayer/jupyter-lexical": "^1.0.
|
|
149
|
-
"@datalayer/jupyter-react": "^2.0.
|
|
148
|
+
"@datalayer/jupyter-lexical": "^1.0.24",
|
|
149
|
+
"@datalayer/jupyter-react": "^2.0.15",
|
|
150
150
|
"@datalayer/jupyter-server-nbmodel": "^0.2.8",
|
|
151
151
|
"@datalayer/lexical-loro": "^1.0.0",
|
|
152
152
|
"@datalayer/primer-addons": "^1.0.15",
|
|
@@ -362,7 +362,13 @@
|
|
|
362
362
|
"pyodide": "0.29.4",
|
|
363
363
|
"react": "19.2.8",
|
|
364
364
|
"react-dom": "19.2.8",
|
|
365
|
-
"typescript": "5.9.3"
|
|
365
|
+
"typescript": "5.9.3",
|
|
366
|
+
"@datalayer/core": {
|
|
367
|
+
"react-router-dom": "$react-router-dom"
|
|
368
|
+
},
|
|
369
|
+
"eslint-plugin-react": {
|
|
370
|
+
"eslint": "$eslint"
|
|
371
|
+
}
|
|
366
372
|
},
|
|
367
373
|
"lint-staged": {
|
|
368
374
|
"src/**/*.{js,jsx,ts,tsx}": [
|