@datalayer/agent-runtimes 0.0.9 → 0.0.10
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 +2 -1
- package/lib/{examples/components → components}/AgentConfiguration.d.ts +27 -12
- package/lib/{examples/components → components}/AgentConfiguration.js +170 -22
- package/lib/{examples/components → components}/FooterMetrics.d.ts +1 -2
- package/lib/{examples/components → components}/Header.d.ts +1 -6
- package/lib/{examples/components → components}/Header.js +5 -39
- package/lib/{examples/components → components}/HeaderControls.d.ts +1 -2
- package/lib/{examples/components → components}/HeaderControls.js +1 -1
- package/lib/{examples/components → components}/LexicalEditor.d.ts +2 -3
- package/lib/{examples/components → components}/LexicalEditor.js +2 -2
- package/lib/components/MainContent.d.ts +34 -0
- package/lib/{examples/components → components}/MainContent.js +18 -9
- package/lib/components/McpServerManager.d.ts +30 -0
- package/lib/components/McpServerManager.js +331 -0
- package/lib/{examples/components → components}/MockFileBrowser.d.ts +1 -2
- package/lib/{examples/components → components}/SessionTabs.d.ts +2 -3
- package/lib/{examples/components → components}/TimeTravel.d.ts +1 -2
- package/lib/components/chat/components/AgentDetails.d.ts +3 -1
- package/lib/components/chat/components/AgentDetails.js +323 -31
- package/lib/components/chat/components/Chat.d.ts +37 -3
- package/lib/components/chat/components/Chat.js +29 -10
- package/lib/components/chat/components/ChatFloating.d.ts +27 -2
- package/lib/components/chat/components/ChatFloating.js +17 -10
- package/lib/components/chat/components/ChatPopupStandalone.js +1 -1
- package/lib/components/chat/components/ChatSidebar.d.ts +1 -1
- package/lib/components/chat/components/ChatStandalone.d.ts +1 -1
- package/lib/components/chat/components/ChatStandalone.js +1 -1
- package/lib/components/chat/components/ContextDistribution.d.ts +70 -6
- package/lib/components/chat/components/ContextDistribution.js +11 -4
- package/lib/components/chat/components/ContextInspector.d.ts +81 -0
- package/lib/components/chat/components/ContextInspector.js +261 -0
- package/lib/components/chat/components/ContextPanel.d.ts +112 -0
- package/lib/components/chat/components/ContextPanel.js +373 -0
- package/lib/components/chat/components/base/ChatBase.d.ts +74 -19
- package/lib/components/chat/components/base/ChatBase.js +296 -37
- package/lib/components/chat/components/index.d.ts +3 -1
- package/lib/components/chat/components/index.js +2 -0
- package/lib/components/chat/extensions/ExtensionRegistry.d.ts +1 -1
- package/lib/components/chat/extensions/index.d.ts +1 -0
- package/lib/components/chat/index.d.ts +3 -3
- package/lib/components/chat/protocols/AGUIAdapter.js +24 -4
- package/lib/components/chat/protocols/VercelAIAdapter.js +35 -1
- package/lib/components/chat/store/chatStore.d.ts +2 -3
- package/lib/components/chat/store/conversationStore.d.ts +83 -0
- package/lib/components/chat/store/conversationStore.js +174 -0
- package/lib/components/chat/store/index.d.ts +2 -1
- package/lib/components/chat/store/index.js +1 -0
- package/lib/components/chat/types/inference.d.ts +17 -0
- package/lib/components/chat/types/protocol.d.ts +10 -0
- package/lib/components/index.d.ts +23 -0
- package/lib/components/index.js +11 -0
- package/lib/config/agents.d.ts +33 -0
- package/lib/config/agents.js +424 -0
- package/lib/config/index.d.ts +4 -0
- package/lib/config/index.js +8 -0
- package/lib/config/mcpServers.d.ts +18 -0
- package/lib/config/mcpServers.js +129 -0
- package/lib/config/skills.d.ts +25 -0
- package/lib/config/skills.js +54 -0
- package/lib/{lib → config}/utils.d.ts +1 -1
- package/lib/{lib → config}/utils.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexical2Example.js +3 -2
- package/lib/examples/AgentRuntimeLexicalExample.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexicalExample.js +5 -3
- package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +3 -3
- package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
- package/lib/examples/AgentSpaceFormExample.d.ts +2 -2
- package/lib/examples/AgentSpaceFormExample.js +167 -29
- package/lib/examples/CopilotKitLexicalExample.d.ts +1 -0
- package/lib/examples/CopilotKitLexicalExample.js +3 -2
- package/lib/examples/index.d.ts +1 -0
- package/lib/examples/stores/notebooks/NotebookExample2.ipynb.json +43 -43
- package/lib/hooks/useAGUI.d.ts +1 -1
- package/lib/hooks/useAGUI.js +1 -1
- package/lib/identity/types.d.ts +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +1 -0
- package/lib/runtime/index.d.ts +3 -0
- package/lib/runtime/runtimeStore.d.ts +3 -4
- package/lib/runtime/useAgentConnection.d.ts +2 -3
- package/lib/runtime/useAgentRuntime.d.ts +2 -3
- package/lib/stories/Cell.stories.js +1 -1
- package/lib/tools/adapters/agent-runtimes/notebookHooks.js +1 -0
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -0
- package/lib/types.d.ts +150 -0
- package/package.json +4 -5
- package/scripts/apply-patches.sh +1 -1
- package/scripts/codegen/generate_agents.py +452 -0
- package/scripts/codegen/generate_mcp_servers.py +424 -0
- package/scripts/codegen/generate_skills.py +321 -0
- package/scripts/download-ai-elements.py +35 -20
- package/scripts/sync-jupyter.sh +6 -0
- package/lib/components/ui/accordion.d.ts +0 -7
- package/lib/components/ui/accordion.js +0 -22
- package/lib/components/ui/alert-dialog.d.ts +0 -14
- package/lib/components/ui/alert-dialog.js +0 -43
- package/lib/components/ui/alert.d.ts +0 -9
- package/lib/components/ui/alert.js +0 -24
- package/lib/components/ui/aspect-ratio.d.ts +0 -3
- package/lib/components/ui/aspect-ratio.js +0 -11
- package/lib/components/ui/avatar.d.ts +0 -6
- package/lib/components/ui/avatar.js +0 -18
- package/lib/components/ui/badge.d.ts +0 -9
- package/lib/components/ui/badge.js +0 -22
- package/lib/components/ui/breadcrumb.d.ts +0 -11
- package/lib/components/ui/breadcrumb.js +0 -27
- package/lib/components/ui/button-group.d.ts +0 -11
- package/lib/components/ui/button-group.js +0 -31
- package/lib/components/ui/button.d.ts +0 -13
- package/lib/components/ui/button.js +0 -39
- package/lib/components/ui/calendar.d.ts +0 -8
- package/lib/components/ui/calendar.js +0 -80
- package/lib/components/ui/card.d.ts +0 -9
- package/lib/components/ui/card.js +0 -24
- package/lib/components/ui/carousel.d.ts +0 -19
- package/lib/components/ui/carousel.js +0 -95
- package/lib/components/ui/chart.d.ts +0 -53
- package/lib/components/ui/chart.js +0 -136
- package/lib/components/ui/checkbox.d.ts +0 -4
- package/lib/components/ui/checkbox.js +0 -13
- package/lib/components/ui/collapsible.d.ts +0 -5
- package/lib/components/ui/collapsible.js +0 -17
- package/lib/components/ui/command.d.ts +0 -18
- package/lib/components/ui/command.js +0 -38
- package/lib/components/ui/context-menu.d.ts +0 -25
- package/lib/components/ui/context-menu.js +0 -55
- package/lib/components/ui/dialog.d.ts +0 -15
- package/lib/components/ui/dialog.js +0 -40
- package/lib/components/ui/drawer.d.ts +0 -13
- package/lib/components/ui/drawer.js +0 -39
- package/lib/components/ui/dropdown-menu.d.ts +0 -25
- package/lib/components/ui/dropdown-menu.js +0 -55
- package/lib/components/ui/empty.d.ts +0 -11
- package/lib/components/ui/empty.js +0 -37
- package/lib/components/ui/field.d.ts +0 -24
- package/lib/components/ui/field.js +0 -80
- package/lib/components/ui/form.d.ts +0 -24
- package/lib/components/ui/form.js +0 -63
- package/lib/components/ui/hover-card.d.ts +0 -6
- package/lib/components/ui/hover-card.js +0 -18
- package/lib/components/ui/input-group.d.ts +0 -19
- package/lib/components/ui/input-group.js +0 -69
- package/lib/components/ui/input-otp.d.ts +0 -11
- package/lib/components/ui/input-otp.js +0 -25
- package/lib/components/ui/input.d.ts +0 -3
- package/lib/components/ui/input.js +0 -6
- package/lib/components/ui/item.d.ts +0 -23
- package/lib/components/ui/item.js +0 -66
- package/lib/components/ui/kbd.d.ts +0 -3
- package/lib/components/ui/kbd.js +0 -13
- package/lib/components/ui/label.d.ts +0 -4
- package/lib/components/ui/label.js +0 -12
- package/lib/components/ui/menubar.d.ts +0 -26
- package/lib/components/ui/menubar.js +0 -58
- package/lib/components/ui/navigation-menu.d.ts +0 -14
- package/lib/components/ui/navigation-menu.js +0 -31
- package/lib/components/ui/pagination.d.ts +0 -13
- package/lib/components/ui/pagination.js +0 -29
- package/lib/components/ui/popover.d.ts +0 -7
- package/lib/components/ui/popover.js +0 -21
- package/lib/components/ui/progress.d.ts +0 -4
- package/lib/components/ui/progress.js +0 -12
- package/lib/components/ui/radio-group.d.ts +0 -5
- package/lib/components/ui/radio-group.js +0 -16
- package/lib/components/ui/resizable.d.ts +0 -8
- package/lib/components/ui/resizable.js +0 -19
- package/lib/components/ui/scroll-area.d.ts +0 -5
- package/lib/components/ui/scroll-area.js +0 -17
- package/lib/components/ui/select.d.ts +0 -15
- package/lib/components/ui/select.js +0 -42
- package/lib/components/ui/separator.d.ts +0 -4
- package/lib/components/ui/separator.js +0 -12
- package/lib/components/ui/sheet.d.ts +0 -13
- package/lib/components/ui/sheet.js +0 -44
- package/lib/components/ui/sidebar.d.ts +0 -69
- package/lib/components/ui/sidebar.js +0 -216
- package/lib/components/ui/skeleton.d.ts +0 -2
- package/lib/components/ui/skeleton.js +0 -10
- package/lib/components/ui/slider.d.ts +0 -4
- package/lib/components/ui/slider.js +0 -18
- package/lib/components/ui/sonner.d.ts +0 -3
- package/lib/components/ui/sonner.js +0 -25
- package/lib/components/ui/spinner.d.ts +0 -2
- package/lib/components/ui/spinner.js +0 -11
- package/lib/components/ui/switch.d.ts +0 -4
- package/lib/components/ui/switch.js +0 -12
- package/lib/components/ui/table.d.ts +0 -10
- package/lib/components/ui/table.js +0 -32
- package/lib/components/ui/tabs.d.ts +0 -7
- package/lib/components/ui/tabs.js +0 -21
- package/lib/components/ui/textarea.d.ts +0 -3
- package/lib/components/ui/textarea.js +0 -6
- package/lib/components/ui/toast.d.ts +0 -15
- package/lib/components/ui/toast.js +0 -38
- package/lib/components/ui/toaster.d.ts +0 -1
- package/lib/components/ui/toaster.js +0 -14
- package/lib/components/ui/toggle-group.d.ts +0 -9
- package/lib/components/ui/toggle-group.js +0 -26
- package/lib/components/ui/toggle.d.ts +0 -9
- package/lib/components/ui/toggle.js +0 -30
- package/lib/components/ui/tooltip.d.ts +0 -7
- package/lib/components/ui/tooltip.js +0 -21
- package/lib/components/vercel-ai-elements/artifact.d.ts +0 -23
- package/lib/components/vercel-ai-elements/artifact.js +0 -24
- package/lib/components/vercel-ai-elements/code-block.d.ts +0 -17
- package/lib/components/vercel-ai-elements/code-block.js +0 -94
- package/lib/components/vercel-ai-elements/conversation.d.ts +0 -15
- package/lib/components/vercel-ai-elements/conversation.js +0 -21
- package/lib/components/vercel-ai-elements/loader.d.ts +0 -5
- package/lib/components/vercel-ai-elements/loader.js +0 -8
- package/lib/components/vercel-ai-elements/message.d.ts +0 -46
- package/lib/components/vercel-ai-elements/message.js +0 -109
- package/lib/components/vercel-ai-elements/model-selector.d.ts +0 -35
- package/lib/components/vercel-ai-elements/model-selector.js +0 -22
- package/lib/components/vercel-ai-elements/prompt-input.d.ts +0 -195
- package/lib/components/vercel-ai-elements/prompt-input.js +0 -589
- package/lib/components/vercel-ai-elements/reasoning.d.ts +0 -26
- package/lib/components/vercel-ai-elements/reasoning.js +0 -80
- package/lib/components/vercel-ai-elements/shimmer.d.ts +0 -9
- package/lib/components/vercel-ai-elements/shimmer.js +0 -22
- package/lib/components/vercel-ai-elements/sources.d.ts +0 -12
- package/lib/components/vercel-ai-elements/sources.js +0 -13
- package/lib/components/vercel-ai-elements/suggestion.d.ts +0 -10
- package/lib/components/vercel-ai-elements/suggestion.js +0 -16
- package/lib/components/vercel-ai-elements/tool.d.ts +0 -23
- package/lib/components/vercel-ai-elements/tool.js +0 -52
- package/lib/examples/components/MainContent.d.ts +0 -19
- package/lib/examples/components/index.d.ts +0 -10
- package/lib/examples/components/index.js +0 -13
- package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.d.ts +0 -12
- package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.js +0 -69
- package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.js +0 -85
- package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.js +0 -62
- package/lib/examples/vercel-ai-elements/components/ConversationShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ConversationShowcase.js +0 -51
- package/lib/examples/vercel-ai-elements/components/LoaderShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/LoaderShowcase.js +0 -9
- package/lib/examples/vercel-ai-elements/components/MessageShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/MessageShowcase.js +0 -56
- package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.js +0 -50
- package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.js +0 -16
- package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.js +0 -72
- package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.js +0 -9
- package/lib/examples/vercel-ai-elements/components/SourcesShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/SourcesShowcase.js +0 -43
- package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.js +0 -31
- package/lib/examples/vercel-ai-elements/components/ToolShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ToolShowcase.js +0 -54
- package/lib/examples/vercel-ai-elements/index.d.ts +0 -13
- package/lib/examples/vercel-ai-elements/index.js +0 -17
- package/lib/examples/vercel-ai-elements/main.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/main.js +0 -9
- package/lib/examples/vercel-ai-elements/showcase.css +0 -128
- package/lib/hooks/useToast.d.ts +0 -44
- package/lib/hooks/useToast.js +0 -128
- package/patches/@datalayer+jupyter-lexical+1.0.8.patch +0 -11628
- package/patches/@datalayer+jupyter-react+2.0.2.patch +0 -5338
- package/style/showcase-vercel-ai.css +0 -137
- /package/lib/{examples/components → components}/FooterMetrics.js +0 -0
- /package/lib/{examples/components → components}/MockFileBrowser.js +0 -0
- /package/lib/{examples/components → components}/SessionTabs.js +0 -0
- /package/lib/{examples/components → components}/TimeTravel.js +0 -0
- /package/lib/{models → types}/AIAgent.d.ts +0 -0
- /package/lib/{models → types}/AIAgent.js +0 -0
- /package/lib/{models → types}/index.d.ts +0 -0
- /package/lib/{models → types}/index.js +0 -0
|
@@ -26,6 +26,7 @@ import { Streamdown } from 'streamdown';
|
|
|
26
26
|
import { PoweredByTag } from '../elements/PoweredByTag';
|
|
27
27
|
import { requestAPI } from '../../handler';
|
|
28
28
|
import { useChatStore } from '../../store/chatStore';
|
|
29
|
+
import { useConversationStore } from '../../store/conversationStore';
|
|
29
30
|
import { generateMessageId, createUserMessage, createAssistantMessage, } from '../../types/message';
|
|
30
31
|
import { AGUIAdapter, A2AAdapter, VercelAIAdapter, ACPAdapter, } from '../../protocols';
|
|
31
32
|
import { ToolCallDisplay } from '../display/ToolCallDisplay';
|
|
@@ -155,6 +156,7 @@ function useConfigQuery(enabled, configEndpoint, authToken) {
|
|
|
155
156
|
},
|
|
156
157
|
queryKey: ['models', configEndpoint || 'jupyter'],
|
|
157
158
|
enabled,
|
|
159
|
+
retry: 1,
|
|
158
160
|
});
|
|
159
161
|
}
|
|
160
162
|
/**
|
|
@@ -195,37 +197,114 @@ function useSkillsQuery(enabled, baseEndpoint, authToken) {
|
|
|
195
197
|
queryKey: ['skills', baseEndpoint || 'jupyter'],
|
|
196
198
|
enabled,
|
|
197
199
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
200
|
+
retry: 1,
|
|
198
201
|
});
|
|
199
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Format token count for compact display
|
|
205
|
+
*/
|
|
206
|
+
function formatTokenCount(tokens) {
|
|
207
|
+
if (tokens >= 1_000_000)
|
|
208
|
+
return `${(tokens / 1_000_000).toFixed(1)}M`;
|
|
209
|
+
if (tokens >= 1_000)
|
|
210
|
+
return `${(tokens / 1_000).toFixed(1)}K`;
|
|
211
|
+
return tokens.toString();
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Derive the API base URL from a configEndpoint.
|
|
215
|
+
* configEndpoint may look like:
|
|
216
|
+
* "http://host:port/api/v1/config" (from agentRuntimeConfig)
|
|
217
|
+
* "http://host:port/api/v1/configure" (from Chat component)
|
|
218
|
+
* We strip the trailing path segment to get "http://host:port/api/v1".
|
|
219
|
+
*/
|
|
220
|
+
function getApiBaseFromConfig(configEndpoint) {
|
|
221
|
+
return configEndpoint.replace(/\/(config|configure)\/?$/, '');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Hook to poll agent context-snapshot from the backend.
|
|
225
|
+
* Returns cumulative token usage (input/output breakdown) tracked by the agent server.
|
|
226
|
+
* Uses the same endpoint as codeai: GET /api/v1/configure/agents/{agentId}/context-snapshot
|
|
227
|
+
*/
|
|
228
|
+
function useContextSnapshotQuery(enabled, configEndpoint, agentId, authToken) {
|
|
229
|
+
const queryClient = useContext(QueryClientContext);
|
|
230
|
+
if (!queryClient) {
|
|
231
|
+
return { data: undefined, isLoading: false, isError: false, error: null };
|
|
232
|
+
}
|
|
233
|
+
const snapshotUrl = configEndpoint && agentId
|
|
234
|
+
? `${getApiBaseFromConfig(configEndpoint)}/configure/agents/${encodeURIComponent(agentId)}/context-snapshot`
|
|
235
|
+
: undefined;
|
|
236
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
237
|
+
const result = useQuery({
|
|
238
|
+
queryKey: ['context-snapshot-header', agentId, snapshotUrl],
|
|
239
|
+
queryFn: async () => {
|
|
240
|
+
if (!snapshotUrl) {
|
|
241
|
+
throw new Error('No context-snapshot URL available');
|
|
242
|
+
}
|
|
243
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
244
|
+
if (authToken) {
|
|
245
|
+
headers['Authorization'] = `Bearer ${authToken}`;
|
|
246
|
+
}
|
|
247
|
+
const response = await fetch(snapshotUrl, { headers });
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
throw new Error(`Context snapshot fetch failed: ${response.statusText}`);
|
|
250
|
+
}
|
|
251
|
+
return response.json();
|
|
252
|
+
},
|
|
253
|
+
enabled: enabled && !!snapshotUrl,
|
|
254
|
+
// Poll every 10 seconds, but stop polling once the query has errored (e.g. runtime terminated)
|
|
255
|
+
refetchInterval: query => (query.state.status === 'error' ? false : 10_000),
|
|
256
|
+
refetchOnMount: 'always',
|
|
257
|
+
staleTime: 0,
|
|
258
|
+
retry: 1,
|
|
259
|
+
});
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
200
262
|
/**
|
|
201
263
|
* ChatBase component - Universal chat panel supporting store, protocol, and custom modes
|
|
202
264
|
*/
|
|
203
|
-
export function ChatBase({ title, showHeader = false, showLoadingIndicator = true, showErrors = true, showInput = true, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, codemodeEnabled = false, initialModel,
|
|
265
|
+
export function ChatBase({ title, showHeader = false, showTokenUsage = true, showLoadingIndicator = true, showErrors = true, showInput = true, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, codemodeEnabled = false, initialModel, availableModels, mcpServers, initialSkills, className, loadingState, headerActions,
|
|
204
266
|
// Mode selection
|
|
205
|
-
useStore: useStoreMode = true, protocol, onSendMessage, enableStreaming = false,
|
|
267
|
+
useStore: useStoreMode = true, protocol: protocolProp, agentRuntimeConfig, onSendMessage, enableStreaming = false,
|
|
206
268
|
// Extended props
|
|
207
269
|
brandIcon, avatarConfig, headerButtons, showPoweredBy = false, poweredByProps, emptyState, renderToolResult, footerContent, headerContent, children, borderRadius, backgroundColor, border, boxShadow, compact = false, placeholder, description = 'Start a conversation with the AI agent.', onStateUpdate, onNewChat, onClear, onMessagesChange, autoFocus = false, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, focusTrigger, frontendTools,
|
|
208
270
|
// Identity/Authorization props
|
|
209
|
-
onAuthorizationRequired, connectedIdentities,
|
|
271
|
+
onAuthorizationRequired, connectedIdentities,
|
|
272
|
+
// Conversation persistence
|
|
273
|
+
runtimeId, historyEndpoint, historyAuthToken, }) {
|
|
274
|
+
// Convert agentRuntimeConfig to protocol if provided
|
|
275
|
+
const protocol = agentRuntimeConfig
|
|
276
|
+
? {
|
|
277
|
+
type: agentRuntimeConfig.protocol || 'ag-ui',
|
|
278
|
+
endpoint: agentRuntimeConfig.url,
|
|
279
|
+
authToken: agentRuntimeConfig.authToken,
|
|
280
|
+
agentId: agentRuntimeConfig.agentId,
|
|
281
|
+
enableConfigQuery: true,
|
|
282
|
+
configEndpoint: `${agentRuntimeConfig.url}/api/v1/config`,
|
|
283
|
+
}
|
|
284
|
+
: protocolProp;
|
|
285
|
+
// If agentRuntimeConfig is provided, force protocol mode
|
|
286
|
+
const effectiveUseStoreMode = agentRuntimeConfig ? false : useStoreMode;
|
|
210
287
|
// Check if QueryClientProvider is already available
|
|
211
288
|
const existingQueryClient = useContext(QueryClientContext);
|
|
212
289
|
// If no QueryClient is available, wrap with our internal provider
|
|
213
290
|
if (!existingQueryClient) {
|
|
214
|
-
return (_jsx(QueryClientProvider, { client: internalQueryClient, children: _jsx(ChatBaseInner, { title: title, showHeader: showHeader, showLoadingIndicator: showLoadingIndicator, showErrors: showErrors, showInput: showInput, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel,
|
|
291
|
+
return (_jsx(QueryClientProvider, { client: internalQueryClient, children: _jsx(ChatBaseInner, { title: title, showHeader: showHeader, showTokenUsage: showTokenUsage, showLoadingIndicator: showLoadingIndicator, showErrors: showErrors, showInput: showInput, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, className: className, loadingState: loadingState, headerActions: headerActions, useStore: effectiveUseStoreMode, protocol: protocol, onSendMessage: onSendMessage, enableStreaming: enableStreaming, brandIcon: brandIcon, avatarConfig: avatarConfig, headerButtons: headerButtons, showPoweredBy: showPoweredBy, poweredByProps: poweredByProps, emptyState: emptyState, renderToolResult: renderToolResult, footerContent: footerContent, headerContent: headerContent, children: children, borderRadius: borderRadius, backgroundColor: backgroundColor, border: border, boxShadow: boxShadow, compact: compact, placeholder: placeholder, description: description, onStateUpdate: onStateUpdate, onNewChat: onNewChat, onClear: onClear, onMessagesChange: onMessagesChange, autoFocus: autoFocus, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, hideMessagesAfterToolUI: hideMessagesAfterToolUI, focusTrigger: focusTrigger, frontendTools: frontendTools, onAuthorizationRequired: onAuthorizationRequired, connectedIdentities: connectedIdentities, runtimeId: runtimeId, historyEndpoint: historyEndpoint, historyAuthToken: historyAuthToken }) }));
|
|
215
292
|
}
|
|
216
293
|
// QueryClient already available, render inner component directly
|
|
217
|
-
return (_jsx(ChatBaseInner, { title: title, showHeader: showHeader, showLoadingIndicator: showLoadingIndicator, showErrors: showErrors, showInput: showInput, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel,
|
|
294
|
+
return (_jsx(ChatBaseInner, { title: title, showHeader: showHeader, showTokenUsage: showTokenUsage, showLoadingIndicator: showLoadingIndicator, showErrors: showErrors, showInput: showInput, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, className: className, loadingState: loadingState, headerActions: headerActions, useStore: effectiveUseStoreMode, protocol: protocol, onSendMessage: onSendMessage, enableStreaming: enableStreaming, brandIcon: brandIcon, avatarConfig: avatarConfig, headerButtons: headerButtons, showPoweredBy: showPoweredBy, poweredByProps: poweredByProps, emptyState: emptyState, renderToolResult: renderToolResult, footerContent: footerContent, headerContent: headerContent, children: children, borderRadius: borderRadius, backgroundColor: backgroundColor, border: border, boxShadow: boxShadow, compact: compact, placeholder: placeholder, description: description, onStateUpdate: onStateUpdate, onNewChat: onNewChat, onClear: onClear, onMessagesChange: onMessagesChange, autoFocus: autoFocus, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, hideMessagesAfterToolUI: hideMessagesAfterToolUI, focusTrigger: focusTrigger, frontendTools: frontendTools, onAuthorizationRequired: onAuthorizationRequired, connectedIdentities: connectedIdentities, runtimeId: runtimeId, historyEndpoint: historyEndpoint, historyAuthToken: historyAuthToken }));
|
|
218
295
|
}
|
|
219
296
|
/**
|
|
220
297
|
* Inner ChatBase component - contains all the actual logic
|
|
221
298
|
*/
|
|
222
|
-
function ChatBaseInner({ title, showHeader = false, showLoadingIndicator = true, showErrors = true, showInput = true, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, codemodeEnabled = false, initialModel,
|
|
299
|
+
function ChatBaseInner({ title, showHeader = false, showTokenUsage = true, showLoadingIndicator = true, showErrors = true, showInput = true, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, codemodeEnabled = false, initialModel, availableModels, mcpServers, initialSkills, className, loadingState, headerActions,
|
|
223
300
|
// Mode selection
|
|
224
301
|
useStore: useStoreMode = true, protocol, onSendMessage, enableStreaming = false,
|
|
225
302
|
// Extended props
|
|
226
303
|
brandIcon, avatarConfig, headerButtons, showPoweredBy = false, poweredByProps, emptyState, renderToolResult, footerContent, headerContent, children, borderRadius, backgroundColor, border, boxShadow, compact = false, placeholder, description = 'Start a conversation with the AI agent.', onStateUpdate, onNewChat, onClear, onMessagesChange, autoFocus = false, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, focusTrigger, frontendTools,
|
|
227
304
|
// Identity/Authorization props
|
|
228
|
-
onAuthorizationRequired, connectedIdentities,
|
|
305
|
+
onAuthorizationRequired, connectedIdentities,
|
|
306
|
+
// Conversation persistence
|
|
307
|
+
runtimeId, historyEndpoint, historyAuthToken, }) {
|
|
229
308
|
// Ensure Primer's default portal has high z-index for ActionMenu overlays
|
|
230
309
|
useHighZIndexPortal();
|
|
231
310
|
// Store (optional for message persistence)
|
|
@@ -253,6 +332,10 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
253
332
|
const configQuery = useConfigQuery(Boolean(protocol?.enableConfigQuery), protocol?.configEndpoint, protocol?.authToken);
|
|
254
333
|
// Skills query (for protocols that support it)
|
|
255
334
|
const skillsQuery = useSkillsQuery(Boolean(protocol?.enableConfigQuery) && showSkillsMenu, protocol?.configEndpoint, protocol?.authToken);
|
|
335
|
+
// Context snapshot query — polls agent-level cumulative token usage (input/output breakdown)
|
|
336
|
+
// Gated by showTokenUsage (not showHeader), so usage is visible even without a title bar.
|
|
337
|
+
const contextSnapshotQuery = useContextSnapshotQuery(Boolean(protocol?.enableConfigQuery) && showTokenUsage, protocol?.configEndpoint, protocol?.agentId, protocol?.authToken);
|
|
338
|
+
const agentUsage = contextSnapshotQuery.data;
|
|
256
339
|
// Refs
|
|
257
340
|
const adapterRef = useRef(null);
|
|
258
341
|
const unsubscribeRef = useRef(null);
|
|
@@ -266,6 +349,12 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
266
349
|
// (the array reference changes on every render even if contents are the same)
|
|
267
350
|
const connectedIdentitiesRef = useRef(connectedIdentities);
|
|
268
351
|
connectedIdentitiesRef.current = connectedIdentities;
|
|
352
|
+
const isServerSelected = useCallback((server) => {
|
|
353
|
+
if (!mcpServers)
|
|
354
|
+
return true;
|
|
355
|
+
const origin = server.isConfig === false ? 'catalog' : 'config';
|
|
356
|
+
return mcpServers.some(s => s.id === server.id && s.origin === origin);
|
|
357
|
+
}, [mcpServers]);
|
|
269
358
|
// Auto-focus input on mount
|
|
270
359
|
useEffect(() => {
|
|
271
360
|
if (autoFocus && inputRef.current) {
|
|
@@ -326,18 +415,20 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
326
415
|
}, [adjustTextareaHeight]);
|
|
327
416
|
// Initialize model and tools when config is available
|
|
328
417
|
useEffect(() => {
|
|
329
|
-
if (configQuery.data && !selectedModel) {
|
|
418
|
+
if ((configQuery.data || availableModels) && !selectedModel) {
|
|
419
|
+
// Use availableModels override if provided, otherwise use config models
|
|
420
|
+
const modelsList = availableModels || configQuery.data?.models || [];
|
|
330
421
|
// Use initialModel if provided, otherwise select first available model
|
|
331
422
|
if (initialModel) {
|
|
332
|
-
// Check if the initial model exists in the
|
|
333
|
-
const modelExists =
|
|
423
|
+
// Check if the initial model exists in the models list
|
|
424
|
+
const modelExists = modelsList.some(m => m.id === initialModel);
|
|
334
425
|
if (modelExists) {
|
|
335
426
|
setSelectedModel(initialModel);
|
|
336
427
|
}
|
|
337
428
|
else {
|
|
338
429
|
// Fallback to first available model if initialModel not found
|
|
339
|
-
const firstAvailableModel =
|
|
340
|
-
const firstModel = firstAvailableModel ||
|
|
430
|
+
const firstAvailableModel = modelsList.find(m => m.isAvailable !== false);
|
|
431
|
+
const firstModel = firstAvailableModel || modelsList[0];
|
|
341
432
|
if (firstModel) {
|
|
342
433
|
setSelectedModel(firstModel.id);
|
|
343
434
|
}
|
|
@@ -345,24 +436,22 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
345
436
|
}
|
|
346
437
|
else {
|
|
347
438
|
// No initialModel provided, select first available model
|
|
348
|
-
const firstAvailableModel =
|
|
349
|
-
const firstModel = firstAvailableModel ||
|
|
439
|
+
const firstAvailableModel = modelsList.find(m => m.isAvailable !== false);
|
|
440
|
+
const firstModel = firstAvailableModel || modelsList[0];
|
|
350
441
|
if (firstModel) {
|
|
351
442
|
setSelectedModel(firstModel.id);
|
|
352
443
|
}
|
|
353
444
|
}
|
|
354
|
-
const allToolIds = configQuery.data
|
|
445
|
+
const allToolIds = configQuery.data?.builtinTools?.map(tool => tool.id) || [];
|
|
355
446
|
setEnabledTools(allToolIds);
|
|
356
447
|
// Initialize MCP server tools
|
|
357
|
-
if (configQuery.data
|
|
448
|
+
if (configQuery.data?.mcpServers) {
|
|
358
449
|
const newEnabledMcpTools = new Map();
|
|
359
450
|
for (const server of configQuery.data.mcpServers) {
|
|
360
451
|
if (server.isAvailable && server.enabled) {
|
|
361
|
-
// If
|
|
452
|
+
// If mcpServers is provided, only enable those servers
|
|
362
453
|
// If not provided, enable all available servers
|
|
363
|
-
const shouldEnableServer =
|
|
364
|
-
? initialMcpServers.includes(server.id)
|
|
365
|
-
: true;
|
|
454
|
+
const shouldEnableServer = isServerSelected(server);
|
|
366
455
|
if (shouldEnableServer) {
|
|
367
456
|
const enabledToolNames = new Set(server.tools.filter(t => t.enabled).map(t => t.name));
|
|
368
457
|
newEnabledMcpTools.set(server.id, enabledToolNames);
|
|
@@ -372,7 +461,38 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
372
461
|
setEnabledMcpTools(newEnabledMcpTools);
|
|
373
462
|
}
|
|
374
463
|
}
|
|
375
|
-
}, [
|
|
464
|
+
}, [
|
|
465
|
+
configQuery.data,
|
|
466
|
+
selectedModel,
|
|
467
|
+
initialModel,
|
|
468
|
+
availableModels,
|
|
469
|
+
mcpServers,
|
|
470
|
+
isServerSelected,
|
|
471
|
+
]);
|
|
472
|
+
// Update enabled MCP servers when mcpServers prop changes (e.g., server removed)
|
|
473
|
+
useEffect(() => {
|
|
474
|
+
if (!configQuery.data?.mcpServers || !mcpServers)
|
|
475
|
+
return;
|
|
476
|
+
setEnabledMcpTools(prev => {
|
|
477
|
+
const newMap = new Map();
|
|
478
|
+
// Only keep servers that are in mcpServers
|
|
479
|
+
for (const server of configQuery.data?.mcpServers ?? []) {
|
|
480
|
+
if (isServerSelected(server) && prev.has(server.id)) {
|
|
481
|
+
// Keep existing tool selection for this server
|
|
482
|
+
newMap.set(server.id, prev.get(server.id));
|
|
483
|
+
}
|
|
484
|
+
else if (isServerSelected(server) &&
|
|
485
|
+
server.isAvailable &&
|
|
486
|
+
server.enabled) {
|
|
487
|
+
// Newly added server - enable all tools
|
|
488
|
+
const enabledToolNames = new Set(server.tools.filter(t => t.enabled).map(t => t.name));
|
|
489
|
+
newMap.set(server.id, enabledToolNames);
|
|
490
|
+
}
|
|
491
|
+
// Servers not in mcpServers are excluded
|
|
492
|
+
}
|
|
493
|
+
return newMap;
|
|
494
|
+
});
|
|
495
|
+
}, [mcpServers, configQuery.data?.mcpServers, isServerSelected]);
|
|
376
496
|
// Initialize enabled skills from initialSkills prop
|
|
377
497
|
useEffect(() => {
|
|
378
498
|
if (initialSkills && initialSkills.length > 0) {
|
|
@@ -425,13 +545,17 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
425
545
|
setEnabledSkills(enable ? new Set(allSkillIds) : new Set());
|
|
426
546
|
}, []);
|
|
427
547
|
// Get all enabled MCP tool names (for sending with requests)
|
|
548
|
+
// Only counts tools from servers that are in mcpServers (if provided)
|
|
428
549
|
const getEnabledMcpToolNames = useCallback(() => {
|
|
429
550
|
const toolNames = [];
|
|
430
|
-
enabledMcpTools.forEach(tools => {
|
|
431
|
-
|
|
551
|
+
enabledMcpTools.forEach((tools, serverId) => {
|
|
552
|
+
// Filter by mcpServers if provided
|
|
553
|
+
if (!mcpServers || mcpServers.some(s => s.id === serverId)) {
|
|
554
|
+
tools.forEach(toolName => toolNames.push(toolName));
|
|
555
|
+
}
|
|
432
556
|
});
|
|
433
557
|
return toolNames;
|
|
434
|
-
}, [enabledMcpTools]);
|
|
558
|
+
}, [enabledMcpTools, mcpServers]);
|
|
435
559
|
// Get all enabled skill IDs (for sending with requests)
|
|
436
560
|
const getEnabledSkillIds = useCallback(() => {
|
|
437
561
|
return Array.from(enabledSkills);
|
|
@@ -445,6 +569,95 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
445
569
|
}
|
|
446
570
|
}
|
|
447
571
|
}, [useStoreMode]);
|
|
572
|
+
// Track previous runtimeId to detect changes
|
|
573
|
+
const prevRuntimeIdRef = useRef(undefined);
|
|
574
|
+
// Clear displayItems and load messages when runtimeId changes
|
|
575
|
+
// This ensures each agent space has isolated conversation history
|
|
576
|
+
useEffect(() => {
|
|
577
|
+
// If runtimeId changed, clear displayItems first
|
|
578
|
+
if (runtimeId !== prevRuntimeIdRef.current) {
|
|
579
|
+
prevRuntimeIdRef.current = runtimeId;
|
|
580
|
+
// Clear current display items when switching runtime
|
|
581
|
+
setDisplayItems([]);
|
|
582
|
+
toolCallsRef.current.clear();
|
|
583
|
+
// If no runtimeId, nothing more to do
|
|
584
|
+
if (!runtimeId)
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
// runtimeId didn't change, skip
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const store = useConversationStore.getState();
|
|
592
|
+
// Check if we need to fetch (not already fetched and not currently fetching)
|
|
593
|
+
if (!store.needsFetch(runtimeId)) {
|
|
594
|
+
// Already fetched - load from in-memory store
|
|
595
|
+
const storedMessages = store.getMessages(runtimeId);
|
|
596
|
+
if (storedMessages.length > 0) {
|
|
597
|
+
setDisplayItems(storedMessages);
|
|
598
|
+
}
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
// Mark as fetching to prevent duplicate requests
|
|
602
|
+
store.setFetching(runtimeId, true);
|
|
603
|
+
// Build the history endpoint URL
|
|
604
|
+
const endpoint = historyEndpoint ||
|
|
605
|
+
(protocol?.endpoint ? `${protocol.endpoint}/history` : null);
|
|
606
|
+
if (!endpoint) {
|
|
607
|
+
console.warn('[ChatBase] No history endpoint available for runtimeId:', runtimeId);
|
|
608
|
+
store.markFetched(runtimeId);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
// Fetch conversation history from server
|
|
612
|
+
const fetchHistory = async () => {
|
|
613
|
+
try {
|
|
614
|
+
const authToken = historyAuthToken || protocol?.authToken;
|
|
615
|
+
const headers = {
|
|
616
|
+
'Content-Type': 'application/json',
|
|
617
|
+
};
|
|
618
|
+
if (authToken) {
|
|
619
|
+
headers['Authorization'] = `Bearer ${authToken}`;
|
|
620
|
+
}
|
|
621
|
+
const response = await fetch(endpoint, {
|
|
622
|
+
method: 'GET',
|
|
623
|
+
headers,
|
|
624
|
+
credentials: 'include',
|
|
625
|
+
});
|
|
626
|
+
if (!response.ok) {
|
|
627
|
+
throw new Error(`Failed to fetch history: ${response.status} ${response.statusText}`);
|
|
628
|
+
}
|
|
629
|
+
const data = await response.json();
|
|
630
|
+
const messages = data.messages || [];
|
|
631
|
+
// Store in memory and update display
|
|
632
|
+
if (messages.length > 0) {
|
|
633
|
+
store.setMessages(runtimeId, messages);
|
|
634
|
+
setDisplayItems(messages);
|
|
635
|
+
}
|
|
636
|
+
store.markFetched(runtimeId);
|
|
637
|
+
}
|
|
638
|
+
catch (err) {
|
|
639
|
+
console.error('[ChatBase] Failed to fetch conversation history:', err);
|
|
640
|
+
store.markFetched(runtimeId);
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
fetchHistory();
|
|
644
|
+
}, [
|
|
645
|
+
runtimeId,
|
|
646
|
+
historyEndpoint,
|
|
647
|
+
historyAuthToken,
|
|
648
|
+
protocol?.endpoint,
|
|
649
|
+
protocol?.authToken,
|
|
650
|
+
]);
|
|
651
|
+
// Keep in-memory store in sync with displayItems (for session persistence)
|
|
652
|
+
useEffect(() => {
|
|
653
|
+
if (runtimeId && displayItems.length > 0) {
|
|
654
|
+
// Filter to only save ChatMessage items (not tool call items)
|
|
655
|
+
const messagesToSave = displayItems.filter((item) => !isToolCallMessage(item));
|
|
656
|
+
if (messagesToSave.length > 0) {
|
|
657
|
+
useConversationStore.getState().setMessages(runtimeId, messagesToSave);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}, [runtimeId, displayItems]);
|
|
448
661
|
// Derived state
|
|
449
662
|
const messages = displayItems.filter((item) => !isToolCallMessage(item));
|
|
450
663
|
const ready = true;
|
|
@@ -954,9 +1167,13 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
954
1167
|
if (useStoreMode) {
|
|
955
1168
|
clearStoreMessages();
|
|
956
1169
|
}
|
|
1170
|
+
// Clear from conversation store if runtimeId is provided
|
|
1171
|
+
if (runtimeId) {
|
|
1172
|
+
useConversationStore.getState().clearMessages(runtimeId);
|
|
1173
|
+
}
|
|
957
1174
|
onNewChat?.();
|
|
958
1175
|
headerButtons?.onNewChat?.();
|
|
959
|
-
}, [clearStoreMessages, onNewChat, headerButtons, useStoreMode]);
|
|
1176
|
+
}, [clearStoreMessages, onNewChat, headerButtons, useStoreMode, runtimeId]);
|
|
960
1177
|
// Handle clear
|
|
961
1178
|
const handleClear = useCallback(() => {
|
|
962
1179
|
if (window.confirm('Clear all messages?')) {
|
|
@@ -965,10 +1182,14 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
965
1182
|
if (useStoreMode) {
|
|
966
1183
|
clearStoreMessages();
|
|
967
1184
|
}
|
|
1185
|
+
// Clear from conversation store if runtimeId is provided
|
|
1186
|
+
if (runtimeId) {
|
|
1187
|
+
useConversationStore.getState().clearMessages(runtimeId);
|
|
1188
|
+
}
|
|
968
1189
|
onClear?.();
|
|
969
1190
|
headerButtons?.onClear?.();
|
|
970
1191
|
}
|
|
971
|
-
}, [clearStoreMessages, onClear, headerButtons, useStoreMode]);
|
|
1192
|
+
}, [clearStoreMessages, onClear, headerButtons, useStoreMode, runtimeId]);
|
|
972
1193
|
// Not ready yet (store mode only)
|
|
973
1194
|
if (!ready) {
|
|
974
1195
|
return (_jsx(Box, { className: className, sx: {
|
|
@@ -1000,6 +1221,34 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1000
1221
|
p: padding,
|
|
1001
1222
|
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [brandIcon || _jsx(AiAgentIcon, { colored: true, size: 20 }), title && (_jsx(Heading, { as: "h3", sx: { fontSize: 2, fontWeight: 'semibold' }, children: title })), headerContent] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [headerButtons?.showNewChat && (_jsx(IconButton, { icon: PlusIcon, "aria-label": "New chat", variant: "invisible", size: "small", onClick: handleNewChat })), headerButtons?.showClear && messages.length > 0 && (_jsx(IconButton, { icon: TrashIcon, "aria-label": "Clear messages", variant: "invisible", size: "small", onClick: handleClear })), headerButtons?.showSettings && (_jsx(IconButton, { icon: GearIcon, "aria-label": "Settings", variant: "invisible", size: "small", onClick: headerButtons.onSettings })), headerActions] })] }) }));
|
|
1002
1223
|
};
|
|
1224
|
+
// Render token usage bar between input and selectors
|
|
1225
|
+
const renderTokenUsage = () => {
|
|
1226
|
+
if (!showTokenUsage)
|
|
1227
|
+
return null;
|
|
1228
|
+
// Show bar when we have any context data (totalTokens > 0 means agent is active)
|
|
1229
|
+
const hasContext = agentUsage && !agentUsage.error && agentUsage.totalTokens > 0;
|
|
1230
|
+
const hasTurn = agentUsage?.turnUsage &&
|
|
1231
|
+
(agentUsage.turnUsage.inputTokens > 0 ||
|
|
1232
|
+
agentUsage.turnUsage.outputTokens > 0);
|
|
1233
|
+
const hasSession = agentUsage?.sessionUsage &&
|
|
1234
|
+
(agentUsage.sessionUsage.inputTokens > 0 ||
|
|
1235
|
+
agentUsage.sessionUsage.outputTokens > 0);
|
|
1236
|
+
if (!hasContext)
|
|
1237
|
+
return null;
|
|
1238
|
+
return (_jsxs(Box, { sx: {
|
|
1239
|
+
display: 'flex',
|
|
1240
|
+
alignItems: 'center',
|
|
1241
|
+
justifyContent: 'flex-start',
|
|
1242
|
+
gap: 2,
|
|
1243
|
+
py: 1,
|
|
1244
|
+
px: padding,
|
|
1245
|
+
bg: 'canvas.subtle',
|
|
1246
|
+
flexWrap: 'nowrap',
|
|
1247
|
+
overflow: 'hidden',
|
|
1248
|
+
whiteSpace: 'nowrap',
|
|
1249
|
+
minWidth: 0,
|
|
1250
|
+
}, children: [_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', flexShrink: 0 }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'semibold', color: 'fg.default', fontSize: 0 }, children: formatTokenCount(agentUsage.totalTokens) }), ' / ', formatTokenCount(agentUsage.contextWindow), ' ctx'] }), hasSession && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', flexShrink: 0 }, children: ['· ', formatTokenCount(agentUsage.sessionUsage.inputTokens), _jsx(Text, { as: "span", sx: { color: 'success.fg', fontSize: 0 }, children: '▲' }), ' ', formatTokenCount(agentUsage.sessionUsage.outputTokens), _jsx(Text, { as: "span", sx: { color: 'attention.fg', fontSize: 0 }, children: '▼' })] })), hasTurn && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', flexShrink: 0 }, children: ['· turn ', formatTokenCount(agentUsage.turnUsage.inputTokens), _jsx(Text, { as: "span", sx: { color: 'success.fg', fontSize: 0 }, children: '▲' }), ' ', formatTokenCount(agentUsage.turnUsage.outputTokens), _jsx(Text, { as: "span", sx: { color: 'attention.fg', fontSize: 0 }, children: '▼' })] }))] }));
|
|
1251
|
+
};
|
|
1003
1252
|
// Render empty state
|
|
1004
1253
|
const renderEmptyState = () => {
|
|
1005
1254
|
if (emptyState?.render) {
|
|
@@ -1263,7 +1512,9 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1263
1512
|
maxWidth: '85%',
|
|
1264
1513
|
p: 2,
|
|
1265
1514
|
borderRadius: 2,
|
|
1266
|
-
backgroundColor: isUser
|
|
1515
|
+
backgroundColor: isUser
|
|
1516
|
+
? 'accent.emphasis'
|
|
1517
|
+
: 'canvas.subtle',
|
|
1267
1518
|
color: isUser ? 'fg.onEmphasis' : 'fg.default',
|
|
1268
1519
|
// Streamdown code block styling
|
|
1269
1520
|
// Code block container
|
|
@@ -1279,10 +1530,10 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1279
1530
|
display: 'flex',
|
|
1280
1531
|
alignItems: 'center',
|
|
1281
1532
|
justifyContent: 'space-between',
|
|
1282
|
-
backgroundColor: '
|
|
1533
|
+
backgroundColor: 'canvas.subtle',
|
|
1283
1534
|
padding: '8px 12px',
|
|
1284
1535
|
fontSize: '12px',
|
|
1285
|
-
color: '
|
|
1536
|
+
color: 'fg.muted',
|
|
1286
1537
|
},
|
|
1287
1538
|
// Style the buttons in the header
|
|
1288
1539
|
'& [data-streamdown="code-block-header"] button': {
|
|
@@ -1290,16 +1541,16 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1290
1541
|
border: 'none',
|
|
1291
1542
|
cursor: 'pointer',
|
|
1292
1543
|
padding: '4px',
|
|
1293
|
-
color: '
|
|
1544
|
+
color: 'fg.muted',
|
|
1294
1545
|
borderRadius: '4px',
|
|
1295
1546
|
'&:hover': {
|
|
1296
|
-
backgroundColor: '
|
|
1297
|
-
color: '
|
|
1547
|
+
backgroundColor: 'neutral.muted',
|
|
1548
|
+
color: 'fg.default',
|
|
1298
1549
|
},
|
|
1299
1550
|
},
|
|
1300
1551
|
// Code block body
|
|
1301
1552
|
'& [data-streamdown="code-block-body"]': {
|
|
1302
|
-
backgroundColor: '
|
|
1553
|
+
backgroundColor: 'canvas.subtle',
|
|
1303
1554
|
padding: '12px',
|
|
1304
1555
|
margin: 0,
|
|
1305
1556
|
overflow: 'auto',
|
|
@@ -1429,7 +1680,7 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1429
1680
|
// Render protocol mode input
|
|
1430
1681
|
const renderProtocolInput = () => {
|
|
1431
1682
|
const availableTools = configQuery.data?.builtinTools || [];
|
|
1432
|
-
const models = configQuery.data?.models || [];
|
|
1683
|
+
const models = availableModels || configQuery.data?.models || [];
|
|
1433
1684
|
return (_jsxs(Box, { children: [_jsx(Box, { sx: {
|
|
1434
1685
|
p: padding,
|
|
1435
1686
|
borderTop: '1px solid',
|
|
@@ -1445,7 +1696,7 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1445
1696
|
maxHeight: '120px',
|
|
1446
1697
|
overflow: 'hidden',
|
|
1447
1698
|
transition: 'height 0.1s ease-out',
|
|
1448
|
-
}, rows: 1 }), isLoading ? (_jsx(IconButton, { icon: SquareCircleIcon, "aria-label": "Stop", onClick: handleStop, sx: { alignSelf: 'flex-end' } })) : (_jsx(IconButton, { icon: PaperAirplaneIcon, "aria-label": "Send", onClick: handleSend, disabled: !input.trim(), sx: { alignSelf: 'flex-end' } }))] }) }), (showModelSelector || showToolsMenu || showSkillsMenu) &&
|
|
1699
|
+
}, rows: 1 }), isLoading ? (_jsx(IconButton, { icon: SquareCircleIcon, "aria-label": "Stop", onClick: handleStop, sx: { alignSelf: 'flex-end' } })) : (_jsx(IconButton, { icon: PaperAirplaneIcon, "aria-label": "Send", onClick: handleSend, disabled: !input.trim(), sx: { alignSelf: 'flex-end' } }))] }) }), renderTokenUsage(), (showModelSelector || showToolsMenu || showSkillsMenu) &&
|
|
1449
1700
|
(configQuery.data || skillsQuery.data) && (_jsxs(Box, { sx: {
|
|
1450
1701
|
display: 'flex',
|
|
1451
1702
|
gap: 2,
|
|
@@ -1460,7 +1711,12 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1460
1711
|
maxHeight: '60vh',
|
|
1461
1712
|
overflowY: 'auto',
|
|
1462
1713
|
}, children: _jsxs(ActionList, { children: [codemodeEnabled && (_jsx(ActionList.Group, { title: "Codemode", children: _jsx(ActionList.Item, { disabled: true, children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "MCP tools are accessible via Codemode meta-tools (search_tools, list_tool_names, execute_code)." }) }) })), configQuery.data?.mcpServers &&
|
|
1463
|
-
configQuery.data.mcpServers.length > 0 ? (
|
|
1714
|
+
configQuery.data.mcpServers.length > 0 ? (
|
|
1715
|
+
// Filter to only show selected servers (if mcpServers was provided)
|
|
1716
|
+
// If mcpServers is empty array, show no servers
|
|
1717
|
+
configQuery.data.mcpServers.filter(server => !mcpServers || isServerSelected(server)).length > 0 ? (configQuery.data.mcpServers
|
|
1718
|
+
.filter(server => !mcpServers || isServerSelected(server))
|
|
1719
|
+
.map(server => {
|
|
1464
1720
|
const serverTools = enabledMcpTools.get(server.id);
|
|
1465
1721
|
const allToolNames = server.tools.map(t => t.name);
|
|
1466
1722
|
const enabledCount = serverTools?.size ?? 0;
|
|
@@ -1506,7 +1762,10 @@ onAuthorizationRequired, connectedIdentities, }) {
|
|
|
1506
1762
|
color: 'fg.muted',
|
|
1507
1763
|
fontStyle: 'italic',
|
|
1508
1764
|
}, children: "Server unavailable" }) }))] }, server.id));
|
|
1509
|
-
})) : (_jsx(ActionList.Group, { title: "
|
|
1765
|
+
})) : (_jsx(ActionList.Group, { title: "MCP Servers", children: _jsx(ActionList.Item, { disabled: true, children: _jsx(Text, { sx: {
|
|
1766
|
+
color: 'fg.muted',
|
|
1767
|
+
fontStyle: 'italic',
|
|
1768
|
+
}, children: "No MCP servers selected" }) }) }))) : (_jsx(ActionList.Group, { title: "Available Tools", children: availableTools.length > 0 ? (availableTools.map(tool => (_jsxs(ActionList.Item, { disabled: true, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(Box, { sx: {
|
|
1510
1769
|
width: 8,
|
|
1511
1770
|
height: 8,
|
|
1512
1771
|
borderRadius: '50%',
|
|
@@ -7,11 +7,13 @@ export { ChatMessages, type ChatMessagesProps } from './elements/ChatMessages';
|
|
|
7
7
|
export { ChatInputPrompt, type ChatInputPromptProps, } from './elements/ChatInputPrompt';
|
|
8
8
|
export { ChatSidebar, type ChatSidebarProps } from './ChatSidebar';
|
|
9
9
|
export { ChatStandalone, type ChatStandaloneProps, type MessageHandler, } from './ChatStandalone';
|
|
10
|
-
export { ChatBase, type ChatBaseProps, type ProtocolConfig, } from './base/ChatBase';
|
|
10
|
+
export { ChatBase, type ChatBaseProps, type ProtocolConfig, type AgentRuntimeConfig, type AvatarConfig, type EmptyStateConfig, type HeaderButtonsConfig, type StreamingMessageOptions, } from './base/ChatBase';
|
|
11
11
|
export { AgentDetails, type AgentDetailsProps } from './AgentDetails';
|
|
12
12
|
export { AgentIdentity, IdentityCard, getTokenStatus, formatDuration, formatExpirationStatus, type AgentIdentityProps, type IdentityCardProps, type TokenStatus, } from './AgentIdentity';
|
|
13
13
|
export { ContextUsage, type ContextUsageProps, type ContextDetailsResponse, } from './ContextUsage';
|
|
14
14
|
export { ContextDistribution, type ContextDistributionProps, type ContextSnapshotResponse, } from './ContextDistribution';
|
|
15
|
+
export { ContextPanel, type ContextPanelProps } from './ContextPanel';
|
|
16
|
+
export { ContextInspector, type ContextInspectorProps, type FullContextResponse, } from './ContextInspector';
|
|
15
17
|
export { ToolApprovalDialog, useToolApprovalDialog, type ToolApprovalDialogProps, } from './elements/ToolApprovalDialog';
|
|
16
18
|
export { PoweredByTag, type PoweredByTagProps } from './elements/PoweredByTag';
|
|
17
19
|
export { FloatingBrandButton, type FloatingBrandButtonProps, } from './elements/FloatingBrandButton';
|
|
@@ -16,6 +16,8 @@ export { AgentDetails } from './AgentDetails';
|
|
|
16
16
|
export { AgentIdentity, IdentityCard, getTokenStatus, formatDuration, formatExpirationStatus, } from './AgentIdentity';
|
|
17
17
|
export { ContextUsage, } from './ContextUsage';
|
|
18
18
|
export { ContextDistribution, } from './ContextDistribution';
|
|
19
|
+
export { ContextPanel } from './ContextPanel';
|
|
20
|
+
export { ContextInspector, } from './ContextInspector';
|
|
19
21
|
export { ToolApprovalDialog, useToolApprovalDialog, } from './elements/ToolApprovalDialog';
|
|
20
22
|
export { PoweredByTag } from './elements/PoweredByTag';
|
|
21
23
|
export { FloatingBrandButton, } from './elements/FloatingBrandButton';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { ChatExtension, MessageRendererExtension, ActivityRendererExtension, ToolUIExtension, ProtocolEventExtension, PanelExtension } from '../types/extension';
|
|
8
8
|
/** Internal extension type for registry organization */
|
|
9
|
-
type InternalExtensionType = 'message-renderer' | 'activity-renderer' | 'tool-ui' | 'protocol-event' | 'panel';
|
|
9
|
+
export type InternalExtensionType = 'message-renderer' | 'activity-renderer' | 'tool-ui' | 'protocol-event' | 'panel';
|
|
10
10
|
/**
|
|
11
11
|
* Extension registry class
|
|
12
12
|
*/
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @module components/chat/extensions
|
|
5
5
|
*/
|
|
6
6
|
export { ExtensionRegistry, createMessageRenderer, createActivityRenderer, } from './ExtensionRegistry';
|
|
7
|
+
export type { InternalExtensionType } from './ExtensionRegistry';
|
|
7
8
|
export { createA2UIRenderer, A2UIExtensionImpl, type A2UIMessage, } from './A2UIExtension';
|
|
8
9
|
export { createMCPUIRenderer, MCPUIExtensionImpl, type MCPUIMessage, type MCPUIResource, } from './MCPUIExtension';
|
|
9
10
|
export type { ChatExtension, ExtensionType, MessageRendererExtension, ActivityRendererExtension, ToolUIExtension, ProtocolEventExtension, PanelExtension, A2UIExtension, } from '../types/extension';
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
51
|
export * from './types';
|
|
52
|
-
export { useChatStore, useChatMessages, useChatLoading, useChatStreaming, useChatError, useChatTools, useChatOpen, useChatConfig, useChatReady, useChatInferenceProvider, useChatExtensionRegistry, defaultChatConfig, type ChatStore, type ChatConfig, } from './store';
|
|
52
|
+
export { useChatStore, useChatMessages, useChatLoading, useChatStreaming, useChatError, useChatTools, useChatOpen, useChatConfig, useChatReady, useChatInferenceProvider, useChatExtensionRegistry, defaultChatConfig, type ChatStore, type ChatState, type ChatActions, type ChatConfig, type ToolCallState, } from './store';
|
|
53
53
|
export { useChat, useFrontendTool, useBackendTool, ActionRegistrar, type UseChatReturn, type UseFrontendToolFn, } from '../../hooks';
|
|
54
54
|
export { BaseInferenceProvider, DatalayerInferenceProvider, SelfHostedInferenceProvider, type DatalayerInferenceConfig, type SelfHostedInferenceConfig, } from './inference';
|
|
55
55
|
export { BaseProtocolAdapter, AGUIAdapter, A2AAdapter, ACPAdapter, type AGUIAdapterConfig, type A2AAdapterConfig, type ACPAdapterConfig, type ACPSession, type ACPAgent, type ACPPendingPermission, } from './protocols';
|
|
56
56
|
export { ToolExecutor, type ToolExecutionContext } from './tools';
|
|
57
57
|
export { MiddlewarePipeline, createMiddleware, loggingMiddleware, createHITLMiddleware, type RequestContext, type ResponseContext, } from './middleware';
|
|
58
|
-
export { ExtensionRegistry, createMessageRenderer, createActivityRenderer, createA2UIRenderer, A2UIExtensionImpl, type A2UIMessage, } from './extensions';
|
|
59
|
-
export { ChatMessages, ChatInputPrompt, ChatSidebar, ChatStandalone, ChatBase, ToolApprovalDialog, useToolApprovalDialog, PoweredByTag, FloatingBrandButton, ChatHeader, MessagePart, TextPart, ReasoningPart, ToolPart, DynamicToolPart, ToolCallDisplay, Chat, ChatFloating, AgentDetails, AgentIdentity, IdentityCard, getTokenStatus, formatDuration, formatExpirationStatus, type ChatMessagesProps, type ChatInputPromptProps, type ChatSidebarProps, type ChatStandaloneProps, type MessageHandler, type ChatBaseProps, type ProtocolConfig, type ToolApprovalDialogProps, type PoweredByTagProps, type FloatingBrandButtonProps, type ChatFloatingProps, type ToolCallRenderContext, type ToolCallStatus, type RenderToolResult, type RespondCallback, type Suggestion, type RemoteConfig, type ModelConfig, type BuiltinTool, type MCPServerConfig, type MCPServerTool, type AgentDetailsProps, type AgentIdentityProps, type IdentityCardProps, type TokenStatus, type ChatHeaderProps, type ConnectionState, type MessagePartProps, type TextPartProps, type ReasoningPartProps, type ToolPartProps, type DynamicToolPartProps, type ToolCallDisplayProps, type ChatProps, type Transport, type Extension, } from './components';
|
|
58
|
+
export { ExtensionRegistry, createMessageRenderer, createActivityRenderer, createA2UIRenderer, A2UIExtensionImpl, type A2UIMessage, type InternalExtensionType, } from './extensions';
|
|
59
|
+
export { ChatMessages, ChatInputPrompt, ChatSidebar, ChatStandalone, ChatBase, ToolApprovalDialog, useToolApprovalDialog, PoweredByTag, FloatingBrandButton, ChatHeader, MessagePart, TextPart, ReasoningPart, ToolPart, DynamicToolPart, ToolCallDisplay, Chat, ChatFloating, AgentDetails, AgentIdentity, IdentityCard, getTokenStatus, formatDuration, formatExpirationStatus, type ChatMessagesProps, type ChatInputPromptProps, type ChatSidebarProps, type ChatStandaloneProps, type MessageHandler, type ChatBaseProps, type ProtocolConfig, type AgentRuntimeConfig, type AvatarConfig, type EmptyStateConfig, type HeaderButtonsConfig, type StreamingMessageOptions, type ToolApprovalDialogProps, type PoweredByTagProps, type FloatingBrandButtonProps, type ChatFloatingProps, type ToolCallRenderContext, type ToolCallStatus, type RenderToolResult, type RespondCallback, type Suggestion, type RemoteConfig, type ModelConfig, type BuiltinTool, type MCPServerConfig, type MCPServerTool, type AgentDetailsProps, type AgentIdentityProps, type IdentityCardProps, type TokenStatus, type ChatHeaderProps, type ConnectionState, type MessagePartProps, type TextPartProps, type ReasoningPartProps, type ToolPartProps, type DynamicToolPartProps, type ToolCallDisplayProps, type ChatProps, type Transport, type Extension, } from './components';
|
|
60
60
|
export { requestAPI } from './handler';
|
|
61
61
|
export { useKeyboardShortcuts, useChatKeyboardShortcuts, getShortcutDisplay, type KeyboardShortcut, type UseKeyboardShortcutsOptions, } from '../../hooks';
|