@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
@@ -2,8 +2,8 @@
2
2
  * Copyright (c) 2025-2026 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import clsx from "clsx";
6
- import { twMerge } from "tailwind-merge";
5
+ import clsx from 'clsx';
6
+ import { twMerge } from 'tailwind-merge';
7
7
  export function cn(...inputs) {
8
8
  return twMerge(clsx(inputs));
9
9
  }
@@ -27,6 +27,7 @@ import 'prismjs/components/prism-rust';
27
27
  import 'prismjs/components/prism-swift';
28
28
  import type { ServiceManager } from '@jupyterlab/services';
29
29
  import '@datalayer/jupyter-lexical/style/index.css';
30
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
30
31
  import './lexical/lexical-theme.css';
31
32
  /**
32
33
  * Chat Lexical Example with Simple integration
@@ -48,12 +48,13 @@ import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
48
48
  import { Box } from '@datalayer/primer-addons';
49
49
  import { Text } from '@primer/react';
50
50
  import { JupyterReactTheme, useJupyter } from '@datalayer/jupyter-react';
51
- import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, AutoLinkPlugin, AutoEmbedPlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, } from '@datalayer/jupyter-lexical';
51
+ import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, TableCellResizerPlugin, TablePlugin, } from '@datalayer/jupyter-lexical';
52
52
  // Import Chat components
53
53
  import { ChatFloating, useChatStore, useFrontendTool, DatalayerInferenceProvider, } from '../components/chat';
54
54
  import { useLexicalToolActions, ActionRegistrar, } from '../tools/adapters/copilotkit/lexicalHooks';
55
55
  import { editorConfig } from './lexical/editorConfig';
56
56
  import '@datalayer/jupyter-lexical/style/index.css';
57
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
57
58
  import './lexical/lexical-theme.css';
58
59
  // Fixed lexical document ID
59
60
  const LEXICAL_ID = 'chat-popup-lexical-example';
@@ -154,7 +155,7 @@ function LexicalEditor({ serviceManager: _serviceManager, }) {
154
155
  left: '24px',
155
156
  color: 'var(--fgColor-muted)',
156
157
  pointerEvents: 'none',
157
- }, children: "Start typing or click the chat button to open the AI assistant..." }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(CodeHighlightingPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterInputOutputPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(ComponentPickerMenuPlugin, {}), _jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }));
158
+ }, children: "Start typing or click the chat button to open the AI assistant..." }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(CodeHighlightingPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterInputOutputPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(ComponentPickerMenuPlugin, {}), _jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }));
158
159
  }
159
160
  export function ChatLexicalExampleInner({ serviceManager, }) {
160
161
  // Chat configuration - set up the inference provider in the store
@@ -25,6 +25,7 @@ import 'prismjs/components/prism-swift';
25
25
  import type { ServiceManager } from '@jupyterlab/services';
26
26
  import '@datalayer/jupyter-lexical/style/index.css';
27
27
  import './lexical/lexical-theme.css';
28
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
28
29
  /**
29
30
  * Main Agent Runtime lexical example component
30
31
  */
@@ -45,7 +45,7 @@ import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
45
45
  import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
46
46
  import { Box } from '@datalayer/primer-addons';
47
47
  import { JupyterReactTheme, useJupyter } from '@datalayer/jupyter-react';
48
- import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, } from '@datalayer/jupyter-lexical';
48
+ import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, TableCellResizerPlugin, TablePlugin, } from '@datalayer/jupyter-lexical';
49
49
  // Agent-runtimes imports
50
50
  import { ChatFloating } from '../components/chat';
51
51
  import { ChatInlinePlugin } from '../lexical/ChatInlinePlugin';
@@ -53,12 +53,13 @@ import { useLexicalTools } from '../tools/adapters/agent-runtimes/lexicalHooks';
53
53
  import { editorConfig } from './lexical/editorConfig';
54
54
  import '@datalayer/jupyter-lexical/style/index.css';
55
55
  import './lexical/lexical-theme.css';
56
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
56
57
  // Fixed lexical document ID
57
58
  const LEXICAL_ID = 'agui-lexical-example';
58
59
  // Base URL for agent-runtimes server
59
60
  const BASE_URL = 'http://localhost:8765';
60
61
  const AGENT_ID = 'lexical-agent-runtime-example';
61
- // AG-UI endpoint for lexical operations
62
+ // AG-UI endpoint for lexical operations (trailing slash required for mounted Starlette apps)
62
63
  const AG_UI_ENDPOINT = `${BASE_URL}/api/v1/ag-ui/${AGENT_ID}/`;
