@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.
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 +1 -1
  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
@@ -1,18 +1,27 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  // Copyright (c) 2025-2026 Datalayer, Inc.
3
3
  // Distributed under the terms of the Modified BSD License.
4
4
  /**
5
5
  * AgentDetails component - Shows detailed information about the agent
6
6
  * including name, protocol, URL, message count, and context details.
7
7
  */
8
- import { ArrowLeftIcon, GlobeIcon, CommentDiscussionIcon, CheckCircleIcon, XCircleIcon, } from '@primer/octicons-react';
9
- import { Box, Button, Heading, IconButton, Text, Label, Spinner, } from '@primer/react';
8
+ import { ArrowLeftIcon, CheckCircleIcon, XCircleIcon, CodeIcon, ZapIcon, DownloadIcon, } from '@primer/octicons-react';
9
+ import { Button, Heading, IconButton, Text, Label, Spinner, ToggleSwitch, } from '@primer/react';
10
+ import { Box } from '@datalayer/primer-addons';
10
11
  import { AiAgentIcon } from '@datalayer/icons-react';
11
- import { useQuery } from '@tanstack/react-query';
12
- import { ContextUsage } from './ContextUsage';
13
- import { ContextDistribution } from './ContextDistribution';
12
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
13
+ import { ContextPanel } from './ContextPanel';
14
+ import { ContextInspector } from './ContextInspector';
14
15
  import { AgentIdentity } from './AgentIdentity';
