@datalayer/agent-runtimes 1.3.27 ā 1.3.29
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/chat/ChatFloating.d.ts +12 -2
- package/lib/chat/ChatFloating.js +196 -25
- package/lib/chat/assistant/AssistantStage.d.ts +70 -0
- package/lib/chat/assistant/AssistantStage.js +192 -0
- package/lib/chat/assistant/SpeechBalloon.d.ts +26 -0
- package/lib/chat/assistant/SpeechBalloon.js +46 -0
- package/lib/chat/assistant/SpriteCharacter.d.ts +26 -0
- package/lib/chat/assistant/SpriteCharacter.js +73 -0
- package/lib/chat/assistant/characters.d.ts +30 -0
- package/lib/chat/assistant/characters.js +41 -0
- package/lib/chat/assistant/formats/acs.d.ts +88 -0
- package/lib/chat/assistant/formats/acs.js +493 -0
- package/lib/chat/assistant/formats/agentCompression.d.ts +5 -0
- package/lib/chat/assistant/formats/agentCompression.js +92 -0
- package/lib/chat/assistant/formats/blobs.d.ts +6 -0
- package/lib/chat/assistant/formats/blobs.js +52 -0
- package/lib/chat/assistant/formats/clippy.d.ts +21 -0
- package/lib/chat/assistant/formats/clippy.js +167 -0
- package/lib/chat/assistant/formats/index.d.ts +13 -0
- package/lib/chat/assistant/formats/index.js +15 -0
- package/lib/chat/assistant/formats/objectLiteral.d.ts +23 -0
- package/lib/chat/assistant/formats/objectLiteral.js +233 -0
- package/lib/chat/assistant/formats/stateAnimations.d.ts +16 -0
- package/lib/chat/assistant/formats/stateAnimations.js +115 -0
- package/lib/chat/assistant/formats/types.d.ts +56 -0
- package/lib/chat/assistant/formats/types.js +11 -0
- package/lib/chat/assistant/state.d.ts +62 -0
- package/lib/chat/assistant/state.js +116 -0
- package/lib/chat/header/ChatViewModeToggle.js +6 -3
- package/lib/chat/presence/Presence.d.ts +9 -0
- package/lib/chat/presence/Presence.js +57 -0
- package/lib/chat/presence/presenceStatus.d.ts +32 -0
- package/lib/chat/presence/presenceStatus.js +46 -0
- package/lib/chat/viewModes.d.ts +6 -0
- package/lib/chat/viewModes.js +10 -1
- package/lib/examples/ChatAssistantExample.d.ts +8 -0
- package/lib/examples/ChatAssistantExample.js +59 -0
- package/lib/examples/example-selector.js +1 -0
- package/lib/examples/main.js +3 -0
- package/lib/loop/apps/AppRenderer.d.ts +8 -1
- package/lib/loop/apps/AppRenderer.js +2 -1
- package/lib/loop/apps/appspec.d.ts +5 -1
- package/lib/loop/apps/appspec.js +21 -1
- package/lib/loop/apps/checks.js +3 -1
- package/lib/loop/core/index.d.ts +15 -0
- package/lib/loop/core/index.js +1 -0
- package/lib/loop/plugins/assistant-characters/index.d.ts +30 -0
- package/lib/loop/plugins/assistant-characters/index.js +41 -0
- package/lib/loop/plugins/chat/ChatView.js +21 -1
- package/lib/loop/plugins/chat/index.d.ts +8 -0
- package/lib/loop/plugins/page-layout/index.js +5 -1
- package/lib/specs/actions.js +6 -0
- package/lib/specs/apps.d.ts +3 -0
- package/lib/specs/apps.js +793 -65
- package/lib/specs/appspecSchema.js +20 -2
- package/lib/types/agentspecs.d.ts +10 -1
- package/lib/types/chat.d.ts +1 -1
- package/package.json +1 -1
package/lib/loop/core/index.js
CHANGED
|
@@ -141,6 +141,7 @@ export const LoopChatComposer = defineContributionPoint('loop.chat.composer');
|
|
|
141
141
|
export const LoopChatHeader = defineContributionPoint('loop.chat.header');
|
|
142
142
|
export const LoopAgentBlueprint = defineContributionPoint('loop.agent.blueprint');
|
|
143
143
|
export const LoopChatSuggestion = defineContributionPoint('loop.chat.suggestion');
|
|
144
|
+
export const LoopAssistantCharacter = defineContributionPoint('loop.assistant.character');
|
|
144
145
|
export const LoopChatExtras = defineContributionPoint('loop.chat.extras');
|
|
145
146
|
export const LoopOpeningNotebook = defineContributionPoint('loop.notebook.opening');
|
|
146
147
|
export const LoopOpeningDocument = defineContributionPoint('loop.document.opening');
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datalayer's own characters for the floating assistant, contributed
|
|
3
|
+
* (LOOP T-24, T-25): the paper clip, the wizard, the cat and the LšP eyes.
|
|
4
|
+
* Disabled, they leave the catalogue; another plugin may contribute others.
|
|
5
|
+
*
|
|
6
|
+
* @module loop/plugins/assistant-characters
|
|
7
|
+
*/
|
|
8
|
+
import { type ReactorPlugin } from '@datalayer/reactor';
|
|
9
|
+
import { type AssistantCharacter } from '../../../chat/assistant/characters';
|
|
10
|
+
import type { AssistantCharacterData } from '../../../chat/assistant/formats/types';
|
|
11
|
+
import { LoopAssistantCharacter, type AssistantCharacterContribution } from '../../core';
|
|
12
|
+
/** What is read of a reactor here: its contributions to the point. */
|
|
13
|
+
type ContributionsReader = {
|
|
14
|
+
getContributions: (point: typeof LoopAssistantCharacter) => ReadonlyArray<{
|
|
15
|
+
value: AssistantCharacterContribution;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
export declare const ASSISTANT_CHARACTERS_PLUGIN_NAME = "@datalayer/loop-plugin-assistant-characters";
|
|
19
|
+
export declare const AssistantCharactersPlugin: ReactorPlugin<Record<string, never>, unknown, unknown>;
|
|
20
|
+
/** The characters the enabled plugins contribute, in contribution order. */
|
|
21
|
+
export declare function assistantCharactersOf(reactor: ContributionsReader): {
|
|
22
|
+
id: string;
|
|
23
|
+
character: AssistantCharacter | AssistantCharacterData;
|
|
24
|
+
}[];
|
|
25
|
+
/**
|
|
26
|
+
* The character an application names, from what is contributed; an id no
|
|
27
|
+
* enabled plugin contributes is an error that says which ids there are.
|
|
28
|
+
*/
|
|
29
|
+
export declare function assistantCharacterNamed(reactor: ContributionsReader, id: string): AssistantCharacter | AssistantCharacterData;
|
|
30
|
+
export default AssistantCharactersPlugin;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Datalayer's own characters for the floating assistant, contributed
|
|
7
|
+
* (LOOP T-24, T-25): the paper clip, the wizard, the cat and the LšP eyes.
|
|
8
|
+
* Disabled, they leave the catalogue; another plugin may contribute others.
|
|
9
|
+
*
|
|
10
|
+
* @module loop/plugins/assistant-characters
|
|
11
|
+
*/
|
|
12
|
+
import { contribution, definePlugin, } from '@datalayer/reactor';
|
|
13
|
+
import { ASSISTANT_CHARACTERS, } from '../../../chat/assistant/characters';
|
|
14
|
+
import { LoopAssistantCharacter, } from '../../core';
|
|
15
|
+
export const ASSISTANT_CHARACTERS_PLUGIN_NAME = '@datalayer/loop-plugin-assistant-characters';
|
|
16
|
+
export const AssistantCharactersPlugin = definePlugin({
|
|
17
|
+
name: ASSISTANT_CHARACTERS_PLUGIN_NAME,
|
|
18
|
+
displayName: 'Assistant characters',
|
|
19
|
+
description: "Datalayer's own characters for the floating assistant: a paper clip, a wizard, a cat and the LšP eyes.",
|
|
20
|
+
octicon: 'paperclip',
|
|
21
|
+
contributes: ASSISTANT_CHARACTERS.map(character => contribution(LoopAssistantCharacter, { id: character.id, character }, { id: character.id })),
|
|
22
|
+
});
|
|
23
|
+
/** The characters the enabled plugins contribute, in contribution order. */
|
|
24
|
+
export function assistantCharactersOf(reactor) {
|
|
25
|
+
return reactor
|
|
26
|
+
.getContributions(LoopAssistantCharacter)
|
|
27
|
+
.map(entry => entry.value);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The character an application names, from what is contributed; an id no
|
|
31
|
+
* enabled plugin contributes is an error that says which ids there are.
|
|
32
|
+
*/
|
|
33
|
+
export function assistantCharacterNamed(reactor, id) {
|
|
34
|
+
const all = assistantCharactersOf(reactor);
|
|
35
|
+
const found = all.find(entry => entry.id === id);
|
|
36
|
+
if (!found) {
|
|
37
|
+
throw new Error(`No enabled plugin contributes the assistant character "${id}"; the characters are ${all.map(entry => entry.id).join(', ') || 'none'}.`);
|
|
38
|
+
}
|
|
39
|
+
return found.character;
|
|
40
|
+
}
|
|
41
|
+
export default AssistantCharactersPlugin;
|
|
@@ -43,6 +43,8 @@ import { 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';
|
|
47
|
+
import { presenceState, presenceToolOf, } from '../../../chat/presence/presenceStatus';
|
|
46
48
|
/** No editor: the conversation on its own. */
|
|
47
49
|
const NO_SURFACE = '';
|
|
48
50
|
/**
|
|
@@ -186,6 +188,16 @@ export default function ChatView({ workspace }) {
|
|
|
186
188
|
*/
|
|
187
189
|
const [busy, setBusy] = useState(false);
|
|
188
190
|
const [sendReady, setSendReady] = useState(false);
|
|
191
|
+
const [presenceTool, setPresenceTool] = useState({
|
|
192
|
+
open: false,
|
|
193
|
+
pendingApproval: false,
|
|
194
|
+
});
|
|
195
|
+
const presenceNow = presenceState(busy, presenceTool);
|
|
196
|
+
const onPresence = config?.presence?.onPresence;
|
|
197
|
+
// A host drawing the face in a frame of its own is told as it changes.
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
onPresence?.(presenceNow);
|
|
200
|
+
}, [onPresence, presenceNow]);
|
|
189
201
|
const handleSendReady = useCallback((controls) => {
|
|
190
202
|
controlsRef.current = controls;
|
|
191
203
|
setSendReady(!!controls);
|
|
@@ -199,6 +211,11 @@ export default function ChatView({ workspace }) {
|
|
|
199
211
|
* Cleared when nothing is running.
|
|
200
212
|
*/
|
|
201
213
|
const handleDisplayItemsChange = useCallback((items) => {
|
|
214
|
+
// The newest tool call, for an application's line of status (T-08).
|
|
215
|
+
const { open, pendingApproval } = presenceToolOf(items);
|
|
216
|
+
setPresenceTool(previous => previous.open === open && previous.pendingApproval === pendingApproval
|
|
217
|
+
? previous
|
|
218
|
+
: { open, pendingApproval });
|
|
202
219
|
const feed = turnFeedRef.current;
|
|
203
220
|
if (!feed) {
|
|
204
221
|
return;
|
|
@@ -1436,7 +1453,10 @@ export default function ChatView({ workspace }) {
|
|
|
1436
1453
|
// Big enough to read as the agent's mark rather than as
|
|
1437
1454
|
// punctuation before its name, and still short enough not to
|
|
1438
1455
|
// set the header's height.
|
|
1439
|
-
brandIcon: presence?.face ? (_jsx(
|
|
1456
|
+
brandIcon: presence?.face ? (_jsx(PresenceFace, { face: presence.face, size: 20, state: presenceNow })) : (_jsx(BrandIcon, { size: 20 })),
|
|
1457
|
+
// An application says what it is doing, in plain words, beside
|
|
1458
|
+
// its name (T-08); an agent's chat keeps its header as it is.
|
|
1459
|
+
headerContent: presence ? _jsx(PresenceLine, { state: presenceNow }) : undefined, emptyState: {
|
|
1440
1460
|
// An application's own face, large: the thing a person's eye
|
|
1441
1461
|
// lands on first (LOOP T-08).
|
|
1442
1462
|
icon: presence?.face ? (_jsx("span", { "aria-hidden": true, style: { fontSize: 48, lineHeight: 1 }, children: presence.face })) : (_jsx(BrandIcon, { size: 48 })),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PresenceState } from '../../../chat/presence/presenceStatus';
|
|
1
2
|
/** What a host may set on the chat. */
|
|
2
3
|
/** Who is answering, as the person meets them. */
|
|
3
4
|
export interface ChatPresence {
|
|
@@ -6,6 +7,13 @@ export interface ChatPresence {
|
|
|
6
7
|
face?: string;
|
|
7
8
|
/** What it says before anyone writes. */
|
|
8
9
|
welcome?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Told what it is doing as it changes ā idle, thinking, working, waiting
|
|
12
|
+
* for you ā for a host that draws the face itself, in a frame of its own.
|
|
13
|
+
* Read once, when the workspace is built: pass a stable function, such as
|
|
14
|
+
* a state setter.
|
|
15
|
+
*/
|
|
16
|
+
onPresence?: (state: PresenceState) => void;
|
|
9
17
|
}
|
|
10
18
|
export type ChatPluginConfig = {
|
|
11
19
|
/**
|
|
@@ -35,6 +35,8 @@ const promptStance = signal('floating-top');
|
|
|
35
35
|
* page layout to a page, the assumption that signal already makes.
|
|
36
36
|
*/
|
|
37
37
|
let floatingStance = 'floating-top';
|
|
38
|
+
/** The modes the page layout does not place. */
|
|
39
|
+
const PAGE_LAYOUT_DISABLED_MODES = ['assistant'];
|
|
38
40
|
export function pageLayoutForChatMode(mode) {
|
|
39
41
|
switch (mode) {
|
|
40
42
|
case 'sidebar':
|
|
@@ -60,7 +62,9 @@ export function setPageLayoutChatMode(mode) {
|
|
|
60
62
|
/** The toggle in the floating composer's footer. */
|
|
61
63
|
function ChatModeAction() {
|
|
62
64
|
const mode = useSignalValue(pageLayoutChatMode);
|
|
63
|
-
|
|
65
|
+
// The page layout places the chat itself: the floating assistant, which
|
|
66
|
+
// ChatFloating draws, is offered greyed out with its reason (T-21).
|
|
67
|
+
return (_jsx(ChatViewModeToggle, { value: mode, onChange: setPageLayoutChatMode, disabledModes: PAGE_LAYOUT_DISABLED_MODES }));
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* The chat view's parts on the page layout.
|
package/lib/specs/actions.js
CHANGED
|
@@ -439,6 +439,7 @@ export const SERVER_ACTIONS = {
|
|
|
439
439
|
* to reproduce.
|
|
440
440
|
*/
|
|
441
441
|
export const APP_BEHAVIOURS = {
|
|
442
|
+
'data-quality': {},
|
|
442
443
|
'inbox-triage': {
|
|
443
444
|
'google-workspace.append_table_rows': 'leave_to_me',
|
|
444
445
|
'google-workspace.batch_modify_gmail_message_labels': 'do_it',
|
|
@@ -561,8 +562,10 @@ export const APP_BEHAVIOURS = {
|
|
|
561
562
|
'google-workspace.update_drive_file': 'leave_to_me',
|
|
562
563
|
'google-workspace.update_paragraph_style': 'leave_to_me',
|
|
563
564
|
},
|
|
565
|
+
'model-choice': {},
|
|
564
566
|
'quote-calculator': {},
|
|
565
567
|
'ship-or-fix': {},
|
|
568
|
+
'supplier-comparison': {},
|
|
566
569
|
'web-research': {
|
|
567
570
|
'tavily.tavily_crawl': 'do_it',
|
|
568
571
|
'tavily.tavily_extract': 'do_it',
|
|
@@ -576,6 +579,7 @@ export const APP_BEHAVIOURS = {
|
|
|
576
579
|
* application and tool, each condition and the behaviour when it holds.
|
|
577
580
|
*/
|
|
578
581
|
export const APP_ESCALATIONS = {
|
|
582
|
+
'data-quality': {},
|
|
579
583
|
'inbox-triage': {
|
|
580
584
|
'google-workspace.batch_modify_gmail_message_labels': [
|
|
581
585
|
{
|
|
@@ -610,7 +614,9 @@ export const APP_ESCALATIONS = {
|
|
|
610
614
|
},
|
|
611
615
|
],
|
|
612
616
|
},
|
|
617
|
+
'model-choice': {},
|
|
613
618
|
'quote-calculator': {},
|
|
614
619
|
'ship-or-fix': {},
|
|
620
|
+
'supplier-comparison': {},
|
|
615
621
|
'web-research': {},
|
|
616
622
|
};
|
package/lib/specs/apps.d.ts
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
* DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
|
|
9
9
|
*/
|
|
10
10
|
import type { AppKind, AppSpec } from '../types/agentspecs';
|
|
11
|
+
export declare const DATA_QUALITY_APP_0_0_1: AppSpec;
|
|
11
12
|
export declare const INBOX_TRIAGE_APP_0_0_1: AppSpec;
|
|
13
|
+
export declare const MODEL_CHOICE_APP_0_0_1: AppSpec;
|
|
12
14
|
export declare const QUOTE_CALCULATOR_APP_0_0_1: AppSpec;
|
|
13
15
|
export declare const SHIP_OR_FIX_APP_0_0_1: AppSpec;
|
|
16
|
+
export declare const SUPPLIER_COMPARISON_APP_0_0_1: AppSpec;
|
|
14
17
|
export declare const WEB_RESEARCH_APP_0_0_1: AppSpec;
|
|
15
18
|
export declare const APP_CATALOGUE: Record<string, AppSpec>;
|
|
16
19
|
/** An application, by `id` or `id:version`, or undefined. */
|