63
64
  /**
64
65
  * Hook to ensure the demo-agent exists on the server.
@@ -185,6 +186,7 @@ function LexicalToolsPlugin({ onToolsReady, }) {
185
186
  }
186
187
  const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, serviceManager, onToolsReady, }) {
187
188
  const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
189
+ const [_isLinkEditMode, setIsLinkEditMode] = useState(false);
188
190
  const onRef = (_floatingAnchorElem) => {
189
191
  if (_floatingAnchorElem !== null) {
190
192
  setFloatingAnchorElem(_floatingAnchorElem);
@@ -211,7 +213,7 @@ const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, ser
211
213
  padding: 3,
212
214
  backgroundColor: 'canvas.default',
213
215
  minHeight: '600px',
214
- }, children: _jsxs(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: [_jsx(LexicalToolsPlugin, { onToolsReady: onToolsReady }), _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] })), _jsx(ChatInlinePlugin, { protocol: {
216
+ }, children: _jsxs(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: [_jsx(LexicalToolsPlugin, { onToolsReady: onToolsReady }), _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] })), _jsx(ChatInlinePlugin, { protocol: {
215
217
  type: 'ag-ui',
216
218
  endpoint: AG_UI_ENDPOINT,
217
219
  } })] }) })] }) })] }));
@@ -26,6 +26,7 @@ import 'prismjs/components/prism-rust';
26
26
  import 'prismjs/components/prism-swift';
27
27
  import type { ServiceManager } from '@jupyterlab/services';
28
28
  import '@datalayer/jupyter-lexical/style/index.css';
29
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
29
30
  import './lexical/lexical-theme.css';
30
31
  /**
31
32
  * Agent Runtime Lexical Sidebar Example with Simple integration
@@ -44,15 +44,15 @@ import { registerCodeHighlighting } from '@lexical/code';
44
44
  import { ListPlugin } from '@lexical/react/LexicalListPlugin';
45
45
  import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
46
46
  import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
47
- import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
48
47
  import { Box } from '@datalayer/primer-addons';
49
48
  import { JupyterReactTheme, useJupyter } from '@datalayer/jupyter-react';
50
- import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, LexicalConfigProvider, LexicalStatePlugin, } from '@datalayer/jupyter-lexical';
49
+ import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, LexicalConfigProvider, LexicalStatePlugin, TableCellResizerPlugin, TablePlugin, } from '@datalayer/jupyter-lexical';
51
50
  // Import Chat components
52
51
  import { ChatSidebar, } from '../components/chat';
53
52
  import { useLexicalTools } from '../tools/adapters/agent-runtimes/lexicalHooks';
54
53
  import { editorConfig } from './lexical/editorConfig';
55
54
  import '@datalayer/jupyter-lexical/style/index.css';
55
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
56
56
  import './lexical/lexical-theme.css';
57
57
  // Fixed lexical document ID
58
58
  const LEXICAL_ID = 'chat-lexical-example';
@@ -98,7 +98,7 @@ function LexicalEditor({ serviceManager }) {
98
98
  left: '24px',
99
99
  color: 'var(--fgColor-muted)',
100
100
  pointerEvents: 'none',
101
- }, children: "Start typing or use the chat to create content..." }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(CodeHighlightingPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(TablePlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterInputOutputPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(ComponentPickerMenuPlugin, {}), _jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] })] }) }));
101
+ }, children: "Start typing or use the chat to create content..." }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(OnChangePlugin, { onChange: onChange }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(CodeHighlightingPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterInputOutputPlugin, {}), _jsx(ImagesPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(ComponentPickerMenuPlugin, {}), _jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] })] }) }));
102
102
  }
103
103
  export function ChatLexicalExampleInner({ serviceManager, }) {
104
104
  // Get lexical tools for ChatSidebar
@@ -30,7 +30,7 @@ const NOTEBOOK_CONTENT = MatplotlibNotebook;
30
30
  // Base URL for agent-runtimes server
31
31
  const BASE_URL = 'http://localhost:8765';
32
32
  const AGENT_ID = 'notebook-agent-runtime-example';
33
- // AG-UI endpoint for notebook operations
33
+ // AG-UI endpoint for notebook operations (trailing slash required for mounted Starlette apps)
34
34
  const AG_UI_ENDPOINT = `${BASE_URL}/api/v1/ag-ui/${AGENT_ID}/`;
35
35
  /**
36
36
  * Hook to ensure the demo-agent exists on the server.
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { Transport } from '../components/chat';
3
- import { type AgentLibrary } from './components';
3
+ import { type AgentLibrary, type McpServerSelection } from '../components';
4
4
  /**
5
5
  * Agent Runtime Example Component
6
6
  *
@@ -64,7 +64,7 @@ type AgentSpaceFormExampleProps = {
64
64
  initialEnableCodemode?: boolean;
65
65
  initialAllowDirectToolCalls?: boolean;
66
66
  initialEnableToolReranker?: boolean;
67
- initialSelectedMcpServers?: string[];
67
+ initialSelectedMcpServers?: McpServerSelection[];
68
68
  autoSelectMcpServers?: boolean;
69
69
  /**
70
70
  * Identity providers configuration.
@@ -9,13 +9,13 @@ import { PageLayout, IconButton } from '@primer/react';
9
9
  import { SidebarCollapseIcon, SidebarExpandIcon } from '@primer/octicons-react';
10
10
  import { AiAgentIcon } from '@datalayer/icons-react';
11
11
  import { Blankslate } from '@primer/react/experimental';
12
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
12
+ import { QueryClient, QueryClientProvider, useQuery, } from '@tanstack/react-query';
13
13
  import { Box } from '@datalayer/primer-addons';
14
14
  import { DatalayerThemeProvider } from '@datalayer/core';
15
- import { Chat } from '../components/chat';
15
+ import { Chat, useChatStore } from '../components/chat';
16
16
  import { useAgentsStore } from './stores/examplesStore';
17
17
  import { useIdentity } from '../identity';
18
- import { MockFileBrowser, MainContent, Header, FooterMetrics, AgentConfiguration, } from './components';
18
+ import { MockFileBrowser, MainContent, Header, FooterMetrics, AgentConfiguration, } from '../components';
19
19
  // Create a query client for React Query
20
20
  const queryClient = new QueryClient({
21
21
  defaultOptions: {
@@ -27,6 +27,47 @@ const queryClient = new QueryClient({
27
27
  },
28
28
  },
29
29
  });
30
+ /**
31
+ * Hook to fetch codemode status and compute Jupyter error banner.
32
+ * Must be used inside QueryClientProvider.
33
+ */
34
+ function useJupyterSandboxStatus(baseUrl, isConfigured, enableCodemode, useJupyterSandbox) {
35
+ const { data: codemodeStatus } = useQuery({
36
+ queryKey: ['codemode-status', baseUrl],
37
+ queryFn: async () => {
38
+ const response = await fetch(`${baseUrl}/api/v1/configure/codemode-status`);
39
+ if (!response.ok) {
40
+ throw new Error('Failed to fetch codemode status');
41
+ }
42
+ return response.json();
43
+ },
44
+ enabled: isConfigured && enableCodemode && useJupyterSandbox,
45
+ refetchInterval: 10000, // Refresh every 10 seconds
46
+ });
47
+ return React.useMemo(() => {
48
+ if (!isConfigured || !enableCodemode || !useJupyterSandbox) {
49
+ return undefined;
50
+ }
51
+ const sandbox = codemodeStatus?.sandbox;
52
+ if (!sandbox) {
53
+ return undefined;
54
+ }
55
+ // Check if Jupyter variant is selected but not connected
56
+ if (sandbox.variant === 'local-jupyter' && !sandbox.jupyter_connected) {
57
+ return {
58
+ message: sandbox.jupyter_error
59
+ ? `Jupyter Sandbox Error: ${sandbox.jupyter_error}`
60
+ : 'Jupyter Sandbox not connected. Code execution may fail.',
61
+ variant: 'danger',
62
+ };
63
+ }
64
+ return undefined;
65
+ }, [isConfigured, enableCodemode, useJupyterSandbox, codemodeStatus]);
66
+ }
67
+ function ChatWithJupyterStatus({ baseUrl, isConfigured, enableCodemode, useJupyterSandbox, chatProps, }) {
68
+ const jupyterErrorBanner = useJupyterSandboxStatus(baseUrl, isConfigured, enableCodemode, useJupyterSandbox);
69
+ return _jsx(Chat, { ...chatProps, errorBanner: jupyterErrorBanner });
70
+ }
30
71
  // Default configuration - use environment variable if available
