@datalayer/agent-runtimes 1.0.4 → 1.0.6

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 (299) hide show
  1. package/README.md +182 -1
  2. package/lib/AgentNode.d.ts +3 -0
  3. package/lib/AgentNode.js +676 -0
  4. package/lib/App.js +1 -1
  5. package/lib/agent-node/themeStore.d.ts +3 -0
  6. package/lib/agent-node/themeStore.js +156 -0
  7. package/lib/agent-node-main.d.ts +1 -0
  8. package/lib/agent-node-main.js +14 -0
  9. package/lib/agents/AgentDetails.d.ts +22 -1
  10. package/lib/agents/AgentDetails.js +34 -47
  11. package/lib/api/index.d.ts +0 -1
  12. package/lib/api/index.js +4 -2
  13. package/lib/chat/Chat.d.ts +5 -106
  14. package/lib/chat/Chat.js +20 -14
  15. package/lib/chat/ChatFloating.d.ts +7 -140
  16. package/lib/chat/ChatFloating.js +3 -3
  17. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  18. package/lib/chat/ChatPopupStandalone.js +3 -3
  19. package/lib/chat/ChatSidebar.d.ts +4 -69
  20. package/lib/chat/ChatSidebar.js +83 -51
  21. package/lib/chat/ChatStandalone.d.ts +4 -54
  22. package/lib/chat/ChatStandalone.js +3 -3
  23. package/lib/chat/base/ChatBase.js +1414 -174
  24. package/lib/chat/display/FloatingBrandButton.js +8 -1
  25. package/lib/chat/header/ChatHeader.d.ts +3 -1
  26. package/lib/chat/header/ChatHeader.js +15 -12
  27. package/lib/chat/header/ChatHeaderBase.d.ts +30 -5
  28. package/lib/chat/header/ChatHeaderBase.js +41 -16
  29. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  30. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  31. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  32. package/lib/chat/indicators/SandboxStatusIndicator.js +91 -56
  33. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  34. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  35. package/lib/chat/indicators/index.d.ts +1 -0
  36. package/lib/chat/indicators/index.js +1 -0
  37. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  38. package/lib/chat/messages/ChatMessageList.js +154 -114
  39. package/lib/chat/messages/ChatMessages.js +6 -2
  40. package/lib/chat/prompt/InputFooter.d.ts +21 -6
  41. package/lib/chat/prompt/InputFooter.js +76 -20
  42. package/lib/chat/prompt/InputPrompt.d.ts +5 -1
  43. package/lib/chat/prompt/InputPrompt.js +4 -4
  44. package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
  45. package/lib/chat/prompt/InputPromptFooter.js +3 -3
  46. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  47. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  48. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  49. package/lib/chat/prompt/InputPromptText.js +2 -2
  50. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  51. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  52. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  53. package/lib/chat/usage/TokenUsageBar.js +20 -2
  54. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  55. package/lib/client/AgentRuntimesClientContext.js +55 -0
  56. package/lib/client/AgentsMixin.d.ts +0 -18
  57. package/lib/client/AgentsMixin.js +20 -30
  58. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  59. package/lib/client/IAgentRuntimesClient.js +5 -0
  60. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  61. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  62. package/lib/client/index.d.ts +4 -1
  63. package/lib/client/index.js +3 -1
  64. package/lib/components/NotificationEventCard.js +5 -1
  65. package/lib/config/AgentConfiguration.d.ts +22 -0
  66. package/lib/config/AgentConfiguration.js +319 -64
  67. package/lib/context/ContextDistribution.d.ts +3 -1
  68. package/lib/context/ContextDistribution.js +8 -27
  69. package/lib/context/ContextInspector.d.ts +3 -1
  70. package/lib/context/ContextInspector.js +19 -67
  71. package/lib/context/ContextPanel.d.ts +3 -1
  72. package/lib/context/ContextPanel.js +104 -64
  73. package/lib/context/ContextUsage.d.ts +3 -1
  74. package/lib/context/ContextUsage.js +3 -3
  75. package/lib/context/CostTracker.d.ts +9 -3
  76. package/lib/context/CostTracker.js +26 -47
  77. package/lib/context/CostUsageChart.d.ts +12 -0
  78. package/lib/context/CostUsageChart.js +378 -0
  79. package/lib/context/GraphFlowChart.d.ts +16 -0
  80. package/lib/context/GraphFlowChart.js +182 -0
  81. package/lib/context/TokenUsageChart.d.ts +8 -1
  82. package/lib/context/TokenUsageChart.js +349 -211
  83. package/lib/context/TurnGraphChart.d.ts +39 -0
  84. package/lib/context/TurnGraphChart.js +538 -0
  85. package/lib/context/otelWsPool.d.ts +20 -0
  86. package/lib/context/otelWsPool.js +69 -0
  87. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  88. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  89. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  90. package/lib/examples/A2UiContactCardExample.js +154 -411
  91. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  92. package/lib/examples/A2UiRestaurantExample.js +114 -212
  93. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  94. package/lib/examples/A2UiViewerExample.js +283 -532
  95. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  96. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  97. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  98. package/lib/examples/AgUiSharedStateExample.js +2 -1
  99. package/lib/examples/AgentCheckpointsExample.js +14 -28
  100. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  101. package/lib/examples/AgentCodemodeExample.js +603 -169
  102. package/lib/examples/AgentEvalsExample.js +339 -53
  103. package/lib/examples/AgentGuardrailsExample.js +383 -66
  104. package/lib/examples/AgentHooksExample.d.ts +3 -0
  105. package/lib/examples/AgentHooksExample.js +122 -0
  106. package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
  107. package/lib/examples/AgentInferenceProviderExample.js +329 -0
  108. package/lib/examples/AgentMCPExample.d.ts +3 -0
  109. package/lib/examples/AgentMCPExample.js +481 -0
  110. package/lib/examples/AgentMemoryExample.d.ts +1 -2
  111. package/lib/examples/AgentMemoryExample.js +78 -33
  112. package/lib/examples/AgentMonitoringExample.js +261 -200
  113. package/lib/examples/AgentNotificationsExample.d.ts +1 -2
  114. package/lib/examples/AgentNotificationsExample.js +114 -33
  115. package/lib/examples/AgentOtelExample.js +32 -42
  116. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  117. package/lib/examples/AgentOutputsExample.js +433 -81
  118. package/lib/examples/AgentParametersExample.d.ts +3 -0
  119. package/lib/examples/AgentParametersExample.js +248 -0
  120. package/lib/examples/AgentSandboxExample.d.ts +3 -3
  121. package/lib/examples/AgentSandboxExample.js +74 -45
  122. package/lib/examples/AgentSkillsExample.js +95 -103
  123. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  124. package/lib/examples/AgentSubagentsExample.js +228 -0
  125. package/lib/examples/AgentToolApprovalsExample.js +49 -561
  126. package/lib/examples/AgentTriggersExample.js +823 -569
  127. package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
  128. package/lib/examples/AgentspecsExample.js +1096 -0
  129. package/lib/examples/ChatCustomExample.js +16 -28
  130. package/lib/examples/ChatExample.js +13 -29
  131. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  132. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  133. package/lib/examples/HomeExample.d.ts +15 -0
  134. package/lib/examples/HomeExample.js +77 -0
  135. package/lib/examples/Lexical2Example.js +4 -2
  136. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  137. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +66 -17
  138. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  139. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  140. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  141. package/lib/examples/NotebookAgentExample.js +192 -0
  142. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  143. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  144. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  145. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  146. package/lib/examples/NotebookExample.d.ts +4 -7
  147. package/lib/examples/NotebookExample.js +14 -146
  148. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  149. package/lib/examples/components/AuthRequiredView.js +33 -0
  150. package/lib/examples/components/ExampleWrapper.d.ts +9 -3
  151. package/lib/examples/components/ExampleWrapper.js +45 -9
  152. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  153. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  154. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  155. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  156. package/lib/examples/components/index.d.ts +3 -0
  157. package/lib/examples/components/index.js +4 -0
  158. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  159. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  160. package/lib/examples/example-selector.d.ts +17 -4
  161. package/lib/examples/example-selector.js +108 -41
  162. package/lib/examples/index.d.ts +10 -6
  163. package/lib/examples/index.js +10 -6
  164. package/lib/examples/lexical/initial-content.json +6 -6
  165. package/lib/examples/main.js +257 -27
  166. package/lib/examples/utils/a2ui.d.ts +18 -0
  167. package/lib/examples/utils/a2ui.js +69 -0
  168. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  169. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  170. package/lib/examples/utils/agentId.d.ts +18 -0
  171. package/lib/examples/utils/agentId.js +54 -0
  172. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  173. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  174. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  175. package/lib/examples/utils/agents/stock-market.json +11 -11
  176. package/lib/examples/utils/examplesStore.js +82 -27
  177. package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
  178. package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
  179. package/lib/hooks/index.d.ts +8 -8
  180. package/lib/hooks/index.js +7 -7
  181. package/lib/hooks/useA2A.d.ts +2 -3
  182. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  183. package/lib/hooks/useAIAgentsWebSocket.js +153 -12
  184. package/lib/hooks/useAcp.d.ts +1 -2
  185. package/lib/hooks/useAgUi.d.ts +1 -1
  186. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +70 -4
  187. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
  188. package/lib/hooks/useAgentsCatalog.js +1 -1
  189. package/lib/hooks/useAgentsService.d.ts +2 -2
  190. package/lib/hooks/useAgentsService.js +7 -7
  191. package/lib/hooks/useCheckpoints.js +1 -1
  192. package/lib/hooks/useConfig.d.ts +4 -1
  193. package/lib/hooks/useConfig.js +10 -3
  194. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  195. package/lib/hooks/useContextSnapshot.js +9 -37
  196. package/lib/hooks/useMonitoring.js +3 -0
  197. package/lib/hooks/useSandbox.d.ts +20 -8
  198. package/lib/hooks/useSandbox.js +105 -40
  199. package/lib/hooks/useSkills.d.ts +23 -5
  200. package/lib/hooks/useSkills.js +94 -39
  201. package/lib/hooks/useToolApprovals.d.ts +60 -36
  202. package/lib/hooks/useToolApprovals.js +318 -69
  203. package/lib/hooks/useVercelAI.d.ts +1 -1
  204. package/lib/index.d.ts +2 -1
  205. package/lib/index.js +1 -0
  206. package/lib/inference/index.d.ts +0 -1
  207. package/lib/middleware/index.d.ts +0 -1
  208. package/lib/protocols/AGUIAdapter.js +6 -0
  209. package/lib/protocols/VercelAIAdapter.d.ts +7 -0
  210. package/lib/protocols/VercelAIAdapter.js +59 -7
  211. package/lib/specs/agents/agents.d.ts +21 -4
  212. package/lib/specs/agents/agents.js +2879 -316
  213. package/lib/specs/agents/index.js +3 -1
  214. package/lib/specs/benchmarks.d.ts +20 -0
  215. package/lib/specs/benchmarks.js +205 -0
  216. package/lib/specs/envvars.js +27 -20
  217. package/lib/specs/evals.d.ts +10 -9
  218. package/lib/specs/evals.js +128 -88
  219. package/lib/specs/events.d.ts +3 -10
  220. package/lib/specs/events.js +127 -84
  221. package/lib/specs/frontendTools.js +2 -2
  222. package/lib/specs/guardrails.d.ts +0 -7
  223. package/lib/specs/guardrails.js +240 -159
  224. package/lib/specs/mcpServers.js +35 -6
  225. package/lib/specs/memory.d.ts +0 -2
  226. package/lib/specs/memory.js +4 -17
  227. package/lib/specs/models.d.ts +0 -2
  228. package/lib/specs/models.js +20 -15
  229. package/lib/specs/notifications.js +102 -18
  230. package/lib/specs/outputs.js +15 -9
  231. package/lib/specs/personas.d.ts +41 -0
  232. package/lib/specs/personas.js +168 -0
  233. package/lib/specs/skills.d.ts +1 -1
  234. package/lib/specs/skills.js +23 -23
  235. package/lib/specs/teams/index.js +3 -1
  236. package/lib/specs/teams/teams.js +468 -348
  237. package/lib/specs/tools.js +4 -4
  238. package/lib/specs/triggers.js +61 -11
  239. package/lib/stores/agentRuntimeStore.d.ts +208 -0
  240. package/lib/stores/agentRuntimeStore.js +650 -0
  241. package/lib/stores/conversationStore.js +2 -2
  242. package/lib/stores/index.d.ts +1 -1
  243. package/lib/stores/index.js +1 -1
  244. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  245. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  246. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  247. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  248. package/lib/tools/index.d.ts +0 -2
  249. package/lib/tools/index.js +0 -1
  250. package/lib/types/agents-lifecycle.d.ts +18 -0
  251. package/lib/types/agents.d.ts +6 -0
  252. package/lib/types/agentspecs.d.ts +54 -1
  253. package/lib/types/benchmarks.d.ts +43 -0
  254. package/lib/types/benchmarks.js +5 -0
  255. package/lib/types/chat.d.ts +325 -8
  256. package/lib/types/context.d.ts +27 -0
  257. package/lib/types/cost.d.ts +2 -2
  258. package/lib/types/evals.d.ts +26 -17
  259. package/lib/types/index.d.ts +3 -0
  260. package/lib/types/index.js +3 -0
  261. package/lib/types/mcp.d.ts +8 -0
  262. package/lib/types/models.d.ts +2 -2
  263. package/lib/types/personas.d.ts +25 -0
  264. package/lib/types/personas.js +5 -0
  265. package/lib/types/skills.d.ts +43 -1
  266. package/lib/types/stream.d.ts +110 -0
  267. package/lib/types/stream.js +36 -0
  268. package/lib/utils/utils.d.ts +9 -5
  269. package/lib/utils/utils.js +9 -5
  270. package/package.json +19 -11
  271. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  272. package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
  273. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  274. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  275. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  276. package/scripts/codegen/generate_agents.py +187 -45
  277. package/scripts/codegen/generate_benchmarks.py +441 -0
  278. package/scripts/codegen/generate_evals.py +94 -16
  279. package/scripts/codegen/generate_events.py +35 -14
  280. package/scripts/codegen/generate_personas.py +319 -0
  281. package/scripts/codegen/generate_skills.py +9 -9
  282. package/scripts/sync-jupyter.sh +26 -7
  283. package/lib/api/tool-approvals.d.ts +0 -62
  284. package/lib/api/tool-approvals.js +0 -145
  285. package/lib/examples/AgentspecExample.js +0 -705
  286. package/lib/examples/LexicalSidebarExample.js +0 -163
  287. package/lib/examples/NotebookSidebarExample.js +0 -119
  288. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  289. package/lib/examples/NotebookSimpleExample.js +0 -22
  290. package/lib/examples/ag-ui/index.d.ts +0 -10
  291. package/lib/examples/ag-ui/index.js +0 -16
  292. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  293. package/lib/hooks/useAgentsRegistry.js +0 -20
  294. package/lib/stores/agentsStore.d.ts +0 -123
  295. package/lib/stores/agentsStore.js +0 -270
  296. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  297. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  298. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  299. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -8,6 +8,7 @@ import { Text, TextInput, Button, FormControl, Select, Checkbox, Spinner, Flash,
8
8
  import { ToolsIcon, KeyIcon, SyncIcon, PlusIcon, XIcon, LinkExternalIcon, } from '@primer/octicons-react';
9
9
  import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
10
10
  import { Box } from '@datalayer/primer-addons';
11
+ import { getSkillSpec, getSkillSpecs } from '../specs/skills';
11
12
  import { IdentityCard, IdentityConnect, useIdentity } from '../identity';
12
13
  /**
13
14
  * Helper: is the selected agent id a library spec?
@@ -17,6 +18,14 @@ export const isSpecSelection = (id) => id.startsWith('spec:');
17
18
  * Helper: extract the spec id from a spec selection value.
18
19
  */
19
20
  export const getSpecId = (id) => id.replace(/^spec:/, '');
21
+ /**
22
+ * Helper: is the selected agent id a cloud library spec?
23
+ */
24
+ export const isCloudSpecSelection = (id) => id.startsWith('cloud-spec:');
25
+ /**
26
+ * Helper: extract the cloud spec id from a cloud selection value.
27
+ */
28
+ export const getCloudSpecId = (id) => id.replace(/^cloud-spec:/, '');
20
29
  /**
21
30
  * Token-based identity providers that can be connected via API key
22
31
  */
@@ -143,6 +152,35 @@ function IdentityConnectWithStatus({ identityProviders = {}, disabled = false, o
143
152
  setTokenInput('');
144
153
  }, variant: "invisible" })] })] }))] }, tp.provider))) }))] }));
