@datalayer/agent-runtimes 1.3.74 → 1.3.78
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/agents/AgentDetails.d.ts +16 -2
- package/lib/agents/AgentDetails.js +381 -272
- package/lib/chat/ChatFloating.d.ts +27 -1
- package/lib/chat/ChatFloating.js +97 -13
- package/lib/chat/assistant/AgentDetailsDialog.d.ts +21 -0
- package/lib/chat/assistant/AgentDetailsDialog.js +19 -0
- package/lib/chat/assistant/AssistantContextMenu.d.ts +67 -0
- package/lib/chat/assistant/AssistantContextMenu.js +68 -0
- package/lib/chat/assistant/AssistantStage.d.ts +144 -4
- package/lib/chat/assistant/AssistantStage.js +280 -10
- package/lib/chat/assistant/BalloonParts.d.ts +33 -5
- package/lib/chat/assistant/BalloonParts.js +66 -44
- package/lib/chat/assistant/BalloonVisual.d.ts +10 -2
- package/lib/chat/assistant/BalloonVisual.js +4 -3
- package/lib/chat/assistant/SandboxDetailsDialog.d.ts +44 -0
- package/lib/chat/assistant/SandboxDetailsDialog.js +214 -0
- package/lib/chat/assistant/SpeechBalloon.d.ts +54 -6
- package/lib/chat/assistant/SpeechBalloon.js +73 -22
- package/lib/chat/assistant/assistantDetails.d.ts +84 -0
- package/lib/chat/assistant/assistantDetails.js +140 -0
- package/lib/chat/assistant/formats/files.d.ts +23 -0
- package/lib/chat/assistant/formats/files.js +48 -0
- package/lib/chat/assistant/formats/index.d.ts +2 -0
- package/lib/chat/assistant/formats/index.js +1 -0
- package/lib/chat/assistant/state.d.ts +7 -14
- package/lib/chat/assistant/state.js +21 -20
- package/lib/chat/assistant/toolLine.d.ts +16 -0
- package/lib/chat/assistant/toolLine.js +46 -0
- package/lib/chat/base/ChatBase.js +71 -1
- package/lib/chat/base/loopMessage.d.ts +37 -0
- package/lib/chat/base/loopMessage.js +37 -0
- package/lib/chat/indicators/TypingDots.d.ts +13 -0
- package/lib/chat/indicators/TypingDots.js +21 -0
- package/lib/chat/messages/ChatMarkdown.d.ts +16 -0
- package/lib/chat/messages/ChatMarkdown.js +18 -0
- package/lib/chat/messages/ChatMessageList.d.ts +8 -1
- package/lib/chat/messages/ChatMessageList.js +25 -33
- package/lib/chat/styles/streamdownStyles.js +3 -1
- package/lib/chat/tools/ToolCallDisplay.d.ts +8 -1
- package/lib/chat/tools/ToolCallDisplay.js +8 -7
- package/lib/components/code-sandboxes/CodeSandboxCellVariablesDialog.js +5 -11
- package/lib/components/code-sandboxes/CodeSandboxVariables.d.ts +8 -0
- package/lib/components/code-sandboxes/CodeSandboxVariables.js +17 -11
- 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 +69 -1
- package/lib/components/teams/A2ATeamGraph.js +277 -37
- 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/TeamNotebookView.js +15 -0
- 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/teamNotebookKernel.d.ts +3 -0
- package/lib/components/teams/teamNotebookKernel.js +17 -0
- package/lib/components/teams/useA2ATeam.d.ts +20 -3
- package/lib/components/teams/useA2ATeam.js +108 -23
- package/lib/examples/AgentA2ATeamExample.d.ts +13 -0
- package/lib/examples/AgentA2ATeamExample.js +67 -13
- package/lib/examples/AssistantExample.js +65 -26
- package/lib/examples/AssistantGalleryExample.js +2 -1
- package/lib/examples/exampleGroups.d.ts +1 -1
- package/lib/examples/exampleGroups.js +1 -1
- package/lib/examples/utils/assistantGallery.d.ts +7 -6
- package/lib/examples/utils/assistantGallery.js +23 -8
- package/lib/jupyter/exec/Python.d.ts +0 -1
- package/lib/jupyter/exec/Python.js +0 -32
- package/lib/jupyter/exec/Snippets.d.ts +4 -12
- package/lib/jupyter/exec/Snippets.js +0 -8
- package/lib/loop/apps/AppFeedback.js +3 -1
- package/lib/loop/apps/AppKept.d.ts +22 -0
- package/lib/loop/apps/AppKept.js +36 -0
- package/lib/loop/apps/AppRenderer.d.ts +11 -1
- package/lib/loop/apps/AppRenderer.js +22 -4
- package/lib/loop/apps/checks.d.ts +7 -0
- package/lib/loop/apps/checks.js +39 -0
- package/lib/loop/apps/index.d.ts +3 -0
- package/lib/loop/apps/index.js +3 -0
- package/lib/loop/apps/kept.d.ts +30 -0
- package/lib/loop/apps/kept.js +52 -0
- package/lib/loop/apps/records.d.ts +12 -4
- package/lib/loop/apps/records.js +13 -5
- package/lib/loop/apps/saved.d.ts +30 -0
- package/lib/loop/apps/saved.js +40 -0
- package/lib/loop/core/index.d.ts +17 -0
- package/lib/loop/core/index.js +1 -0
- package/lib/loop/embed/AppEmbed.d.ts +8 -1
- package/lib/loop/embed/AppEmbed.js +4 -4
- package/lib/loop/embed/LoopEmbed.d.ts +6 -1
- package/lib/loop/embed/LoopEmbed.js +4 -2
- package/lib/loop/embed/element.js +1 -1
- package/lib/loop/plugins/agents/DatalayerAgentBridge.js +12 -6
- package/lib/loop/plugins/agents/browserService.d.ts +7 -1
- package/lib/loop/plugins/agents/browserService.js +4 -0
- package/lib/loop/plugins/agents/plugin.d.ts +16 -0
- package/lib/loop/plugins/agents/switchable.d.ts +3 -0
- package/lib/loop/plugins/agents/switchable.js +1 -0
- package/lib/loop/plugins/app-activity/index.js +3 -0
- package/lib/loop/plugins/app-computer/index.js +3 -0
- package/lib/loop/plugins/app-rules/AppRulesCard.d.ts +5 -0
- package/lib/loop/plugins/app-rules/AppRulesCard.js +25 -6
- package/lib/loop/plugins/app-rules/index.js +3 -0
- package/lib/loop/plugins/assistant/index.d.ts +7 -2
- package/lib/loop/plugins/assistant/index.js +58 -4
- package/lib/loop/plugins/assistant-characters/index.d.ts +7 -0
- package/lib/loop/plugins/assistant-characters/index.js +17 -0
- package/lib/loop/plugins/chat/ChatView.js +4 -1
- package/lib/loop/plugins/page-layout/SplitLayout.d.ts +2 -1
- package/lib/loop/plugins/page-layout/SplitLayout.js +4 -0
- package/lib/loop/presets.d.ts +4 -0
- package/lib/loop/presets.js +3 -1
- package/lib/loop/shell/LoopWorkspace.d.ts +7 -0
- package/lib/loop/shell/LoopWorkspace.js +5 -4
- package/lib/loop/shell/SidebarRail.d.ts +53 -0
- package/lib/loop/shell/SidebarRail.js +74 -0
- package/lib/loop/shell/index.d.ts +2 -0
- package/lib/loop/shell/index.js +2 -0
- package/lib/loop/shell/paneMotion.d.ts +21 -0
- package/lib/loop/shell/paneMotion.js +37 -0
- package/lib/runtimes/browser/a2aPeer.d.ts +4 -1
- package/lib/specs/apps.js +8 -5
- package/lib/specs/uiPlugins.js +529 -0
- package/lib/types/agentspecs.d.ts +5 -3
- package/lib/types/chat.d.ts +12 -0
- package/package.json +2 -2
- package/scripts/codegen/generate_jupyter_theme_variables.mjs +57 -0
- package/scripts/codegen/generate_ui_plugins.py +112 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An agent's words, as markdown: what the chat's messages draw them with
|
|
3
|
+
* (`ChatMessageList`), and what the floating assistant's balloon draws its
|
|
4
|
+
* current line with — one renderer, so a code block, a table or a list
|
|
5
|
+
* looks the same wherever the words are read.
|
|
6
|
+
*
|
|
7
|
+
* @module chat/messages/ChatMarkdown
|
|
8
|
+
*/
|
|
9
|
+
import type { JSX } from 'react';
|
|
10
|
+
/** How dense the chat's components draw: the chat's own, or the balloon's. */
|
|
11
|
+
export type ChatDensity = 'comfortable' | 'compact';
|
|
12
|
+
export declare function ChatMarkdown({ text, density, }: {
|
|
13
|
+
text: string;
|
|
14
|
+
density?: ChatDensity;
|
|
15
|
+
}): JSX.Element;
|
|
16
|
+
export default ChatMarkdown;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
|
+
import { Streamdown } from 'streamdown';
|
|
4
|
+
import { streamdownMarkdownStyles } from '../styles/streamdownStyles';
|
|
5
|
+
import { normalizeAssistantMarkdown } from './assistantMarkdown';
|
|
6
|
+
export function ChatMarkdown({ text, density = 'comfortable', }) {
|
|
7
|
+
return (_jsx(Box, { "data-chat-markdown": "", sx: {
|
|
8
|
+
...streamdownMarkdownStyles,
|
|
9
|
+
...(density === 'compact'
|
|
10
|
+
? {
|
|
11
|
+
lineHeight: 1.4,
|
|
12
|
+
'& p': { marginTop: 0, marginBottom: '0.4em' },
|
|
13
|
+
'& p:last-child': { marginBottom: 0 },
|
|
14
|
+
}
|
|
15
|
+
: {}),
|
|
16
|
+
}, children: _jsx(Streamdown, { children: normalizeAssistantMarkdown(text) }) }));
|
|
17
|
+
}
|
|
18
|
+
export default ChatMarkdown;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode, type RefObject } from 'react';
|
|
2
|
+
import { type ChatDensity } from './ChatMarkdown';
|
|
2
3
|
import { type MarkedMcpServer } from '../marks';
|
|
3
4
|
import type { DisplayItem, AvatarConfig, RenderToolResult } from '../../types/chat';
|
|
4
5
|
import type { ChatMessage } from '../../types/messages';
|
|
@@ -67,6 +68,12 @@ export interface ChatMessageListProps {
|
|
|
67
68
|
* and runtime tools are found in the catalogues.
|
|
68
69
|
*/
|
|
69
70
|
mcpServers?: readonly MarkedMcpServer[];
|
|
71
|
+
/**
|
|
72
|
+
* How dense it draws: the chat's own (`comfortable`), or the floating
|
|
73
|
+
* assistant's balloon (`compact`: no avatars, smaller bubbles and tool
|
|
74
|
+
* rows, no turn footers). The same components either way.
|
|
75
|
+
*/
|
|
76
|
+
density?: ChatDensity;
|
|
70
77
|
}
|
|
71
78
|
type SubagentAvatarConfig = Required<Pick<AvatarConfig, 'userAvatar' | 'assistantAvatar' | 'showAvatars' | 'avatarSize' | 'userAvatarBg' | 'assistantAvatarBg'>>;
|
|
72
79
|
export interface SubagentChatPanelProps {
|
|
@@ -86,5 +93,5 @@ export interface SubagentChatPanelProps {
|
|
|
86
93
|
* approval decisions are sent over the shared monitoring socket.
|
|
87
94
|
*/
|
|
88
95
|
export declare function SubagentChatPanel({ toolCallId, subagentName: subagentNameHint, height, avatarConfig, }: SubagentChatPanelProps): React.ReactElement | null;
|
|
89
|
-
export declare function ChatMessageList({ displayItems, isLoading, isStreaming, showLoadingIndicator, hideMessagesAfterToolUI, avatarConfig, padding, renderToolResult, emptyContent, messagesEndRef, onRespond, approvalConfig, showTurnFooters, agentUsage, onRemoveItems, renderMessageFooter, mcpServers, }: ChatMessageListProps): import("react").JSX.Element;
|
|
96
|
+
export declare function ChatMessageList({ displayItems, isLoading, isStreaming, showLoadingIndicator, hideMessagesAfterToolUI, avatarConfig, padding, renderToolResult, emptyContent, messagesEndRef, onRespond, approvalConfig, showTurnFooters, agentUsage, onRemoveItems, renderMessageFooter, mcpServers, density, }: ChatMessageListProps): import("react").JSX.Element;
|
|
90
97
|
export {};
|
|
@@ -14,12 +14,12 @@ import { Fragment, useState, useCallback, useEffect, useMemo, useRef, } from 're
|
|
|
14
14
|
import { Text, Spinner, Link, Label, RelativeTime } from '@primer/react';
|
|
15
15
|
import { ArrowRightIcon, BroadcastIcon, ClockIcon, DependabotIcon, PersonIcon, SkipIcon, ToolsIcon, XCircleFillIcon, } from '@primer/octicons-react';
|
|
16
16
|
import { Box } from '@datalayer/primer-addons';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
17
|
+
import { streamdownCodeBlockStyles } from '../styles/streamdownStyles';
|
|
18
|
+
import { ChatMarkdown } from './ChatMarkdown';
|
|
19
19
|
import { ToolCallDisplay } from '../tools/ToolCallDisplay';
|
|
20
20
|
import { marksOfToolCall, skillIdOfCall } from '../marks';
|
|
21
|
+
import { TypingDots } from '../indicators/TypingDots';
|
|
21
22
|
import { TurnFooter } from './TurnFooter';
|
|
22
|
-
import { normalizeAssistantMarkdown } from './assistantMarkdown';
|
|
23
23
|
import { parseFormSubmission } from './formSubmission';
|
|
24
24
|
import { FormSubmissionMessage } from './FormSubmissionMessage';
|
|
25
25
|
import { isToolCallMessage, getMessageText } from '../../utils';
|
|
@@ -62,21 +62,6 @@ function toneColorsOf(tone) {
|
|
|
62
62
|
fg: `${tone}.fg`,
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
/** Three pulsing dots: a speaker is still writing and has not settled yet. */
|
|
66
|
-
function TypingDots({ size = 8 }) {
|
|
67
|
-
return (_jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [0, 0.2, 0.4].map((delay, index) => (_jsx(Box, { sx: {
|
|
68
|
-
width: size,
|
|
69
|
-
height: size,
|
|
70
|
-
borderRadius: '50%',
|
|
71
|
-
bg: 'fg.muted',
|
|
72
|
-
animation: 'typingPulse 1.4s ease-in-out infinite',
|
|
73
|
-
animationDelay: `${delay}s`,
|
|
74
|
-
'@keyframes typingPulse': {
|
|
75
|
-
'0%, 60%, 100%': { transform: 'scale(0.6)', opacity: 0.4 },
|
|
76
|
-
'30%': { transform: 'scale(1)', opacity: 1 },
|
|
77
|
-
},
|
|
78
|
-
} }, index))) }));
|
|
79
|
-
}
|
|
80
65
|
const SUBAGENT_AVATAR_CONFIG = {
|
|
81
66
|
userAvatar: _jsx(PersonIcon, { size: 14 }),
|
|
82
67
|
assistantAvatar: _jsx(DependabotIcon, { size: 14 }),
|
|
@@ -277,7 +262,7 @@ export function SubagentChatPanel({ toolCallId, subagentName: subagentNameHint,
|
|
|
277
262
|
// DefaultToolCallRenderer — reads approvals from the Zustand store,
|
|
278
263
|
// sends decisions over the shared WebSocket (no REST polling).
|
|
279
264
|
// ---------------------------------------------------------------------------
|
|
280
|
-
function DefaultToolCallRenderer({ item, onRespond, mcpServers, }) {
|
|
265
|
+
function DefaultToolCallRenderer({ item, onRespond, mcpServers, density, }) {
|
|
281
266
|
const resultObject = item.result && typeof item.result === 'object'
|
|
282
267
|
? item.result
|
|
283
268
|
: undefined;
|
|
@@ -393,12 +378,18 @@ function DefaultToolCallRenderer({ item, onRespond, mcpServers, }) {
|
|
|
393
378
|
? () => makeDecision('approve')
|
|
394
379
|
: undefined, onDeny: effectiveApprovalId && !decision && !externalDecision
|
|
395
380
|
? () => makeDecision('reject')
|
|
396
|
-
: undefined, approvalLoading: false, marks: marks }), isSubagentDelegation && (_jsx(SubagentChatPanel, { toolCallId: item.toolCallId, subagentName: delegatedSubagentName }))] }));
|
|
381
|
+
: undefined, approvalLoading: false, marks: marks, summary: item.summary, density: density }), isSubagentDelegation && (_jsx(SubagentChatPanel, { toolCallId: item.toolCallId, subagentName: delegatedSubagentName }))] }));
|
|
397
382
|
}
|
|
398
383
|
// ---------------------------------------------------------------------------
|
|
399
384
|
// Component
|
|
400
385
|
// ---------------------------------------------------------------------------
|
|
401
|
-
export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoadingIndicator, hideMessagesAfterToolUI, avatarConfig, padding, renderToolResult, emptyContent, messagesEndRef, onRespond, approvalConfig, showTurnFooters = false, agentUsage, onRemoveItems, renderMessageFooter, mcpServers, }) {
|
|
386
|
+
export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoadingIndicator, hideMessagesAfterToolUI, avatarConfig, padding, renderToolResult, emptyContent, messagesEndRef, onRespond, approvalConfig, showTurnFooters = false, agentUsage, onRemoveItems, renderMessageFooter, mcpServers, density = 'comfortable', }) {
|
|
387
|
+
const compact = density === 'compact';
|
|
388
|
+
if (compact) {
|
|
389
|
+
// The balloon's: no avatars, no turn footers.
|
|
390
|
+
avatarConfig = { ...avatarConfig, showAvatars: false };
|
|
391
|
+
showTurnFooters = false;
|
|
392
|
+
}
|
|
402
393
|
if (displayItems.length === 0) {
|
|
403
394
|
return _jsx(_Fragment, { children: emptyContent });
|
|
404
395
|
}
|
|
@@ -500,7 +491,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
500
491
|
not care about hid those tools entirely. Offering the default as a
|
|
501
492
|
node lets it compose instead of choosing.
|
|
502
493
|
*/
|
|
503
|
-
const defaultUI = (_jsx(DefaultToolCallRenderer, { item: item, approvalConfig: approvalConfig, onRespond: createRespondCallback(item.toolCallId), mcpServers: mcpServers }));
|
|
494
|
+
const defaultUI = (_jsx(DefaultToolCallRenderer, { item: item, approvalConfig: approvalConfig, onRespond: createRespondCallback(item.toolCallId), mcpServers: mcpServers, density: density }));
|
|
504
495
|
const toolUI = renderToolResult
|
|
505
496
|
? renderToolResult({
|
|
506
497
|
toolCallId: item.toolCallId,
|
|
@@ -516,7 +507,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
516
507
|
: defaultUI;
|
|
517
508
|
if (toolUI === null || toolUI === undefined)
|
|
518
509
|
return null;
|
|
519
|
-
return (_jsx(Box, { sx: {
|
|
510
|
+
return (_jsx(Box, { "data-chat-tool-row": item.toolName, sx: {
|
|
520
511
|
display: 'flex',
|
|
521
512
|
flexDirection: 'column',
|
|
522
513
|
alignItems: 'flex-start',
|
|
@@ -531,7 +522,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
531
522
|
*/
|
|
532
523
|
width: '100%',
|
|
533
524
|
px: padding,
|
|
534
|
-
py: 1,
|
|
525
|
+
py: compact ? '2px' : 1,
|
|
535
526
|
}, children: toolUI }, item.id));
|
|
536
527
|
}
|
|
537
528
|
// ---- Chat message item ----
|
|
@@ -600,12 +591,12 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
600
591
|
}
|
|
601
592
|
}
|
|
602
593
|
}
|
|
603
|
-
return (_jsx(Box, { sx: {
|
|
594
|
+
return (_jsx(Box, { "data-chat-message": message.role, sx: {
|
|
604
595
|
display: 'flex',
|
|
605
596
|
flexDirection: 'column',
|
|
606
597
|
alignItems: isUser ? 'flex-end' : 'flex-start',
|
|
607
598
|
px: padding,
|
|
608
|
-
py: 1,
|
|
599
|
+
py: compact ? '2px' : 1,
|
|
609
600
|
}, children: _jsxs(Box, { sx: {
|
|
610
601
|
display: 'flex',
|
|
611
602
|
gap: 2,
|
|
@@ -649,7 +640,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
649
640
|
? speaker.initials || '?'
|
|
650
641
|
: isUser
|
|
651
642
|
? avatarConfig.userAvatar
|
|
652
|
-
: avatarConfig.assistantAvatar })), _jsxs(Box, { sx: { maxWidth: '85%', minWidth: 0 }, children: [speaker ? (_jsxs(Box, { sx: {
|
|
643
|
+
: avatarConfig.assistantAvatar })), _jsxs(Box, { sx: { maxWidth: compact ? '92%' : '85%', minWidth: 0 }, children: [speaker ? (_jsxs(Box, { sx: {
|
|
653
644
|
display: 'flex',
|
|
654
645
|
gap: 2,
|
|
655
646
|
alignItems: 'baseline',
|
|
@@ -671,7 +662,8 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
671
662
|
fontSize: 1,
|
|
672
663
|
color: toneColorsOf(message.directedTo.tone).fg,
|
|
673
664
|
}, children: message.directedTo.name })] })) : speaker.role ? (_jsx(Label, { size: "small", children: speaker.role })) : null, message.createdAt ? (_jsx(RelativeTime, { datetime: message.createdAt.toISOString(), sx: { fontSize: 0, color: 'fg.muted' } })) : null] })) : null, _jsxs(Box, { sx: {
|
|
674
|
-
p: 2,
|
|
665
|
+
p: compact ? 1 : 2,
|
|
666
|
+
px: compact ? 2 : 2,
|
|
675
667
|
overflowX: 'auto',
|
|
676
668
|
// The theme's bubble (LOOP T-03, T-06): today's 6px elsewhere.
|
|
677
669
|
borderRadius: 'var(--theme-radius-bubble, 6px)',
|
|
@@ -710,7 +702,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
710
702
|
const text = getMessageText(message);
|
|
711
703
|
const submission = parseFormSubmission(text);
|
|
712
704
|
return submission ? (_jsx(FormSubmissionMessage, { submission: submission })) : (_jsxs(Text, { sx: {
|
|
713
|
-
fontSize: 1,
|
|
705
|
+
fontSize: compact ? 0 : 1,
|
|
714
706
|
whiteSpace: 'pre-wrap',
|
|
715
707
|
wordBreak: 'break-word',
|
|
716
708
|
}, children: [message.metadata?.input === 'voice' ? (_jsx(Box, { as: "span", "data-spoken": "", title: "Said aloud", "aria-label": "Said aloud:", sx: {
|
|
@@ -719,7 +711,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
719
711
|
mr: 1,
|
|
720
712
|
opacity: 0.85,
|
|
721
713
|
}, children: _jsx(MicrophoneIcon, { size: 14, "aria-hidden": "true" }) })) : null, text] }));
|
|
722
|
-
})()) : message.live && !getMessageText(message) ? (_jsx(TypingDots, { size: 6 })) : (_jsx(
|
|
714
|
+
})()) : message.live && !getMessageText(message) ? (_jsx(TypingDots, { size: 6 })) : (_jsx(ChatMarkdown, { density: density, text: getMessageText(message) || (isStreaming ? '...' : '') }))] }), renderMessageFooter ? (_jsx(Box, { sx: {
|
|
723
715
|
display: 'flex',
|
|
724
716
|
gap: 2,
|
|
725
717
|
alignItems: 'center',
|
|
@@ -735,7 +727,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
735
727
|
return null;
|
|
736
728
|
}
|
|
737
729
|
return (_jsxs(Fragment, { children: [itemUI, footer] }, item.id));
|
|
738
|
-
}), showLoadingIndicator && (isLoading || isStreaming) && (_jsx(Box, { sx: {
|
|
730
|
+
}), showLoadingIndicator && (isLoading || isStreaming) && (_jsx(Box, { "data-chat-typing": "", sx: {
|
|
739
731
|
display: 'flex',
|
|
740
732
|
alignItems: 'flex-start',
|
|
741
733
|
px: padding,
|
|
@@ -757,9 +749,9 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
|
|
|
757
749
|
}, children: avatarConfig.assistantAvatar })), _jsx(Box, { sx: {
|
|
758
750
|
display: 'flex',
|
|
759
751
|
alignItems: 'center',
|
|
760
|
-
p: 2,
|
|
752
|
+
p: compact ? 1 : 2,
|
|
761
753
|
borderRadius: 'var(--theme-radius-bubble, 6px)',
|
|
762
754
|
bg: 'canvas.subtle',
|
|
763
|
-
minHeight: '32px',
|
|
755
|
+
minHeight: compact ? '20px' : '32px',
|
|
764
756
|
}, children: _jsx(TypingDots, {}) })] }) })), _jsx("div", { ref: messagesEndRef })] }));
|
|
765
757
|
}
|
|
@@ -215,8 +215,10 @@ export const streamdownMarkdownStyles = {
|
|
|
215
215
|
marginRight: 0,
|
|
216
216
|
color: 'fg.muted',
|
|
217
217
|
},
|
|
218
|
+
// A link reads as its theme says (LOOP T-06): in the accent, or plain —
|
|
219
|
+
// the colour of the words around it — and underlined in every theme.
|
|
218
220
|
'& a': {
|
|
219
|
-
color: 'accent
|
|
221
|
+
color: 'var(--theme-message-link, var(--fgColor-accent, #0969da))',
|
|
220
222
|
textDecoration: 'underline',
|
|
221
223
|
},
|
|
222
224
|
'& table': {
|
|
@@ -50,6 +50,13 @@ export interface ToolCallDisplayProps {
|
|
|
50
50
|
* icon, else the emoji, else nothing.
|
|
51
51
|
*/
|
|
52
52
|
marks?: Marks | null;
|
|
53
|
+
/** What it does in its runtime's words: shown in place of the arguments. */
|
|
54
|
+
summary?: string;
|
|
55
|
+
/**
|
|
56
|
+
* How dense: the chat's (`comfortable`), or the floating assistant's
|
|
57
|
+
* balloon (`compact`: a smaller header, the same card).
|
|
58
|
+
*/
|
|
59
|
+
density?: 'comfortable' | 'compact';
|
|
53
60
|
}
|
|
54
61
|
/**
|
|
55
62
|
* ToolCallDisplay component - Default display for tool calls in chat
|
|
@@ -61,5 +68,5 @@ export interface ToolCallDisplayProps {
|
|
|
61
68
|
* - Color-coded status indicators
|
|
62
69
|
* - Rich error display distinguishing execution errors from code errors
|
|
63
70
|
*/
|
|
64
|
-
export declare function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading, marks, }: ToolCallDisplayProps): React.JSX.Element;
|
|
71
|
+
export declare function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading, marks, summary, density, }: ToolCallDisplayProps): React.JSX.Element;
|
|
65
72
|
export default ToolCallDisplay;
|
|
@@ -125,7 +125,8 @@ function getArgsSummary(args) {
|
|
|
125
125
|
* - Color-coded status indicators
|
|
126
126
|
* - Rich error display distinguishing execution errors from code errors
|
|
127
127
|
*/
|
|
128
|
-
export function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired = false, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading = false, marks, }) {
|
|
128
|
+
export function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired = false, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading = false, marks, summary, density = 'comfortable', }) {
|
|
129
|
+
const compact = density === 'compact';
|
|
129
130
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
130
131
|
// Determine effective exit code from props or execution result
|
|
131
132
|
const effectiveExitCode = exitCode ?? executionResult?.exit_code;
|
|
@@ -143,7 +144,7 @@ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, er
|
|
|
143
144
|
: undefined;
|
|
144
145
|
const statusDisplay = getStatusDisplay(status, errorType);
|
|
145
146
|
const displayName = formatToolName(toolName);
|
|
146
|
-
const argsSummary = getArgsSummary(args);
|
|
147
|
+
const argsSummary = summary || getArgsSummary(args);
|
|
147
148
|
const resultObject = result && typeof result === 'object'
|
|
148
149
|
? result
|
|
149
150
|
: undefined;
|
|
@@ -168,19 +169,19 @@ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, er
|
|
|
168
169
|
result.stderr ??
|
|
169
170
|
undefined)
|
|
170
171
|
: undefined);
|
|
171
|
-
return (_jsxs(Box, { sx: {
|
|
172
|
+
return (_jsxs(Box, { "data-tool-call": toolName, "data-tool-call-status": status, sx: {
|
|
172
173
|
width: '100%',
|
|
173
174
|
border: '1px solid',
|
|
174
175
|
borderColor: 'border.default',
|
|
175
|
-
borderRadius: '12px',
|
|
176
|
+
borderRadius: compact ? '8px' : '12px',
|
|
176
177
|
overflow: 'hidden',
|
|
177
178
|
backgroundColor: 'canvas.default',
|
|
178
179
|
}, children: [_jsxs(Box, { as: "button", onClick: () => setIsExpanded(!isExpanded), sx: {
|
|
179
180
|
width: '100%',
|
|
180
181
|
display: 'flex',
|
|
181
182
|
alignItems: 'center',
|
|
182
|
-
gap: 2,
|
|
183
|
-
padding: 2,
|
|
183
|
+
gap: compact ? 1 : 2,
|
|
184
|
+
padding: compact ? 1 : 2,
|
|
184
185
|
backgroundColor: 'canvas.subtle',
|
|
185
186
|
border: 'none',
|
|
186
187
|
borderBottom: isExpanded ? '1px solid' : 'none',
|
|
@@ -192,7 +193,7 @@ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, er
|
|
|
192
193
|
},
|
|
193
194
|
}, children: [_jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0 }, children: isExpanded ? (_jsx(ChevronDownIcon, { size: 16 })) : (_jsx(ChevronRightIcon, { size: 16 })) }), hasMark(marks) && (_jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0, display: 'flex' }, children: _jsx(SpecMark, { icon: marks?.icon, emoji: marks?.emoji, size: 16 }) })), _jsx(Text, { sx: {
|
|
194
195
|
fontWeight: 'semibold',
|
|
195
|
-
fontSize: 1,
|
|
196
|
+
fontSize: compact ? 0 : 1,
|
|
196
197
|
color: 'fg.default',
|
|
197
198
|
flexShrink: 0,
|
|
198
199
|
}, children: displayName }), _jsxs(Box, { sx: {
|
|
@@ -3,8 +3,9 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
3
3
|
import { Dialog } from '@primer/react/experimental';
|
|
4
4
|
import { nullTranslator } from '@jupyterlab/translation';
|
|
5
5
|
import { JSONExt } from '@lumino/coreutils';
|
|
6
|
-
import {
|
|
6
|
+
import { kernelConnectionExecutor, listKernelVariables, } from '@datalayer/jupyter-react';
|
|
7
7
|
import { RuntimeSnippetsFacade } from '../../jupyter';
|
|
8
|
+
import { transferableVariables } from './CodeSandboxVariables';
|
|
8
9
|
import { CodeSandboxCellVariables } from './CodeSandboxCellVariables';
|
|
9
10
|
/**
|
|
10
11
|
* Dialog to define the runtime cell variables to transfer
|
|
@@ -53,16 +54,9 @@ export function CodeSandboxCellVariablesDialog(props) {
|
|
|
53
54
|
}
|
|
54
55
|
const connection = sessionContext.session.kernel;
|
|
55
56
|
const spec = sessionContext.specsManager.specs.kernelspecs[connection.model.name];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (content) {
|
|
60
|
-
const runtimeVariables = JSON.parse(
|
|
61
|
-
// We need to remove the quotes prior to parsing
|
|
62
|
-
content.slice(1, content.length - 1));
|
|
63
|
-
return Object.keys(runtimeVariables ?? {});
|
|
64
|
-
}
|
|
65
|
-
return [];
|
|
57
|
+
return Object.keys(transferableVariables(await listKernelVariables(kernelConnectionExecutor(connection), {
|
|
58
|
+
language: spec.language,
|
|
59
|
+
})));
|
|
66
60
|
}, [preference, sessionContext]);
|
|
67
61
|
const getOutputCandidates = useCallback(async () => {
|
|
68
62
|
// TODO this is only valid for python - using cell mimetype?
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { ISessionContext } from '@jupyterlab/apputils';
|
|
3
3
|
import { ITranslator } from '@jupyterlab/translation';
|
|
4
|
+
import { type KernelVariable } from '@datalayer/jupyter-react';
|
|
4
5
|
import type { IRuntimeDesc } from '../../models';
|
|
6
|
+
/**
|
|
7
|
+
* The variables that can be carried to another sandbox, by name and type:
|
|
8
|
+
* values, not the modules, functions and classes code defines again.
|
|
9
|
+
*/
|
|
10
|
+
export declare function transferableVariables(variables: readonly KernelVariable[]): {
|
|
11
|
+
[name: string]: string;
|
|
12
|
+
};
|
|
5
13
|
/** What {@link useCodeSandboxVariablesTransfer} answers. */
|
|
6
14
|
export interface ICodeSandboxVariablesTransfer {
|
|
7
15
|
/**
|
|
@@ -10,8 +10,19 @@ import { Blankslate, DataTable, Table } from '@primer/react/experimental';
|
|
|
10
10
|
import { nullTranslator } from '@jupyterlab/translation';
|
|
11
11
|
import { checkIcon } from '@jupyterlab/ui-components';
|
|
12
12
|
import { JSONExt } from '@lumino/coreutils';
|
|
13
|
-
import {
|
|
13
|
+
import { kernelConnectionExecutor, listKernelVariables, } from '@datalayer/jupyter-react';
|
|
14
14
|
import { RuntimeSnippetsFacade } from '../../jupyter';
|
|
15
|
+
/**
|
|
16
|
+
* The variables that can be carried to another sandbox, by name and type:
|
|
17
|
+
* values, not the modules, functions and classes code defines again.
|
|
18
|
+
*/
|
|
19
|
+
export function transferableVariables(variables) {
|
|
20
|
+
return Object.fromEntries(variables
|
|
21
|
+
.filter(variable => variable.kind !== 'module' &&
|
|
22
|
+
variable.kind !== 'function' &&
|
|
23
|
+
variable.kind !== 'class')
|
|
24
|
+
.map(variable => [variable.name, variable.type]));
|
|
25
|
+
}
|
|
15
26
|
/**
|
|
16
27
|
* The variables of the current sandbox, and which of them to carry over.
|
|
17
28
|
*
|
|
@@ -45,18 +56,13 @@ export function useCodeSandboxVariablesTransfer(sessionContext, target, enabled
|
|
|
45
56
|
setVariables({});
|
|
46
57
|
return;
|
|
47
58
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
setVariables({});
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
// The payload comes quoted, as the representation of a string.
|
|
56
|
-
const listedVariables = JSON.parse(content.slice(1, content.length - 1));
|
|
59
|
+
// jupyter-react's snippet, run silently: the variables, typed.
|
|
60
|
+
const listedVariables = transferableVariables(await listKernelVariables(kernelConnectionExecutor(connection), {
|
|
61
|
+
language: spec.language,
|
|
62
|
+
}));
|
|
57
63
|
setVariables(listedVariables);
|
|
58
64
|
// Everything is carried over unless the user says otherwise.
|
|
59
|
-
setSelectedState(Object.keys(listedVariables
|
|
65
|
+
setSelectedState(Object.keys(listedVariables));
|
|
60
66
|
}, [listed, sessionContext]);
|
|
61
67
|
const setSelected = useCallback((names) => {
|
|
62
68
|
setSelectedState(current => JSONExt.deepEqual(current, names) ? current : names);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Agent Inspector: what agents do, one row a thing, newest last — the
|
|
3
|
+
* time (to the millisecond, and since the first), who did it and toward
|
|
4
|
+
* whom, its source and kind, its name with its mark, its status and
|
|
5
|
+
* duration, and a line that says it. A row unfolds to its payload as a JSON
|
|
6
|
+
* tree (a call's arguments and its result), and to what was made of it.
|
|
7
|
+
*
|
|
8
|
+
* Filters by source, kind and actor; *Pause* holds the rows still while the
|
|
9
|
+
* record goes on, *Clear* empties it, *Export* saves the session as JSON. A
|
|
10
|
+
* large payload (a notebook) says its size and stays folded until asked.
|
|
11
|
+
*
|
|
12
|
+
* Fed by a sink (`useAgentInspector`) or given its entries.
|
|
13
|
+
*
|
|
14
|
+
* @module components/inspector/AgentInspector
|
|
15
|
+
*/
|
|
16
|
+
import type { JSX } from 'react';
|
|
17
|
+
import { type AgentInspectorEntry, type AgentInspectorExport, type AgentInspectorSink, type AgentInspectorSource } from './agentInspector';
|
|
18
|
+
export type AgentInspectorProps = {
|
|
19
|
+
/** The record to show, kept current. */
|
|
20
|
+
sink?: AgentInspectorSink | null;
|
|
21
|
+
/** Or its entries, as given. */
|
|
22
|
+
entries?: readonly AgentInspectorEntry[];
|
|
23
|
+
/** How tall the rows grow before they scroll. */
|
|
24
|
+
maxHeight?: number | string;
|
|
25
|
+
/** Payloads larger than this, in bytes, stay folded until asked. */
|
|
26
|
+
largeBytes?: number;
|
|
27
|
+
/** What is said while nothing is recorded. */
|
|
28
|
+
emptyText?: string;
|
|
29
|
+
/** The file name the session is exported as, without `.json`. */
|
|
30
|
+
exportName?: string;
|
|
31
|
+
/**
|
|
32
|
+
* One agent's own record: what it did (`actor`), and the A2A messages it
|
|
33
|
+
* sent or received — one message shows in the sender's and in the
|
|
34
|
+
* receiver's, the same entry, as sent in one and received in the other.
|
|
35
|
+
*/
|
|
36
|
+
agent?: string;
|
|
37
|
+
};
|
|
38
|
+
/** Whether an entry is one agent's: done by it, or sent to or by it. */
|
|
39
|
+
export declare function isAgentsEntry(entry: AgentInspectorEntry, agent: string): boolean;
|
|
40
|
+
/** Which way an entry went, from one agent's side: `→ Accounting`, `← Accounting`. */
|
|
41
|
+
export declare function directionFrom(entry: AgentInspectorEntry, agent: string | undefined): string;
|
|
42
|
+
/** A time of day, to the millisecond: `15:44:31.299`. */
|
|
43
|
+
export declare function clockTime(at: number): string;
|
|
44
|
+
/** Time since the first entry: `+1.204s`. */
|
|
45
|
+
export declare function sinceFirst(at: number, first: number): string;
|
|
46
|
+
/** How long a call took: `412 ms`, `3.4 s`. */
|
|
47
|
+
export declare function durationText(ms: number): string;
|
|
48
|
+
export type AgentInspectorFilter = {
|
|
49
|
+
sources: ReadonlySet<AgentInspectorSource>;
|
|
50
|
+
kinds: ReadonlySet<string>;
|
|
51
|
+
actors: ReadonlySet<string>;
|
|
52
|
+
};
|
|
53
|
+
/** The entries a filter keeps: an empty set keeps every value. */
|
|
54
|
+
export declare function filterEntries(entries: readonly AgentInspectorEntry[], filter: AgentInspectorFilter): AgentInspectorEntry[];
|
|
55
|
+
/** A session, as JSON. */
|
|
56
|
+
export declare function exportEntries(entries: readonly AgentInspectorEntry[]): AgentInspectorExport;
|
|
57
|
+
/** The Agent Inspector. */
|
|
58
|
+
export declare function AgentInspector({ sink, entries: given, maxHeight, largeBytes, emptyText, exportName, agent, }: AgentInspectorProps): JSX.Element;
|
|
59
|
+
export default AgentInspector;
|