31
72
  // Note: Vercel AI connects to Jupyter server (8888), other protocols connect to agent-runtimes server (8765)
32
73
  const DEFAULT_WS_URL = import.meta.env.VITE_ACP_WS_URL || 'ws://localhost:8765/api/v1/acp/ws';
@@ -80,11 +121,70 @@ githubClientId, kaggleToken, }) => {
80
121
  // Agent capabilities state (moved from Header toggles)
81
122
  const [selectedSkills, setSelectedSkills] = useState([]);
82
123
  const [enableCodemode, setEnableCodemode] = useState(initialEnableCodemode);
124
+ const [useJupyterSandbox, setUseJupyterSandbox] = useState(false);
83
125
  const [allowDirectToolCalls, setAllowDirectToolCalls] = useState(initialAllowDirectToolCalls);
84
126
  const [enableToolReranker, setEnableToolReranker] = useState(initialEnableToolReranker);
85
127
  const [selectedMcpServers, setSelectedMcpServers] = useState(initialSelectedMcpServers);
86
128
  const autoSelectRef = useRef(false);
87
129
  const enableSkills = selectedSkills.length > 0;
130
+ // =====================================================================
131
+ // Two-Container Codemode Architecture
132
+ // =====================================================================
133
+ //
134
+ // When Jupyter sandbox is enabled, the architecture uses two containers:
135
+ //
136
+ // ┌─────────────────────────────────────┐ ┌─────────────────────────────────┐
137
+ // │ agent-runtimes (port 8765) │ │ jupyter server (port 8888) │
138
+ // │ ┌─────────────────────────────┐ │ │ ┌─────────────────────────┐ │
139
+ // │ │ MCP Servers (stdio) │ │ │ │ Jupyter Kernel │ │
140
+ // │ │ - github, filesystem, etc │◀───┼──┼──│ executes generated │ │
141
+ // │ └─────────────────────────────┘ │ │ │ Python code │ │
142
+ // │ ┌─────────────────────────────┐ │ │ └─────────────────────────┘ │
143
+ // │ │ /api/v1/mcp/proxy/* │ │ │ │
144
+ // │ │ HTTP proxy for tool calls │ │ │ Tool calls go via HTTP to │
145
+ // │ └─────────────────────────────┘ │ │ agent-runtimes MCP proxy │
146
+ // └─────────────────────────────────────┘ └─────────────────────────────────┘
147
+ //
148
+ // The backend automatically configures mcp_proxy_url when jupyter_sandbox
149
+ // is provided, defaulting to http://0.0.0.0:8765/api/v1/mcp/proxy
150
+ //
151
+ // =====================================================================
152
+ // Jupyter sandbox URL (used when useJupyterSandbox is true)
153
+ // Can be configured via VITE_JUPYTER_SANDBOX_URL environment variable
154
+ const jupyterSandboxUrl = import.meta.env.VITE_JUPYTER_SANDBOX_URL ||
155
+ 'http://localhost:8888/api/jupyter-server?token=60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6';
156
+ const handleSelectedServersChange = React.useCallback((newServers) => {
157
+ const oldServers = selectedMcpServers;
158
+ // Find added and removed servers
159
+ const oldIds = new Set(oldServers.map(s => `${s.id}:${s.origin}`));
160
+ const newIds = new Set(newServers.map(s => `${s.id}:${s.origin}`));
161
+ const added = newServers.filter(s => !oldIds.has(`${s.id}:${s.origin}`));
162
+ const removed = oldServers.filter(s => !newIds.has(`${s.id}:${s.origin}`));
163
+ // Add system message about tool changes if there are any
164
+ if ((added.length > 0 || removed.length > 0) && isConfigured) {
165
+ let messageContent = '';
166
+ if (added.length > 0) {
167
+ const addedNames = added.map(s => `${s.id} (${s.origin})`).join(', ');
168
+ messageContent += `🔧 Tools added: ${addedNames}. `;
169
+ }
170
+ if (removed.length > 0) {
171
+ const removedNames = removed
172
+ .map(s => `${s.id} (${s.origin})`)
173
+ .join(', ');
174
+ messageContent += `🔧 Tools removed: ${removedNames}. You no longer have access to these tools.`;
175
+ }
176
+ if (messageContent) {
177
+ const systemMessage = {
178
+ id: `system-mcp-${Date.now()}`,
179
+ role: 'system',
180
+ content: messageContent.trim(),
181
+ createdAt: new Date(),
182
+ };
183
+ useChatStore.getState().addMessage(systemMessage);
184
+ }
185
+ }
186
+ setSelectedMcpServers(newServers);
187
+ }, [selectedMcpServers, isConfigured]);
88
188
  // Merge deprecated props into identityProviders for backward compatibility
89
189
  const mergedIdentityProviders = React.useMemo(() => {
90
190
  const merged = { ...identityProviders };
@@ -180,12 +280,11 @@ githubClientId, kaggleToken, }) => {
180
280
  if (!enabled) {
181
281
  setAllowDirectToolCalls(false);
182
282
  setEnableToolReranker(false);
283
+ setUseJupyterSandbox(false);
183
284
  }
184
285
  };
185
286
  // UI state
186
287
  const [activeSession, setActiveSession] = useState('session-1');
187
- const [richEditor, setRichEditor] = useState(false);
188
- const [durable, setDurable] = useState(true);
189
288
  const [codemode, _] = useState(false);
190
289
  const [showContextTree, setShowContextTree] = useState(false);
191
290
  const [showNotebook] = useState(true);
@@ -224,7 +323,7 @@ githubClientId, kaggleToken, }) => {
224
323
  const servers = data?.mcpServers || [];
225
324
  const available = servers.filter((s) => s.isAvailable);
226
325
  if (available.length > 0) {
227
- setSelectedMcpServers([available[0].id]);
326
+ setSelectedMcpServers([{ id: available[0].id, origin: 'config' }]);
228
327
  autoSelectRef.current = true;
229
328
  }
230
329
  }