145
154
  }
155
+ const normalizeEnvVarRef = (ref) => ref.replace(/:\d+\.\d+\.\d+$/, '');
156
+ const normalizeMcpServerId = (id) => id.replace(/:\d+\.\d+\.\d+$/, '');
157
+ const normalizeToolLabel = (tool) => {
158
+ if (typeof tool === 'string') {
159
+ return tool;
160
+ }
161
+ if (typeof tool === 'object' && tool !== null) {
162
+ const toolObj = tool;
163
+ const fromName = typeof toolObj.name === 'string' && toolObj.name.trim().length > 0
164
+ ? toolObj.name.trim()
165
+ : null;
166
+ if (fromName) {
167
+ return fromName;
168
+ }
169
+ const fromId = typeof toolObj.id === 'string' && toolObj.id.trim().length > 0
170
+ ? toolObj.id.trim()
171
+ : null;
172
+ if (fromId) {
173
+ return fromId;
174
+ }
175
+ const fromTool = typeof toolObj.tool === 'string' && toolObj.tool.trim().length > 0
176
+ ? toolObj.tool.trim()
177
+ : null;
178
+ if (fromTool) {
179
+ return fromTool;
180
+ }
181
+ }
182
+ return null;
183
+ };
146
184
  const AGENT_LIBRARIES = [
147
185
  {
148
186
  value: 'pydantic-ai',
@@ -206,7 +244,7 @@ const EXTENSIONS = [
206
244
  *
207
245
  * Form for configuring agent connection settings.
208
246
  */
209
- export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensions, wsUrl, baseUrl, agentName, description, goal, model, systemPrompt, systemPromptCodemodeAddons, tools, sandboxVariant, agents, selectedAgentId, isCreatingAgent = false, createError = null, enableCodemode = false, allowDirectToolCalls = false, enableToolReranker = false, useJupyterSandbox = false, availableSkills = [], selectedSkills = [], selectedMcpServers = [], identityProviders, onIdentityConnect, onIdentityDisconnect, onAgentLibraryChange, onTransportChange, onExtensionsChange, onWsUrlChange, onBaseUrlChange, onAgentNameChange, onDescriptionChange, onGoalChange, onModelChange, onSystemPromptChange, onSystemPromptCodemodeAddonsChange, onToolsChange, onSandboxVariantChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onUseJupyterSandboxChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
247
+ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensions, wsUrl, baseUrl, agentName, description, goal, model, systemPrompt, systemPromptCodemodeAddons, tools, sandboxVariant, agents, selectedAgentId, isCreatingAgent = false, createError = null, enableCodemode = false, allowDirectToolCalls = false, enableToolReranker = false, useJupyterSandbox = false, availableSkills = [], selectedSkills = [], selectedMcpServers = [], cloudLibrarySpecs = [], cloudLibraryLoading = false, cloudLibraryError = null, launchTarget = 'local', launchStatus = 'idle', launchBaseUrl, identityProviders, onIdentityConnect, onIdentityDisconnect, onAgentLibraryChange, onTransportChange, onExtensionsChange, onWsUrlChange, onBaseUrlChange, onAgentNameChange, onDescriptionChange, onGoalChange, onModelChange, onSystemPromptChange, onSystemPromptCodemodeAddonsChange, onToolsChange, onSandboxVariantChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onUseJupyterSandboxChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
210
248
  // Fetch general configuration from the backend (models, etc.)
211
249
  const configQuery = useQuery({
212
250
  queryKey: ['agent-config', baseUrl],
@@ -250,22 +288,25 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
250
288
  retry: 1,
251
289
  });
252
290
  const librarySpecs = libraryQuery.data || [];
253
- // The currently selected library spec (if any)
291
+ // The currently selected local library spec (if any)
254
292
  const selectedSpec = useMemo(() => {
255
293
  if (!isSpecSelection(selectedAgentId))
256
294
  return null;
257
295
  const specId = getSpecId(selectedAgentId);
258
296
  return librarySpecs.find(s => s.id === specId) || null;
259
297
  }, [selectedAgentId, librarySpecs]);
260
- const selectedSpecEntries = useMemo(() => {
261
- if (!selectedSpec)
262
- return [];
263
- return Object.entries(selectedSpec).filter(([, value]) => value !== undefined);
264
- }, [selectedSpec]);
298
+ const selectedCloudSpec = useMemo(() => {
299
+ if (!isCloudSpecSelection(selectedAgentId))
300
+ return null;
301
+ const specId = getCloudSpecId(selectedAgentId);
302
+ return cloudLibrarySpecs.find(s => s.id === specId) || null;
303
+ }, [selectedAgentId, cloudLibrarySpecs]);
265
304
  // When a spec is selected, form behaves like new-agent but with pre-filled values
266
- const isNewAgentMode = selectedAgentId === 'new-agent' || isSpecSelection(selectedAgentId);
305
+ const isNewAgentMode = selectedAgentId === 'new-agent' ||
306
+ isSpecSelection(selectedAgentId) ||
307
+ isCloudSpecSelection(selectedAgentId);
267
308
  // True when a library spec is selected (fields locked down except Name, URL, Library, Model, Transport, Extensions)
268
- const isSpecMode = isSpecSelection(selectedAgentId);
309
+ const isSpecMode = isSpecSelection(selectedAgentId) || isCloudSpecSelection(selectedAgentId);
269
310
  // Entire form is read-only for existing agents and library spec selections.
270
311
  const isFormReadOnly = !isNewAgentMode || isSpecMode;
271
312
  // Fetch skills from the backend (always available, independent of codemode)
@@ -320,16 +361,157 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
320
361
  const configServers = mcpServersQuery.data || configQuery.data?.mcpServers || [];
321
362
  const catalogServers = catalogServersQuery.data || [];
322
363
  const models = configQuery.data?.models || [];
323
- // Use fetched skills when available, otherwise use passed availableSkills (which may be empty)
324
- const fetchedSkills = skillsQuery.data?.skills || [];
325
- const displaySkills = fetchedSkills.length > 0 ? fetchedSkills : availableSkills;
364
+ const activeSpec = selectedSpec || selectedCloudSpec;
365
+ const availableEnvVars = useMemo(() => {
366
+ const vars = new Set();
367
+ for (const model of models) {
368
+ if (model.isAvailable !== false) {
369
+ for (const envVar of model.requiredEnvVars || []) {
370
+ vars.add(normalizeEnvVarRef(envVar));
371
+ }
372
+ }
373
+ }
374
+ for (const server of [...configServers, ...catalogServers]) {
375
+ const serverAvailable = server.isAvailable === true || server.isRunning === true;
376
+ if (!serverAvailable) {
377
+ continue;
378
+ }
379
+ for (const envVar of server.requiredEnvVars || []) {
380
+ vars.add(normalizeEnvVarRef(envVar));
381
+ }
382
+ }
383
+ return vars;
384
+ }, [models, configServers, catalogServers]);
385
+ const skillsFromSelectedSpec = useMemo(() => {
386
+ if (!activeSpec || !Array.isArray(activeSpec.skills)) {
387
+ return [];
388
+ }
389
+ return activeSpec.skills
390
+ .map(skillRef => {
391
+ if (typeof skillRef === 'string') {
392
+ const catalog = getSkillSpec(skillRef);
393
+ return {
394
+ id: skillRef,
395
+ name: catalog?.name || skillRef,
396
+ description: catalog?.description,
397
+ requiredEnvVars: catalog?.requiredEnvVars || [],
398
+ };
399
+ }
400
+ if (typeof skillRef === 'object' && skillRef !== null) {
401
+ const skillObj = skillRef;
402
+ const rawId = skillObj.id || skillObj.name || '';
403
+ if (!rawId) {
404
+ return null;
405
+ }
406
+ const catalog = getSkillSpec(rawId);
407
+ return {
408
+ id: rawId,
409
+ name: skillObj.name || catalog?.name || rawId,
410
+ description: skillObj.description || catalog?.description,
411
+ requiredEnvVars: skillObj.requiredEnvVars || catalog?.requiredEnvVars || [],
412
+ };
413
+ }
414
+ return null;
415
+ })
416
+ .filter((skill) => skill !== null);
417
+ }, [activeSpec]);
418
+ const skillsFromCatalog = useMemo(() => {
419
+ return getSkillSpecs().map(skill => ({
420
+ id: skill.id,
421
+ name: skill.name,
422
+ description: skill.description,
423
+ requiredEnvVars: skill.requiredEnvVars || [],
424
+ }));
425
+ }, []);
426
+ const baseSkills = useMemo(() => {
427
+ if (skillsFromSelectedSpec.length > 0) {
428
+ return skillsFromSelectedSpec;
429
+ }
430
+ return skillsFromCatalog;
431
+ }, [skillsFromSelectedSpec, skillsFromCatalog]);
432
+ const displaySkills = useMemo(() => {
433
+ return baseSkills.map(skill => {
434
+ const required = (skill.requiredEnvVars || []).map(normalizeEnvVarRef);
435
+ const envVarsAvailable = required.length === 0 ||
436
+ required.every(envVar => availableEnvVars.has(envVar));
437
+ return {
438
+ ...skill,
439
+ requiredEnvVars: required,
440
+ isAvailable: envVarsAvailable,
441
+ };
442
+ });
443
+ }, [baseSkills, availableEnvVars]);
444
+ const usingSpecSkills = skillsFromSelectedSpec.length > 0;
445
+ const usingCatalogFallback = !usingSpecSkills;
326
446
  const skillsEnabled = selectedSkills.length > 0;
327
- const selectedConfigServers = selectedMcpServers
328
- .filter(s => s.origin === 'config')
329
- .map(s => s.id);
330
- const selectedCatalogServers = selectedMcpServers
331
- .filter(s => s.origin === 'catalog')
332
- .map(s => s.id);
447
+ const configServerIdSet = useMemo(() => new Set(configServers.map(server => normalizeMcpServerId(server.id))), [configServers]);
448
+ const catalogServerIdSet = useMemo(() => new Set(catalogServers.map(server => normalizeMcpServerId(server.id))), [catalogServers]);
449
+ const selectedConfigServers = useMemo(() => {
450
+ return selectedMcpServers
451
+ .filter(selection => {
452
+ const normalizedId = normalizeMcpServerId(selection.id);
453
+ if (selection.origin === 'config') {
454
+ return configServerIdSet.has(normalizedId);
455
+ }
456
+ if (selection.origin === 'catalog') {
457
+ return (!catalogServerIdSet.has(normalizedId) &&
458
+ configServerIdSet.has(normalizedId));
459
+ }
460
+ return false;
461
+ })
462
+ .map(selection => normalizeMcpServerId(selection.id));
463
+ }, [selectedMcpServers, configServerIdSet]);
464
+ const selectedCatalogServers = useMemo(() => {
465
+ return selectedMcpServers
466
+ .filter(selection => {
467
+ const normalizedId = normalizeMcpServerId(selection.id);
468
+ if (selection.origin === 'catalog') {
469
+ return catalogServerIdSet.has(normalizedId);
470
+ }
471
+ if (selection.origin === 'config') {
472
+ return (!configServerIdSet.has(normalizedId) &&
473
+ catalogServerIdSet.has(normalizedId));
474
+ }
475
+ return false;
476
+ })
477
+ .map(selection => normalizeMcpServerId(selection.id));
478
+ }, [selectedMcpServers, catalogServerIdSet]);
479
+ const resolvedSpecTools = useMemo(() => {
480
+ if (!activeSpec || !Array.isArray(activeSpec.tools)) {
481
+ return [];
482
+ }
483
+ return activeSpec.tools
484
+ .map(tool => normalizeToolLabel(tool))
485
+ .filter((tool) => !!tool);
486
+ }, [activeSpec]);
487
+ const toolsInputValue = isSpecMode && resolvedSpecTools.length > 0
488
+ ? resolvedSpecTools.join(', ')
489
+ : tools.join(', ');
490
+ const toolsInputPlaceholder = isSpecMode
491
+ ? 'No tools defined by selected spec'
492
+ : 'runtime-echo, runtime-send-mail';
493
+ const unresolvedSelectedMcpServers = useMemo(() => {
494
+ return selectedMcpServers
495
+ .map(selection => normalizeMcpServerId(selection.id))
496
+ .filter(id => !configServerIdSet.has(id) && !catalogServerIdSet.has(id))
497
+ .filter((id, index, arr) => arr.indexOf(id) === index);
498
+ }, [selectedMcpServers, configServerIdSet, catalogServerIdSet]);
499
+ const enabledLocalSpecs = [...librarySpecs]
500
+ .filter(s => s.enabled)
501
+ .sort((a, b) => {
502
+ const pkgA = a.id.includes('/') ? a.id.split('/')[0] : '';
503
+ const pkgB = b.id.includes('/') ? b.id.split('/')[0] : '';
504
+ const cmp = pkgA.localeCompare(pkgB);
505
+ return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
506
+ });
507
+ const enabledCloudSpecs = [...cloudLibrarySpecs]
508
+ .filter(s => s.enabled)
509
+ .sort((a, b) => {
510
+ const pkgA = a.id.includes('/') ? a.id.split('/')[0] : '';
511
+ const pkgB = b.id.includes('/') ? b.id.split('/')[0] : '';
512
+ const cmp = pkgA.localeCompare(pkgB);
513
+ return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
514
+ });
333
515
  // Preview servers combines both config and catalog selections
334
516
  const previewConfigServers = selectedConfigServers.length
335
517
  ? configServers.filter(server => selectedConfigServers.includes(server.id))
@@ -341,16 +523,19 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
341
523
  const handleConfigServerChange = (serverId, checked) => {
342
524
  if (!onSelectedMcpServersChange)
343
525
  return;
526
+ const normalizedServerId = normalizeMcpServerId(serverId);
344
527
  if (checked) {
345
- if (!selectedMcpServers.some(s => s.id === serverId && s.origin === 'config')) {
528
+ if (!selectedMcpServers.some(s => normalizeMcpServerId(s.id) === normalizedServerId &&
529
+ s.origin === 'config')) {
346
530
  onSelectedMcpServersChange([
347
- ...selectedMcpServers,
348
- { id: serverId, origin: 'config' },
531
+ ...selectedMcpServers.filter(s => normalizeMcpServerId(s.id) !== normalizedServerId),
532
+ { id: normalizedServerId, origin: 'config' },
349
533
  ]);
350
534
  }
351
535
  }
352
536
  else {
353
- onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id === serverId && s.origin === 'config')));
537
+ onSelectedMcpServersChange(selectedMcpServers.filter(s => !(normalizeMcpServerId(s.id) === normalizedServerId &&
538
+ s.origin === 'config')));
354
539
  }
355
540
  };
356
541
  // Handle MCP Catalog server checkbox change
@@ -358,6 +543,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
358
543
  const handleCatalogServerChange = async (serverId, checked, isRunning) => {
359
544
  if (!onSelectedMcpServersChange)
360
545
  return;
546
+ const normalizedServerId = normalizeMcpServerId(serverId);
361
547
  if (checked) {
362
548
  // If not running, start the server first
363
549
  if (!isRunning) {
@@ -369,15 +555,17 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
369
555
  return; // Don't add to selection if enable failed
370
556
  }
371
557
  }
372
- if (!selectedMcpServers.some(s => s.id === serverId && s.origin === 'catalog')) {
558
+ if (!selectedMcpServers.some(s => normalizeMcpServerId(s.id) === normalizedServerId &&
559
+ s.origin === 'catalog')) {
373
560
  onSelectedMcpServersChange([
374
- ...selectedMcpServers,
375
- { id: serverId, origin: 'catalog' },
561
+ ...selectedMcpServers.filter(s => normalizeMcpServerId(s.id) !== normalizedServerId),
562
+ { id: normalizedServerId, origin: 'catalog' },
376
563
  ]);
377
564
  }
378
565
  }
379
566
  else {
380
- onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id === serverId && s.origin === 'catalog')));
567
+ onSelectedMcpServersChange(selectedMcpServers.filter(s => !(normalizeMcpServerId(s.id) === normalizedServerId &&
568
+ s.origin === 'catalog')));
381
569
  }
