@datalayer/agent-runtimes 1.3.74 → 1.3.75
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 +17 -1
- package/lib/chat/ChatFloating.js +52 -5
- package/lib/chat/assistant/AssistantContextMenu.d.ts +67 -0
- package/lib/chat/assistant/AssistantContextMenu.js +68 -0
- package/lib/chat/assistant/AssistantStage.d.ts +95 -1
- package/lib/chat/assistant/AssistantStage.js +227 -7
- package/lib/chat/assistant/BalloonParts.d.ts +15 -1
- package/lib/chat/assistant/BalloonParts.js +26 -9
- package/lib/chat/assistant/BalloonVisual.d.ts +10 -2
- package/lib/chat/assistant/BalloonVisual.js +3 -3
- package/lib/chat/assistant/SpeechBalloon.d.ts +47 -1
- package/lib/chat/assistant/SpeechBalloon.js +60 -8
- package/lib/chat/base/ChatBase.js +51 -1
- package/lib/chat/indicators/TypingDots.d.ts +13 -0
- package/lib/chat/indicators/TypingDots.js +21 -0
- package/lib/chat/messages/ChatMessageList.js +1 -15
- package/lib/components/inspector/AgentInspector.d.ts +59 -0
- package/lib/components/inspector/AgentInspector.js +220 -0
- package/lib/components/inspector/AgentInspectorDialog.d.ts +19 -0
- package/lib/components/inspector/AgentInspectorDialog.js +9 -0
- package/lib/components/inspector/JsonTree.d.ts +24 -0
- package/lib/components/inspector/JsonTree.js +89 -0
- package/lib/components/inspector/a2aInspect.d.ts +56 -0
- package/lib/components/inspector/a2aInspect.js +478 -0
- package/lib/components/inspector/agentInspector.d.ts +179 -0
- package/lib/components/inspector/agentInspector.js +267 -0
- package/lib/components/inspector/chatInspect.d.ts +38 -0
- package/lib/components/inspector/chatInspect.js +65 -0
- package/lib/components/inspector/classify.d.ts +19 -0
- package/lib/components/inspector/classify.js +42 -0
- package/lib/components/inspector/index.d.ts +14 -0
- package/lib/components/inspector/index.js +18 -0
- package/lib/components/teams/A2ATeamGraph.d.ts +42 -1
- package/lib/components/teams/A2ATeamGraph.js +24 -7
- package/lib/components/teams/NotebookPreviewView.js +9 -1
- package/lib/components/teams/TeamNotebook.d.ts +3 -1
- package/lib/components/teams/TeamNotebook.js +3 -3
- package/lib/components/teams/jupyterThemeVariables.d.ts +9 -0
- package/lib/components/teams/jupyterThemeVariables.js +441 -0
- package/lib/components/teams/teamConnections.d.ts +9 -1
- package/lib/components/teams/teamConnections.js +20 -0
- package/lib/components/teams/useA2ATeam.d.ts +17 -4
- package/lib/components/teams/useA2ATeam.js +87 -23
- package/lib/examples/AgentA2ATeamExample.d.ts +13 -0
- package/lib/examples/AgentA2ATeamExample.js +61 -13
- package/lib/examples/AssistantExample.js +62 -2
- package/lib/loop/apps/AppRenderer.js +1 -1
- package/lib/loop/core/index.d.ts +17 -0
- package/lib/loop/core/index.js +1 -0
- package/lib/loop/plugins/assistant/index.d.ts +1 -1
- package/lib/loop/plugins/assistant/index.js +8 -3
- package/lib/runtimes/browser/a2aPeer.d.ts +4 -1
- package/lib/types/chat.d.ts +7 -0
- package/package.json +1 -1
- package/scripts/codegen/generate_jupyter_theme_variables.mjs +57 -0
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
import type { JSX } from 'react';
|
|
26
26
|
import { type Edge, type EdgeProps, type Viewport } from '@xyflow/react';
|
|
27
27
|
import '@xyflow/react/dist/base.css';
|
|
28
|
+
import { type AssistantAbout } from '../../chat/assistant/AssistantStage';
|
|
29
|
+
import type { BalloonSuggestion } from '../../chat/assistant/SpeechBalloon';
|
|
30
|
+
import type { BalloonHistoryMessage } from '../../chat/assistant/state';
|
|
31
|
+
import type { AssistantMenuItem } from '../../chat/assistant/AssistantContextMenu';
|
|
32
|
+
import type { AgentInspectorSink } from '../inspector/agentInspector';
|
|
28
33
|
import { type A2ATeamCall, type A2ATeamConnection, type A2ATeamFlow } from './a2aTeamFlow';
|
|
29
34
|
import type { A2ATeamPersona } from './useA2ATeam';
|
|
30
35
|
import type { BalloonExpandTarget } from '../../chat/assistant/BalloonVisual';
|
|
@@ -65,6 +70,36 @@ export type A2ATeamGraphMember = {
|
|
|
65
70
|
expandTarget?: BalloonExpandTarget;
|
|
66
71
|
/** What its notebook is called: `Accounting's notebook`. */
|
|
67
72
|
notebookTitle?: string;
|
|
73
|
+
/**
|
|
74
|
+
* What the person may ask it: chips in its balloon while it waits for a
|
|
75
|
+
* question, and a group of its menu; one chosen is sent (`onSuggestion`).
|
|
76
|
+
*/
|
|
77
|
+
suggestions?: readonly BalloonSuggestion[];
|
|
78
|
+
onSuggestion?: (suggestion: BalloonSuggestion) => void;
|
|
79
|
+
/**
|
|
80
|
+
* The team's Agent Inspector: its menu offers *Inspect the agent…*, its
|
|
81
|
+
* own record (what it did, and the A2A messages it sent or received).
|
|
82
|
+
*/
|
|
83
|
+
inspector?: AgentInspectorSink | null;
|
|
84
|
+
/** Stops its turn, from its menu, while it works. */
|
|
85
|
+
onStop?: () => void;
|
|
86
|
+
/** What its menu's *About* says. */
|
|
87
|
+
about?: AssistantAbout;
|
|
88
|
+
/** The host's own entries of its menu. */
|
|
89
|
+
contextMenu?: readonly AssistantMenuItem[];
|
|
90
|
+
/**
|
|
91
|
+
* What its menu calls a click on it (`onToggle`): `Ask Sales` where it
|
|
92
|
+
* takes the person to the composer. Without `onToggle`, its menu has no
|
|
93
|
+
* such entry.
|
|
94
|
+
*/
|
|
95
|
+
conversationLabel?: string;
|
|
96
|
+
/**
|
|
97
|
+
* What it said and did, as its `history` balloon lists it (`useA2ATeam`'s
|
|
98
|
+
* `entryHistory`, `peerHistory`): shown when its menu chooses *History*.
|
|
99
|
+
*/
|
|
100
|
+
history?: readonly BalloonHistoryMessage[];
|
|
101
|
+
/** Its balloon's display was chosen in its menu: the page may keep it. */
|
|
102
|
+
onBalloonDisplayChange?: (display: BalloonDisplay) => void;
|
|
68
103
|
};
|
|
69
104
|
export type A2ATeamGraphProps = {
|
|
70
105
|
/** The member that asks: drawn on the left. */
|
|
@@ -81,6 +116,12 @@ export type A2ATeamGraphProps = {
|
|
|
81
116
|
size?: number;
|
|
82
117
|
/** The tool calls running now, to the members' connections (`useA2ATeam`). */
|
|
83
118
|
calls?: A2ATeamCall[];
|
|
119
|
+
/**
|
|
120
|
+
* The room above the members for their balloons, in pixels at full scale:
|
|
121
|
+
* a page that shows suggestions, *more* and a notebook in them gives more.
|
|
122
|
+
* A notebook in a balloon gets at least its own.
|
|
123
|
+
*/
|
|
124
|
+
balloonRoom?: number;
|
|
84
125
|
};
|
|
85
126
|
/** The words on the edge for a flow. */
|
|
86
127
|
export declare function flowWords(flow: A2ATeamFlow, entry: string, peer: string): string;
|
|
@@ -95,5 +136,5 @@ export declare function callWords(member: string, connection: A2ATeamConnection,
|
|
|
95
136
|
/** The viewport that shows the graph's width whole in a box `width` wide, never larger than drawn. */
|
|
96
137
|
export declare function teamViewport(width: number): Viewport;
|
|
97
138
|
/** Draw a team of two over A2A, the link moving with what travels on it. */
|
|
98
|
-
export declare function A2ATeamGraph({ entry, peer, flow, connected, label, size, calls, }: A2ATeamGraphProps): JSX.Element;
|
|
139
|
+
export declare function A2ATeamGraph({ entry, peer, flow, connected, label, size, calls, balloonRoom, }: A2ATeamGraphProps): JSX.Element;
|
|
99
140
|
export default A2ATeamGraph;
|
|
@@ -4,7 +4,7 @@ import { BaseEdge, EdgeLabelRenderer, Handle, Position, ReactFlow, } from '@xyfl
|
|
|
4
4
|
import '@xyflow/react/dist/base.css';
|
|
5
5
|
import { Button, Label, Text } from '@primer/react';
|
|
6
6
|
import { Box } from '@datalayer/primer-addons';
|
|
7
|
-
import { AssistantStage } from '../../chat/assistant/AssistantStage';
|
|
7
|
+
import { AssistantStage, } from '../../chat/assistant/AssistantStage';
|
|
8
8
|
import { SpecMark } from '../../chat/marks/SpecMark';
|
|
9
9
|
import { toolWords, } from './a2aTeamFlow';
|
|
10
10
|
import { NotebookPreview } from './NotebookPreview';
|
|
@@ -14,7 +14,7 @@ import { toolLineText } from '../../chat/assistant/toolLine';
|
|
|
14
14
|
const NODE_WIDTH = 200;
|
|
15
15
|
const BALLOON_ROOM = 144;
|
|
16
16
|
/** The room a balloon that holds a notebook needs above its member. */
|
|
17
|
-
const NOTEBOOK_BALLOON_ROOM =
|
|
17
|
+
const NOTEBOOK_BALLOON_ROOM = 480;
|
|
18
18
|
/** How tall the notebook in a balloon grows before it scrolls. */
|
|
19
19
|
const NOTEBOOK_PREVIEW_HEIGHT = 180;
|
|
20
20
|
const GAP = 220;
|
|
@@ -50,10 +50,17 @@ const MemberNode = memo(function MemberNode({ data, }) {
|
|
|
50
50
|
const { id, side, size } = data;
|
|
51
51
|
const member = useContext(Members)[id];
|
|
52
52
|
const stageRef = useRef(null);
|
|
53
|
+
// Its balloon's display, as its menu changes it.
|
|
54
|
+
const [display, setDisplay] = useState();
|
|
53
55
|
if (!member) {
|
|
54
56
|
return null;
|
|
55
57
|
}
|
|
56
58
|
const { persona } = member;
|
|
59
|
+
const shownDisplay = display ?? member.balloonDisplay ?? 'current';
|
|
60
|
+
// History: what it said and did, listed.
|
|
61
|
+
const listed = shownDisplay === 'history' && member.history?.length
|
|
62
|
+
? { history: member.history }
|
|
63
|
+
: {};
|
|
57
64
|
// A notebook it was given: read-only in its balloon, and its large visual
|
|
58
65
|
// the one that runs, editable — under the graph, or in a dialog.
|
|
59
66
|
const notebookTitle = member.notebookTitle ?? (persona.notebook?.name || 'The notebook');
|
|
@@ -86,24 +93,34 @@ const MemberNode = memo(function MemberNode({ data, }) {
|
|
|
86
93
|
// middle of the graph: rightward from the left member.
|
|
87
94
|
place: side === 'left'
|
|
88
95
|
? { position: 'absolute', left: 'auto' }
|
|
89
|
-
: { position: 'absolute', right: 'auto' }, stageRef: stageRef, onDragStart: () => undefined, open: false, onToggle: member.onToggle ?? (() => undefined), balloonDisplay:
|
|
96
|
+
: { position: 'absolute', right: 'auto' }, stageRef: stageRef, onDragStart: () => undefined, open: false, onToggle: member.onToggle ?? (() => undefined), balloonDisplay: shownDisplay, onBalloonDisplayChange: next => {
|
|
97
|
+
setDisplay(next);
|
|
98
|
+
member.onBalloonDisplayChange?.(next);
|
|
99
|
+
}, conversationLabel: member.onToggle ? (member.conversationLabel ?? undefined) : false, balloon: persona.tool
|
|
90
100
|
? {
|
|
91
101
|
text: toolLineText(persona.tool),
|
|
92
102
|
tool: persona.tool,
|
|
93
103
|
busy: persona.state !== 'idle',
|
|
94
104
|
...given,
|
|
105
|
+
...listed,
|
|
95
106
|
}
|
|
96
107
|
: persona.saying
|
|
97
108
|
? {
|
|
98
109
|
text: persona.saying,
|
|
110
|
+
...(persona.full ? { fullText: persona.full } : {}),
|
|
99
111
|
more: persona.saying.endsWith('…'),
|
|
100
112
|
speaking: persona.state === 'speaking',
|
|
101
113
|
busy: persona.state === 'thinking' ||
|
|
102
114
|
persona.state === 'working' ||
|
|
103
115
|
persona.state === 'speaking',
|
|
104
116
|
...given,
|
|
117
|
+
...listed,
|
|
105
118
|
}
|
|
106
|
-
:
|
|
119
|
+
: 'history' in listed
|
|
120
|
+
? { text: '', ...listed }
|
|
121
|
+
: undefined, expandTarget: member.expandTarget, expandOnArrival: !!member.expandTarget,
|
|
122
|
+
// History, chosen in its menu: shown until Current is.
|
|
123
|
+
insist: persona.insist || display === 'history', onDismiss: away => member.onAway?.(away !== 'none'), suggestions: member.suggestions, onSuggestion: member.onSuggestion, inspector: member.inspector, inspectAgent: member.name, onStop: member.onStop, about: member.about, contextMenu: member.contextMenu,
|
|
107
124
|
// A member of the graph: what is clicked around it is the graph.
|
|
108
125
|
stayPut: true })) }), _jsxs(Text, { sx: { fontWeight: 600, textAlign: 'center' }, children: [member.emoji ? `${member.emoji} ` : '', member.name] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', textAlign: 'center' }, "data-member-where": "", children: member.where }), _jsx(Handle, { type: "source", position: Position.Right, style: HANDLE(size), isConnectable: false }), member.connections?.length ? (_jsx(Handle, { id: "connections", type: "source", position: Position.Bottom, style: { ...HANDLE(size), top: 'auto', bottom: 0 }, isConnectable: false })) : null] }));
|
|
109
126
|
});
|
|
@@ -201,7 +218,7 @@ export function teamViewport(width) {
|
|
|
201
218
|
return { zoom, x: (width - WIDTH * zoom) / 2, y: 0 };
|
|
202
219
|
}
|
|
203
220
|
/** Draw a team of two over A2A, the link moving with what travels on it. */
|
|
204
|
-
export function A2ATeamGraph({ entry, peer, flow, connected, label = 'A2A', size = 96, calls = [], }) {
|
|
221
|
+
export function A2ATeamGraph({ entry, peer, flow, connected, label = 'A2A', size = 96, calls = [], balloonRoom = BALLOON_ROOM, }) {
|
|
205
222
|
const box = useRef(null);
|
|
206
223
|
const [width, setWidth] = useState(0);
|
|
207
224
|
useEffect(() => {
|
|
@@ -234,8 +251,8 @@ export function A2ATeamGraph({ entry, peer, flow, connected, label = 'A2A', size
|
|
|
234
251
|
const hasConnections = placed.some(({ connections }) => connections.length);
|
|
235
252
|
// A notebook in a balloon: more room above the members.
|
|
236
253
|
const room = [entry, peer].some(member => member.persona.notebook)
|
|
237
|
-
? NOTEBOOK_BALLOON_ROOM
|
|
238
|
-
:
|
|
254
|
+
? Math.max(NOTEBOOK_BALLOON_ROOM, balloonRoom)
|
|
255
|
+
: balloonRoom;
|
|
239
256
|
const height = Math.ceil((room +
|
|
240
257
|
memberHeight +
|
|
241
258
|
(hasConnections ? CONNECTION_GAP + connectionHeight : 0)) *
|
|
@@ -3,6 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { useTheme } from '@primer/react';
|
|
4
4
|
import { Box } from '@datalayer/primer-addons';
|
|
5
5
|
import { JupyterReactTheme, Notebook, ServiceManagerLess, } from '@datalayer/jupyter-react';
|
|
6
|
+
import { JUPYTER_DARK_VARIABLES, JUPYTER_LIGHT_VARIABLES, } from './jupyterThemeVariables';
|
|
6
7
|
/** Each preview has its own id in jupyter-react's store. */
|
|
7
8
|
let drawn = 0;
|
|
8
9
|
export function NotebookPreviewView({ nbformat, height, }) {
|
|
@@ -16,7 +17,14 @@ export function NotebookPreviewView({ nbformat, height, }) {
|
|
|
16
17
|
}, [nbformat]);
|
|
17
18
|
const content = useMemo(() => JSON.parse(JSON.stringify(nbformat)), [nbformat]);
|
|
18
19
|
const { colorScheme } = useTheme();
|
|
19
|
-
|
|
20
|
+
const mode = colorScheme?.startsWith('dark') ? 'dark' : 'light';
|
|
21
|
+
return (_jsxs(Box, { "data-notebook-preview-theme": mode, sx: { height },
|
|
22
|
+
// JupyterLab writes its theme for the whole page, so two previews in
|
|
23
|
+
// two modes would share the last one written: each carries its own
|
|
24
|
+
// mode's variables on its own subtree.
|
|
25
|
+
style: (mode === 'dark'
|
|
26
|
+
? JUPYTER_DARK_VARIABLES
|
|
27
|
+
: JUPYTER_LIGHT_VARIABLES), children: [_jsx("span", { "data-jupyter-react-theme-root": "notebook-preview", hidden: true }), _jsx(JupyterReactTheme, { colormode: mode, children: _jsx(Box, { "data-notebook-preview-view": id, sx: {
|
|
20
28
|
height,
|
|
21
29
|
// No toolbar: no room kept for one.
|
|
22
30
|
'& .datalayer-NotebookPanel-header': {
|
|
@@ -25,11 +25,13 @@ export type TeamNotebookProps = {
|
|
|
25
25
|
title: string;
|
|
26
26
|
/** How tall the notebook is, in pixels. */
|
|
27
27
|
height?: number;
|
|
28
|
+
/** Leave the heading out: the dialog it is drawn in shows the title. */
|
|
29
|
+
hideTitle?: boolean;
|
|
28
30
|
};
|
|
29
31
|
/** The file a notebook is saved as: the peer's name for it, else its name. */
|
|
30
32
|
export declare function notebookFileName(notebook: A2APeerArtifact): string;
|
|
31
33
|
/** A notebook a member of the team gave, under its title, to run in the page. */
|
|
32
|
-
export declare function TeamNotebook({ notebook, title, height, }: TeamNotebookProps): JSX.Element;
|
|
34
|
+
export declare function TeamNotebook({ notebook, title, height, hideTitle, }: TeamNotebookProps): JSX.Element;
|
|
33
35
|
/**
|
|
34
36
|
* A notebook as a balloon's large visual: read-only in the balloon, and,
|
|
35
37
|
* expanded, this notebook — editable, run on the browser sandbox, loaded
|
|
@@ -16,7 +16,7 @@ export function notebookFileName(notebook) {
|
|
|
16
16
|
return `${stem}.ipynb`;
|
|
17
17
|
}
|
|
18
18
|
/** A notebook a member of the team gave, under its title, to run in the page. */
|
|
19
|
-
export function TeamNotebook({ notebook, title, height = 560, }) {
|
|
19
|
+
export function TeamNotebook({ notebook, title, height = 560, hideTitle = false, }) {
|
|
20
20
|
return (_jsxs(Box, { as: "section", "aria-label": title, "data-team-notebook": "",
|
|
21
21
|
// Focused when the notebook in a balloon is clicked (`focusExpanded`).
|
|
22
22
|
tabIndex: -1, sx: {
|
|
@@ -32,7 +32,7 @@ export function TeamNotebook({ notebook, title, height = 560, }) {
|
|
|
32
32
|
outlineOffset: 4,
|
|
33
33
|
borderRadius: 2,
|
|
34
34
|
},
|
|
35
|
-
}, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0 }, children: title }), _jsx(Suspense, { fallback: _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Opening the notebook\u2026" }), children: _jsx(TeamNotebookView, { notebook: notebook, fileName: notebookFileName(notebook), height: height }) })] }));
|
|
35
|
+
}, children: [!hideTitle && (_jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0 }, children: title })), _jsx(Suspense, { fallback: _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Opening the notebook\u2026" }), children: _jsx(TeamNotebookView, { notebook: notebook, fileName: notebookFileName(notebook), height: height }) })] }));
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* A notebook as a balloon's large visual: read-only in the balloon, and,
|
|
@@ -43,7 +43,7 @@ export function notebookBalloonVisual(notebook, title, height) {
|
|
|
43
43
|
return {
|
|
44
44
|
id: `notebook:${notebook.filename ?? notebook.name}`,
|
|
45
45
|
title,
|
|
46
|
-
render:
|
|
46
|
+
render: place => (_jsx(TeamNotebook, { notebook: notebook, title: title, height: height, hideTitle: place === 'overlay' })),
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
export default TeamNotebook;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JupyterLab's theme variables, light and dark, as its theme extensions state
|
|
3
|
+
* them. Generated by scripts/codegen/generate_jupyter_theme_variables.mjs: do
|
|
4
|
+
* not edit.
|
|
5
|
+
*
|
|
6
|
+
* @module components/teams/jupyterThemeVariables
|
|
7
|
+
*/
|
|
8
|
+
export declare const JUPYTER_LIGHT_VARIABLES: Readonly<Record<string, string>>;
|
|
9
|
+
export declare const JUPYTER_DARK_VARIABLES: Readonly<Record<string, string>>;
|