@datalayer/agent-runtimes 0.0.5 → 0.0.8
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 +150 -22
- package/lib/components/chat/components/AgentDetails.d.ts +15 -2
- package/lib/components/chat/components/AgentDetails.js +9 -93
- package/lib/components/chat/components/AgentIdentity.d.ts +92 -0
- package/lib/components/chat/components/AgentIdentity.js +318 -0
- package/lib/components/chat/components/Chat.d.ts +24 -1
- package/lib/components/chat/components/Chat.js +41 -19
- package/lib/components/chat/components/ChatFloating.d.ts +6 -1
- package/lib/components/chat/components/ChatFloating.js +12 -6
- package/lib/components/chat/components/ContextDistribution.d.ts +47 -0
- package/lib/components/chat/components/ContextDistribution.js +146 -0
- package/lib/components/chat/components/ContextUsage.d.ts +33 -0
- package/lib/components/chat/components/ContextUsage.js +127 -0
- package/lib/components/chat/components/base/ChatBase.d.ts +51 -1
- package/lib/components/chat/components/base/ChatBase.js +278 -74
- package/lib/components/chat/components/display/ToolCallDisplay.d.ts +16 -2
- package/lib/components/chat/components/display/ToolCallDisplay.js +148 -6
- package/lib/components/chat/components/display/index.d.ts +1 -1
- package/lib/components/chat/components/display/index.js +1 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.d.ts +12 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.js +8 -3
- package/lib/components/chat/components/index.d.ts +3 -0
- package/lib/components/chat/components/index.js +3 -0
- package/lib/components/chat/components/parts/ToolPart.d.ts +1 -1
- package/lib/components/chat/components/parts/ToolPart.js +142 -6
- package/lib/components/chat/index.d.ts +1 -1
- package/lib/components/chat/index.js +1 -1
- package/lib/components/chat/protocols/A2AAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/A2AAdapter.js +13 -2
- package/lib/components/chat/protocols/ACPAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/ACPAdapter.js +13 -2
- package/lib/components/chat/protocols/AGUIAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/AGUIAdapter.js +19 -1
- package/lib/components/chat/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/components/chat/protocols/VercelAIAdapter.js +19 -0
- package/lib/components/chat/types/execution.d.ts +78 -0
- package/lib/components/chat/types/execution.js +64 -0
- package/lib/components/chat/types/index.d.ts +1 -0
- package/lib/components/chat/types/index.js +1 -0
- package/lib/components/chat/types/protocol.d.ts +9 -0
- package/lib/components/ui/pagination.d.ts +2 -2
- package/lib/components/ui/pagination.js +4 -4
- package/lib/components/ui/resizable.d.ts +4 -4
- package/lib/components/ui/resizable.js +4 -4
- package/lib/examples/A2UiRestaurantExample.js +2 -2
- package/lib/examples/AgUiAgenticExample.js +2 -2
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
- package/lib/examples/AgUiHaikuGenUIExample.js +2 -2
- package/lib/examples/AgUiHumanInTheLoopExample.js +2 -2
- package/lib/examples/AgUiSharedStateExample.js +2 -2
- package/lib/examples/AgUiToolsBasedGenUIExample.js +2 -2
- package/lib/examples/AgentRuntimeCustomExample.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.js +2 -1
- package/lib/examples/AgentRuntimeLexicalExample.js +5 -2
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +4 -2
- package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
- package/lib/examples/AgentRuntimeStandaloneExample.js +2 -2
- package/lib/examples/AgentSpaceFormExample.d.ts +70 -2
- package/lib/examples/AgentSpaceFormExample.js +204 -35
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/components/AgentConfiguration.d.ts +37 -0
- package/lib/examples/components/AgentConfiguration.js +239 -8
- package/lib/examples/components/Header.d.ts +0 -2
- package/lib/examples/components/Header.js +2 -16
- package/lib/examples/components/LexicalEditor.js +2 -1
- package/lib/examples/components/MockFileBrowser.js +6 -2
- package/lib/examples/components/index.d.ts +0 -1
- package/lib/examples/components/index.js +0 -1
- package/lib/examples/example-selector.js +0 -1
- package/lib/examples/index.d.ts +0 -1
- package/lib/examples/index.js +0 -1
- package/lib/examples/lexical/editorConfig.d.ts +3 -2
- package/lib/examples/lexical/editorConfig.js +7 -1
- package/lib/examples/lexical/initial-content.json +2210 -0
- package/lib/examples/main.js +15 -1
- package/lib/identity/IdentityConnect.d.ts +90 -0
- package/lib/identity/IdentityConnect.js +316 -0
- package/lib/identity/OAuthCallback.d.ts +58 -0
- package/lib/identity/OAuthCallback.js +223 -0
- package/lib/identity/dcr.d.ts +257 -0
- package/lib/identity/dcr.js +282 -0
- package/lib/identity/identityStore.d.ts +72 -0
- package/lib/identity/identityStore.js +529 -0
- package/lib/identity/index.d.ts +46 -0
- package/lib/identity/index.js +17 -0
- package/lib/identity/pkce.d.ts +30 -0
- package/lib/identity/pkce.js +65 -0
- package/lib/identity/types.d.ts +293 -0
- package/lib/identity/types.js +73 -0
- package/lib/identity/useIdentity.d.ts +108 -0
- package/lib/identity/useIdentity.js +323 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/lib/utils.js +1 -1
- package/lib/renderers/a2ui/lib/utils.js +1 -1
- package/lib/runtime/index.d.ts +35 -0
- package/lib/runtime/index.js +40 -0
- package/lib/runtime/runtimeStore.d.ts +77 -0
- package/lib/runtime/runtimeStore.js +184 -0
- package/lib/runtime/types.d.ts +84 -0
- package/lib/runtime/types.js +15 -0
- package/lib/runtime/useAgentConnection.d.ts +46 -0
- package/lib/runtime/useAgentConnection.js +112 -0
- package/lib/runtime/useAgentRuntime.d.ts +94 -0
- package/lib/runtime/useAgentRuntime.js +125 -0
- package/lib/test-setup.d.ts +1 -1
- package/lib/test-setup.js +1 -0
- package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.js +32 -1
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +6 -0
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +16 -17
- package/package.json +20 -7
- package/patches/@datalayer+jupyter-lexical+1.0.8.patch +11628 -0
- package/patches/@datalayer+jupyter-react+2.0.2.patch +5338 -0
- package/lib/examples/AgentSpaceHomeExample.d.ts +0 -8
- package/lib/examples/AgentSpaceHomeExample.js +0 -171
- package/lib/examples/components/AgentsDataTable.d.ts +0 -13
- package/lib/examples/components/AgentsDataTable.js +0 -74
- package/lib/examples/components/Rating.d.ts +0 -14
- package/lib/examples/components/Rating.js +0 -12
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* AgentIdentity component - Shows connected identity providers with token status.
|
|
8
|
+
* Displays expiration details and allows reconnection if token expired.
|
|
9
|
+
*
|
|
10
|
+
* @module components/chat/components/AgentIdentity
|
|
11
|
+
*/
|
|
12
|
+
import React, { useCallback, useMemo } from 'react';
|
|
13
|
+
import { Box, Text, Button, Label, Avatar, Flash, Tooltip, } from '@primer/react';
|
|
14
|
+
import { MarkGithubIcon, LinkIcon, UnlinkIcon, CheckCircleFillIcon, AlertIcon, ClockIcon, SyncIcon, KeyIcon, } from '@primer/octicons-react';
|
|
15
|
+
import { useIdentity, IdentityButton } from '../../../identity';
|
|
16
|
+
import { GITHUB_PROVIDER, GOOGLE_PROVIDER, KAGGLE_PROVIDER, } from '../../../identity';
|
|
17
|
+
const PROVIDER_DISPLAY = {
|
|
18
|
+
github: {
|
|
19
|
+
name: 'GitHub',
|
|
20
|
+
icon: MarkGithubIcon,
|
|
21
|
+
color: '#24292f',
|
|
22
|
+
description: 'Access GitHub repositories and APIs',
|
|
23
|
+
},
|
|
24
|
+
google: {
|
|
25
|
+
name: 'Google',
|
|
26
|
+
icon: KeyIcon,
|
|
27
|
+
color: '#4285f4',
|
|
28
|
+
description: 'Access Google services and APIs',
|
|
29
|
+
},
|
|
30
|
+
kaggle: {
|
|
31
|
+
name: 'Kaggle',
|
|
32
|
+
icon: KeyIcon,
|
|
33
|
+
color: '#20beff',
|
|
34
|
+
description: 'Access Kaggle datasets and notebooks',
|
|
35
|
+
},
|
|
36
|
+
linkedin: {
|
|
37
|
+
name: 'LinkedIn',
|
|
38
|
+
icon: KeyIcon,
|
|
39
|
+
color: '#0077b5',
|
|
40
|
+
description: 'Access LinkedIn profile',
|
|
41
|
+
},
|
|
42
|
+
slack: {
|
|
43
|
+
name: 'Slack',
|
|
44
|
+
icon: KeyIcon,
|
|
45
|
+
color: '#4a154b',
|
|
46
|
+
description: 'Access Slack workspaces',
|
|
47
|
+
},
|
|
48
|
+
notion: {
|
|
49
|
+
name: 'Notion',
|
|
50
|
+
icon: KeyIcon,
|
|
51
|
+
color: '#000000',
|
|
52
|
+
description: 'Access Notion pages',
|
|
53
|
+
},
|
|
54
|
+
custom: {
|
|
55
|
+
name: 'Custom',
|
|
56
|
+
icon: LinkIcon,
|
|
57
|
+
color: '#6f42c1',
|
|
58
|
+
description: 'Custom OAuth provider',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
const DEFAULT_SCOPES = {
|
|
62
|
+
github: ['read:user', 'user:email', 'repo'],
|
|
63
|
+
google: ['openid', 'profile', 'email'],
|
|
64
|
+
kaggle: ['read'],
|
|
65
|
+
linkedin: ['r_liteprofile', 'r_emailaddress'],
|
|
66
|
+
slack: ['users:read', 'channels:read'],
|
|
67
|
+
notion: ['read_content'],
|
|
68
|
+
custom: [],
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Calculate token status from expiration timestamp
|
|
72
|
+
*/
|
|
73
|
+
export function getTokenStatus(expiresAt) {
|
|
74
|
+
if (!expiresAt) {
|
|
75
|
+
return { isExpired: false, isExpiringSoon: false };
|
|
76
|
+
}
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
const expiresAtDate = new Date(expiresAt);
|
|
79
|
+
const timeUntilExpiry = expiresAt - now;
|
|
80
|
+
const timeSinceExpiry = now - expiresAt;
|
|
81
|
+
// Token expires within 5 minutes - considered "expiring soon"
|
|
82
|
+
const EXPIRING_SOON_THRESHOLD = 5 * 60 * 1000;
|
|
83
|
+
return {
|
|
84
|
+
isExpired: timeUntilExpiry < 0,
|
|
85
|
+
isExpiringSoon: timeUntilExpiry > 0 && timeUntilExpiry < EXPIRING_SOON_THRESHOLD,
|
|
86
|
+
expiresAt: expiresAtDate,
|
|
87
|
+
timeUntilExpiry: timeUntilExpiry > 0 ? timeUntilExpiry : undefined,
|
|
88
|
+
timeSinceExpiry: timeUntilExpiry < 0 ? timeSinceExpiry : undefined,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Format duration for display
|
|
93
|
+
*/
|
|
94
|
+
export function formatDuration(ms) {
|
|
95
|
+
const seconds = Math.floor(ms / 1000);
|
|
96
|
+
const minutes = Math.floor(seconds / 60);
|
|
97
|
+
const hours = Math.floor(minutes / 60);
|
|
98
|
+
const days = Math.floor(hours / 24);
|
|
99
|
+
if (days > 0) {
|
|
100
|
+
return days === 1 ? '1 day' : `${days} days`;
|
|
101
|
+
}
|
|
102
|
+
if (hours > 0) {
|
|
103
|
+
return hours === 1 ? '1 hour' : `${hours} hours`;
|
|
104
|
+
}
|
|
105
|
+
if (minutes > 0) {
|
|
106
|
+
return minutes === 1 ? '1 minute' : `${minutes} minutes`;
|
|
107
|
+
}
|
|
108
|
+
return seconds === 1 ? '1 second' : `${seconds} seconds`;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Format expiration status text
|
|
112
|
+
*/
|
|
113
|
+
export function formatExpirationStatus(status) {
|
|
114
|
+
if (status.isExpired && status.timeSinceExpiry) {
|
|
115
|
+
return `Expired ${formatDuration(status.timeSinceExpiry)} ago`;
|
|
116
|
+
}
|
|
117
|
+
if (status.timeUntilExpiry) {
|
|
118
|
+
if (status.isExpiringSoon) {
|
|
119
|
+
return `Expires in ${formatDuration(status.timeUntilExpiry)}`;
|
|
120
|
+
}
|
|
121
|
+
return `Expires in ${formatDuration(status.timeUntilExpiry)}`;
|
|
122
|
+
}
|
|
123
|
+
// Token has no expiration info - likely a long-lived token
|
|
124
|
+
return 'Token does not expire';
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Single identity card with status and actions
|
|
128
|
+
*/
|
|
129
|
+
export function IdentityCard({ identity, providerConfig, showExpirationDetails = true, allowReconnect = true, onConnect: _onConnect, onDisconnect, onError, }) {
|
|
130
|
+
const { connect, disconnect, configureProvider, isAuthorizing } = useIdentity();
|
|
131
|
+
const provider = identity.provider;
|
|
132
|
+
const display = PROVIDER_DISPLAY[provider] || PROVIDER_DISPLAY.custom;
|
|
133
|
+
const tokenStatus = useMemo(() => getTokenStatus(identity.token?.expiresAt), [identity.token?.expiresAt]);
|
|
134
|
+
// Configure provider on mount if config is provided
|
|
135
|
+
React.useEffect(() => {
|
|
136
|
+
if (providerConfig?.clientId) {
|
|
137
|
+
const baseConfig = provider === 'github'
|
|
138
|
+
? GITHUB_PROVIDER
|
|
139
|
+
: provider === 'google'
|
|
140
|
+
? GOOGLE_PROVIDER
|
|
141
|
+
: provider === 'kaggle'
|
|
142
|
+
? KAGGLE_PROVIDER
|
|
143
|
+
: undefined;
|
|
144
|
+
if (baseConfig) {
|
|
145
|
+
const redirectUri = providerConfig.config?.redirectUri ||
|
|
146
|
+
(typeof window !== 'undefined'
|
|
147
|
+
? `${window.location.origin}${window.location.pathname}`
|
|
148
|
+
: '');
|
|
149
|
+
configureProvider({
|
|
150
|
+
...baseConfig,
|
|
151
|
+
...providerConfig.config,
|
|
152
|
+
provider,
|
|
153
|
+
clientId: providerConfig.clientId,
|
|
154
|
+
redirectUri,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}, [providerConfig, provider, configureProvider]);
|
|
159
|
+
const handleReconnect = useCallback(async () => {
|
|
160
|
+
try {
|
|
161
|
+
const scopes = providerConfig?.scopes || DEFAULT_SCOPES[provider];
|
|
162
|
+
await connect(provider, scopes);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
166
|
+
}
|
|
167
|
+
}, [provider, providerConfig?.scopes, connect, onError]);
|
|
168
|
+
const handleDisconnect = useCallback(async () => {
|
|
169
|
+
try {
|
|
170
|
+
await disconnect(provider);
|
|
171
|
+
onDisconnect?.(provider);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
175
|
+
}
|
|
176
|
+
}, [provider, disconnect, onDisconnect, onError]);
|
|
177
|
+
return (_jsxs(Box, { sx: {
|
|
178
|
+
display: 'flex',
|
|
179
|
+
flexDirection: 'column',
|
|
180
|
+
gap: 2,
|
|
181
|
+
p: 3,
|
|
182
|
+
border: '1px solid',
|
|
183
|
+
borderColor: tokenStatus.isExpired
|
|
184
|
+
? 'danger.muted'
|
|
185
|
+
: tokenStatus.isExpiringSoon
|
|
186
|
+
? 'attention.muted'
|
|
187
|
+
: 'success.muted',
|
|
188
|
+
borderRadius: 2,
|
|
189
|
+
backgroundColor: tokenStatus.isExpired
|
|
190
|
+
? 'danger.subtle'
|
|
191
|
+
: tokenStatus.isExpiringSoon
|
|
192
|
+
? 'attention.subtle'
|
|
193
|
+
: 'success.subtle',
|
|
194
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { sx: {
|
|
195
|
+
width: 32,
|
|
196
|
+
height: 32,
|
|
197
|
+
borderRadius: 2,
|
|
198
|
+
display: 'flex',
|
|
199
|
+
alignItems: 'center',
|
|
200
|
+
justifyContent: 'center',
|
|
201
|
+
backgroundColor: display.color,
|
|
202
|
+
color: 'white',
|
|
203
|
+
flexShrink: 0,
|
|
204
|
+
}, children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { sx: { flex: 1, display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: display.name }), _jsx(Label, { size: "small", variant: "secondary", children: identity.authType === 'token' ? 'API Key' : 'OAuth' })] }), tokenStatus.isExpired ? (_jsx(Label, { variant: "danger", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(AlertIcon, { size: 12 }), " Expired"] }) })) : tokenStatus.isExpiringSoon ? (_jsx(Label, { variant: "attention", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(ClockIcon, { size: 12 }), " Expiring Soon"] }) })) : (_jsx(Label, { variant: "success", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(CheckCircleFillIcon, { size: 12 }), " Connected"] }) }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
205
|
+
(provider === 'github'
|
|
206
|
+
? `https://github.com/${identity.userInfo.username}`
|
|
207
|
+
: undefined), target: "_blank", rel: "noopener noreferrer", style: { display: 'block', lineHeight: 0, flexShrink: 0 }, children: _jsx(Avatar, { src: identity.userInfo.avatarUrl, size: 32, alt: identity.userInfo.name ||
|
|
208
|
+
identity.userInfo.username ||
|
|
209
|
+
display.name, sx: { cursor: 'pointer' } }) })), _jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [identity.userInfo?.name && (_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1, display: 'block' }, children: identity.userInfo.name })), (identity.userInfo?.username || identity.userInfo?.email) && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
210
|
+
(provider === 'github'
|
|
211
|
+
? `https://github.com/${identity.userInfo.username}`
|
|
212
|
+
: undefined), target: "_blank", rel: "noopener noreferrer", style: { textDecoration: 'none' }, children: _jsx(Text, { sx: {
|
|
213
|
+
fontSize: 0,
|
|
214
|
+
color: 'fg.muted',
|
|
215
|
+
display: 'block',
|
|
216
|
+
':hover': { textDecoration: 'underline' },
|
|
217
|
+
}, children: identity.userInfo.username
|
|
218
|
+
? `@${identity.userInfo.username}`
|
|
219
|
+
: identity.userInfo.email }) }))] })] }), showExpirationDetails && (_jsxs(Box, { sx: {
|
|
220
|
+
display: 'flex',
|
|
221
|
+
alignItems: 'center',
|
|
222
|
+
gap: 1,
|
|
223
|
+
}, children: [_jsx(ClockIcon, { size: 12 }), _jsx(Text, { sx: {
|
|
224
|
+
fontSize: 0,
|
|
225
|
+
color: tokenStatus.isExpired
|
|
226
|
+
? 'danger.fg'
|
|
227
|
+
: tokenStatus.isExpiringSoon
|
|
228
|
+
? 'attention.fg'
|
|
229
|
+
: 'fg.muted',
|
|
230
|
+
}, children: formatExpirationStatus(tokenStatus) })] })), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, { sx: {
|
|
231
|
+
display: 'flex',
|
|
232
|
+
flexWrap: 'wrap',
|
|
233
|
+
gap: 1,
|
|
234
|
+
}, children: identity.scopes.map(scope => (_jsx(Label, { size: "small", variant: "secondary", children: scope }, scope))) })), _jsxs(Box, { sx: {
|
|
235
|
+
display: 'flex',
|
|
236
|
+
gap: 2,
|
|
237
|
+
mt: 1,
|
|
238
|
+
}, children: [tokenStatus.isExpired &&
|
|
239
|
+
allowReconnect &&
|
|
240
|
+
providerConfig?.clientId && (_jsx(Tooltip, { text: "Reconnect to refresh token", children: _jsx(Button, { variant: "primary", size: "small", leadingVisual: SyncIcon, onClick: handleReconnect, disabled: isAuthorizing, children: isAuthorizing ? 'Connecting...' : 'Reconnect' }) })), _jsxs(Button, { variant: tokenStatus.isExpired ? 'invisible' : 'danger', size: "small", leadingVisual: UnlinkIcon, onClick: handleDisconnect, disabled: isAuthorizing, children: ["Disconnect from ", display.name] })] })] }));
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* AgentIdentity component - Displays all connected identities with status
|
|
244
|
+
*
|
|
245
|
+
* Features:
|
|
246
|
+
* - Shows connected OAuth identities (GitHub, Google, Kaggle, etc.)
|
|
247
|
+
* - Displays token expiration status with detailed timing
|
|
248
|
+
* - Allows reconnection if token expired
|
|
249
|
+
* - Reusable across AgentDetails, AgentConfiguration, etc.
|
|
250
|
+
*/
|
|
251
|
+
export function AgentIdentity({ providers, title = 'Connected Accounts', showHeader = true, showDescription = true, description = 'Connected identities for this agent. Agents can use these to access external services on your behalf.', showExpirationDetails = true, allowReconnect = true, onConnect, onDisconnect, onError, }) {
|
|
252
|
+
const { identities, error } = useIdentity();
|
|
253
|
+
// Filter to show configured providers AND any token-based connected identities
|
|
254
|
+
// Token-based identities (like Kaggle) should always be shown if connected
|
|
255
|
+
const displayIdentities = useMemo(() => {
|
|
256
|
+
if (providers) {
|
|
257
|
+
const providerKeys = Object.keys(providers);
|
|
258
|
+
// Include configured providers AND any token-based connected identities
|
|
259
|
+
return identities.filter(id => providerKeys.includes(id.provider) ||
|
|
260
|
+
(id.authType === 'token' && id.isConnected));
|
|
261
|
+
}
|
|
262
|
+
return identities;
|
|
263
|
+
}, [identities, providers]);
|
|
264
|
+
// Get list of connected provider names
|
|
265
|
+
const connectedProviderNames = useMemo(() => new Set(identities.map(id => id.provider)), [identities]);
|
|
266
|
+
// Get providers that are NOT yet connected (to show connect buttons)
|
|
267
|
+
const unconnectedProviders = useMemo(() => {
|
|
268
|
+
if (!providers)
|
|
269
|
+
return {};
|
|
270
|
+
const providerKeys = Object.keys(providers);
|
|
271
|
+
const unconnected = {};
|
|
272
|
+
for (const provider of providerKeys) {
|
|
273
|
+
if (!connectedProviderNames.has(provider)) {
|
|
274
|
+
unconnected[provider] = providers[provider];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return unconnected;
|
|
278
|
+
}, [providers, connectedProviderNames]);
|
|
279
|
+
const hasUnconnected = Object.keys(unconnectedProviders).length > 0;
|
|
280
|
+
const handleError = useCallback((provider) => (err) => {
|
|
281
|
+
onError?.(provider, err);
|
|
282
|
+
}, [onError]);
|
|
283
|
+
// No identities and no providers configured
|
|
284
|
+
if (displayIdentities.length === 0 && !providers) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return (_jsxs(Box, { children: [showHeader && (_jsxs(Box, { sx: {
|
|
288
|
+
display: 'flex',
|
|
289
|
+
alignItems: 'center',
|
|
290
|
+
gap: 2,
|
|
291
|
+
mb: 2,
|
|
292
|
+
}, children: [_jsx(KeyIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.muted' }, children: title })] })), _jsxs(Box, { sx: {
|
|
293
|
+
p: 3,
|
|
294
|
+
bg: 'canvas.subtle',
|
|
295
|
+
borderRadius: 2,
|
|
296
|
+
border: '1px solid',
|
|
297
|
+
borderColor: 'border.default',
|
|
298
|
+
}, children: [showDescription && (_jsx(Text, { sx: {
|
|
299
|
+
fontSize: 0,
|
|
300
|
+
color: 'fg.muted',
|
|
301
|
+
display: 'block',
|
|
302
|
+
mb: displayIdentities.length > 0 ? 3 : 0,
|
|
303
|
+
}, children: description })), error && (_jsx(Flash, { variant: "danger", sx: { mb: 3 }, children: error instanceof Error ? error.message : String(error) })), displayIdentities.length > 0 ? (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: displayIdentities.map(identity => (_jsx(IdentityCard, { identity: identity, providerConfig: providers?.[identity.provider], showExpirationDetails: showExpirationDetails, allowReconnect: allowReconnect, onConnect: onConnect, onDisconnect: onDisconnect, onError: handleError(identity.provider) }, identity.provider))) })) : !hasUnconnected ? (_jsxs(Box, { sx: {
|
|
304
|
+
display: 'flex',
|
|
305
|
+
alignItems: 'center',
|
|
306
|
+
gap: 2,
|
|
307
|
+
color: 'fg.muted',
|
|
308
|
+
}, children: [_jsx(LinkIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1 }, children: "No connected accounts" })] })) : null, hasUnconnected && (_jsxs(Box, { sx: { mt: displayIdentities.length > 0 ? 3 : 0 }, children: [displayIdentities.length > 0 && (_jsx(Text, { sx: {
|
|
309
|
+
fontSize: 0,
|
|
310
|
+
color: 'fg.muted',
|
|
311
|
+
display: 'block',
|
|
312
|
+
mb: 2,
|
|
313
|
+
}, children: "Connect additional accounts:" })), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: Object.keys(unconnectedProviders).map(provider => {
|
|
314
|
+
const config = unconnectedProviders[provider];
|
|
315
|
+
return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: "medium", variant: "full", onConnect: onConnect, onDisconnect: onDisconnect, onError: handleError(provider) }, provider));
|
|
316
|
+
}) })] }))] })] }));
|
|
317
|
+
}
|
|
318
|
+
export default AgentIdentity;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Suggestion } from './base/ChatBase';
|
|
2
|
+
import type { OAuthProvider, OAuthProviderConfig, Identity } from '../../../identity';
|
|
2
3
|
/**
|
|
3
4
|
* Supported transports (communication transports)
|
|
4
5
|
*/
|
|
@@ -49,6 +50,16 @@ export interface ChatProps {
|
|
|
49
50
|
showModelSelector?: boolean;
|
|
50
51
|
/** Show tools menu (fetched from /configure endpoint) */
|
|
51
52
|
showToolsMenu?: boolean;
|
|
53
|
+
/** Show skills menu (fetched from /skills endpoint) */
|
|
54
|
+
showSkillsMenu?: boolean;
|
|
55
|
+
/** Indicate tools are accessed via Codemode meta-tools */
|
|
56
|
+
codemodeEnabled?: boolean;
|
|
57
|
+
/** Initial model ID to select (e.g., 'openai:gpt-4o-mini') */
|
|
58
|
+
initialModel?: string;
|
|
59
|
+
/** Initial MCP server IDs to enable (others will be disabled) */
|
|
60
|
+
initialMcpServers?: string[];
|
|
61
|
+
/** Initial skill IDs to enable */
|
|
62
|
+
initialSkills?: string[];
|
|
52
63
|
/** Clear messages when component mounts or agentId changes */
|
|
53
64
|
clearOnMount?: boolean;
|
|
54
65
|
/** Suggestions to show in empty state */
|
|
@@ -59,6 +70,18 @@ export interface ChatProps {
|
|
|
59
70
|
description?: string;
|
|
60
71
|
/** Auto-focus the input on mount */
|
|
61
72
|
autoFocus?: boolean;
|
|
73
|
+
/** Identity providers configuration for OAuth */
|
|
74
|
+
identityProviders?: {
|
|
75
|
+
[K in OAuthProvider]?: {
|
|
76
|
+
clientId: string;
|
|
77
|
+
scopes?: string[];
|
|
78
|
+
config?: Partial<OAuthProviderConfig>;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/** Callback when identity connects */
|
|
82
|
+
onIdentityConnect?: (identity: Identity) => void;
|
|
83
|
+
/** Callback when identity disconnects */
|
|
84
|
+
onIdentityDisconnect?: (provider: OAuthProvider) => void;
|
|
62
85
|
}
|
|
63
86
|
/**
|
|
64
87
|
* Chat Component
|
|
@@ -101,5 +124,5 @@ export interface ChatProps {
|
|
|
101
124
|
* />
|
|
102
125
|
* ```
|
|
103
126
|
*/
|
|
104
|
-
export declare function Chat({ transport, extensions: _extensions, baseUrl, wsUrl, agentId, placeholder, title, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showModelSelector, showToolsMenu, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, autoFocus, }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
127
|
+
export declare function Chat({ transport, extensions: _extensions, baseUrl, wsUrl, agentId, placeholder, title, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showModelSelector, showToolsMenu, showSkillsMenu, codemodeEnabled, initialModel, initialMcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
105
128
|
export default Chat;
|
|
@@ -24,6 +24,7 @@ import { AlertIcon, SyncIcon, InfoIcon } from '@primer/octicons-react';
|
|
|
24
24
|
import { Box } from '@datalayer/primer-addons';
|
|
25
25
|
import { ChatBase } from './base/ChatBase';
|
|
26
26
|
import { AgentDetails } from './AgentDetails';
|
|
27
|
+
import { useConnectedIdentities } from '../../../identity';
|
|
27
28
|
// Try to get Jupyter settings if available
|
|
28
29
|
let getJupyterSettings;
|
|
29
30
|
try {
|
|
@@ -129,11 +130,34 @@ function getProtocolType(transport) {
|
|
|
129
130
|
* />
|
|
130
131
|
* ```
|
|
131
132
|
*/
|
|
132
|
-
export function Chat({ transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, placeholder = 'Type your message...', title, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showModelSelector = true, showToolsMenu = true, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, autoFocus = false, }) {
|
|
133
|
+
export function Chat({ transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, placeholder = 'Type your message...', title, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showModelSelector = true, showToolsMenu = true, showSkillsMenu = false, codemodeEnabled = false, initialModel, initialMcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, }) {
|
|
133
134
|
const [error, setError] = useState(null);
|
|
134
135
|
const [isInitializing, setIsInitializing] = useState(true);
|
|
135
136
|
const [showDetails, setShowDetails] = useState(false);
|
|
136
137
|
const [messageCount, setMessageCount] = useState(0);
|
|
138
|
+
const [focusTrigger, setFocusTrigger] = useState(0);
|
|
139
|
+
// Get connected identities to pass to backend for skill execution
|
|
140
|
+
const connectedIdentities = useConnectedIdentities();
|
|
141
|
+
// Map identities to the format expected by ChatBase
|
|
142
|
+
// Filter out identities without tokens (not fully connected)
|
|
143
|
+
const identitiesForChat = useMemo(() => {
|
|
144
|
+
return connectedIdentities
|
|
145
|
+
.filter(identity => identity.token?.accessToken)
|
|
146
|
+
.map(identity => ({
|
|
147
|
+
provider: identity.provider,
|
|
148
|
+
accessToken: identity.token.accessToken,
|
|
149
|
+
}));
|
|
150
|
+
}, [connectedIdentities]);
|
|
151
|
+
// Focus the input when returning from details view
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (!showDetails) {
|
|
154
|
+
// Small delay to ensure the chat view is visible before focusing
|
|
155
|
+
const timer = setTimeout(() => {
|
|
156
|
+
setFocusTrigger(prev => prev + 1);
|
|
157
|
+
}, 100);
|
|
158
|
+
return () => clearTimeout(timer);
|
|
159
|
+
}
|
|
160
|
+
}, [showDetails]);
|
|
137
161
|
// Build protocol config based on transport
|
|
138
162
|
const protocolConfig = useMemo(() => {
|
|
139
163
|
try {
|
|
@@ -248,28 +272,26 @@ export function Chat({ transport, extensions: _extensions, baseUrl = 'http://loc
|
|
|
248
272
|
bg: 'canvas.default',
|
|
249
273
|
}, children: [_jsx(Spinner, { size: "large" }), _jsxs(Text, { sx: { mt: 3, color: 'fg.muted' }, children: ["Connecting to ", transport.toUpperCase().replace('-', ' '), " agent..."] })] }));
|
|
250
274
|
}
|
|
251
|
-
|
|
252
|
-
if (showDetails) {
|
|
253
|
-
return (_jsx(Box, { className: className, sx: {
|
|
254
|
-
position: 'relative',
|
|
255
|
-
height,
|
|
256
|
-
bg: 'canvas.default',
|
|
257
|
-
display: 'flex',
|
|
258
|
-
flexDirection: 'column',
|
|
259
|
-
}, children: _jsx(AgentDetails, { name: title || 'AI Agent', protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, onBack: () => setShowDetails(false) }) }));
|
|
260
|
-
}
|
|
261
|
-
return (_jsx(Box, { className: className, sx: {
|
|
275
|
+
return (_jsxs(Box, { className: className, sx: {
|
|
262
276
|
position: 'relative',
|
|
263
277
|
height,
|
|
264
278
|
bg: 'canvas.default',
|
|
265
279
|
display: 'flex',
|
|
266
280
|
flexDirection: 'column',
|
|
267
|
-
}, children: _jsx(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
281
|
+
}, children: [_jsx(Box, { sx: {
|
|
282
|
+
display: showDetails ? 'flex' : 'none',
|
|
283
|
+
flexDirection: 'column',
|
|
284
|
+
height: '100%',
|
|
285
|
+
}, children: _jsx(AgentDetails, { name: title || 'AI Agent', protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, identityProviders: identityProviders, onIdentityConnect: onIdentityConnect, onIdentityDisconnect: onIdentityDisconnect, onBack: () => setShowDetails(false) }) }), _jsx(Box, { sx: {
|
|
286
|
+
display: showDetails ? 'none' : 'flex',
|
|
287
|
+
flexDirection: 'column',
|
|
288
|
+
height: '100%',
|
|
289
|
+
}, children: _jsx(ChatBase, { title: title, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, headerContent: _jsx(IconButton, { icon: InfoIcon, "aria-label": "Agent details", variant: "invisible", size: "small", onClick: () => setShowDetails(true) }), showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel, initialMcpServers: initialMcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: messages => setMessageCount(messages.length), headerButtons: {
|
|
290
|
+
showNewChat: true,
|
|
291
|
+
showClear: true,
|
|
292
|
+
onNewChat: handleNewChat,
|
|
293
|
+
}, avatarConfig: {
|
|
294
|
+
showAvatars: true,
|
|
295
|
+
}, backgroundColor: "canvas.default", focusTrigger: focusTrigger }) })] }));
|
|
274
296
|
}
|
|
275
297
|
export default Chat;
|
|
@@ -145,6 +145,11 @@ export interface ChatFloatingProps {
|
|
|
145
145
|
* @default false
|
|
146
146
|
*/
|
|
147
147
|
showToolsMenu?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Show skills menu in footer.
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
showSkillsMenu?: boolean;
|
|
148
153
|
/** Additional ChatBase props */
|
|
149
154
|
panelProps?: Partial<ChatBaseProps>;
|
|
150
155
|
}
|
|
@@ -152,5 +157,5 @@ export interface ChatFloatingProps {
|
|
|
152
157
|
* ChatFloating component
|
|
153
158
|
* A floating chat window built on ChatBase
|
|
154
159
|
*/
|
|
155
|
-
export declare function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode, title, description, position, defaultOpen, width, height, showHeader, showButton, showNewChatButton, showClearButton, showSettingsButton, enableKeyboardShortcuts, toggleShortcut, showPoweredBy, poweredByProps, clickOutsideToClose, escapeToClose, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip, brandColor, offset, animationDuration, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick, hideMessagesAfterToolUI, defaultViewMode, showPanelBackdrop, showModelSelector, showToolsMenu, panelProps, }: ChatFloatingProps): import("react/jsx-runtime").JSX.Element;
|
|
160
|
+
export declare function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode, title, description, position, defaultOpen, width, height, showHeader, showButton, showNewChatButton, showClearButton, showSettingsButton, enableKeyboardShortcuts, toggleShortcut, showPoweredBy, poweredByProps, clickOutsideToClose, escapeToClose, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip, brandColor, offset, animationDuration, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick, hideMessagesAfterToolUI, defaultViewMode, showPanelBackdrop, showModelSelector, showToolsMenu, showSkillsMenu, panelProps, }: ChatFloatingProps): import("react/jsx-runtime").JSX.Element;
|
|
156
161
|
export default ChatFloating;
|
|
@@ -43,7 +43,7 @@ function useIsMobile(breakpoint = 640) {
|
|
|
43
43
|
* ChatFloating component
|
|
44
44
|
* A floating chat window built on ChatBase
|
|
45
45
|
*/
|
|
46
|
-
export function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode = true, title = 'Chat', description = 'Start a conversation with the AI agent.', position = 'bottom-right', defaultOpen = false, width = 400, height = 550, showHeader = true, showButton = true, showNewChatButton = true, showClearButton = true, showSettingsButton = false, enableKeyboardShortcuts = true, toggleShortcut = '/', showPoweredBy = true, poweredByProps, clickOutsideToClose = true, escapeToClose = true, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip = 'Chat with AI', brandColor = '#7c3aed', offset = 20, animationDuration = 200, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, defaultViewMode = 'floating', showPanelBackdrop = false, showModelSelector = false, showToolsMenu = false, panelProps, }) {
|
|
46
|
+
export function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode = true, title = 'Chat', description = 'Start a conversation with the AI agent.', position = 'bottom-right', defaultOpen = false, width = 400, height = 550, showHeader = true, showButton = true, showNewChatButton = true, showClearButton = true, showSettingsButton = false, enableKeyboardShortcuts = true, toggleShortcut = '/', showPoweredBy = true, poweredByProps, clickOutsideToClose = true, escapeToClose = true, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip = 'Chat with AI', brandColor = '#7c3aed', offset = 20, animationDuration = 200, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, defaultViewMode = 'floating', showPanelBackdrop = false, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, panelProps, }) {
|
|
47
47
|
// Store-based state
|
|
48
48
|
const storeIsOpen = useChatOpen();
|
|
49
49
|
const storeMessages = useChatMessages();
|
|
@@ -73,14 +73,20 @@ export function ChatFloating({ endpoint, protocol: protocolProp, useStore: useSt
|
|
|
73
73
|
return {
|
|
74
74
|
type: 'ag-ui',
|
|
75
75
|
endpoint,
|
|
76
|
-
// Enable config query for model/tools selector
|
|
77
|
-
enableConfigQuery: showModelSelector || showToolsMenu,
|
|
76
|
+
// Enable config query for model/tools/skills selector
|
|
77
|
+
enableConfigQuery: showModelSelector || showToolsMenu || showSkillsMenu,
|
|
78
78
|
// Config endpoint is at /api/v1/configure (global, not per-agent)
|
|
79
|
-
configEndpoint: showModelSelector || showToolsMenu
|
|
79
|
+
configEndpoint: showModelSelector || showToolsMenu || showSkillsMenu
|
|
80
80
|
? `${baseUrl}/api/v1/configure`
|
|
81
81
|
: undefined,
|
|
82
82
|
};
|
|
83
|
-
}, [
|
|
83
|
+
}, [
|
|
84
|
+
protocolProp,
|
|
85
|
+
endpoint,
|
|
86
|
+
showModelSelector,
|
|
87
|
+
showToolsMenu,
|
|
88
|
+
showSkillsMenu,
|
|
89
|
+
]);
|
|
84
90
|
// Clear messages when endpoint/protocol changes (e.g., switching examples)
|
|
85
91
|
useEffect(() => {
|
|
86
92
|
clearStoreMessages();
|
|
@@ -387,6 +393,6 @@ export function ChatFloating({ endpoint, protocol: protocolProp, useStore: useSt
|
|
|
387
393
|
...poweredByProps,
|
|
388
394
|
}, renderToolResult: renderToolResult, description: description, onStateUpdate: onStateUpdate, onNewChat: onNewChat, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, hideMessagesAfterToolUI: hideMessagesAfterToolUI, avatarConfig: {
|
|
389
395
|
showAvatars: true,
|
|
390
|
-
}, placeholder: "Type a message...", backgroundColor: "canvas.subtle", frontendTools: _tools, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, ...panelProps, children: children }) })] }));
|
|
396
|
+
}, placeholder: "Type a message...", backgroundColor: "canvas.subtle", frontendTools: _tools, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, ...panelProps, children: children }) })] }));
|
|
391
397
|
}
|
|
392
398
|
export default ChatFloating;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distribution child item
|
|
3
|
+
*/
|
|
4
|
+
interface DistributionChild {
|
|
5
|
+
name: string;
|
|
6
|
+
value: number;
|
|
7
|
+
children?: DistributionChild[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Distribution data for treemap
|
|
11
|
+
*/
|
|
12
|
+
interface Distribution {
|
|
13
|
+
name: string;
|
|
14
|
+
value: number;
|
|
15
|
+
children: DistributionChild[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Context snapshot response from API
|
|
19
|
+
*/
|
|
20
|
+
export interface ContextSnapshotResponse {
|
|
21
|
+
agentId: string;
|
|
22
|
+
systemPrompts: string[];
|
|
23
|
+
systemPromptTokens: number;
|
|
24
|
+
messages: Array<{
|
|
25
|
+
role: string;
|
|
26
|
+
content: string;
|
|
27
|
+
estimatedTokens: number;
|
|
28
|
+
timestamp: string | null;
|
|
29
|
+
}>;
|
|
30
|
+
userMessageTokens: number;
|
|
31
|
+
assistantMessageTokens: number;
|
|
32
|
+
totalTokens: number;
|
|
33
|
+
contextWindow: number;
|
|
34
|
+
distribution: Distribution;
|
|
35
|
+
error?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ContextDistributionProps {
|
|
38
|
+
/** Agent ID for fetching context snapshot */
|
|
39
|
+
agentId: string;
|
|
40
|
+
/** Height of the chart */
|
|
41
|
+
height?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* ContextDistribution component displays context distribution as a treemap.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ContextDistribution({ agentId, height, }: ContextDistributionProps): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
export default ContextDistribution;
|