382
570
  };
383
571
  const handleSkillChange = (skillId, checked) => {
@@ -420,31 +608,103 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
420
608
  fontWeight: 'bold',
421
609
  display: 'block',
422
610
  marginBottom: 3,
423
- }, children: "Create a new Agent" }), _jsxs(FormControl, { sx: { marginBottom: 3 }, children: [_jsx(FormControl.Label, { children: "Available Agents" }), _jsxs(Select, { value: selectedAgentId, onChange: e => onAgentSelect(e.target.value), sx: { width: '100%' }, children: [_jsx(Select.Option, { value: "new-agent", children: "+ New Agent..." }), [...librarySpecs]
424
- .filter(s => s.enabled)
425
- .sort((a, b) => {
426
- const pkgA = a.id.includes('/') ? a.id.split('/')[0] : '';
427
- const pkgB = b.id.includes('/') ? b.id.split('/')[0] : '';
428
- const cmp = pkgA.localeCompare(pkgB);
429
- return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
430
- })
431
- .map(spec => {
432
- const pkg = spec.id.includes('/') ? spec.id.split('/')[0] : '';
433
- return (_jsxs(Select.Option, { value: `spec:${spec.id}`, children: [spec.emoji ? `${spec.emoji} ` : '', pkg ? `[${pkg}] ` : '', spec.name] }, `spec:${spec.id}`));
434
- }), agents.map(agent => (_jsxs(Select.Option, { value: agent.id, children: ["[Example] ", agent.status === 'running' && '● ', agent.name] }, agent.id)))] }), _jsx(FormControl.Caption, { children: isNewAgentMode
435
- ? selectedSpec
436
- ? `Creating from spec: ${selectedSpec.name} capabilities are locked`
437
- : 'Configure a new custom agent'
438
- : 'Selected agent - form fields below are disabled' })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Name" }), _jsx(TextInput, { value: agentName, onChange: e => onAgentNameChange(e.target.value), placeholder: "demo-agent", sx: { width: '100%' } }), _jsx(FormControl.Caption, { children: "The name of the agent to connect to" })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(TextInput, { value: description, onChange: e => onDescriptionChange(e.target.value), placeholder: "Short agent description", sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Goal" }), _jsx(TextInput, { value: goal, onChange: e => onGoalChange(e.target.value), placeholder: "User-facing objective", sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: transport === 'acp' ? 'WebSocket URL' : 'Base URL' }), _jsx(TextInput, { value: transport === 'acp' ? wsUrl : baseUrl, onChange: e => transport === 'acp'
611
+ }, children: "Create a new Agent" }), _jsxs(FormControl, { sx: { marginBottom: 3 }, children: [_jsx(FormControl.Label, { children: "Available Agents" }), _jsxs(Box, { sx: { display: 'flex', gap: 2, mb: 2 }, children: [_jsxs(Label, { variant: launchTarget === 'cloud' ? 'accent' : 'secondary', children: ["Target: ", launchTarget === 'cloud' ? 'Cloud' : 'Local'] }), _jsxs(Label, { variant: launchStatus === 'error' ? 'danger' : 'attention', children: ["Launch: ", launchStatus] })] }), launchBaseUrl ? (_jsxs(Box, { sx: {
612
+ mb: 2,
613
+ p: 2,
614
+ border: '1px solid',
615
+ borderColor: 'border.default',
616
+ borderRadius: 2,
617
+ bg: 'canvas.default',
618
+ }, children: [_jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.muted' }, children: "Launch URL" }), _jsx(Text, { sx: {
619
+ display: 'block',
620
+ fontSize: 1,
621
+ fontFamily: 'mono',
622
+ wordBreak: 'break-all',
623
+ }, children: launchBaseUrl })] })) : null, _jsxs(Select, { value: selectedAgentId, onChange: e => onAgentSelect(e.target.value), sx: { width: '100%' }, children: [_jsxs("optgroup", { label: "Local Agents", children: [_jsx(Select.Option, { value: "new-agent", disabled: selectedAgentId === 'new-agent', children: "+ New Agent..." }), enabledLocalSpecs.map(spec => {
624
+ const pkg = spec.id.includes('/') ? spec.id.split('/')[0] : '';
625
+ const optionValue = `spec:${spec.id}`;
626
+ return (_jsxs(Select.Option, { value: optionValue, disabled: selectedAgentId === optionValue, children: [spec.emoji ? `${spec.emoji} ` : '', pkg ? `[${pkg}] ` : '', spec.name] }, optionValue));
627
+ }), agents.map(agent => (_jsxs(Select.Option, { value: agent.id, disabled: true, children: ["[Persona] ", agent.status === 'running' && '● ', agent.name] }, agent.id)))] }), _jsxs("optgroup", { label: "Cloud Agents", children: [cloudLibraryLoading && (_jsx(Select.Option, { value: "__cloud_loading", disabled: true, children: "Loading cloud agents..." })), !cloudLibraryLoading && enabledCloudSpecs.length === 0 && (_jsx(Select.Option, { value: "__cloud_empty", disabled: true, children: "No cloud agents available" })), !cloudLibraryLoading &&
628
+ enabledCloudSpecs.map(spec => {
629
+ const pkg = spec.id.includes('/') ? spec.id.split('/')[0] : '';
630
+ const optionValue = `cloud-spec:${spec.id}`;
631
+ return (_jsxs(Select.Option, { value: optionValue, disabled: selectedAgentId === optionValue, children: [spec.emoji ? `${spec.emoji} ` : '', pkg ? `[${pkg}] ` : '', spec.name] }, optionValue));
632
+ })] })] }), _jsxs(FormControl.Caption, { children: [isNewAgentMode
633
+ ? selectedSpec || selectedCloudSpec
634
+ ? `Creating from spec: ${(selectedSpec || selectedCloudSpec)?.name} — capabilities are locked`
635
+ : 'Configure a new custom agent'
636
+ : 'Selected agent - form fields below are disabled', cloudLibraryError ? ` Cloud fetch error: ${cloudLibraryError}` : ''] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Name" }), _jsx(TextInput, { value: agentName, onChange: e => onAgentNameChange(e.target.value), placeholder: "demo-agent", sx: { width: '100%' } }), _jsx(FormControl.Caption, { children: "The name of the agent to connect to" })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Box, { as: "textarea", value: description, onChange: e => onDescriptionChange(e.target.value), placeholder: "Short agent description", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 3, sx: {
637
+ width: '100%',
638
+ maxWidth: '100%',
639
+ minHeight: '88px',
640
+ resize: 'vertical',
641
+ border: '1px solid',
642
+ borderColor: 'border.default',
643
+ borderRadius: 2,
644
+ p: 2,
645
+ fontSize: 1,
646
+ whiteSpace: 'pre-wrap',
647
+ overflowWrap: 'anywhere',
648
+ bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
649
+ color: isFormReadOnly ? 'fg.muted' : 'fg.default',
650
+ } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Goal" }), _jsx(Box, { as: "textarea", value: goal, onChange: e => onGoalChange(e.target.value), placeholder: "User-facing objective", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 3, sx: {
651
+ width: '100%',
652
+ maxWidth: '100%',
653
+ minHeight: '88px',
654
+ resize: 'vertical',
655
+ border: '1px solid',
656
+ borderColor: 'border.default',
657
+ borderRadius: 2,
658
+ p: 2,
659
+ fontSize: 1,
660
+ whiteSpace: 'pre-wrap',
661
+ overflowWrap: 'anywhere',
662
+ bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
663
+ color: isFormReadOnly ? 'fg.muted' : 'fg.default',
664
+ } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: transport === 'acp' ? 'WebSocket URL' : 'Base URL' }), _jsx(TextInput, { value: transport === 'acp' ? wsUrl : baseUrl, onChange: e => transport === 'acp'
439
665
  ? onWsUrlChange(e.target.value)
440
666
  : onBaseUrlChange(e.target.value), placeholder: transport === 'acp'
441
667
  ? 'ws://localhost:8000/api/v1/acp/ws'
442
668
  : 'http://localhost:8000', sx: { width: '100%' } }), _jsx(FormControl.Caption, { children: transport === 'acp'
443
669
  ? 'The WebSocket endpoint of your agent-runtimes server'
444
- : 'The base URL of your agent-runtimes server' })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Library" }), _jsx(Select, { value: agentLibrary, onChange: e => onAgentLibraryChange(e.target.value), sx: { width: '100%' }, children: AGENT_LIBRARIES.map(lib => (_jsxs(Select.Option, { value: lib.value, disabled: lib.disabled, children: [lib.label, lib.disabled && ' (Coming Soon)'] }, lib.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly || models.length === 0, children: [_jsx(FormControl.Label, { children: "Model" }), _jsx(Select, { value: model, onChange: e => onModelChange(e.target.value), sx: { width: '100%' }, children: models.length === 0 ? (_jsx(Select.Option, { value: "", children: "Loading models..." })) : (models.map(m => (_jsxs(Select.Option, { value: m.id, disabled: !m.isAvailable, children: [m.name, !m.isAvailable && ' (API key required)'] }, m.id)))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Transport" }), _jsx(Select, { value: transport, onChange: e => onTransportChange(e.target.value), sx: { width: '100%' }, children: TRANSPORTS.map(t => (_jsx(Select.Option, { value: t.value, children: t.label }, t.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Extensions" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: EXTENSIONS.map(ext => (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { value: ext.value, checked: extensions.includes(ext.value), disabled: isFormReadOnly || !isExtensionEnabled(ext.value), onChange: e => handleExtensionChange(ext.value, e.target.checked) }), _jsx(Text, { children: ext.label })] }, ext.value))) })] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt" }), _jsx(TextInput, { value: systemPrompt, onChange: e => onSystemPromptChange(e.target.value), placeholder: "You are a helpful AI assistant.", sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt Codemode Addons" }), _jsx(TextInput, { value: systemPromptCodemodeAddons, onChange: e => onSystemPromptCodemodeAddonsChange(e.target.value), placeholder: "Additional codemode instructions", sx: { width: '100%' } })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Tools (comma-separated)" }), _jsx(TextInput, { value: tools.join(', '), onChange: e => onToolsChange(e.target.value
670
+ : 'The base URL of your agent-runtimes server' })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Library" }), _jsx(Select, { value: agentLibrary, onChange: e => onAgentLibraryChange(e.target.value), sx: { width: '100%' }, children: AGENT_LIBRARIES.map(lib => (_jsxs(Select.Option, { value: lib.value, disabled: lib.disabled, children: [lib.label, lib.disabled && ' (Coming Soon)'] }, lib.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly || models.length === 0, children: [_jsx(FormControl.Label, { children: "Model" }), _jsx(Select, { value: model, onChange: e => onModelChange(e.target.value), sx: { width: '100%' }, children: models.length === 0 ? (_jsx(Select.Option, { value: "", children: "Loading models..." })) : (models.map(m => (_jsxs(Select.Option, { value: m.id, disabled: !m.isAvailable, children: [m.name, !m.isAvailable && ' (API key required)'] }, m.id)))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Transport" }), _jsx(Select, { value: transport, onChange: e => onTransportChange(e.target.value), sx: { width: '100%' }, children: TRANSPORTS.map(t => (_jsx(Select.Option, { value: t.value, children: t.label }, t.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Extensions" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: EXTENSIONS.map(ext => (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { value: ext.value, checked: extensions.includes(ext.value), disabled: isFormReadOnly || !isExtensionEnabled(ext.value), onChange: e => handleExtensionChange(ext.value, e.target.checked) }), _jsx(Text, { children: ext.label })] }, ext.value))) })] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt" }), _jsx(Box, { as: "textarea", value: systemPrompt, onChange: e => onSystemPromptChange(e.target.value), placeholder: "You are a helpful AI assistant.", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 5, sx: {
671
+ width: '100%',
672
+ maxWidth: '100%',
673
+ minHeight: '120px',
674
+ resize: 'vertical',
675
+ border: '1px solid',
676
+ borderColor: 'border.default',
677
+ borderRadius: 2,
678
+ p: 2,
679
+ fontFamily: 'mono',
680
+ fontSize: 1,
681
+ whiteSpace: 'pre-wrap',
682
+ overflowWrap: 'anywhere',
683
+ bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
684
+ color: isFormReadOnly ? 'fg.muted' : 'fg.default',
685
+ userSelect: isFormReadOnly ? 'none' : 'text',
686
+ cursor: isFormReadOnly ? 'not-allowed' : 'text',
687
+ } })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt Codemode Addons" }), _jsx(Box, { as: "textarea", value: systemPromptCodemodeAddons, onChange: e => onSystemPromptCodemodeAddonsChange(e.target.value), placeholder: "Additional codemode instructions", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 4, sx: {
688
+ width: '100%',
689
+ maxWidth: '100%',
690
+ minHeight: '110px',
691
+ resize: 'vertical',
692
+ border: '1px solid',
693
+ borderColor: 'border.default',
694
+ borderRadius: 2,
695
+ p: 2,
696
+ fontFamily: 'mono',
697
+ fontSize: 1,
698
+ whiteSpace: 'pre-wrap',
699
+ overflowWrap: 'anywhere',
700
+ bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
701
+ color: isFormReadOnly ? 'fg.muted' : 'fg.default',
702
+ userSelect: isFormReadOnly ? 'none' : 'text',
703
+ cursor: isFormReadOnly ? 'not-allowed' : 'text',
704
+ } })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Tools (comma-separated)" }), _jsx(TextInput, { value: toolsInputValue, onChange: e => onToolsChange(e.target.value
445
705
  .split(',')
446
706
  .map(tool => tool.trim())
447
- .filter(Boolean)), placeholder: "tool_a, tool_b", sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Sandbox Variant" }), _jsxs(Select, { value: sandboxVariant, onChange: e => onSandboxVariantChange(e.target.value), sx: { width: '100%' }, children: [_jsx(Select.Option, { value: "", children: "Default" }), _jsx(Select.Option, { value: "local-eval", children: "local-eval" }), _jsx(Select.Option, { value: "jupyter", children: "jupyter" }), _jsx(Select.Option, { value: "local-jupyter", children: "local-jupyter" })] })] })] }), _jsxs(Box, { sx: {
707
+ .filter(Boolean)), placeholder: toolsInputPlaceholder, sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Sandbox Variant" }), _jsxs(Select, { value: sandboxVariant, onChange: e => onSandboxVariantChange(e.target.value), sx: { width: '100%' }, children: [_jsx(Select.Option, { value: "", children: "Default" }), _jsx(Select.Option, { value: "eval", children: "eval" }), _jsx(Select.Option, { value: "jupyter", children: "jupyter" })] })] })] }), _jsxs(Box, { sx: {
448
708
  marginBottom: 3,
