@datalayer/agent-runtimes 0.0.8 → 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.
Files changed (275) hide show
  1. package/README.md +2 -1
  2. package/lib/{examples/components → components}/AgentConfiguration.d.ts +27 -12
  3. package/lib/{examples/components → components}/AgentConfiguration.js +170 -22
  4. package/lib/{examples/components → components}/FooterMetrics.d.ts +1 -2
  5. package/lib/{examples/components → components}/Header.d.ts +1 -6
  6. package/lib/{examples/components → components}/Header.js +5 -39
  7. package/lib/{examples/components → components}/HeaderControls.d.ts +1 -2
  8. package/lib/{examples/components → components}/HeaderControls.js +1 -1
  9. package/lib/{examples/components → components}/LexicalEditor.d.ts +2 -3
  10. package/lib/{examples/components → components}/LexicalEditor.js +2 -2
  11. package/lib/components/MainContent.d.ts +34 -0
  12. package/lib/{examples/components → components}/MainContent.js +18 -9
  13. package/lib/components/McpServerManager.d.ts +30 -0
  14. package/lib/components/McpServerManager.js +331 -0
  15. package/lib/{examples/components → components}/MockFileBrowser.d.ts +1 -2
  16. package/lib/{examples/components → components}/SessionTabs.d.ts +2 -3
  17. package/lib/{examples/components → components}/TimeTravel.d.ts +1 -2
  18. package/lib/components/chat/components/AgentDetails.d.ts +3 -1
  19. package/lib/components/chat/components/AgentDetails.js +323 -31
  20. package/lib/components/chat/components/Chat.d.ts +37 -3
  21. package/lib/components/chat/components/Chat.js +29 -10
  22. package/lib/components/chat/components/ChatFloating.d.ts +27 -2
  23. package/lib/components/chat/components/ChatFloating.js +17 -10
  24. package/lib/components/chat/components/ChatPopupStandalone.js +1 -1
  25. package/lib/components/chat/components/ChatSidebar.d.ts +1 -1
  26. package/lib/components/chat/components/ChatStandalone.d.ts +1 -1
  27. package/lib/components/chat/components/ChatStandalone.js +1 -1
  28. package/lib/components/chat/components/ContextDistribution.d.ts +70 -6
  29. package/lib/components/chat/components/ContextDistribution.js +11 -4
  30. package/lib/components/chat/components/ContextInspector.d.ts +81 -0
  31. package/lib/components/chat/components/ContextInspector.js +261 -0
  32. package/lib/components/chat/components/ContextPanel.d.ts +112 -0
  33. package/lib/components/chat/components/ContextPanel.js +373 -0
  34. package/lib/components/chat/components/base/ChatBase.d.ts +74 -19
  35. package/lib/components/chat/components/base/ChatBase.js +296 -37
  36. package/lib/components/chat/components/index.d.ts +3 -1
  37. package/lib/components/chat/components/index.js +2 -0
  38. package/lib/components/chat/extensions/ExtensionRegistry.d.ts +1 -1
  39. package/lib/components/chat/extensions/index.d.ts +1 -0
  40. package/lib/components/chat/index.d.ts +3 -3
  41. package/lib/components/chat/protocols/AGUIAdapter.js +24 -4
  42. package/lib/components/chat/protocols/VercelAIAdapter.js +35 -1
  43. package/lib/components/chat/store/chatStore.d.ts +2 -3
  44. package/lib/components/chat/store/conversationStore.d.ts +83 -0
  45. package/lib/components/chat/store/conversationStore.js +174 -0
  46. package/lib/components/chat/store/index.d.ts +2 -1
  47. package/lib/components/chat/store/index.js +1 -0
  48. package/lib/components/chat/types/inference.d.ts +17 -0
  49. package/lib/components/chat/types/protocol.d.ts +10 -0
  50. package/lib/components/index.d.ts +23 -0
  51. package/lib/components/index.js +11 -0
  52. package/lib/config/agents.d.ts +33 -0
  53. package/lib/config/agents.js +424 -0
  54. package/lib/config/index.d.ts +4 -0
  55. package/lib/config/index.js +8 -0
  56. package/lib/config/mcpServers.d.ts +18 -0
  57. package/lib/config/mcpServers.js +129 -0
  58. package/lib/config/skills.d.ts +25 -0
  59. package/lib/config/skills.js +54 -0
  60. package/lib/{lib → config}/utils.d.ts +1 -1
  61. package/lib/{lib → config}/utils.js +2 -2
  62. package/lib/examples/AgentRuntimeLexical2Example.d.ts +1 -0
  63. package/lib/examples/AgentRuntimeLexical2Example.js +3 -2
  64. package/lib/examples/AgentRuntimeLexicalExample.d.ts +1 -0
  65. package/lib/examples/AgentRuntimeLexicalExample.js +5 -3
  66. package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +1 -0
  67. package/lib/examples/AgentRuntimeLexicalSidebarExample.js +3 -3
  68. package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
  69. package/lib/examples/AgentSpaceFormExample.d.ts +2 -2
  70. package/lib/examples/AgentSpaceFormExample.js +167 -29
  71. package/lib/examples/CopilotKitLexicalExample.d.ts +1 -0
  72. package/lib/examples/CopilotKitLexicalExample.js +3 -2
  73. package/lib/examples/index.d.ts +1 -0
  74. package/lib/examples/stores/notebooks/NotebookExample2.ipynb.json +43 -43
  75. package/lib/hooks/useAGUI.d.ts +1 -1
  76. package/lib/hooks/useAGUI.js +1 -1
  77. package/lib/identity/types.d.ts +1 -1
  78. package/lib/index.d.ts +2 -0
  79. package/lib/index.js +1 -0
  80. package/lib/runtime/index.d.ts +3 -0
  81. package/lib/runtime/runtimeStore.d.ts +3 -4
  82. package/lib/runtime/useAgentConnection.d.ts +2 -3
  83. package/lib/runtime/useAgentRuntime.d.ts +2 -3
  84. package/lib/stories/Cell.stories.js +1 -1
  85. package/lib/tools/adapters/agent-runtimes/notebookHooks.js +1 -0
  86. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -0
  87. package/lib/types.d.ts +150 -0
  88. package/package.json +4 -5
  89. package/scripts/apply-patches.sh +32 -0
  90. package/scripts/codegen/generate_agents.py +452 -0
  91. package/scripts/codegen/generate_mcp_servers.py +424 -0
  92. package/scripts/codegen/generate_skills.py +321 -0
  93. package/scripts/download-ai-elements.py +35 -20
  94. package/scripts/sync-jupyter.sh +6 -0
  95. package/lib/components/ui/accordion.d.ts +0 -7
  96. package/lib/components/ui/accordion.js +0 -22
  97. package/lib/components/ui/alert-dialog.d.ts +0 -14
  98. package/lib/components/ui/alert-dialog.js +0 -43
  99. package/lib/components/ui/alert.d.ts +0 -9
  100. package/lib/components/ui/alert.js +0 -24
  101. package/lib/components/ui/aspect-ratio.d.ts +0 -3
  102. package/lib/components/ui/aspect-ratio.js +0 -11
  103. package/lib/components/ui/avatar.d.ts +0 -6
  104. package/lib/components/ui/avatar.js +0 -18
  105. package/lib/components/ui/badge.d.ts +0 -9
  106. package/lib/components/ui/badge.js +0 -22
  107. package/lib/components/ui/breadcrumb.d.ts +0 -11
  108. package/lib/components/ui/breadcrumb.js +0 -27
  109. package/lib/components/ui/button-group.d.ts +0 -11
  110. package/lib/components/ui/button-group.js +0 -31
  111. package/lib/components/ui/button.d.ts +0 -13
  112. package/lib/components/ui/button.js +0 -39
  113. package/lib/components/ui/calendar.d.ts +0 -8
  114. package/lib/components/ui/calendar.js +0 -80
  115. package/lib/components/ui/card.d.ts +0 -9
  116. package/lib/components/ui/card.js +0 -24
  117. package/lib/components/ui/carousel.d.ts +0 -19
  118. package/lib/components/ui/carousel.js +0 -95
  119. package/lib/components/ui/chart.d.ts +0 -53
  120. package/lib/components/ui/chart.js +0 -136
  121. package/lib/components/ui/checkbox.d.ts +0 -4
  122. package/lib/components/ui/checkbox.js +0 -13
  123. package/lib/components/ui/collapsible.d.ts +0 -5
  124. package/lib/components/ui/collapsible.js +0 -17
  125. package/lib/components/ui/command.d.ts +0 -18
  126. package/lib/components/ui/command.js +0 -38
  127. package/lib/components/ui/context-menu.d.ts +0 -25
  128. package/lib/components/ui/context-menu.js +0 -55
  129. package/lib/components/ui/dialog.d.ts +0 -15
  130. package/lib/components/ui/dialog.js +0 -40
  131. package/lib/components/ui/drawer.d.ts +0 -13
  132. package/lib/components/ui/drawer.js +0 -39
  133. package/lib/components/ui/dropdown-menu.d.ts +0 -25
  134. package/lib/components/ui/dropdown-menu.js +0 -55
  135. package/lib/components/ui/empty.d.ts +0 -11
  136. package/lib/components/ui/empty.js +0 -37
  137. package/lib/components/ui/field.d.ts +0 -24
  138. package/lib/components/ui/field.js +0 -80
  139. package/lib/components/ui/form.d.ts +0 -24
  140. package/lib/components/ui/form.js +0 -63
  141. package/lib/components/ui/hover-card.d.ts +0 -6
  142. package/lib/components/ui/hover-card.js +0 -18
  143. package/lib/components/ui/input-group.d.ts +0 -19
  144. package/lib/components/ui/input-group.js +0 -69
  145. package/lib/components/ui/input-otp.d.ts +0 -11
  146. package/lib/components/ui/input-otp.js +0 -25
  147. package/lib/components/ui/input.d.ts +0 -3
  148. package/lib/components/ui/input.js +0 -6
  149. package/lib/components/ui/item.d.ts +0 -23
  150. package/lib/components/ui/item.js +0 -66
  151. package/lib/components/ui/kbd.d.ts +0 -3
  152. package/lib/components/ui/kbd.js +0 -13
  153. package/lib/components/ui/label.d.ts +0 -4
  154. package/lib/components/ui/label.js +0 -12
  155. package/lib/components/ui/menubar.d.ts +0 -26
  156. package/lib/components/ui/menubar.js +0 -58
  157. package/lib/components/ui/navigation-menu.d.ts +0 -14
  158. package/lib/components/ui/navigation-menu.js +0 -31
  159. package/lib/components/ui/pagination.d.ts +0 -13
  160. package/lib/components/ui/pagination.js +0 -29
  161. package/lib/components/ui/popover.d.ts +0 -7
  162. package/lib/components/ui/popover.js +0 -21
  163. package/lib/components/ui/progress.d.ts +0 -4
  164. package/lib/components/ui/progress.js +0 -12
  165. package/lib/components/ui/radio-group.d.ts +0 -5
  166. package/lib/components/ui/radio-group.js +0 -16
  167. package/lib/components/ui/resizable.d.ts +0 -8
  168. package/lib/components/ui/resizable.js +0 -19
  169. package/lib/components/ui/scroll-area.d.ts +0 -5
  170. package/lib/components/ui/scroll-area.js +0 -17
  171. package/lib/components/ui/select.d.ts +0 -15
  172. package/lib/components/ui/select.js +0 -42
  173. package/lib/components/ui/separator.d.ts +0 -4
  174. package/lib/components/ui/separator.js +0 -12
  175. package/lib/components/ui/sheet.d.ts +0 -13
  176. package/lib/components/ui/sheet.js +0 -44
  177. package/lib/components/ui/sidebar.d.ts +0 -69
  178. package/lib/components/ui/sidebar.js +0 -216
  179. package/lib/components/ui/skeleton.d.ts +0 -2
  180. package/lib/components/ui/skeleton.js +0 -10
  181. package/lib/components/ui/slider.d.ts +0 -4
  182. package/lib/components/ui/slider.js +0 -18
  183. package/lib/components/ui/sonner.d.ts +0 -3
  184. package/lib/components/ui/sonner.js +0 -25
  185. package/lib/components/ui/spinner.d.ts +0 -2
  186. package/lib/components/ui/spinner.js +0 -11
  187. package/lib/components/ui/switch.d.ts +0 -4
  188. package/lib/components/ui/switch.js +0 -12
  189. package/lib/components/ui/table.d.ts +0 -10
  190. package/lib/components/ui/table.js +0 -32
  191. package/lib/components/ui/tabs.d.ts +0 -7
  192. package/lib/components/ui/tabs.js +0 -21
  193. package/lib/components/ui/textarea.d.ts +0 -3
  194. package/lib/components/ui/textarea.js +0 -6
  195. package/lib/components/ui/toast.d.ts +0 -15
  196. package/lib/components/ui/toast.js +0 -38
  197. package/lib/components/ui/toaster.d.ts +0 -1
  198. package/lib/components/ui/toaster.js +0 -14
  199. package/lib/components/ui/toggle-group.d.ts +0 -9
  200. package/lib/components/ui/toggle-group.js +0 -26
  201. package/lib/components/ui/toggle.d.ts +0 -9
  202. package/lib/components/ui/toggle.js +0 -30
  203. package/lib/components/ui/tooltip.d.ts +0 -7
  204. package/lib/components/ui/tooltip.js +0 -21
  205. package/lib/components/vercel-ai-elements/artifact.d.ts +0 -23
  206. package/lib/components/vercel-ai-elements/artifact.js +0 -24
  207. package/lib/components/vercel-ai-elements/code-block.d.ts +0 -17
  208. package/lib/components/vercel-ai-elements/code-block.js +0 -94
  209. package/lib/components/vercel-ai-elements/conversation.d.ts +0 -15
  210. package/lib/components/vercel-ai-elements/conversation.js +0 -21
  211. package/lib/components/vercel-ai-elements/loader.d.ts +0 -5
  212. package/lib/components/vercel-ai-elements/loader.js +0 -8
  213. package/lib/components/vercel-ai-elements/message.d.ts +0 -46
  214. package/lib/components/vercel-ai-elements/message.js +0 -109
  215. package/lib/components/vercel-ai-elements/model-selector.d.ts +0 -35
  216. package/lib/components/vercel-ai-elements/model-selector.js +0 -22
  217. package/lib/components/vercel-ai-elements/prompt-input.d.ts +0 -195
  218. package/lib/components/vercel-ai-elements/prompt-input.js +0 -589
  219. package/lib/components/vercel-ai-elements/reasoning.d.ts +0 -26
  220. package/lib/components/vercel-ai-elements/reasoning.js +0 -80
  221. package/lib/components/vercel-ai-elements/shimmer.d.ts +0 -9
  222. package/lib/components/vercel-ai-elements/shimmer.js +0 -22
  223. package/lib/components/vercel-ai-elements/sources.d.ts +0 -12
  224. package/lib/components/vercel-ai-elements/sources.js +0 -13
  225. package/lib/components/vercel-ai-elements/suggestion.d.ts +0 -10
  226. package/lib/components/vercel-ai-elements/suggestion.js +0 -16
  227. package/lib/components/vercel-ai-elements/tool.d.ts +0 -23
  228. package/lib/components/vercel-ai-elements/tool.js +0 -52
  229. package/lib/examples/components/MainContent.d.ts +0 -19
  230. package/lib/examples/components/index.d.ts +0 -10
  231. package/lib/examples/components/index.js +0 -13
  232. package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.d.ts +0 -12
  233. package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.js +0 -69
  234. package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.d.ts +0 -1
  235. package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.js +0 -85
  236. package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.d.ts +0 -1
  237. package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.js +0 -62
  238. package/lib/examples/vercel-ai-elements/components/ConversationShowcase.d.ts +0 -1
  239. package/lib/examples/vercel-ai-elements/components/ConversationShowcase.js +0 -51
  240. package/lib/examples/vercel-ai-elements/components/LoaderShowcase.d.ts +0 -1
  241. package/lib/examples/vercel-ai-elements/components/LoaderShowcase.js +0 -9
  242. package/lib/examples/vercel-ai-elements/components/MessageShowcase.d.ts +0 -1
  243. package/lib/examples/vercel-ai-elements/components/MessageShowcase.js +0 -56
  244. package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.d.ts +0 -1
  245. package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.js +0 -50
  246. package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.d.ts +0 -1
  247. package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.js +0 -16
  248. package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.d.ts +0 -1
  249. package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.js +0 -72
  250. package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.d.ts +0 -1
  251. package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.js +0 -9
  252. package/lib/examples/vercel-ai-elements/components/SourcesShowcase.d.ts +0 -1
  253. package/lib/examples/vercel-ai-elements/components/SourcesShowcase.js +0 -43
  254. package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.d.ts +0 -1
  255. package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.js +0 -31
  256. package/lib/examples/vercel-ai-elements/components/ToolShowcase.d.ts +0 -1
  257. package/lib/examples/vercel-ai-elements/components/ToolShowcase.js +0 -54
  258. package/lib/examples/vercel-ai-elements/index.d.ts +0 -13
  259. package/lib/examples/vercel-ai-elements/index.js +0 -17
  260. package/lib/examples/vercel-ai-elements/main.d.ts +0 -1
  261. package/lib/examples/vercel-ai-elements/main.js +0 -9
  262. package/lib/examples/vercel-ai-elements/showcase.css +0 -128
  263. package/lib/hooks/useToast.d.ts +0 -44
  264. package/lib/hooks/useToast.js +0 -128
  265. package/patches/@datalayer+jupyter-lexical+1.0.8.patch +0 -11628
  266. package/patches/@datalayer+jupyter-react+2.0.2.patch +0 -5338
  267. package/style/showcase-vercel-ai.css +0 -137
  268. /package/lib/{examples/components → components}/FooterMetrics.js +0 -0
  269. /package/lib/{examples/components → components}/MockFileBrowser.js +0 -0
  270. /package/lib/{examples/components → components}/SessionTabs.js +0 -0
  271. /package/lib/{examples/components → components}/TimeTravel.js +0 -0
  272. /package/lib/{models → types}/AIAgent.d.ts +0 -0
  273. /package/lib/{models → types}/AIAgent.js +0 -0
  274. /package/lib/{models → types}/index.d.ts +0 -0
  275. /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, initialMcpServers, initialSkills, className, loadingState, headerActions,
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, initialMcpServers: initialMcpServers, initialSkills: initialSkills, className: className, loadingState: loadingState, headerActions: headerActions, useStore: useStoreMode, 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 }) }));
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, initialMcpServers: initialMcpServers, initialSkills: initialSkills, className: className, loadingState: loadingState, headerActions: headerActions, useStore: useStoreMode, 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 }));
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, initialMcpServers, initialSkills, className, loadingState, headerActions,
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 config
333
- const modelExists = configQuery.data.models.some(m => m.id === initialModel);
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 = configQuery.data.models.find(m => m.isAvailable !== false);
340
- const firstModel = firstAvailableModel || configQuery.data.models[0];
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 = configQuery.data.models.find(m => m.isAvailable !== false);
349
- const firstModel = firstAvailableModel || configQuery.data.models[0];
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.builtinTools?.map(tool => tool.id) || [];
445
+ const allToolIds = configQuery.data?.builtinTools?.map(tool => tool.id) || [];
355
446
  setEnabledTools(allToolIds);
356
447
  // Initialize MCP server tools
357
- if (configQuery.data.mcpServers) {
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 initialMcpServers is provided, only enable those servers
452
+ // If mcpServers is provided, only enable those servers
362
453
  // If not provided, enable all available servers
363
- const shouldEnableServer = initialMcpServers
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
- }, [configQuery.data, selectedModel, initialModel, initialMcpServers]);
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
- tools.forEach(toolName => toolNames.push(toolName));
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 ? 'accent.emphasis' : '#f6f8fa',
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: '#e1e4e8',
1533
+ backgroundColor: 'canvas.subtle',
1283
1534
  padding: '8px 12px',
1284
1535
  fontSize: '12px',
1285
- color: '#586069',
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: '#586069',
1544
+ color: 'fg.muted',
1294
1545
  borderRadius: '4px',
1295
1546
  '&:hover': {
1296
- backgroundColor: 'rgba(0,0,0,0.1)',
1297
- color: '#24292e',
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: '#f6f8fa',
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 ? (configQuery.data.mcpServers.map(server => {
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: "Available Tools", children: availableTools.length > 0 ? (availableTools.map(tool => (_jsxs(ActionList.Item, { disabled: true, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(Box, { sx: {
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';