@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
@@ -1,46 +1,100 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /*
3
3
  * Copyright (c) 2025-2026 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  /// <reference types="vite/client" />
7
- import { useCallback, useEffect, useRef, useState } from 'react';
7
+ import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
8
8
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
9
9
  import { Box } from '@datalayer/primer-addons';
10
- import { ErrorView } from './components';
11
- import { Button, Heading, Label, Spinner, Text, Token as PrimerToken, } from '@primer/react';
12
- import { BeakerIcon, BriefcaseIcon, PackageIcon, SignOutIcon, } from '@primer/octicons-react';
10
+ import { AuthRequiredView, ErrorView } from './components';
11
+ import { Button, Dialog, Heading, Label, Spinner, Text, Token as PrimerToken, } from '@primer/react';
12
+ import { BriefcaseIcon, FileIcon } from '@primer/octicons-react';
13
13
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
14
- import { SignInSimple } from '@datalayer/core/lib/views/iam';
15
- import { UserBadge } from '@datalayer/core/lib/views/profile';
16
14
  import { ThemedProvider } from './utils/themedProvider';
15
+ import { uniqueAgentId } from './utils/agentId';
17
16
  import { Chat } from '../chat';
17
+ import { useSkills, useSkillActions } from '../hooks';
18
18
  const queryClient = new QueryClient();
19
- const AGENT_NAME = 'skills-demo-agent';
20
- const AGENT_SPEC_ID = 'demo-full';
19
+ const AGENT_NAME = 'skills-example-agent';
20
+ const AGENT_SPEC_ID = 'example-skills';
21
21
  const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
22
- const SkillCard = ({ skill }) => (_jsxs(Box, { sx: {
23
- border: '1px solid',
24
- borderColor: 'border.default',
25
- borderRadius: 2,
26
- p: 2,
27
- mb: 2,
28
- bg: 'canvas.default',
29
- }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [skill.emoji && _jsx(Text, { sx: { fontSize: 2 }, children: skill.emoji }), _jsx(Text, { sx: { fontWeight: 600, fontSize: 1 }, children: skill.name }), _jsx(Label, { size: "small", variant: skill.variant === 'package' ? 'accent' : 'primary', children: skill.variant === 'package'
30
- ? 'package-based'
31
- : skill.variant === 'path'
32
- ? 'path-based'
33
- : 'name-based' })] }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 1, mt: 0 }, children: skill.description }), skill.variant === 'module' && skill.module && (_jsxs(Text, { sx: { fontSize: 0, fontFamily: 'mono', color: 'fg.muted' }, children: ["module: ", skill.module] })), skill.variant === 'package' && (_jsxs(Box, { sx: { fontSize: 0, fontFamily: 'mono', color: 'fg.muted' }, children: [_jsxs(Text, { sx: { display: 'block' }, children: ["package: ", skill.package] }), _jsxs(Text, { sx: { display: 'block' }, children: ["method: ", skill.method] })] })), skill.variant === 'path' && skill.path && (_jsxs(Text, { sx: { fontSize: 0, fontFamily: 'mono', color: 'fg.muted' }, children: ["path: ", skill.path] })), skill.license && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block', mt: 1 }, children: ["License: ", skill.license] })), skill.compatibility && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: ["Compat: ", skill.compatibility] })), skill.allowedTools && skill.allowedTools.length > 0 && (_jsx(Box, { sx: { mt: 1, display: 'flex', gap: 1, flexWrap: 'wrap' }, children: skill.allowedTools.map(tool => (_jsx(PrimerToken, { text: tool, size: "small" }, tool))) })), skill.tags && skill.tags.length > 0 && (_jsx(Box, { sx: { mt: 1, display: 'flex', gap: 1, flexWrap: 'wrap' }, children: skill.tags.map(tag => (_jsx(PrimerToken, { text: tag, size: "small" }, tag))) }))] }));
22
+ const SkillCard = ({ skill, onToggle, onToggleApproval }) => {
23
+ const [showDefinition, setShowDefinition] = useState(false);
24
+ const sourceVariant = skill.source_variant ?? 'unknown';
25
+ const sourceLabel = sourceVariant === 'path'
26
+ ? 'file-based'
27
+ : sourceVariant === 'package'
28
+ ? 'package-based'
29
+ : sourceVariant === 'module'
30
+ ? 'module-based'
31
+ : 'unknown';
32
+ const sourceDetail = sourceVariant === 'package'
33
+ ? [skill.package, skill.method].filter(Boolean).join('#')
34
+ : sourceVariant === 'module'
35
+ ? skill.module
36
+ : sourceVariant === 'path'
37
+ ? skill.path
38
+ : undefined;
39
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
40
+ border: '1px solid',
41
+ borderColor: 'border.default',
42
+ borderRadius: 2,
43
+ p: 2,
44
+ mb: 2,
45
+ bg: 'canvas.default',
46
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600, fontSize: 1 }, children: skill.name }), skill.status && (_jsx(Label, { size: "small", variant: skill.status === 'loaded'
47
+ ? 'success'
48
+ : skill.status === 'enabled'
49
+ ? 'attention'
50
+ : 'secondary', children: skill.status })), skill.approved && (_jsx(Label, { size: "small", variant: "success", children: "approved" })), skill.status === 'loaded' && skill.skill_definition && (_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowDefinition(true), leadingVisual: FileIcon, sx: { fontSize: 0, p: 0, color: 'fg.muted' }, "aria-label": "View SKILL.md", children: "SKILL.md" })), _jsxs(Box, { sx: { ml: 'auto', display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Button, { size: "small", variant: "invisible", onClick: () => onToggleApproval(skill.id), sx: { fontSize: 0 }, children: skill.approved ? 'Unapprove' : 'Approve' }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => onToggle(skill.id), sx: { fontSize: 0 }, children: skill.status === 'available' ? 'Enable' : 'Disable' })] })] }), skill.description && (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 1, mt: 0 }, children: skill.description })), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(Label, { size: "small", variant: "secondary", children: sourceLabel }), sourceDetail && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: sourceDetail }))] }), skill.tags && skill.tags.length > 0 && (_jsx(Box, { sx: { mt: 1, display: 'flex', gap: 1, flexWrap: 'wrap' }, children: skill.tags.map(tag => (_jsx(PrimerToken, { text: tag, size: "small" }, tag))) }))] }), showDefinition && skill.skill_definition && (_jsx(Dialog, { title: `${skill.name} — SKILL.md`, onClose: () => setShowDefinition(false), width: "xlarge", children: _jsx(Box, { sx: { p: 3, maxHeight: '70vh', overflow: 'auto' }, children: _jsx(Box, { as: "pre", sx: {
51
+ fontFamily: 'mono',
52
+ fontSize: 0,
53
+ whiteSpace: 'pre-wrap',
54
+ wordBreak: 'break-word',
55
+ m: 0,
56
+ p: 3,
57
+ bg: 'canvas.inset',
58
+ borderRadius: 2,
59
+ border: '1px solid',
60
+ borderColor: 'border.muted',
61
+ }, children: skill.skill_definition }) }) }))] }));
62
+ };
34
63
  const AgentSkillsInner = ({ onLogout }) => {
35
64
  const { token } = useSimpleAuthStore();
65
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
36
66
  const [runtimeStatus, setRuntimeStatus] = useState('launching');
37
67
  const [isReady, setIsReady] = useState(false);
38
68
  const [hookError, setHookError] = useState(null);
39
- const [agentId, setAgentId] = useState(AGENT_NAME);
69
+ const [agentId, setAgentId] = useState(agentName);
40
70
  const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
41
- const [skills, setSkills] = useState([]);
42
71
  const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
43
72
  const chatAuthToken = token === null ? undefined : token;
73
+ // WS-sourced skills (reads from codemodeStatus pushed via monitoring WS)
74
+ const skillsQuery = useSkills(isReady);
75
+ const skills = useMemo(() => skillsQuery.data?.skills ?? [], [skillsQuery.data]);
76
+ const { enableSkill, disableSkill, approveSkill, unapproveSkill } = useSkillActions(agentId);
77
+ const toggleSkill = useCallback((skillId) => {
78
+ const skill = skills.find(s => s.id === skillId);
79
+ if (skill?.status === 'available') {
80
+ enableSkill(skillId);
81
+ }
82
+ else {
83
+ disableSkill(skillId);
84
+ }
85
+ }, [skills, enableSkill, disableSkill]);
86
+ const toggleSkillApproval = useCallback((skillId) => {
87
+ const skill = skills.find(s => s.id === skillId);
88
+ if (skill?.approved) {
89
+ unapproveSkill(skillId);
90
+ }
91
+ else {
92
+ approveSkill(skillId);
93
+ }
94
+ }, [skills, approveSkill, unapproveSkill]);
95
+ const fileBasedSkills = skills.filter(s => s.source_variant === 'path');
96
+ const packageBasedSkills = skills.filter(s => s.source_variant === 'package');
97
+ const moduleBasedSkills = skills.filter(s => s.source_variant === 'module');
44
98
  const authFetch = useCallback((url, opts = {}) => fetch(url, {
45
99
  ...opts,
46
100
  headers: {
@@ -57,13 +111,13 @@ const AgentSkillsInner = ({ onLogout }) => {
57
111
  setHookError(null);
58
112
  setIsReconnectedAgent(false);
59
113
  try {
60
- // Create local agent runtime using the demo-full spec.
61
- // The spec contains both code-based and path-based skills.
114
+ // Create local agent runtime using the example-full spec.
115
+ // The spec contains module-based, package-based and file-based skills.
62
116
  const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
63
117
  method: 'POST',
64
118
  body: JSON.stringify({
65
- name: AGENT_NAME,
66
- description: 'Agent with skills demo - code-based and path-based skills',
119
+ name: agentName,
120
+ description: 'Agent with skills example - module, package and file based skills',
67
121
  agent_library: 'pydantic-ai',
68
122
  transport: 'vercel-ai',
69
123
  agent_spec_id: AGENT_SPEC_ID,
@@ -71,11 +125,11 @@ const AgentSkillsInner = ({ onLogout }) => {
71
125
  tools: [],
72
126
  }),
73
127
  });
74
- let resolvedAgentId = AGENT_NAME;
128
+ let resolvedAgentId = agentName;
75
129
  let isAlreadyRunning = false;
76
130
  if (response.ok) {
77
131
  const data = await response.json();
78
- resolvedAgentId = data?.id || AGENT_NAME;
132
+ resolvedAgentId = data?.id || agentName;
79
133
  }
80
134
  else {
81
135
  const contentType = response.headers.get('content-type') || '';
@@ -115,68 +169,7 @@ const AgentSkillsInner = ({ onLogout }) => {
115
169
  return () => {
116
170
  isCancelled = true;
117
171
  };
118
- }, [agentBaseUrl, authFetch]);
119
- // Fetch skill information from the agent's spec endpoint
120
- useEffect(() => {
121
- if (!isReady)
122
- return;
123
- const fetchSkills = async () => {
124
- try {
125
- const res = await authFetch(`${agentBaseUrl}/api/v1/agents/${agentId}/spec`);
126
- if (!res.ok)
127
- return;
128
- const spec = await res.json();
129
- const skillNames = spec?.skills ?? [];
130
- // For each skill name, build a SkillInfo from the catalog when possible.
131
- const { getSkillSpec } = await import('../specs/skills');
132
- const infos = skillNames.map((name) => {
133
- const baseName = name.includes(':') ? name.split(':')[0] : name;
134
- const catalogSpec = getSkillSpec(baseName);
135
- if (catalogSpec?.path) {
136
- // Variant 3: path-based skill
137
- return {
138
- name: catalogSpec.name,
139
- description: catalogSpec.description || `Skill: ${baseName}`,
140
- variant: 'path',
141
- path: catalogSpec.path,
142
- tags: catalogSpec.tags ? [...catalogSpec.tags] : [],
143
- emoji: catalogSpec.emoji,
144
- };
145
- }
146
- if (catalogSpec?.package && catalogSpec?.method) {
147
- // Variant 2: package-based skill
148
- return {
149
- name: catalogSpec.name,
150
- description: catalogSpec.description || `Skill: ${baseName}`,
151
- variant: 'package',
152
- package: catalogSpec.package,
153
- method: catalogSpec.method,
154
- license: catalogSpec.license,
155
- compatibility: catalogSpec.compatibility,
156
- allowedTools: catalogSpec.allowedTools,
157
- skillMetadata: catalogSpec.skillMetadata,
158
- tags: catalogSpec.tags ? [...catalogSpec.tags] : [],
159
- emoji: catalogSpec.emoji,
160
- };
161
- }
162
- // Variant 1: name-based (module discovery)
163
- return {
164
- name: catalogSpec?.name ?? baseName,
165
- description: catalogSpec?.description ?? `Skill: ${baseName}`,
166
- variant: 'module',
167
- module: catalogSpec?.module ?? `agent_skills.skills.${baseName}`,
168
- tags: catalogSpec?.tags ? [...catalogSpec.tags] : [],
169
- emoji: catalogSpec?.emoji,
170
- };
171
- });
172
- setSkills(infos);
173
- }
174
- catch {
175
- // Non-fatal: skill display is informational
176
- }
177
- };
178
- void fetchSkills();
179
- }, [isReady, agentId, agentBaseUrl, authFetch]);
172
+ }, [agentBaseUrl, agentName, authFetch]);
180
173
  if (!isReady && runtimeStatus !== 'error') {
181
174
  return (_jsxs(Box, { sx: {
182
175
  display: 'flex',
@@ -185,7 +178,7 @@ const AgentSkillsInner = ({ onLogout }) => {
185
178
  justifyContent: 'center',
186
179
  height: '100vh',
187
180
  gap: 3,
188
- }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching skills demo agent..." })] }));
181
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching skills example agent..." })] }));
189
182
  }
190
183
  if (runtimeStatus === 'error' || hookError) {
191
184
  return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
@@ -199,11 +192,15 @@ const AgentSkillsInner = ({ onLogout }) => {
199
192
  py: 1,
200
193
  borderBottom: '1px solid',
201
194
  borderColor: 'border.default',
202
- }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: `Skills Demo Agent`, placeholder: "Ask the agent to use its skills...", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Skills: ", skills.length] }), token && _jsx(UserBadge, { token: token, variant: "small" }), _jsx(Button, { size: "small", variant: "invisible", onClick: onLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] }), suggestions: [
195
+ }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: `Skills Demo Agent`, brandIcon: _jsx(BriefcaseIcon, { size: 16 }), placeholder: "Ask the agent to use its skills...", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, showSkillsMenu: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Skills: ", skills.length] }) }), suggestions: [
203
196
  {
204
197
  title: 'List available skills',
205
198
  message: 'List all your available skills and what they can do.',
206
199
  },
200
+ {
201
+ title: '👤 Who am I',
202
+ message: 'Use the datalayer-whoami skill to tell me who I am, including my user identity and available context.',
203
+ },
207
204
  {
208
205
  title: '🌐 Crawl a webpage',
209
206
  message: 'Use the crawl skill to fetch the content of https://datalayer.ai and summarize it.',
@@ -214,7 +211,7 @@ const AgentSkillsInner = ({ onLogout }) => {
214
211
  },
215
212
  {
216
213
  title: '🐙 GitHub repos',
217
- message: 'Use the GitHub skill to list the public repositories for the "datalayer" organization.',
214
+ message: 'Use the GitHub skill to show two sections: first, the top 3 recently updated public repositories from the datalayer organization; second, my top 3 recently updated private repositories. Keep the output clear and concise.',
218
215
  },
219
216
  {
220
217
  title: '📄 Read a PDF',
@@ -241,14 +238,14 @@ const AgentSkillsInner = ({ onLogout }) => {
241
238
  p: 2,
242
239
  borderBottom: '1px solid',
243
240
  borderColor: 'border.default',
244
- }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 1 }, children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(BriefcaseIcon, { size: 16 }), "Agent Skills"] }) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Loaded: ", skills.length, " skill", skills.length !== 1 ? 's' : ''] })] }), _jsxs(Box, { sx: { p: 2, overflow: 'auto', flex: 1 }, children: [skills.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills loaded." })) : (skills.map(skill => _jsx(SkillCard, { skill: skill }, skill.name))), _jsxs(Box, { sx: {
241
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 1 }, children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(BriefcaseIcon, { size: 16 }), "Agent Skills"] }) }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [skills.length, " skill", skills.length !== 1 ? 's' : '', " \u00B7", ' ', skills.filter(s => s.status === 'loaded').length, " loaded \u00B7", ' ', skills.filter(s => s.approved).length, " approved"] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 1, display: 'block' }, children: [fileBasedSkills.length, " file-based \u00B7", ' ', packageBasedSkills.length, " package-based \u00B7", ' ', moduleBasedSkills.length, " module-based"] })] }), _jsxs(Box, { sx: { p: 2, overflow: 'auto', flex: 1 }, children: [skills.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Waiting for skills snapshot..." })) : (skills.map(skill => (_jsx(SkillCard, { skill: skill, onToggle: toggleSkill, onToggleApproval: toggleSkillApproval }, skill.id)))), _jsxs(Box, { sx: {
245
242
  mt: 3,
246
243
  p: 2,
247
244
  borderRadius: 2,
248
245
  bg: 'canvas.inset',
249
246
  border: '1px solid',
250
247
  borderColor: 'border.muted',
251
- }, children: [_jsx(Heading, { as: "h5", sx: { fontSize: 0, mb: 1 }, children: "Skill Spec Variants" }), _jsxs(Box, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(BeakerIcon, { size: 12 }), _jsxs(Text, { children: [_jsx("strong", { children: "Path-based:" }), " Discovered from a local SKILL.md directory path"] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(PackageIcon, { size: 12 }), _jsxs(Text, { children: [_jsx("strong", { children: "Module-based:" }), " Python module or package + method with frontmatter"] })] })] })] })] })] })] })] }));
248
+ }, children: [_jsx(Heading, { as: "h5", sx: { fontSize: 0, mb: 1 }, children: "Skill Statuses" }), _jsxs(Box, { sx: { fontSize: 0, color: 'fg.muted' }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(Label, { size: "small", variant: "secondary", children: "available" }), _jsx(Text, { children: "In catalog, not yet enabled" })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [_jsx(Label, { size: "small", variant: "attention", children: "enabled" }), _jsx(Text, { children: "Enabled, loading pending" })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Label, { size: "small", variant: "success", children: "loaded" }), _jsx(Text, { children: "SKILL.md loaded, in system prompt" })] })] })] })] })] })] })] }));
252
249
  };
253
250
  const syncTokenToIamStore = (token) => {
254
251
  import('@datalayer/core/lib/state').then(({ iamStore }) => {
@@ -256,7 +253,7 @@ const syncTokenToIamStore = (token) => {
256
253
  });
257
254
  };
258
255
  const AgentSkillsExample = () => {
259
- const { token, setAuth, clearAuth } = useSimpleAuthStore();
256
+ const { token, clearAuth } = useSimpleAuthStore();
260
257
  const hasSynced = useRef(false);
261
258
  useEffect(() => {
262
259
  if (token && !hasSynced.current) {
@@ -264,11 +261,6 @@ const AgentSkillsExample = () => {
264
261
  syncTokenToIamStore(token);
265
262
  }
266
263
  }, [token]);
267
- const handleSignIn = useCallback((newToken, handle) => {
268
- setAuth(newToken, handle);
269
- hasSynced.current = true;
270
- syncTokenToIamStore(newToken);
271
- }, [setAuth]);
272
264
  const handleLogout = useCallback(() => {
273
265
  clearAuth();
274
266
  hasSynced.current = false;
@@ -277,7 +269,7 @@ const AgentSkillsExample = () => {
277
269
  });
278
270
  }, [clearAuth]);
279
271
  if (!token) {
280
- return (_jsx(ThemedProvider, { children: _jsx(SignInSimple, { onSignIn: handleSignIn, onApiKeySignIn: apiKey => handleSignIn(apiKey, 'api-key-user'), title: "Agent Skills Demo", description: "Sign in to test code-based and path-based agent skills.", leadingIcon: _jsx(BriefcaseIcon, { size: 24 }) }) }));
272
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
281
273
  }
282
274
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentSkillsInner, { onLogout: handleLogout }) }) }));
283
275
  };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * AgentSubagentsExample
3
+ *
4
+ * Demonstrates multi-agent delegation using subagents-pydantic-ai.
5
+ * The parent agent orchestrates a researcher and a writer subagent,
6
+ * delegating tasks and combining results for the user.
7
+ *
8
+ * - Creates a local agent from the 'example-subagents' spec
9
+ * - Shows a Chat component for interacting with the orchestrator
10
+ * - Sidebar displays subagent info and active task status
11
+ */
12
+ import React from 'react';
13
+ declare const AgentSubagentsExample: React.FC;
14
+ export default AgentSubagentsExample;
@@ -0,0 +1,228 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2025-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ /**
7
+ * AgentSubagentsExample
8
+ *
9
+ * Demonstrates multi-agent delegation using subagents-pydantic-ai.
10
+ * The parent agent orchestrates a researcher and a writer subagent,
11
+ * delegating tasks and combining results for the user.
12
+ *
13
+ * - Creates a local agent from the 'example-subagents' spec
14
+ * - Shows a Chat component for interacting with the orchestrator
15
+ * - Sidebar displays subagent info and active task status
16
+ */
17
+ /// <reference types="vite/client" />
18
+ import { useEffect, useState, useCallback, useRef } from 'react';
19
+ import { Text, Spinner, Heading, Label, Timeline } from '@primer/react';
20
+ import { PeopleIcon, PersonIcon, CheckCircleFillIcon, ClockIcon, XCircleFillIcon, } from '@primer/octicons-react';
21
+ import { Box } from '@datalayer/primer-addons';
22
+ import { AuthRequiredView, ErrorView } from './components';
23
+ import { ThemedProvider } from './utils/themedProvider';
24
+ import { uniqueAgentId } from './utils/agentId';
25
+ import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
26
+ import { Chat } from '../chat';
27
+ const AGENT_NAME = 'subagents-example-agent';
28
+ const AGENT_SPEC_ID = 'example-subagents';
29
+ const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
30
+ const SUBAGENTS = [
31
+ {
32
+ name: 'researcher',
33
+ description: 'Researches topics, gathers facts, and provides detailed analysis',
34
+ preferredMode: 'sync',
35
+ typicalComplexity: 'moderate',
36
+ canAskQuestions: true,
37
+ },
38
+ {
39
+ name: 'writer',
40
+ description: 'Writes clear, structured content based on research or instructions',
41
+ preferredMode: 'sync',
42
+ typicalComplexity: 'moderate',
43
+ canAskQuestions: false,
44
+ },
45
+ ];
46
+ const AgentSubagentsInner = ({ onLogout, }) => {
47
+ const { token } = useSimpleAuthStore();
48
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
49
+ const [runtimeStatus, setRuntimeStatus] = useState('launching');
50
+ const [isReady, setIsReady] = useState(false);
51
+ const [hookError, setHookError] = useState(null);
52
+ const [agentId, setAgentId] = useState(agentName);
53
+ const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
54
+ const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
55
+ const chatAuthToken = token === null ? undefined : token;
56
+ const authFetch = useCallback((url, opts = {}) => fetch(url, {
57
+ ...opts,
58
+ headers: {
59
+ 'Content-Type': 'application/json',
60
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
61
+ ...(opts.headers ?? {}),
62
+ },
63
+ }), [token]);
64
+ useEffect(() => {
65
+ let isCancelled = false;
66
+ const createLocalAgent = async () => {
67
+ setRuntimeStatus('launching');
68
+ setIsReady(false);
69
+ setHookError(null);
70
+ setIsReconnectedAgent(false);
71
+ try {
72
+ const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
73
+ method: 'POST',
74
+ body: JSON.stringify({
75
+ name: agentName,
76
+ description: 'Subagents example – multi-agent delegation with researcher and writer',
77
+ agent_library: 'pydantic-ai',
78
+ transport: 'vercel-ai',
79
+ agent_spec_id: AGENT_SPEC_ID,
80
+ enable_skills: true,
81
+ tools: [],
82
+ }),
83
+ });
84
+ let resolvedAgentId = agentName;
85
+ let isAlreadyRunning = false;
86
+ if (response.ok) {
87
+ const data = await response.json();
88
+ resolvedAgentId = data?.id || agentName;
89
+ }
90
+ else {
91
+ const contentType = response.headers.get('content-type') || '';
92
+ let detail = '';
93
+ if (contentType.includes('application/json')) {
94
+ const data = await response.json().catch(() => null);
95
+ detail =
96
+ (typeof data?.detail === 'string' && data.detail) ||
97
+ (typeof data?.message === 'string' && data.message) ||
98
+ '';
99
+ }
100
+ else {
101
+ detail = await response.text();
102
+ }
103
+ if (response.status === 409 || /already exists/i.test(detail || '')) {
104
+ isAlreadyRunning = true;
105
+ }
106
+ else {
107
+ throw new Error(detail || `Failed to create local agent: ${response.status}`);
108
+ }
109
+ }
110
+ if (!isCancelled) {
111
+ setAgentId(resolvedAgentId);
112
+ setIsReconnectedAgent(isAlreadyRunning);
113
+ setIsReady(true);
114
+ setRuntimeStatus('ready');
115
+ }
116
+ }
117
+ catch (error) {
118
+ if (!isCancelled) {
119
+ setHookError(error instanceof Error ? error.message : 'Agent failed to start');
120
+ setRuntimeStatus('error');
121
+ }
122
+ }
123
+ };
124
+ void createLocalAgent();
125
+ return () => {
126
+ isCancelled = true;
127
+ };
128
+ }, [agentBaseUrl, authFetch]);
129
+ if (!isReady && runtimeStatus !== 'error') {
130
+ return (_jsxs(Box, { sx: {
131
+ display: 'flex',
132
+ flexDirection: 'column',
133
+ alignItems: 'center',
134
+ justifyContent: 'center',
135
+ height: '100vh',
136
+ gap: 3,
137
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching subagents example agent..." })] }));
138
+ }
139
+ if (runtimeStatus === 'error' || hookError) {
140
+ return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
141
+ }
142
+ return (_jsxs(Box, { sx: {
143
+ height: 'calc(100vh - 60px)',
144
+ display: 'flex',
145
+ flexDirection: 'column',
146
+ }, children: [_jsxs(Box, { sx: {
147
+ display: 'flex',
148
+ alignItems: 'center',
149
+ gap: 2,
150
+ px: 3,
151
+ py: 2,
152
+ borderBottom: '1px solid',
153
+ borderColor: 'border.default',
154
+ flexShrink: 0,
155
+ }, children: [_jsx(PeopleIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: "Subagents Demo" }), isReconnectedAgent && (_jsx(Label, { variant: "secondary", size: "small", children: "Reconnected" })), _jsxs(Label, { variant: "accent", children: [SUBAGENTS.length, " subagents"] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Subagents Orchestrator", brandIcon: _jsx(PeopleIcon, { size: 16 }), placeholder: "Ask me to research a topic, write content, or both...", description: "Multi-agent delegation with researcher & writer", showHeader: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
156
+ {
157
+ title: 'Research & write',
158
+ message: 'Research the pros and cons of Python async patterns and write a summary.',
159
+ },
160
+ {
161
+ title: 'Research only',
162
+ message: 'Find recent advances in LLM fine-tuning and provide a detailed analysis.',
163
+ },
164
+ {
165
+ title: 'Write only',
166
+ message: 'Write a concise guide on REST API design best practices.',
167
+ },
168
+ ], submitOnSuggestionClick: true }) }), _jsxs(Box, { sx: {
169
+ width: 320,
170
+ borderLeft: '1px solid',
171
+ borderColor: 'border.default',
172
+ display: 'flex',
173
+ flexDirection: 'column',
174
+ overflow: 'auto',
175
+ }, children: [_jsxs(Box, { sx: {
176
+ p: 3,
177
+ borderBottom: '1px solid',
178
+ borderColor: 'border.default',
179
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Available Subagents" }), _jsx(Timeline, { children: SUBAGENTS.map(sa => (_jsxs(Timeline.Item, { children: [_jsx(Timeline.Badge, { children: _jsx(PersonIcon, {}) }), _jsxs(Timeline.Body, { children: [_jsx(Box, { sx: { mb: 1 }, children: _jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: sa.name }) }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: sa.description }), _jsxs(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: [_jsx(Label, { size: "small", variant: "secondary", children: sa.preferredMode }), _jsx(Label, { size: "small", variant: "secondary", children: sa.typicalComplexity }), sa.canAskQuestions && (_jsx(Label, { size: "small", variant: "accent", children: "can ask questions" }))] })] })] }, sa.name))) })] }), _jsxs(Box, { sx: {
180
+ p: 3,
181
+ borderBottom: '1px solid',
182
+ borderColor: 'border.default',
183
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Delegation Tools" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [
184
+ {
185
+ name: 'task',
186
+ desc: 'Assign a task to a subagent',
187
+ icon: ClockIcon,
188
+ },
189
+ {
190
+ name: 'check_task',
191
+ desc: 'Check status of a running task',
192
+ icon: CheckCircleFillIcon,
193
+ },
194
+ {
195
+ name: 'list_active_tasks',
196
+ desc: 'View all active delegated tasks',
197
+ icon: PeopleIcon,
198
+ },
199
+ {
200
+ name: 'soft_cancel_task',
201
+ desc: 'Gracefully cancel a task',
202
+ icon: XCircleFillIcon,
203
+ },
204
+ ].map(tool => (_jsxs(Box, { sx: {
205
+ p: 2,
206
+ border: '1px solid',
207
+ borderColor: 'border.default',
208
+ borderRadius: 2,
209
+ display: 'flex',
210
+ alignItems: 'center',
211
+ gap: 2,
212
+ }, children: [_jsx(tool.icon, { size: 14 }), _jsxs(Box, { children: [_jsx(Text, { sx: {
213
+ fontSize: 1,
214
+ fontWeight: 'bold',
215
+ fontFamily: 'mono',
216
+ }, children: tool.name }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 0 }, children: tool.desc })] })] }, tool.name))) })] }), _jsxs(Box, { sx: { p: 3 }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "How It Works" }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 2 }, children: ["The orchestrator agent delegates tasks to specialised subagents using the ", _jsx("code", { children: "task" }), " tool. Each subagent runs independently with its own model, instructions, and context."] }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 0 }, children: "Subagents can be configured with different execution modes (sync, async, auto), complexity hints, and question-asking capabilities for interactive workflows." })] })] })] })] }));
217
+ };
218
+ const AgentSubagentsExample = () => {
219
+ const { token, clearAuth } = useSimpleAuthStore();
220
+ const handleLogout = useCallback(() => {
221
+ clearAuth();
222
+ }, [clearAuth]);
223
+ if (!token) {
224
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
225
+ }
226
+ return (_jsx(ThemedProvider, { children: _jsx(AgentSubagentsInner, { onLogout: handleLogout }) }));
227
+ };
228
+ export default AgentSubagentsExample;