449
709
  padding: 3,
450
710
  border: '1px solid',
@@ -470,7 +730,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
470
730
  color: 'fg.muted',
471
731
  fontWeight: 'normal',
472
732
  ml: 2,
473
- }, children: "\u2014 defined by spec" }))] }), _jsx(Box, { sx: { display: 'flex', gap: 4, opacity: isSpecMode ? 0.6 : 1 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: !isNewAgentMode || isSpecMode, onChange: e => onEnableCodemodeChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Codemode" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code to compose tools" })] })] }) }), skillsEnabled && enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills provide curated capabilities; Codemode composes tools with Python for multi-step execution." }) })), skillsEnabled && !enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills will run with a standalone code sandbox for script execution. Enable Codemode to compose skills with other tools." }) })), enableCodemode && (_jsxs(Box, { sx: { mt: 3, display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: allowDirectToolCalls, disabled: !isNewAgentMode || isSpecMode, onChange: e => onAllowDirectToolCallsChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Allow direct tool calls" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Expose call_tool for simple, single-tool operations" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableToolReranker, disabled: !isNewAgentMode || isSpecMode, onChange: e => onEnableToolRerankerChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Enable tool reranker" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Reorder search results using the configured reranker" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: useJupyterSandbox, disabled: !isNewAgentMode || isSpecMode, onChange: e => onUseJupyterSandboxChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Use Jupyter Sandbox" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code in a Jupyter Sandbox instead of local-eval Sandbox" })] })] })] }))] }), _jsxs(Box, { sx: {
733
+ }, children: "\u2014 defined by spec" }))] }), _jsx(Box, { sx: { display: 'flex', gap: 4, opacity: isSpecMode ? 0.6 : 1 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: !isNewAgentMode || isSpecMode, onChange: e => onEnableCodemodeChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Codemode" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code to compose tools" })] })] }) }), skillsEnabled && enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Codemode composes tools with Python for multi-step execution." }) })), skillsEnabled && !enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills will run with a standalone code sandbox for script execution. Enable Codemode to compose skills with other tools." }) })), enableCodemode && (_jsxs(Box, { sx: { mt: 3, display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: allowDirectToolCalls, disabled: !isNewAgentMode || isSpecMode, onChange: e => onAllowDirectToolCallsChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Allow direct tool calls" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Expose call_tool for simple, single-tool operations" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableToolReranker, disabled: !isNewAgentMode || isSpecMode, onChange: e => onEnableToolRerankerChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Enable tool reranker" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Reorder search results using the configured reranker" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: useJupyterSandbox, disabled: !isNewAgentMode || isSpecMode, onChange: e => onUseJupyterSandboxChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Use Jupyter Sandbox" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code in a Jupyter Sandbox instead of eval Sandbox" })] })] })] }))] }), _jsxs(Box, { sx: {
474
734
  marginBottom: 3,
475
735
  padding: 3,
476
736
  border: '1px solid',
@@ -488,7 +748,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
488
748
  color: 'fg.muted',
489
749
  fontWeight: 'normal',
490
750
  ml: 2,
491
- }, children: "\u2014 defined by spec" }))] }), skillsQuery.isLoading && _jsx(Spinner, { size: "small" }), !skillsQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => skillsQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh skills", children: _jsx(SyncIcon, { size: 14 }) }))] }), skillsQuery.isError ? (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch skills. Check that the server is running." }) })) : displaySkills.length === 0 && !skillsQuery.isLoading ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills available." })) : (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: displaySkills.map(skill => (_jsxs(Box, { sx: {
751
+ }, children: "\u2014 defined by spec" }))] }), skillsQuery.isLoading && _jsx(Spinner, { size: "small" }), !skillsQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => skillsQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh skills", children: _jsx(SyncIcon, { size: 14 }) }))] }), skillsQuery.isError && !usingSpecSkills && (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch runtime skills. Using built-in skill specs catalog." }) })), usingSpecSkills && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills are sourced from the selected agent spec." }) })), usingCatalogFallback && !skillsQuery.isLoading && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills are sourced from the local skill specs catalog." }) })), displaySkills.length === 0 && !skillsQuery.isLoading ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills available." })) : (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: displaySkills.map(skill => (_jsxs(Box, { sx: {
492
752
  display: 'flex',