@@ -234,6 +333,8 @@ githubClientId, kaggleToken, }) => {
234
333
  };
235
334
  void loadServers();
236
335
  }, [autoSelectMcpServers, enableCodemode, selectedMcpServers, baseUrl]);
336
+ // Track previous MCP servers to detect changes
337
+ const prevMcpServersRef = useRef(selectedMcpServers);
237
338
  const handleAgentSelect = (agentId) => {
238
339
  setSelectedAgentId(agentId);
239
340
  setCreateError(null);
@@ -275,6 +376,7 @@ githubClientId, kaggleToken, }) => {
275
376
  enable_tool_reranker: enableToolReranker,
276
377
  selected_mcp_servers: selectedMcpServers,
277
378
  skills: selectedSkills,
379
+ jupyter_sandbox: useJupyterSandbox ? jupyterSandboxUrl : undefined,
278
380
  }),
279
381
  });
280
382
  if (!response.ok) {
@@ -308,6 +410,8 @@ githubClientId, kaggleToken, }) => {
308
410
  enableToolReranker,
309
411
  selectedMcpServers,
310
412
  selectedSkills,
413
+ useJupyterSandbox,
414
+ jupyterSandboxUrl,
311
415
  ]);
312
416
  /**
313
417
  * Delete an agent via the API
@@ -329,6 +433,11 @@ githubClientId, kaggleToken, }) => {
329
433
  return false;
330
434
  }
331
435
  }, [baseUrl]);
436
+ // Track MCP servers for reference (no longer triggers recreation)
437
+ // MCP server updates are now handled via PATCH endpoint by McpServerManager
438
+ useEffect(() => {
439
+ prevMcpServersRef.current = selectedMcpServers;
440
+ }, [selectedMcpServers]);
332
441
  const handleConnect = async () => {
333
442
  // For existing agents (not new-agent), ensure transport and agentName are set
334
443
  if (selectedAgentId !== 'new-agent') {
@@ -375,7 +484,7 @@ githubClientId, kaggleToken, }) => {
375
484
  };
376
485
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(DatalayerThemeProvider, { children: _jsxs(PageLayout, { containerWidth: "full", children: [_jsx(Header, { activeSession: activeSession, agentName: selectedAgentId === 'new-agent' ? undefined : currentAgent?.name, agentDescription: selectedAgentId === 'new-agent'
377
486
  ? undefined
378
- : currentAgent?.description, agentStatus: currentAgent?.status, richEditor: richEditor, durable: durable, showContextTree: showContextTree, isNewAgent: selectedAgentId === 'new-agent', isConfigured: isConfigured, onSessionChange: setActiveSession, onRichEditorChange: setRichEditor, onDurableChange: setDurable, onToggleContextTree: () => setShowContextTree(!showContextTree), onToggleStatus: currentAgent
487
+ : currentAgent?.description, agentStatus: currentAgent?.status, showContextTree: showContextTree, isNewAgent: selectedAgentId === 'new-agent', isConfigured: isConfigured, onSessionChange: setActiveSession, onToggleContextTree: () => setShowContextTree(!showContextTree), onToggleStatus: currentAgent
379
488
  ? () => toggleAgentStatus(currentAgent.id)
380
489
  : undefined }), leftPaneVisible ? (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
381
490
  position: 'fixed',
@@ -389,7 +498,7 @@ githubClientId, kaggleToken, }) => {
389
498
  border: '1px solid',
390
499
  borderLeft: 'none',
391
500
  borderColor: 'border.default',
392
- } }) }), _jsx(PageLayout.Pane, { position: "start", resizable: true, sticky: true, width: { min: '250px', default: '300px', max: '90px' }, children: selectedAgentId === 'new-agent' ? (_jsxs(Blankslate, { border: true, spacious: true, narrow: true, children: [_jsx(Blankslate.Visual, { children: _jsx(AiAgentIcon, { colored: true, size: 48 }) }), _jsx(Blankslate.Heading, { children: "New Agent" }), _jsx(Box, { sx: { textAlign: 'center' }, children: _jsx(Blankslate.Description, { children: "Configure your new agent using the settings on the right" }) })] })) : (_jsx(MockFileBrowser, { codemode: codemode })) })] })) : (_jsx(Box, { sx: {
501
+ } }) }), _jsx(PageLayout.Pane, { position: "start", resizable: true, sticky: true, width: { min: '250px', default: '300px', max: '90px' }, children: selectedAgentId === 'new-agent' ? (_jsxs(Blankslate, { border: true, spacious: true, narrow: true, children: [_jsx(Blankslate.Visual, { children: _jsx(AiAgentIcon, { colored: true, size: 48 }) }), _jsx(Blankslate.Heading, { children: "Agent Runtimes" }), _jsx(Box, { sx: { textAlign: 'center' }, children: _jsx(Blankslate.Description, { children: "Expose AI Agents through multiple protocols." }) })] })) : (_jsx(MockFileBrowser, { codemode: codemode })) })] })) : (_jsx(Box, { sx: {
393
502
  position: 'fixed',
394
503
  left: 0,
395
504
  top: '50%',
@@ -401,7 +510,11 @@ githubClientId, kaggleToken, }) => {
401
510
  border: '1px solid',
402
511
  borderLeft: 'none',
403
512
  borderColor: 'border.default',
404
- } }) })), _jsx(PageLayout.Content, { children: _jsx(MainContent, { showNotebook: showNotebook, timeTravel: timeTravel, onTimeTravelChange: setTimeTravel, richEditor: richEditor, notebookFile: currentAgent?.notebookFile, lexicalFile: currentAgent?.lexicalFile, isNewAgent: selectedAgentId === 'new-agent' }) }), rightPaneVisible ? (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
513
+ } }) })), _jsx(PageLayout.Content, { children: _jsx(MainContent, { showNotebook: showNotebook, timeTravel: timeTravel, onTimeTravelChange: setTimeTravel, richEditor: false, notebookFile: currentAgent?.notebookFile, lexicalFile: currentAgent?.lexicalFile, isNewAgent: selectedAgentId === 'new-agent', isConfigured: isConfigured, baseUrl: baseUrl, agentId: currentAgent?.id || agentName, enableCodemode: enableCodemode, selectedMcpServers: selectedMcpServers, onSelectedMcpServersChange: handleSelectedServersChange, onMcpServersChange: () => {
514
+ // Trigger codemode tool regeneration when MCP servers change at runtime
515
+ console.log('[AgentSpaceFormExample] MCP servers changed, regenerating codemode tools...');
516
+ // The Chat component will pick up the new selectedMcpServers via props
517
+ } }) }), rightPaneVisible ? (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
405
518
  position: 'fixed',
406
519
  right: 0,
407
520
  top: '50%',
@@ -418,29 +531,54 @@ githubClientId, kaggleToken, }) => {
418
531
  display: 'flex',
419
532
  flexDirection: 'column',
420
533
  p: 2,
421
- }, children: !isConfigured ? (_jsx(AgentConfiguration, { agentLibrary: agentLibrary, transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentName: agentName, model: model, agents: agents, selectedAgentId: selectedAgentId, isCreatingAgent: isCreatingAgent, createError: createError, enableCodemode: enableCodemode, allowDirectToolCalls: allowDirectToolCalls, enableToolReranker: enableToolReranker, availableSkills: MOCK_SKILLS, selectedSkills: selectedSkills, selectedMcpServers: selectedMcpServers, identityProviders: oauthProvidersConfig, onIdentityConnect: handleIdentityConnect, onIdentityDisconnect: handleIdentityDisconnect, onAgentLibraryChange: setAgentLibrary, onTransportChange: setTransport, onExtensionsChange: setExtensions, onWsUrlChange: setWsUrl, onBaseUrlChange: setBaseUrl, onAgentNameChange: setAgentName, onModelChange: setModel, onAgentSelect: handleAgentSelect, onConnect: handleConnect, onEnableCodemodeChange: handleEnableCodemodeChange, onAllowDirectToolCallsChange: setAllowDirectToolCalls, onEnableToolRerankerChange: setEnableToolReranker, onSelectedSkillsChange: setSelectedSkills, onSelectedMcpServersChange: setSelectedMcpServers })) : (
534
+ }, children: !isConfigured ? (_jsx(AgentConfiguration, { agentLibrary: agentLibrary, transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentName: agentName, model: model, agents: agents, selectedAgentId: selectedAgentId, isCreatingAgent: isCreatingAgent, createError: createError, enableCodemode: enableCodemode, useJupyterSandbox: useJupyterSandbox, allowDirectToolCalls: allowDirectToolCalls, enableToolReranker: enableToolReranker, availableSkills: MOCK_SKILLS, selectedSkills: selectedSkills, selectedMcpServers: selectedMcpServers, identityProviders: oauthProvidersConfig, onIdentityConnect: handleIdentityConnect, onIdentityDisconnect: handleIdentityDisconnect, onAgentLibraryChange: setAgentLibrary, onTransportChange: setTransport, onExtensionsChange: setExtensions, onWsUrlChange: setWsUrl, onBaseUrlChange: setBaseUrl, onAgentNameChange: setAgentName, onModelChange: setModel, onAgentSelect: handleAgentSelect, onConnect: handleConnect, onEnableCodemodeChange: handleEnableCodemodeChange, onUseJupyterSandboxChange: setUseJupyterSandbox, onAllowDirectToolCallsChange: setAllowDirectToolCalls, onEnableToolRerankerChange: setEnableToolReranker, onSelectedSkillsChange: setSelectedSkills, onSelectedMcpServersChange: setSelectedMcpServers })) : (
422
535
  /* Chat Interface */
