@datalayer/agent-runtimes 1.3.40 → 1.3.43
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/api/runtimes/runtimes.d.ts +21 -0
- package/lib/api/runtimes/runtimes.js +45 -0
- package/lib/chat/ChatFloating.d.ts +30 -1
- package/lib/chat/ChatFloating.js +60 -14
- package/lib/chat/presence/Presence.d.ts +9 -0
- package/lib/chat/presence/Presence.js +11 -2
- package/lib/client/AgentRuntimesClient.d.ts +4 -0
- package/lib/client/mixins/RuntimesMixin.d.ts +9 -0
- package/lib/client/mixins/RuntimesMixin.js +19 -0
- package/lib/loop/apps/AppRenderer.d.ts +30 -6
- package/lib/loop/apps/AppRenderer.js +29 -8
- package/lib/loop/apps/index.d.ts +1 -0
- package/lib/loop/apps/index.js +1 -0
- package/lib/loop/apps/records.d.ts +42 -0
- package/lib/loop/apps/records.js +81 -0
- package/lib/loop/apps/rules.d.ts +13 -0
- package/lib/loop/apps/rules.js +36 -0
- package/lib/loop/embed/AppEmbed.d.ts +2 -0
- package/lib/loop/embed/AppEmbed.js +47 -119
- package/lib/loop/embed/LoopEmbed.js +1 -0
- package/lib/loop/index.d.ts +2 -0
- package/lib/loop/index.js +2 -0
- package/lib/loop/plugins/app-activity/AppActivity.d.ts +21 -0
- package/lib/loop/plugins/app-activity/AppActivity.js +63 -0
- package/lib/loop/plugins/app-activity/index.d.ts +11 -0
- package/lib/loop/plugins/app-activity/index.js +35 -0
- package/lib/loop/plugins/app-rules/AppRulesCard.d.ts +40 -0
- package/lib/loop/plugins/app-rules/AppRulesCard.js +50 -0
- package/lib/loop/plugins/app-rules/index.d.ts +7 -0
- package/lib/loop/plugins/app-rules/index.js +31 -0
- package/lib/loop/plugins/chat/ChatView.js +23 -3
- package/lib/loop/plugins/chat/index.d.ts +23 -0
- package/lib/loop/presets.d.ts +2 -0
- package/lib/loop/presets.js +2 -1
- package/package.json +2 -2
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { definePlugin } from '@datalayer/reactor';
|
|
3
|
+
import { LoopSlots } from '../../core';
|
|
4
|
+
import { AppRulesCard } from './AppRulesCard';
|
|
5
|
+
export const APP_RULES_PLUGIN_NAME = '@datalayer/loop-plugin-app-rules';
|
|
6
|
+
/** The plugin that lists an application's rules and the approvals waiting for the person. */
|
|
7
|
+
export function defineAppRulesPlugin(app) {
|
|
8
|
+
// One component per plugin: the slot keeps it, and the application with it.
|
|
9
|
+
function Card() {
|
|
10
|
+
return _jsx(AppRulesCard, { app: app });
|
|
11
|
+
}
|
|
12
|
+
const plugin = definePlugin({
|
|
13
|
+
name: `${APP_RULES_PLUGIN_NAME}-${app.id}`,
|
|
14
|
+
displayName: `${app.name}: rules and approvals`,
|
|
15
|
+
description: `When ${app.name} acts alone, when it asks, and what waits for your yes.`,
|
|
16
|
+
octicon: 'shield-check',
|
|
17
|
+
build: () => ({
|
|
18
|
+
components: [
|
|
19
|
+
{
|
|
20
|
+
id: 'app-rules',
|
|
21
|
+
slot: LoopSlots.sidebar,
|
|
22
|
+
order: 10,
|
|
23
|
+
Component: Card,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
return plugin;
|
|
29
|
+
}
|
|
30
|
+
export { AppRulesCard, APP_RULES_WORDS, ruleInWords, ruleOfApproval, } from './AppRulesCard';
|
|
31
|
+
export default defineAppRulesPlugin;
|
|
@@ -43,8 +43,9 @@ import { messageText, turnWritersOf } from './turnState';
|
|
|
43
43
|
import { isInactiveSurfaceContribution, orderToolContributions, toolsForChatView, } from './chatViewTools';
|
|
44
44
|
import { useAgentCommandTools } from '../../../tools/adapters/commands';
|
|
45
45
|
import { NONE_EDITOR, seedEditorChoice, setEditorOptions, } from '../shell/editorChoice';
|
|
46
|
-
import { PresenceFace, PresenceLine } from '../../../chat/presence/Presence';
|
|
46
|
+
import { FaceDrawing, PresenceFace, PresenceLine, } from '../../../chat/presence/Presence';
|
|
47
47
|
import { presenceState, presenceToolOf, } from '../../../chat/presence/presenceStatus';
|
|
48
|
+
import { latestSaying, newestIsAnswer, } from '../../../chat/assistant/state';
|
|
48
49
|
/** No editor: the conversation on its own. */
|
|
49
50
|
const NO_SURFACE = '';
|
|
50
51
|
/**
|
|
@@ -203,6 +204,14 @@ export default function ChatView({ workspace }) {
|
|
|
203
204
|
useEffect(() => {
|
|
204
205
|
onPresence?.(presenceNow);
|
|
205
206
|
}, [onPresence, presenceNow]);
|
|
207
|
+
// What it last said, for a host that says it outside the conversation —
|
|
208
|
+
// the embed's floating chrome (LOOP R-01): its balloon and its blink.
|
|
209
|
+
// Through a ref: the handler below is made once.
|
|
210
|
+
const onSayingRef = useRef(config?.presence?.onSaying);
|
|
211
|
+
onSayingRef.current = config?.presence?.onSaying;
|
|
212
|
+
const saidRef = useRef({
|
|
213
|
+
answering: false,
|
|
214
|
+
});
|
|
206
215
|
const handleSendReady = useCallback((controls) => {
|
|
207
216
|
controlsRef.current = controls;
|
|
208
217
|
setSendReady(!!controls);
|
|
@@ -221,6 +230,17 @@ export default function ChatView({ workspace }) {
|
|
|
221
230
|
setPresenceTool(previous => previous.open === open && previous.pendingApproval === pendingApproval
|
|
222
231
|
? previous
|
|
223
232
|
: { open, pendingApproval });
|
|
233
|
+
const said = {
|
|
234
|
+
saying: latestSaying(items),
|
|
235
|
+
answering: newestIsAnswer(items),
|
|
236
|
+
};
|
|
237
|
+
const before = saidRef.current;
|
|
238
|
+
if (before.saying?.id !== said.saying?.id ||
|
|
239
|
+
before.saying?.text !== said.saying?.text ||
|
|
240
|
+
before.answering !== said.answering) {
|
|
241
|
+
saidRef.current = said;
|
|
242
|
+
onSayingRef.current?.(said);
|
|
243
|
+
}
|
|
224
244
|
const feed = turnFeedRef.current;
|
|
225
245
|
if (!feed) {
|
|
226
246
|
return;
|
|
@@ -1484,7 +1504,7 @@ export default function ChatView({ workspace }) {
|
|
|
1484
1504
|
// The theme it wears, when the host names one (an application's).
|
|
1485
1505
|
, {
|
|
1486
1506
|
// The theme it wears, when the host names one (an application's).
|
|
1487
|
-
themeVariant: config?.themeVariant, themeOverrides: config?.themeOverrides,
|
|
1507
|
+
themeVariant: config?.themeVariant, themeOverrides: config?.themeOverrides, colorMode: config?.colorMode,
|
|
1488
1508
|
// The header says why, beside the title, for the same reason the
|
|
1489
1509
|
// placeholder does: a dead control with no explanation is worse
|
|
1490
1510
|
// than an absent one.
|
|
@@ -1525,7 +1545,7 @@ export default function ChatView({ workspace }) {
|
|
|
1525
1545
|
headerContent: presence ? _jsx(PresenceLine, { state: presenceNow }) : undefined, emptyState: {
|
|
1526
1546
|
// An application's own face, at the page's size of the three
|
|
1527
1547
|
// (LOOP T-08, T-19): the thing a person's eye lands on first.
|
|
1528
|
-
icon: presence?.face ? (_jsx("span", { "aria-hidden": true, style: { fontSize: FACE_LARGE, lineHeight: 1 }, children: presence.face })) : (_jsx(BrandIcon, { size: 48 })),
|
|
1548
|
+
icon: presence?.face ? (_jsx("span", { "aria-hidden": true, style: { fontSize: FACE_LARGE, lineHeight: 1 }, children: _jsx(FaceDrawing, { face: presence.face, size: FACE_LARGE }) })) : (_jsx(BrandIcon, { size: 48 })),
|
|
1529
1549
|
// `ChatEmptyState` reads its heading from here and nowhere
|
|
1530
1550
|
// else — the `title` above reaches the header only — so
|
|
1531
1551
|
// without this the agent introduced itself as "Start a
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PresenceState } from '../../../chat/presence/presenceStatus';
|
|
2
|
+
import type { AssistantSaying } from '../../../chat/assistant/state';
|
|
2
3
|
import type { ThemeOverrides } from '../../../types/chat';
|
|
3
4
|
/** What a host may set on the chat. */
|
|
4
5
|
/** Who is answering, as the person meets them. */
|
|
@@ -15,7 +16,22 @@ export interface ChatPresence {
|
|
|
15
16
|
* a state setter.
|
|
16
17
|
*/
|
|
17
18
|
onPresence?: (state: PresenceState) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Told what it last said, and whether its newest words are an answer, as
|
|
21
|
+
* they change — for a host that says them outside the conversation, as the
|
|
22
|
+
* embed's floating chrome does in its balloon and its blink (LOOP R-01).
|
|
23
|
+
* Read once, when the workspace is built: pass a stable function, such as
|
|
24
|
+
* a state setter.
|
|
25
|
+
*/
|
|
26
|
+
onSaying?: (said: ChatSaid) => void;
|
|
18
27
|
}
|
|
28
|
+
/** What the chat last said, as `onSaying` tells it. */
|
|
29
|
+
export type ChatSaid = {
|
|
30
|
+
/** The newest words of the agent, cut for a balloon. */
|
|
31
|
+
saying?: AssistantSaying;
|
|
32
|
+
/** Whether the newest item of the conversation is the agent's answer. */
|
|
33
|
+
answering: boolean;
|
|
34
|
+
};
|
|
19
35
|
export type ChatPluginConfig = {
|
|
20
36
|
/**
|
|
21
37
|
* The theme the conversation wears, by name: the person's unless said. An
|
|
@@ -28,6 +44,13 @@ export type ChatPluginConfig = {
|
|
|
28
44
|
* that its bubbles and its one button wear its colour and not the theme's.
|
|
29
45
|
*/
|
|
30
46
|
themeOverrides?: ThemeOverrides;
|
|
47
|
+
/**
|
|
48
|
+
* The mode the conversation is drawn in, when its host decides it — an
|
|
49
|
+
* embed in another product's page, whose mode is the host's or its
|
|
50
|
+
* visitor's system's, not the person's Datalayer setting. The person's
|
|
51
|
+
* unless said.
|
|
52
|
+
*/
|
|
53
|
+
colorMode?: 'light' | 'dark';
|
|
31
54
|
/**
|
|
32
55
|
* Who is answering, as the person meets them (LOOP T-08): a name, a face
|
|
33
56
|
* and a welcome, in place of the agent's id and a generic icon. An
|
package/lib/loop/presets.d.ts
CHANGED
|
@@ -143,6 +143,8 @@ export type LoopPresetOptions = {
|
|
|
143
143
|
themeVariant?: string;
|
|
144
144
|
/** Laid over that theme, by mode: an application's accent (LOOP T-05). */
|
|
145
145
|
themeOverrides?: ThemeOverrides;
|
|
146
|
+
/** The mode the conversation is drawn in, when the host decides it; the person's unless said. */
|
|
147
|
+
colorMode?: 'light' | 'dark';
|
|
146
148
|
/** Who is answering, as the person meets them (LOOP T-08). */
|
|
147
149
|
presence?: ChatPresence;
|
|
148
150
|
/** Whether the counters are shown under the prompt; on unless said. */
|
package/lib/loop/presets.js
CHANGED
|
@@ -52,7 +52,7 @@ import { LoopPageLayoutPlugin } from './plugins/page-layout';
|
|
|
52
52
|
* be installed or signed into, and the switches a demonstration wants are off.
|
|
53
53
|
*/
|
|
54
54
|
export function loopPlugins(options = {}) {
|
|
55
|
-
const { serverUrl, target = 'browser', defaultEditor: askedEditor, showViewSelector = true, hideChatHeader = false, chatHeaderButtons = false, promptPlacement, autoFocusPrompt = true, suggestionLabels = true, fullScreenTopOffset = 0, showAgentVariants = false, agentSummary = true, teamId, teamPicker = true, pageLayout = false, pageLayoutArrangement = 'page', pageLayoutTurnPanel = 'below', pageLayoutPrompt = 'docked', pageLayoutPromptAnchor = 'top', pageLayoutSize, pageLayoutTurnPanelFooter = 'full', localAgent, localAgentSpec, datalayerAgentSpecId, datalayerCreatePayload, targetFixed, themeVariant, themeOverrides, presence, showTokenUsage, floatingPrompt = false, editorSelector = false, editors = true, conversation = true, graph = false, commandPalette = false, pluginsPanel = false, windowFrame = false, firstPromptHook, } = options;
|
|
55
|
+
const { serverUrl, target = 'browser', defaultEditor: askedEditor, showViewSelector = true, hideChatHeader = false, chatHeaderButtons = false, promptPlacement, autoFocusPrompt = true, suggestionLabels = true, fullScreenTopOffset = 0, showAgentVariants = false, agentSummary = true, teamId, teamPicker = true, pageLayout = false, pageLayoutArrangement = 'page', pageLayoutTurnPanel = 'below', pageLayoutPrompt = 'docked', pageLayoutPromptAnchor = 'top', pageLayoutSize, pageLayoutTurnPanelFooter = 'full', localAgent, localAgentSpec, datalayerAgentSpecId, datalayerCreatePayload, targetFixed, themeVariant, themeOverrides, colorMode, presence, showTokenUsage, floatingPrompt = false, editorSelector = false, editors = true, conversation = true, graph = false, commandPalette = false, pluginsPanel = false, windowFrame = false, firstPromptHook, } = options;
|
|
56
56
|
const defaultEditor = askedEditor ?? (editors ? 'notebook' : 'none');
|
|
57
57
|
// A workspace without a conversation: the theme, the shell's points, and
|
|
58
58
|
// the host's chrome; its view is a host's plugin's.
|
|
@@ -86,6 +86,7 @@ export function loopPlugins(options = {}) {
|
|
|
86
86
|
fullScreenTopOffset,
|
|
87
87
|
themeVariant,
|
|
88
88
|
themeOverrides,
|
|
89
|
+
colorMode,
|
|
89
90
|
presence,
|
|
90
91
|
showTokenUsage,
|
|
91
92
|
}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/agent-runtimes",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"@ai-sdk/react": "4.0.93",
|
|
146
146
|
"@anthropic-ai/sdk": "^0.52.0",
|
|
147
147
|
"@datalayer/agent-teams": "^1.0.0",
|
|
148
|
-
"@datalayer/core": "^1.2.
|
|
148
|
+
"@datalayer/core": "^1.2.14",
|
|
149
149
|
"@datalayer/decks": "^1.0.4",
|
|
150
150
|
"@datalayer/icons-react": "^1.0.14",
|
|
151
151
|
"@datalayer/jupyter-lexical": "^2.0.18",
|