493
753
  alignItems: 'center',
494
754
  gap: 2,
@@ -496,13 +756,16 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
496
756
  borderRadius: 1,
497
757
  backgroundColor: 'canvas.subtle',
498
758
  opacity: !isNewAgentMode || isSpecMode ? 0.6 : 1,
499
- }, children: [_jsx(Checkbox, { checked: selectedSkills.includes(skill.id), disabled: !isNewAgentMode || isSpecMode, onChange: e => handleSkillChange(skill.id, e.target.checked) }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: skill.name }), skill.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: skill.description }))] })] }, skill.id))) }))] }), _jsxs(Box, { sx: {
759
+ }, children: [_jsx(Checkbox, { checked: selectedSkills.includes(skill.id), disabled: !isNewAgentMode || isSpecMode, onChange: e => handleSkillChange(skill.id, e.target.checked) }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: skill.name }), skill.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: skill.description })), skill.requiredEnvVars &&
760
+ skill.requiredEnvVars.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: skill.requiredEnvVars.map(envVar => (_jsx(Label, { size: "small", variant: skill.isAvailable ? 'success' : 'danger', children: envVar }, `${skill.id}-${envVar}`))) })), (!skill.requiredEnvVars ||
761
+ skill.requiredEnvVars.length === 0) && (_jsx(Label, { size: "small", variant: "success", children: "No env vars required" }))] })] }, skill.id))) }))] }), _jsxs(Box, { sx: {
500
762
  marginBottom: 3,
501
763
  padding: 3,
502
764
  border: '1px solid',
503
765
  borderColor: 'border.default',
504
766
  borderRadius: 2,
505
767
  backgroundColor: 'canvas.default',
768
+ opacity: isSpecMode ? 0.6 : 1,
506
769
  }, children: [_jsxs(Box, { sx: {
507
770
  display: 'flex',
508
771
  alignItems: 'center',
@@ -513,9 +776,9 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
513
776
  color: 'fg.muted',
514
777
  fontWeight: 'normal',
515
778
  ml: 2,
516
- }, children: "\u2014 defined by spec" }))] }), mcpServersQuery.isLoading && _jsx(Spinner, { size: "small" }), !mcpServersQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => mcpServersQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh MCP config servers", children: _jsx(SyncIcon, { size: 14 }) }))] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', marginBottom: 2 }, children: "Servers from your mcp.json configuration file. Started automatically." }), mcpServersQuery.isError && (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch MCP config servers. Check that the server is running." }) })), configServers.length === 0 &&
779
+ }, children: "\u2014 defined by spec" }))] }), mcpServersQuery.isLoading && _jsx(Spinner, { size: "small" }), !mcpServersQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => mcpServersQuery.refetch(), disabled: mcpServersDisabled, sx: { padding: 1 }, "aria-label": "Refresh MCP config servers", children: _jsx(SyncIcon, { size: 14 }) }))] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', marginBottom: 2 }, children: "Servers from your mcp.json configuration file. Started automatically." }), mcpServersQuery.isError && (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch MCP config servers. Check that the server is running." }) })), configServers.length === 0 &&
517
780
  !mcpServersQuery.isLoading &&