423
- _jsx(Box, { sx: { flex: 1 }, children: _jsx(Chat, { transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentId: currentAgent?.id || agentName, title: currentAgent?.name || agentName || 'AI Assistant', autoConnect: true, autoFocus: true, placeholder: "Type your message to the agent...", height: "calc(100vh - 250px)", showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, codemodeEnabled: enableCodemode, initialModel: model, initialMcpServers: selectedMcpServers, initialSkills: selectedSkills, identityProviders: oauthProvidersConfig, onIdentityConnect: handleIdentityConnect, onIdentityDisconnect: handleIdentityDisconnect, suggestions: [
424
- {
425
- title: '👋 Say hello',
426
- message: 'Hello! What can you help me with today?',
427
- },
428
- {
429
- title: '💡 Get ideas',
430
- message: 'Can you suggest some creative project ideas?',
431
- },
432
- {
433
- title: '📝 Explain concepts',
434
- message: 'Can you explain how AI agents work?',
536
+ _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(ChatWithJupyterStatus, { baseUrl: baseUrl, isConfigured: isConfigured, enableCodemode: enableCodemode, useJupyterSandbox: useJupyterSandbox, chatProps: {
537
+ transport: currentAgent?.transport || transport,
538
+ extensions: extensions,
539
+ wsUrl: wsUrl,
540
+ baseUrl: baseUrl,
541
+ agentId: currentAgent?.id || agentName,
542
+ title: currentAgent?.name || agentName || 'AI Assistant',
543
+ autoConnect: true,
544
+ autoFocus: true,
545
+ placeholder: 'Type your message to the agent...',
546
+ height: 'calc(100vh - 150px)',
547
+ showModelSelector: true,
548
+ showToolsMenu: true,
549
+ showSkillsMenu: true,
550
+ codemodeEnabled: enableCodemode,
551
+ initialModel: model,
552
+ mcpServers: selectedMcpServers,
553
+ initialSkills: selectedSkills,
554
+ identityProviders: oauthProvidersConfig,
555
+ onIdentityConnect: handleIdentityConnect,
556
+ onIdentityDisconnect: handleIdentityDisconnect,
557
+ suggestions: [
558
+ {
559
+ title: '👋 Say hello',
560
+ message: 'Hello! What can you help me with today?',
561
+ },
562
+ {
563
+ title: '💡 Get ideas',
564
+ message: 'Can you suggest some creative project ideas?',
565
+ },
566
+ {
567
+ title: '📝 Explain concepts',
568
+ message: 'Can you explain how AI agents work?',
569
+ },
570
+ {
571
+ title: '🔧 Help with code',
572
+ message: 'Can you help me write some Python code?',
573
+ },
574
+ ],
575
+ onDisconnect: handleReset,
576
+ onMessageSent: (_content) => {
577
+ // Message sent
435
578
  },
436
- {
437
- title: '🔧 Help with code',
438
- message: 'Can you help me write some Python code?',
579
+ onMessageReceived: (_message) => {
580
+ // Message received
439
581
  },
440
- ], onDisconnect: handleReset, onMessageSent: (_content) => {
441
- // Message sent
442
- }, onMessageReceived: (_message) => {
443
- // Message received
444
582
  } }) })) }) })] })) : (_jsx(Box, { sx: {
445
583
  position: 'fixed',
446
584
  right: 0,
@@ -26,6 +26,7 @@ import 'prismjs/components/prism-swift';
26
26
  import type { ServiceManager } from '@jupyterlab/services';
27
27
  import '@datalayer/jupyter-lexical/style/index.css';
28
28
  import '@copilotkit/react-ui/styles.css';
29
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
29
30
  import './lexical/lexical-theme.css';
30
31
  /**
31
32
  * Main CopilotKit lexical example component
@@ -48,11 +48,12 @@ import { CopilotKit, useFrontendTool } from '@copilotkit/react-core';
48
48
  import { CopilotSidebar } from '@copilotkit/react-ui';
49
49
  import { Box } from '@datalayer/primer-addons';
50
50
  import { JupyterReactTheme, useJupyter } from '@datalayer/jupyter-react';
51
- import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, } from '@datalayer/jupyter-lexical';
51
+ import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, ExcalidrawPlugin, CollapsiblePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, TableCellResizerPlugin, TablePlugin, } from '@datalayer/jupyter-lexical';
52
52
  import { ActionRegistrar, useLexicalToolActions, } from '../tools/adapters/copilotkit/lexicalHooks';
53
53
  import { editorConfig } from './lexical/editorConfig';
54
54
  import '@datalayer/jupyter-lexical/style/index.css';
55
55
  import '@copilotkit/react-ui/styles.css';
56
+ import '@datalayer/jupyter-lexical/style/modal-overrides.css';
56
57
  import './lexical/lexical-theme.css';
57
58
  // Fixed lexical document ID
58
59
  const LEXICAL_ID = 'agui-lexical-example';
@@ -146,7 +147,7 @@ const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, ser
146
147
  padding: 3,
147
148
  backgroundColor: 'canvas.default',
148
149
  minHeight: '600px',
149
- }, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }) }) })] }) }));
150
+ }, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(TablePlugin, {}), _jsx(TableCellResizerPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(ExcalidrawPlugin, {}), _jsx(CollapsiblePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }) }) })] }) }));
150
151
  });
151
152
  function LexicalWithTools({ content, serviceManager, }) {
152
153
  // Get all actions for this lexical document
@@ -18,3 +18,4 @@ export { default as CopilotKitNotebookExample } from './CopilotKitNotebookExampl
18
18
  export { default as DatalayerNotebookExample } from './DatalayerNotebookExample';
19
19
  export { default as JupyterCellExample } from './JupyterCellExample';
20
20
  export { default as JupyterNotebookExample } from './JupyterNotebookExample';
21
+ export type { Agent, AgentStatus, AgentsState, Transport, } from './stores/examplesStore';
@@ -1,48 +1,48 @@
1
1
  {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 1,
6
- "metadata": {},
7
- "outputs": [
2
+ "cells": [
8
3
  {
9
- "data": {
10
- "text/plain": ["4"]
11
- },
12
- "execution_count": 1,
13
- "metadata": {},
14
- "output_type": "execute_result"
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/plain": ["4"]
11
+ },
12
+ "execution_count": 1,
13
+ "metadata": {},
14
+ "output_type": "execute_result"
15
+ }
16
+ ],
17
+ "source": ["2+2"]
18
+ },
19
+ {
20
+ "cell_type": "code",
21
+ "execution_count": null,
22
+ "metadata": {},
23
+ "outputs": [],
24
+ "source": []
25
+ }
26
+ ],
27
+ "metadata": {
28
+ "kernelspec": {
29
+ "display_name": "Python (ipykernel)",
30
+ "language": "python",
31
+ "name": "python"
32
+ },
33
+ "language_info": {
34
+ "codemirror_mode": {
35
+ "name": "ipython",
36
+ "version": 3
37
+ },
38
+ "file_extension": ".py",
39
+ "mimetype": "text/x-python",
40
+ "name": "python",
41
+ "nbconvert_exporter": "python",
42
+ "pygments_lexer": "ipython3",
43
+ "version": "3.10.4"
15
44
  }
16
- ],
17
- "source": ["2+2"]
18
- },
19
- {
20
- "cell_type": "code",
21
- "execution_count": null,
22
- "metadata": {},
23
- "outputs": [],
24
- "source": []
25
- }
26
- ],
27
- "metadata": {
28
- "kernelspec": {
29
- "display_name": "Python (ipykernel)",
30
- "language": "python",
31
- "name": "python"
32
45
  },
33
- "language_info": {
34
- "codemirror_mode": {
35
- "name": "ipython",
36
- "version": 3
37
- },
38
- "file_extension": ".py",
39
- "mimetype": "text/x-python",
40
- "name": "python",
41
- "nbconvert_exporter": "python",
42
- "pygments_lexer": "ipython3",
43
- "version": "3.10.4"
44
- }
45
- },
46
- "nbformat": 4,
47
- "nbformat_minor": 4
46
+ "nbformat": 4,
47
+ "nbformat_minor": 4
48
48
  }