15
- function getLocalApiBase() {
16
+ /**
17
+ * Get the API base URL for fetching data.
18
+ * If apiBase prop is provided, use it.
19
+ * Otherwise, fall back to localhost for local development.
20
+ */
21
+ function getApiBase(apiBase) {
22
+ if (apiBase) {
23
+ return apiBase;
24
+ }
16
25
  if (typeof window === 'undefined') {
17
26
  return '';
18
27
  }
@@ -21,16 +30,155 @@ function getLocalApiBase() {
21
30
  ? 'http://127.0.0.1:8765'
22
31
  : '';
23
32
  }
33
+ /**
34
+ * Convert context snapshot data to CSV format and trigger download
35
+ */
36
+ async function downloadContextSnapshotAsCSV(agentId, apiBase) {
37
+ const base = getApiBase(apiBase);
38
+ const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/full-context`);
39
+ if (!response.ok) {
40
+ throw new Error('Failed to fetch context snapshot');
41
+ }
42
+ const data = await response.json();
43
+ const rows = [];
44
+ // Header section
45
+ rows.push(['Context Snapshot for Agent', data.agentId]);
46
+ rows.push(['Generated At', new Date().toISOString()]);
47
+ rows.push([]);
48
+ // Model Configuration
49
+ rows.push(['=== Model Configuration ===']);
50
+ rows.push([
51
+ 'Model Name',
52
+ data.modelConfiguration?.modelName || 'Not specified',
53
+ ]);
54
+ rows.push([
55
+ 'Context Window',
56
+ String(data.modelConfiguration?.contextWindow || 0),
57
+ ]);
58
+ rows.push([]);
59
+ // Token Summary
60
+ rows.push(['=== Token Summary ===']);
61
+ rows.push(['Category', 'Tokens']);
62
+ rows.push(['System Prompts', String(data.tokenSummary?.systemPrompts || 0)]);
63
+ rows.push(['Tools', String(data.tokenSummary?.tools || 0)]);
64
+ rows.push(['Memory', String(data.tokenSummary?.memory || 0)]);
65
+ rows.push(['History', String(data.tokenSummary?.history || 0)]);
66
+ rows.push(['Current', String(data.tokenSummary?.current || 0)]);
67
+ rows.push(['Total', String(data.tokenSummary?.total || 0)]);
68
+ rows.push(['Context Window', String(data.tokenSummary?.contextWindow || 0)]);
69
+ rows.push([
70
+ 'Usage Percent',
71
+ `${(data.tokenSummary?.usagePercent || 0).toFixed(2)}%`,
72
+ ]);
73
+ rows.push([]);
74
+ // System Prompts
75
+ if (data.systemPrompts?.length > 0) {
76
+ rows.push(['=== System Prompts ===']);
77
+ rows.push(['Index', 'Tokens', 'Content']);
78
+ data.systemPrompts.forEach((prompt, idx) => {
79
+ rows.push([
80
+ String(idx + 1),
81
+ String(prompt.tokens),
82
+ prompt.content.replace(/"/g, '""'),
83
+ ]);
84
+ });
85
+ rows.push([]);
86
+ }
87
+ // Tools
88
+ if (data.tools?.length > 0) {
89
+ rows.push(['=== Tools ===']);
90
+ rows.push([
91
+ 'Name',
92
+ 'Description',
93
+ 'Source Type',
94
+ 'Is Async',
95
+ 'Requires Approval',
96
+ 'Total Tokens',
97
+ ]);
98
+ data.tools.forEach(tool => {
99
+ rows.push([
100
+ tool.name,
101
+ (tool.description || '').replace(/"/g, '""'),
102
+ tool.sourceType,
103
+ String(tool.isAsync),
104
+ String(tool.requiresApproval),
105
+ String(tool.totalTokens),
106
+ ]);
107
+ });
108
+ rows.push([]);
109
+ }
110
+ // Messages
111
+ if (data.messages?.length > 0) {
112
+ rows.push(['=== Messages ===']);
113
+ rows.push([
114
+ 'Role',
115
+ 'In Context',
116
+ 'Estimated Tokens',
117
+ 'Tool Name',
118
+ 'Is Tool Call',
119
+ 'Is Tool Result',
120
+ 'Timestamp',
121
+ 'Content',
122
+ ]);
123
+ data.messages.forEach(msg => {
124
+ rows.push([
125
+ msg.role,
126
+ String(msg.inContext),
127
+ String(msg.estimatedTokens),
128
+ msg.toolName || '',
129
+ String(msg.isToolCall),
130
+ String(msg.isToolResult),
131
+ msg.timestamp || '',
132
+ msg.content.replace(/"/g, '""'),
133
+ ]);
134
+ });
135
+ rows.push([]);
136
+ }
137
+ // Memory Blocks
138
+ if (data.memoryBlocks?.length > 0) {
139
+ rows.push(['=== Memory Blocks ===']);
140
+ rows.push(['Index', 'Content (JSON)']);
141
+ data.memoryBlocks.forEach((block, idx) => {
142
+ rows.push([String(idx + 1), JSON.stringify(block).replace(/"/g, '""')]);
143
+ });
144
+ rows.push([]);
145
+ }
146
+ // Tool Environment
147
+ if (data.toolEnvironment && Object.keys(data.toolEnvironment).length > 0) {
148
+ rows.push(['=== Tool Environment ===']);
149
+ rows.push(['Key', 'Value']);
150
+ Object.entries(data.toolEnvironment).forEach(([key, value]) => {
151
+ rows.push([key, value]);
152
+ });
153
+ rows.push([]);
154
+ }
155
+ // Convert to CSV string
156
+ const csvContent = rows
157
+ .map(row => row.map(cell => `"${cell}"`).join(','))
158
+ .join('\n');
159
+ // Create and trigger download
160
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
161
+ const link = document.createElement('a');
162
+ const url = URL.createObjectURL(blob);
163
+ link.setAttribute('href', url);
164
+ link.setAttribute('download', `context-snapshot-${agentId}-${new Date().toISOString().slice(0, 10)}.csv`);
165
+ link.style.visibility = 'hidden';
166
+ document.body.appendChild(link);
167
+ link.click();
168
+ document.body.removeChild(link);
169
+ URL.revokeObjectURL(url);
170
+ }
24
171
  /**
25
172
  * AgentDetails component displays comprehensive information about the agent.
26
173
  */
27
- export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, agentId, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, }) {
174
+ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, }) {
175
+ const queryClient = useQueryClient();
28
176
  // Fetch MCP toolsets status
29
177
  const { data: mcpStatus, isLoading: mcpLoading } = useQuery({
30
- queryKey: ['mcp-toolsets-status'],
178
+ queryKey: ['mcp-toolsets-status', apiBase],
31
179
  queryFn: async () => {
32
- const apiBase = getLocalApiBase();
33
- const response = await fetch(`${apiBase}/api/v1/configure/mcp-toolsets-status`);
180
+ const base = getApiBase(apiBase);
181
+ const response = await fetch(`${base}/api/v1/configure/mcp-toolsets-status`);
34
182
  if (!response.ok) {
35
183
  throw new Error('Failed to fetch MCP status');
36
184
  }
@@ -38,6 +186,40 @@ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, a
38
186
  },
39
187
  refetchInterval: 5000, // Refresh every 5 seconds
40
188
  });
189
+ // Fetch Codemode status
190
+ const { data: codemodeStatus, isLoading: codemodeLoading } = useQuery({
191
+ queryKey: ['codemode-status', apiBase],
192
+ queryFn: async () => {
193
+ const base = getApiBase(apiBase);
194
+ const response = await fetch(`${base}/api/v1/configure/codemode-status`);
195
+ if (!response.ok) {
196
+ throw new Error('Failed to fetch Codemode status');
197
+ }
198
+ return response.json();
199
+ },
200
+ refetchInterval: 5000, // Refresh every 5 seconds
201
+ });
202
+ // Mutation to toggle codemode
203
+ const toggleCodemodeMutation = useMutation({
204
+ mutationFn: async (enabled) => {
205
+ const base = getApiBase(apiBase);
206
+ const response = await fetch(`${base}/api/v1/configure/codemode/toggle`, {
207
+ method: 'POST',
208
+ headers: {
209
+ 'Content-Type': 'application/json',
210
+ },
211
+ body: JSON.stringify({ enabled }),
212
+ });
213
+ if (!response.ok) {
214
+ throw new Error('Failed to toggle codemode');
215
+ }
216
+ return response.json();
217
+ },
218
+ onSuccess: () => {
219
+ // Invalidate the codemode status query to refetch
220
+ queryClient.invalidateQueries({ queryKey: ['codemode-status'] });
221
+ },
222
+ });
41
223
  return (_jsxs(Box, { sx: {
42
224
  display: 'flex',
43
225
  flexDirection: 'column',
@@ -64,7 +246,7 @@ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, a
64
246
  p: 2,
65
247
  bg: 'accent.subtle',
66
248
  borderRadius: 2,
67
- }, children: _jsx(AiAgentIcon, { colored: true, size: 32 }) }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, fontWeight: 'semibold', mb: 1 }, children: name }), _jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center' }, children: [_jsx(Label, { variant: "accent", size: "small", children: protocol.toUpperCase().replace(/-/g, ' ') }), agentId && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["ID: ", agentId] }))] })] })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
249
+ }, children: _jsx(AiAgentIcon, { colored: true, size: 32 }) }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, fontWeight: 'semibold', mb: 1 }, children: name }), agentId && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["ID: ", agentId] }))] })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
68
250
  fontSize: 1,
69
251
  fontWeight: 'semibold',
70
252
  mb: 2,
@@ -75,7 +257,7 @@ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, a
75
257
  borderRadius: 2,
76
258
  border: '1px solid',
77
259
  borderColor: 'border.default',
78
- }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(GlobeIcon, { size: 16 }), _jsx(Text, { sx: {
260
+ }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Label, { variant: "accent", size: "small", children: protocol.toUpperCase().replace(/-/g, ' ') }), _jsx(Text, { sx: {
79
261
  fontSize: 1,
80
262
  fontFamily: 'mono',
81
263
  wordBreak: 'break-all',
@@ -84,21 +266,7 @@ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, a
84
266
  fontWeight: 'semibold',
85
267
  mb: 2,
86
268
  color: 'fg.muted',
87
- }, children: "Conversation" }), _jsxs(Box, { sx: {
88
- p: 3,
89
- bg: 'canvas.subtle',
90
- borderRadius: 2,
91
- border: '1px solid',
92
- borderColor: 'border.default',
93
- display: 'flex',
94
- alignItems: 'center',
95
- gap: 2,
96
- }, children: [_jsx(CommentDiscussionIcon, { size: 16 }), _jsxs(Text, { sx: { fontSize: 1 }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'semibold' }, children: messageCount }), ' ', messageCount === 1 ? 'message' : 'messages'] })] })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
97
- fontSize: 1,
98
- fontWeight: 'semibold',
99
- mb: 2,
100
- color: 'fg.muted',
101
- }, children: "MCP Toolsets" }), _jsx(Box, { sx: {
269
+ }, children: "Config MCP Servers" }), _jsx(Box, { sx: {
102
270
  p: 3,
103
271
  bg: 'canvas.subtle',
104
272
  borderRadius: 2,
@@ -133,17 +301,141 @@ export function AgentDetails({ name = 'AI Agent', protocol, url, messageCount, a
133
301
  pl: 4,
134
302
  whiteSpace: 'pre-wrap',
135
303
  wordBreak: 'break-word',
136
- }, children: error.split('\n')[0] })] }, server)))] }))] })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load MCP status" })) })] }), agentId && _jsx(ContextUsage, { agentId: agentId }), agentId && (_jsxs(Box, { sx: { mt: 3 }, children: [_jsx(Heading, { as: "h4", sx: {
304
+ }, children: error.split('\n')[0] })] }, server)))] }))] })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load MCP status" })) })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
137
305
  fontSize: 1,
138
306
  fontWeight: 'semibold',
139
307
  mb: 2,
140
308
  color: 'fg.muted',
141
- }, children: "Current Context Distribution" }), _jsx(Box, { sx: {
309
+ }, children: "Codemode" }), _jsx(Box, { sx: {
310
+ p: 3,
311
+ bg: 'canvas.subtle',
312
+ borderRadius: 2,
313
+ border: '1px solid',
314
+ borderColor: 'border.default',
315
+ }, children: codemodeLoading ? (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading Codemode status..." })] })) : codemodeStatus ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs(Box, { sx: {
316
+ display: 'flex',
317
+ alignItems: 'center',
318
+ justifyContent: 'space-between',
319
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(CodeIcon, { size: 16 }), _jsxs(Box, { children: [_jsx(Text, { id: "codemode-toggle-label", sx: { fontSize: 1, fontWeight: 'semibold' }, children: "Codemode" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', marginLeft: 1 }, children: "MCP servers become programmatic tools" })] })] }), _jsx(ToggleSwitch, { "aria-labelledby": "codemode-toggle-label", checked: codemodeStatus.enabled, onClick: () => toggleCodemodeMutation.mutate(!codemodeStatus.enabled), disabled: toggleCodemodeMutation.isPending, size: "small" })] }), codemodeStatus.sandbox && (_jsxs(Box, { sx: {
320
+ display: 'flex',
321
+ flexDirection: 'column',
322
+ gap: 2,
323
+ p: 2,
324
+ bg: 'canvas.default',
325
+ borderRadius: 2,
326
+ border: '1px solid',
327
+ borderColor: 'border.default',
328
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(CodeIcon, { size: 16 }), _jsx(Text, { sx: {
329
+ fontSize: 0,
330
+ fontWeight: 'semibold',
331
+ color: 'fg.muted',
332
+ }, children: "Code Sandbox" })] }), _jsxs(Box, { sx: {
333
+ display: 'flex',
334
+ flexDirection: 'column',
335
+ gap: 1,
336
+ pl: 4,
337
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Variant:" }), _jsx(Label, { variant: codemodeStatus.sandbox.variant === 'local-jupyter'
338
+ ? 'accent'
339
+ : 'secondary', size: "small", children: codemodeStatus.sandbox.variant })] }), codemodeStatus.sandbox.variant === 'local-jupyter' && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
340
+ display: 'flex',
341
+ alignItems: 'center',
342
+ gap: 2,
343
+ }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "URL:" }), _jsx(Text, { sx: {
344
+ fontSize: 0,
345
+ fontFamily: 'mono',
346
+ color: 'fg.default',
347
+ overflow: 'hidden',
348
+ textOverflow: 'ellipsis',
349
+ whiteSpace: 'nowrap',
350
+ }, children: codemodeStatus.sandbox.jupyter_url ||
351
+ 'Not configured' })] }), _jsxs(Box, { sx: {
352
+ display: 'flex',
353
+ alignItems: 'center',
354
+ gap: 2,
355
+ }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Status:" }), codemodeStatus.sandbox.jupyter_connected ? (_jsxs(Box, { sx: {
356
+ display: 'flex',
357
+ alignItems: 'center',
358
+ gap: 1,
359
+ }, children: [_jsx(CheckCircleIcon, { size: 12, fill: "success.fg" }), _jsx(Text, { sx: { fontSize: 0, color: 'success.fg' }, children: "Connected" })] })) : (_jsxs(Box, { sx: {
360
+ display: 'flex',
361
+ flexDirection: 'column',
362
+ gap: 1,
363
+ }, children: [_jsxs(Box, { sx: {
364
+ display: 'flex',
365
+ alignItems: 'center',
366
+ gap: 1,
367
+ }, children: [_jsx(XCircleIcon, { size: 12, fill: "danger.fg" }), _jsx(Text, { sx: { fontSize: 0, color: 'danger.fg' }, children: "Not Connected" })] }), codemodeStatus.sandbox.jupyter_error && (_jsx(Text, { sx: {
368
+ fontSize: 0,
369
+ color: 'danger.fg',
370
+ fontFamily: 'mono',
371
+ whiteSpace: 'pre-wrap',
372
+ wordBreak: 'break-word',
373
+ }, children: codemodeStatus.sandbox.jupyter_error }))] }))] })] })), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Running:" }), codemodeStatus.sandbox.sandbox_running ? (_jsxs(Box, { sx: {
374
+ display: 'flex',
375
+ alignItems: 'center',
376
+ gap: 1,
377
+ }, children: [_jsx(CheckCircleIcon, { size: 12, fill: "success.fg" }), _jsx(Text, { sx: { fontSize: 0, color: 'success.fg' }, children: "Yes" })] })) : (_jsxs(Box, { sx: {
378
+ display: 'flex',
379
+ alignItems: 'center',
380
+ gap: 1,
381
+ }, children: [_jsx(XCircleIcon, { size: 12, fill: "fg.muted" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No" })] }))] }), codemodeStatus.sandbox.generated_path && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Generated:" }), _jsx(Text, { sx: {
382
+ fontSize: 0,
383
+ fontFamily: 'mono',
384
+ color: 'fg.default',
385
+ overflow: 'hidden',
386
+ textOverflow: 'ellipsis',
387
+ whiteSpace: 'nowrap',
388
+ }, title: codemodeStatus.sandbox.generated_path, children: codemodeStatus.sandbox.generated_path })] })), codemodeStatus.sandbox.skills_path && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Skills:" }), _jsx(Text, { sx: {
389
+ fontSize: 0,
390
+ fontFamily: 'mono',
391
+ color: 'fg.default',
392
+ overflow: 'hidden',
393
+ textOverflow: 'ellipsis',
394
+ whiteSpace: 'nowrap',
395
+ }, title: codemodeStatus.sandbox.skills_path, children: codemodeStatus.sandbox.skills_path })] })), codemodeStatus.sandbox.python_path && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Python Path:" }), _jsx(Text, { sx: {
396
+ fontSize: 0,
397
+ fontFamily: 'mono',
398
+ color: 'fg.default',
399
+ overflow: 'hidden',
400
+ textOverflow: 'ellipsis',
401
+ whiteSpace: 'nowrap',
402
+ }, title: codemodeStatus.sandbox.python_path, children: codemodeStatus.sandbox.python_path })] }))] })] })), codemodeStatus.skills.length > 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ZapIcon, { size: 16 }), _jsxs(Text, { sx: {
403
+ fontSize: 0,
404
+ fontWeight: 'semibold',
405
+ color: 'fg.muted',
406
+ }, children: ["Active Skills (", codemodeStatus.skills.length, ")"] })] }), codemodeStatus.skills.map(skill => (_jsxs(Box, { sx: {
407
+ display: 'flex',
408
+ flexDirection: 'column',
409
+ gap: 1,
410
+ pl: 4,
411
+ py: 1,
412
+ borderLeft: '2px solid',
413
+ borderColor: 'accent.emphasis',
414
+ }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: skill.name }), skill.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: skill.description })), skill.tags && skill.tags.length > 0 && (_jsx(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: skill.tags.map(tag => (_jsx(Label, { variant: "secondary", size: "small", children: tag }, tag))) }))] }, skill.name)))] })), codemodeStatus.available_skills.length > 0 &&
415
+ codemodeStatus.skills.length === 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsxs(Text, { sx: {
416
+ fontSize: 0,
417
+ fontWeight: 'semibold',
418
+ color: 'fg.muted',
419
+ }, children: ["Available Skills (", codemodeStatus.available_skills.length, ")"] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Enable skills via CLI with --skills flag" }), _jsx(Box, { sx: {
420
+ display: 'flex',
421
+ gap: 1,
422
+ flexWrap: 'wrap',
423
+ mt: 1,
424
+ }, children: codemodeStatus.available_skills.map(skill => (_jsx(Label, { variant: "secondary", size: "small", children: skill.name }, skill.name))) })] })), codemodeStatus.available_skills.length === 0 && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills available. Add skills to the skills/ directory." }))] })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load Codemode status" })) })] }), agentId && (_jsx(ContextPanel, { agentId: agentId, apiBase: apiBase, messageCount: messageCount, chartHeight: "200px" })), agentId && (_jsxs(Box, { sx: { mt: 3 }, children: [_jsxs(Box, { sx: {
425
+ display: 'flex',
426
+ alignItems: 'center',
427
+ justifyContent: 'space-between',
428
+ mb: 2,
429
+ }, children: [_jsx(Heading, { as: "h4", sx: {
430
+ fontSize: 1,
431
+ fontWeight: 'semibold',
432
+ color: 'fg.muted',
433
+ }, children: "Context Snapshot" }), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => downloadContextSnapshotAsCSV(agentId, apiBase), children: "Download" })] }), _jsx(Box, { sx: {
142
434
  p: 3,
143
435
  bg: 'canvas.subtle',
144
436
  borderRadius: 2,
145
437
  border: '1px solid',
146
438
  borderColor: 'border.default',
147
- }, children: _jsx(ContextDistribution, { agentId: agentId, height: "250px" }) })] })), _jsx(AgentIdentity, { providers: identityProviders, title: "Connected Accounts", showHeader: true, showDescription: true, description: "OAuth identities connected to this agent. Agents can use these to access external services like GitHub repositories on your behalf.", showExpirationDetails: true, allowReconnect: Boolean(identityProviders), onConnect: onIdentityConnect, onDisconnect: onIdentityDisconnect }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { variant: "primary", onClick: onBack, sx: { width: '100%' }, children: "Back to Chat" }) })] })] }));
439
+ }, children: _jsx(ContextInspector, { agentId: agentId, apiBase: apiBase }) })] })), _jsx(AgentIdentity, { providers: identityProviders, title: "Connected Accounts", showHeader: true, showDescription: true, description: "OAuth identities connected to this agent. Agents can use these to access external services like GitHub repositories on your behalf.", showExpirationDetails: true, allowReconnect: Boolean(identityProviders), onConnect: onIdentityConnect, onDisconnect: onIdentityDisconnect }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { variant: "primary", onClick: onBack, sx: { width: '100%' }, children: "Back to Chat" }) })] })] }));
148
440
  }
149
441
  export default AgentDetails;
@@ -1,4 +1,6 @@
1
1
  import { type Suggestion } from './base/ChatBase';
2
+ import type { ModelConfig } from './base/ChatBase';
3
+ import type { McpServerSelection } from '../types';
2
4
  import type { OAuthProvider, OAuthProviderConfig, Identity } from '../../../identity';
3
5
  /**
4
6
  * Supported transports (communication transports)
@@ -54,10 +56,21 @@ export interface ChatProps {
54
56
  showSkillsMenu?: boolean;
55
57
  /** Indicate tools are accessed via Codemode meta-tools */
56
58
  codemodeEnabled?: boolean;
59
+ /**
60
+ * Show token usage bar between input and selectors.
61
+ * @default true
62
+ */
63
+ showTokenUsage?: boolean;
57
64
  /** Initial model ID to select (e.g., 'openai:gpt-4o-mini') */
58
65
  initialModel?: string;
59
- /** Initial MCP server IDs to enable (others will be disabled) */
60
- initialMcpServers?: string[];
66
+ /**
67
+ * Override the list of available models.
68
+ * When provided, this list replaces the models returned by the config endpoint.
69
+ * Use this to restrict the model selector to a specific subset of models.
70
+ */
71
+ availableModels?: ModelConfig[];
72
+ /** MCP server selections to enable (others will be disabled) */
73
+ mcpServers?: McpServerSelection[];
61
74
  /** Initial skill IDs to enable */
62
75
  initialSkills?: string[];
63
76
  /** Clear messages when component mounts or agentId changes */
@@ -82,6 +95,27 @@ export interface ChatProps {
82
95
  onIdentityConnect?: (identity: Identity) => void;
83
96
  /** Callback when identity disconnects */
84
97
  onIdentityDisconnect?: (provider: OAuthProvider) => void;
98
+ /**
99
+ * Runtime ID for conversation persistence.
100
+ * When provided, messages are fetched from the server API on page reload
101
+ * and prevents message mixing between different agent spaces.
102
+ */
103
+ runtimeId?: string;
104
+ /**
105
+ * Endpoint URL for fetching conversation history.
106
+ * When runtimeId is provided, this endpoint is called to fetch
107
+ * the conversation history on mount.
108
+ * If not provided, defaults to `{protocol.endpoint}/history`.
109
+ */
110
+ historyEndpoint?: string;
111
+ /**
112
+ * Error banner to display at the top of the chat.
113
+ * Use this to show sandbox connection errors or other warnings.
114
+ */
115
+ errorBanner?: {
116
+ message: string;
117
+ variant?: 'danger' | 'warning';
118
+ };
85
119
  }
86
120
  /**
87
121
  * Chat Component
@@ -124,5 +158,5 @@ export interface ChatProps {
124
158
  * />
125
159
  * ```
126
160
  */
127
- export declare function Chat({ transport, extensions: _extensions, baseUrl, wsUrl, agentId, placeholder, title, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showModelSelector, showToolsMenu, showSkillsMenu, codemodeEnabled, initialModel, initialMcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, }: ChatProps): import("react/jsx-runtime").JSX.Element;
161
+ export declare function Chat({ transport, extensions: _extensions, baseUrl, wsUrl, agentId, placeholder, title, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showModelSelector, showToolsMenu, showSkillsMenu, codemodeEnabled, showTokenUsage, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, errorBanner, }: ChatProps): import("react/jsx-runtime").JSX.Element;
128
162
  export default Chat;
@@ -70,7 +70,7 @@ function getEndpointPath(transport, agentId) {
70
70
  case 'ag-ui':
71
71
  return `/api/v1/ag-ui/${agentId}/`;
72
72
  case 'a2a':
73
- // A2A requires trailing slash
73
+ // A2A requires trailing slash for FastA2A compatibility
74
74
  return `/api/v1/a2a/agents/${agentId}/`;
75
75
  case 'acp':
76
76
  return `/api/v1/acp/ws/${agentId}`;
@@ -130,7 +130,7 @@ function getProtocolType(transport) {
130
130
  * />
131
131
  * ```
132
132
  */
133
- export function Chat({ transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, placeholder = 'Type your message...', title, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showModelSelector = true, showToolsMenu = true, showSkillsMenu = false, codemodeEnabled = false, initialModel, initialMcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, }) {
133
+ export function Chat({ transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, placeholder = 'Type your message...', title, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showModelSelector = true, showToolsMenu = true, showSkillsMenu = false, codemodeEnabled = false, showTokenUsage = true, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, errorBanner, }) {
134
134
  const [error, setError] = useState(null);
135
135
  const [isInitializing, setIsInitializing] = useState(true);
136
136
  const [showDetails, setShowDetails] = useState(false);
@@ -282,16 +282,35 @@ export function Chat({ transport, extensions: _extensions, baseUrl = 'http://loc
282
282
  display: showDetails ? 'flex' : 'none',
283
283
  flexDirection: 'column',
284
284
  height: '100%',
285
- }, children: _jsx(AgentDetails, { name: title || 'AI Agent', protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, identityProviders: identityProviders, onIdentityConnect: onIdentityConnect, onIdentityDisconnect: onIdentityDisconnect, onBack: () => setShowDetails(false) }) }), _jsx(Box, { sx: {
285
+ }, children: _jsx(AgentDetails, { name: title || 'AI Agent', protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, apiBase: baseUrl, identityProviders: identityProviders, onIdentityConnect: onIdentityConnect, onIdentityDisconnect: onIdentityDisconnect, onBack: () => setShowDetails(false) }) }), _jsxs(Box, { sx: {
286
286
  display: showDetails ? 'none' : 'flex',
287
287
  flexDirection: 'column',
288
288
  height: '100%',
289
- }, children: _jsx(ChatBase, { title: title, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, headerContent: _jsx(IconButton, { icon: InfoIcon, "aria-label": "Agent details", variant: "invisible", size: "small", onClick: () => setShowDetails(true) }), showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, initialModel: initialModel, initialMcpServers: initialMcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: messages => setMessageCount(messages.length), headerButtons: {
290
- showNewChat: true,
291
- showClear: true,
292
- onNewChat: handleNewChat,
293
- }, avatarConfig: {
294
- showAvatars: true,
295
- }, backgroundColor: "canvas.default", focusTrigger: focusTrigger }) })] }));
289
+ }, children: [errorBanner && (_jsxs(Box, { sx: {
290
+ display: 'flex',
291
+ alignItems: 'center',
292
+ gap: 2,
293
+ px: 3,
294
+ py: 2,
295
+ bg: errorBanner.variant === 'warning'
296
+ ? 'attention.subtle'
297
+ : 'danger.subtle',
298
+ borderBottom: '1px solid',
299
+ borderColor: errorBanner.variant === 'warning'
300
+ ? 'attention.muted'
301
+ : 'danger.muted',
302
+ }, children: [_jsx(AlertIcon, { size: 16, fill: errorBanner.variant === 'warning' ? 'attention.fg' : 'danger.fg' }), _jsx(Text, { sx: {
303
+ fontSize: 1,
304
+ color: errorBanner.variant === 'warning'
305
+ ? 'attention.fg'
306
+ : 'danger.fg',
307
+ flex: 1,
308
+ }, children: errorBanner.message })] })), _jsx(ChatBase, { title: title, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, runtimeId: runtimeId, historyEndpoint: historyEndpoint, headerContent: _jsx(IconButton, { icon: InfoIcon, "aria-label": "Agent details", variant: "invisible", size: "small", onClick: () => setShowDetails(true) }), showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, showTokenUsage: showTokenUsage, codemodeEnabled: codemodeEnabled, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: messages => setMessageCount(messages.length), headerButtons: {
309
+ showNewChat: true,
310
+ showClear: true,
311
+ onNewChat: handleNewChat,
312
+ }, avatarConfig: {
313
+ showAvatars: true,
314
+ }, backgroundColor: "canvas.default", focusTrigger: focusTrigger })] })] }));
296
315
  }
297
316
  export default Chat;
@@ -20,7 +20,7 @@ export type { ToolCallStatus, ToolCallRenderContext, RenderToolResult, RespondCa
20
20
  */
21
21
  export interface ChatFloatingProps {
22
22
  /**
23
- * AG-UI endpoint URL (e.g., http://localhost:8000/api/v1/examples/agentic_chat/).
23
+ * AG-UI endpoint URL (e.g., http://localhost:8000/api/v1/examples/agentic_chat).
24
24
  * When provided with useStore=false, enables AG-UI protocol mode.
25
25
  */
26
26
  endpoint?: string;
@@ -135,6 +135,12 @@ export interface ChatFloatingProps {
135
135
  * @default false
136
136
  */
137
137
  showPanelBackdrop?: boolean;
138
+ /**
139
+ * Override the list of available models.
140
+ * When provided, this list replaces the models returned by the config endpoint.
141
+ * Use this to restrict the model selector to a specific subset of models.
142
+ */
143
+ availableModels?: ModelConfig[];
138
144
  /**
139
145
  * Show model selector in footer.
140
146
  * @default false
@@ -150,6 +156,25 @@ export interface ChatFloatingProps {
150
156
  * @default false
151
157
  */
152
158
  showSkillsMenu?: boolean;
159
+ /**
160
+ * Show token usage bar between input and selectors.
161
+ * @default true
162
+ */
163
+ showTokenUsage?: boolean;
164
+ /**
165
+ * Runtime ID used to scope and persist conversation history.
166
+ * When provided, history is fetched on mount from the historyEndpoint.
167
+ */
168
+ runtimeId?: string;
169
+ /**
170
+ * Endpoint URL for fetching conversation history.
171
+ * Defaults to `{protocol.endpoint}/history` when runtimeId is set.
172
+ */
173
+ historyEndpoint?: string;
174
+ /**
175
+ * Auth token for the history endpoint.
176
+ */
177
+ historyAuthToken?: string;
153
178
  /** Additional ChatBase props */
154
179
  panelProps?: Partial<ChatBaseProps>;
155
180
  }
@@ -157,5 +182,5 @@ export interface ChatFloatingProps {
157
182
  * ChatFloating component
158
183
  * A floating chat window built on ChatBase
159
184
  */
160
- export declare function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode, title, description, position, defaultOpen, width, height, showHeader, showButton, showNewChatButton, showClearButton, showSettingsButton, enableKeyboardShortcuts, toggleShortcut, showPoweredBy, poweredByProps, clickOutsideToClose, escapeToClose, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip, brandColor, offset, animationDuration, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick, hideMessagesAfterToolUI, defaultViewMode, showPanelBackdrop, showModelSelector, showToolsMenu, showSkillsMenu, panelProps, }: ChatFloatingProps): import("react/jsx-runtime").JSX.Element;
185
+ export declare function ChatFloating({ endpoint, protocol: protocolProp, useStore: useStoreMode, title, description, position, defaultOpen, width, height, showHeader, showButton, showNewChatButton, showClearButton, showSettingsButton, enableKeyboardShortcuts, toggleShortcut, showPoweredBy, poweredByProps, clickOutsideToClose, escapeToClose, className, onSettingsClick, onNewChat, onOpen, onClose, onStateUpdate, children, brandIcon, buttonIcon, buttonTooltip, brandColor, offset, animationDuration, renderToolResult, tools: _tools, initialState: _initialState, suggestions, submitOnSuggestionClick, hideMessagesAfterToolUI, defaultViewMode, showPanelBackdrop, availableModels, showModelSelector, showToolsMenu, showSkillsMenu, showTokenUsage, runtimeId, historyEndpoint, historyAuthToken, panelProps, }: ChatFloatingProps): import("react/jsx-runtime").JSX.Element;
161
186
  export default ChatFloating;