518
- !mcpServersQuery.isError && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No MCP config servers found. Add servers to ~/.datalayer/mcp.json" })), enableCodemode && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "When Codemode is enabled, selected MCP servers are used to build the Codemode tool registry (tools are exposed via Codemode meta tools like search and execute_code)." }) })), enableCodemode && (_jsxs(Box, { sx: {
781
+ !mcpServersQuery.isError && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No MCP config servers found. Add servers to ~/.datalayer/mcp.json" })), unresolvedSelectedMcpServers.length > 0 && (_jsx(Flash, { variant: "warning", sx: { marginTop: 2, marginBottom: 2 }, children: _jsxs(Text, { sx: { fontSize: 0 }, children: ["Selected in spec but not available in this environment:", ' ', unresolvedSelectedMcpServers.join(', ')] }) })), enableCodemode && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "When Codemode is enabled, selected MCP servers are used to build the Codemode tool registry (tools are exposed via Codemode meta tools like search and execute_code)." }) })), enableCodemode && (_jsxs(Box, { sx: {
519
782
  marginBottom: 2,
520
783
  padding: 2,
521
784
  borderRadius: 1,
@@ -526,7 +789,11 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
526
789
  selectedCatalogServers.length > 0
527
790
  ? 'Using selected MCP servers'
528
791
  : 'No servers selected — select servers to scope Codemode tools.' }), previewConfigServers.length > 0 ||
529
- previewCatalogServers.length > 0 ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [previewConfigServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014 ", server.tools.length, " tools (config)"] }, server.id))), previewCatalogServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014 ", server.tools?.length || 0, " tools (catalog)"] }, server.id)))] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No servers selected." })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 2 }, children: "Exposed meta-tools: list_tool_names, search_tools, get_tool_details, list_servers, execute_code, call_tool (optional)" })] })), configServers.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: configServers.map(server => (_jsxs(Box, { sx: {
792
+ previewCatalogServers.length > 0 ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [previewConfigServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014", server.tools.length > 0
793
+ ? ` ${server.tools.length} tools (config)`
794
+ : ' tools discovered when launched (config)'] }, server.id))), previewCatalogServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014", (server.tools?.length || 0) > 0
795
+ ? ` ${server.tools?.length || 0} tools (catalog)`
796
+ : ' tools discovered when launched (catalog)'] }, server.id)))] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No servers selected." })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 2 }, children: "Exposed meta-tools: list_tool_names, search_tools, get_tool_details, list_servers, execute_code, call_tool (optional)" })] })), configServers.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: configServers.map(server => (_jsxs(Box, { sx: {
530
797
  display: 'flex',
531
798
  alignItems: 'flex-start',
532
799
  gap: 2,
@@ -546,6 +813,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
546
813
  borderColor: 'border.default',
547
814
  borderRadius: 2,
548
815
  backgroundColor: 'canvas.default',
816
+ opacity: isSpecMode ? 0.6 : 1,
549
817
  }, children: [_jsxs(Box, { sx: {
550
818
  display: 'flex',
551
819
  alignItems: 'center',
@@ -580,20 +848,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
580
848
  flex: 1,
581
849
  }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: server.name }), enableCatalogServerMutation.isPending &&
582
850
  enableCatalogServerMutation.variables === server.id ? (_jsx(Label, { variant: "accent", size: "small", children: "Starting..." })) : server.isRunning ? (_jsx(Label, { variant: "success", size: "small", children: "Running" })) : (_jsx(Label, { variant: "secondary", size: "small", children: "Not Started" })), server.isConfig && (_jsx(Label, { variant: "secondary", size: "small", children: "From Config" }))] }), hasRequiredEnvVars ? (_jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: server.requiredEnvVars?.map(envVar => (_jsx(Label, { variant: envVarsAvailable ? 'success' : 'danger', size: "small", children: envVar }, envVar))) })) : (_jsx(Box, { sx: { display: 'flex' }, children: _jsx(Label, { variant: "success", size: "small", children: "No env vars required" }) })), server.tools && server.tools.length > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Tools: ", server.tools.map(t => t.name).join(', ')] }))] })] }, server.id));
583
- }) })] })), createError && (_jsx(Flash, { variant: "danger", sx: { marginBottom: 3 }, children: createError })), selectedSpec && (_jsxs(Box, { sx: {
584
- marginBottom: 3,
585
- padding: 3,
586
- border: '1px solid',
587
- borderColor: 'border.default',
588
- borderRadius: 2,
589
- backgroundColor: 'canvas.default',
590
- }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', display: 'block', mb: 2 }, children: "Agent Spec Attributes" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: selectedSpecEntries.map(([key, value]) => (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold' }, children: key }), _jsx(Text, { sx: {
591
- fontSize: 0,
592
- color: 'fg.muted',
593
- whiteSpace: 'pre-wrap',
594
- }, children: typeof value === 'string'
595
- ? value
596
- : JSON.stringify(value, null, 2) })] }, key))) })] })), _jsx(Button, { variant: "primary", onClick: onConnect, disabled: isCreatingAgent ||
851
+ }) })] })), createError && (_jsx(Flash, { variant: "danger", sx: { marginBottom: 3 }, children: createError })), _jsx(Button, { variant: "primary", onClick: onConnect, disabled: isCreatingAgent ||
597
852
  !agentName ||
598
853
  (transport === 'acp' ? !wsUrl : !baseUrl), sx: { width: '100%' }, children: isCreatingAgent ? (_jsxs(Box, { sx: {
599
854
  display: 'flex',
@@ -103,9 +103,11 @@ export interface ContextDistributionProps {
103
103
  agentId: string;
104
104
  /** Height of the chart */
105
105
  height?: string;
106
+ /** Live snapshot data from WS — bypasses REST polling when provided */
107
+ liveData?: ContextSnapshotResponse | null;
106
108
  }
107
109
  /**
108
110
  * ContextDistribution component displays context distribution as a treemap.
109
111
  */
110
- export declare function ContextDistribution({ agentId, height, }: ContextDistributionProps): import("react/jsx-runtime").JSX.Element;
112
+ export declare function ContextDistribution({ agentId, height, liveData, }: ContextDistributionProps): import("react/jsx-runtime").JSX.Element;
111
113
  export default ContextDistribution;