@datalayer/agent-runtimes 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +35 -119
  2. package/lib/App.js +1 -1
  3. package/lib/agents/AgentDetails.d.ts +22 -1
  4. package/lib/agents/AgentDetails.js +34 -47
  5. package/lib/api/index.d.ts +0 -1
  6. package/lib/api/index.js +4 -2
  7. package/lib/chat/Chat.d.ts +5 -104
  8. package/lib/chat/Chat.js +4 -4
  9. package/lib/chat/ChatFloating.d.ts +7 -140
  10. package/lib/chat/ChatFloating.js +2 -2
  11. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  12. package/lib/chat/ChatPopupStandalone.js +3 -3
  13. package/lib/chat/ChatSidebar.d.ts +4 -69
  14. package/lib/chat/ChatSidebar.js +2 -2
  15. package/lib/chat/ChatStandalone.d.ts +4 -54
  16. package/lib/chat/ChatStandalone.js +3 -3
  17. package/lib/chat/base/ChatBase.js +1118 -141
  18. package/lib/chat/header/ChatHeaderBase.d.ts +11 -6
  19. package/lib/chat/header/ChatHeaderBase.js +18 -16
  20. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  21. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  22. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  23. package/lib/chat/indicators/SandboxStatusIndicator.js +9 -9
  24. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  25. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  26. package/lib/chat/indicators/index.d.ts +1 -0
  27. package/lib/chat/indicators/index.js +1 -0
  28. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  29. package/lib/chat/messages/ChatMessageList.js +110 -102
  30. package/lib/chat/prompt/InputFooter.d.ts +19 -6
  31. package/lib/chat/prompt/InputFooter.js +71 -18
  32. package/lib/chat/prompt/InputPrompt.d.ts +3 -1
  33. package/lib/chat/prompt/InputPrompt.js +4 -4
  34. package/lib/chat/prompt/InputPromptFooter.js +1 -1
  35. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  36. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  37. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  38. package/lib/chat/prompt/InputPromptText.js +2 -2
  39. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  40. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  41. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  42. package/lib/chat/usage/TokenUsageBar.js +20 -2
  43. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  44. package/lib/client/AgentRuntimesClientContext.js +55 -0
  45. package/lib/client/AgentsMixin.d.ts +48 -19
  46. package/lib/client/AgentsMixin.js +115 -30
  47. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  48. package/lib/client/IAgentRuntimesClient.js +5 -0
  49. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  50. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  51. package/lib/client/index.d.ts +4 -1
  52. package/lib/client/index.js +3 -1
  53. package/lib/components/NotificationEventCard.js +55 -26
  54. package/lib/components/OutputCard.js +21 -7
  55. package/lib/components/ToolApprovalCard.js +20 -2
  56. package/lib/config/AgentConfiguration.js +3 -3
  57. package/lib/context/ContextDistribution.d.ts +3 -1
  58. package/lib/context/ContextDistribution.js +8 -27
  59. package/lib/context/ContextInspector.d.ts +3 -1
  60. package/lib/context/ContextInspector.js +19 -67
  61. package/lib/context/ContextPanel.d.ts +3 -1
  62. package/lib/context/ContextPanel.js +104 -64
  63. package/lib/context/ContextUsage.d.ts +3 -1
  64. package/lib/context/ContextUsage.js +3 -3
  65. package/lib/context/CostTracker.d.ts +9 -3
  66. package/lib/context/CostTracker.js +26 -47
  67. package/lib/context/CostUsageChart.d.ts +12 -0
  68. package/lib/context/CostUsageChart.js +378 -0
  69. package/lib/context/GraphFlowChart.d.ts +16 -0
  70. package/lib/context/GraphFlowChart.js +182 -0
  71. package/lib/context/TokenUsageChart.d.ts +8 -1
  72. package/lib/context/TokenUsageChart.js +349 -211
  73. package/lib/context/TurnGraphChart.d.ts +39 -0
  74. package/lib/context/TurnGraphChart.js +538 -0
  75. package/lib/context/otelWsPool.d.ts +20 -0
  76. package/lib/context/otelWsPool.js +69 -0
  77. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  78. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  79. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  80. package/lib/examples/A2UiContactCardExample.js +154 -411
  81. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  82. package/lib/examples/A2UiRestaurantExample.js +114 -212
  83. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  84. package/lib/examples/A2UiViewerExample.js +283 -532
  85. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  86. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  87. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  88. package/lib/examples/AgentCheckpointsExample.js +14 -34
  89. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  90. package/lib/examples/AgentCodemodeExample.js +591 -175
  91. package/lib/examples/AgentEvalsExample.js +13 -23
  92. package/lib/examples/AgentGuardrailsExample.js +371 -71
  93. package/lib/examples/AgentHooksExample.d.ts +3 -0
  94. package/lib/examples/AgentHooksExample.js +104 -0
  95. package/lib/examples/AgentMCPExample.d.ts +3 -0
  96. package/lib/examples/AgentMCPExample.js +480 -0
  97. package/lib/examples/AgentMemoryExample.js +14 -24
  98. package/lib/examples/AgentMonitoringExample.js +261 -206
  99. package/lib/examples/AgentNotificationsExample.js +50 -24
  100. package/lib/examples/AgentOtelExample.js +2 -3
  101. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  102. package/lib/examples/AgentOutputsExample.js +383 -88
  103. package/lib/examples/AgentParametersExample.d.ts +3 -0
  104. package/lib/examples/AgentParametersExample.js +246 -0
  105. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  106. package/lib/examples/AgentSandboxExample.js +69 -47
  107. package/lib/examples/AgentSkillsExample.js +92 -106
  108. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  109. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  110. package/lib/examples/AgentSubagentsExample.js +228 -0
  111. package/lib/examples/AgentToolApprovalsExample.js +30 -493
  112. package/lib/examples/AgentTriggersExample.js +1067 -246
  113. package/lib/examples/ChatCustomExample.js +11 -24
  114. package/lib/examples/ChatExample.js +9 -34
  115. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  116. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  117. package/lib/examples/HomeExample.d.ts +15 -0
  118. package/lib/examples/HomeExample.js +77 -0
  119. package/lib/examples/Lexical2Example.js +4 -2
  120. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  121. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  122. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  123. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  124. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  125. package/lib/examples/NotebookAgentExample.js +192 -0
  126. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  127. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  128. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  129. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  130. package/lib/examples/NotebookExample.d.ts +4 -7
  131. package/lib/examples/NotebookExample.js +14 -146
  132. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  133. package/lib/examples/components/AuthRequiredView.js +33 -0
  134. package/lib/examples/components/ErrorView.d.ts +14 -0
  135. package/lib/examples/components/ErrorView.js +20 -0
  136. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  137. package/lib/examples/components/ExampleWrapper.js +25 -6
  138. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  139. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  140. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  142. package/lib/examples/components/index.d.ts +5 -0
  143. package/lib/examples/components/index.js +5 -0
  144. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  145. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  146. package/lib/examples/example-selector.d.ts +17 -4
  147. package/lib/examples/example-selector.js +107 -41
  148. package/lib/examples/index.d.ts +9 -6
  149. package/lib/examples/index.js +9 -6
  150. package/lib/examples/main.d.ts +1 -0
  151. package/lib/examples/main.js +218 -27
  152. package/lib/examples/utils/a2ui.d.ts +18 -0
  153. package/lib/examples/utils/a2ui.js +69 -0
  154. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  155. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  156. package/lib/examples/utils/agentId.d.ts +18 -0
  157. package/lib/examples/utils/agentId.js +54 -0
  158. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  159. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  160. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  161. package/lib/examples/utils/agents/stock-market.json +11 -11
  162. package/lib/examples/utils/examplesStore.js +82 -27
  163. package/lib/hooks/index.d.ts +8 -8
  164. package/lib/hooks/index.js +7 -7
  165. package/lib/hooks/useA2A.d.ts +2 -3
  166. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  167. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  168. package/lib/hooks/useAcp.d.ts +1 -2
  169. package/lib/hooks/useAgUi.d.ts +1 -1
  170. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  171. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  172. package/lib/hooks/useAgentsCatalog.js +1 -1
  173. package/lib/hooks/useAgentsService.d.ts +2 -2
  174. package/lib/hooks/useAgentsService.js +7 -7
  175. package/lib/hooks/useCheckpoints.js +1 -1
  176. package/lib/hooks/useConfig.d.ts +4 -1
  177. package/lib/hooks/useConfig.js +10 -3
  178. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  179. package/lib/hooks/useContextSnapshot.js +9 -37
  180. package/lib/hooks/useMonitoring.js +3 -0
  181. package/lib/hooks/useSandbox.d.ts +20 -8
  182. package/lib/hooks/useSandbox.js +105 -40
  183. package/lib/hooks/useSkills.d.ts +23 -5
  184. package/lib/hooks/useSkills.js +94 -39
  185. package/lib/hooks/useToolApprovals.d.ts +60 -36
  186. package/lib/hooks/useToolApprovals.js +318 -69
  187. package/lib/hooks/useVercelAI.d.ts +1 -1
  188. package/lib/index.d.ts +2 -1
  189. package/lib/index.js +1 -0
  190. package/lib/inference/index.d.ts +0 -1
  191. package/lib/middleware/index.d.ts +0 -1
  192. package/lib/protocols/AGUIAdapter.js +6 -0
  193. package/lib/protocols/VercelAIAdapter.d.ts +9 -0
  194. package/lib/protocols/VercelAIAdapter.js +144 -26
  195. package/lib/shims/json5.d.ts +4 -0
  196. package/lib/shims/json5.js +8 -0
  197. package/lib/specs/agents/agents.d.ts +10 -0
  198. package/lib/specs/agents/agents.js +752 -24
  199. package/lib/specs/envvars.d.ts +1 -0
  200. package/lib/specs/envvars.js +11 -0
  201. package/lib/specs/events.d.ts +1 -0
  202. package/lib/specs/events.js +1 -0
  203. package/lib/specs/index.d.ts +1 -0
  204. package/lib/specs/index.js +1 -0
  205. package/lib/specs/personas.d.ts +41 -0
  206. package/lib/specs/personas.js +168 -0
  207. package/lib/specs/skills.d.ts +2 -1
  208. package/lib/specs/skills.js +23 -5
  209. package/lib/specs/tools.js +3 -0
  210. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  211. package/lib/stores/agentRuntimeStore.js +636 -0
  212. package/lib/stores/index.d.ts +1 -1
  213. package/lib/stores/index.js +1 -1
  214. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  215. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  216. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  217. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  218. package/lib/tools/index.d.ts +0 -2
  219. package/lib/tools/index.js +0 -1
  220. package/lib/types/agentspecs.d.ts +50 -1
  221. package/lib/types/chat.d.ts +309 -8
  222. package/lib/types/context.d.ts +27 -0
  223. package/lib/types/cost.d.ts +2 -2
  224. package/lib/types/index.d.ts +2 -0
  225. package/lib/types/index.js +2 -0
  226. package/lib/types/mcp.d.ts +8 -0
  227. package/lib/types/models.d.ts +2 -2
  228. package/lib/types/personas.d.ts +25 -0
  229. package/lib/types/personas.js +5 -0
  230. package/lib/types/skills.d.ts +43 -1
  231. package/lib/types/stream.d.ts +110 -0
  232. package/lib/types/stream.js +36 -0
  233. package/lib/types/tools.d.ts +2 -0
  234. package/lib/utils/utils.d.ts +9 -5
  235. package/lib/utils/utils.js +9 -5
  236. package/package.json +13 -9
  237. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  238. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  239. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  240. package/scripts/codegen/generate_agents.py +106 -7
  241. package/scripts/codegen/generate_events.py +47 -17
  242. package/scripts/codegen/generate_personas.py +319 -0
  243. package/scripts/codegen/generate_skills.py +9 -9
  244. package/scripts/codegen/generate_tools.py +20 -0
  245. package/scripts/sync-jupyter.sh +26 -7
  246. package/style/primer-primitives.css +1 -6
  247. package/lib/api/tool-approvals.d.ts +0 -62
  248. package/lib/api/tool-approvals.js +0 -145
  249. package/lib/examples/LexicalSidebarExample.js +0 -163
  250. package/lib/examples/NotebookSidebarExample.js +0 -119
  251. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  252. package/lib/examples/NotebookSimpleExample.js +0 -22
  253. package/lib/examples/ag-ui/index.d.ts +0 -10
  254. package/lib/examples/ag-ui/index.js +0 -16
  255. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  256. package/lib/hooks/useAgentsRegistry.js +0 -20
  257. package/lib/stores/agentsStore.d.ts +0 -123
  258. package/lib/stores/agentsStore.js +0 -270
  259. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  260. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  261. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  262. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  263. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  264. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  265. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  266. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  267. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  268. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  269. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  270. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
  271. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  272. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  273. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  274. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  275. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -3,13 +3,13 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  /**
6
- * Unified hook for managing agents.
6
+ * Unified hook for managing agent runtimes.
7
7
  *
8
8
  * Combines agent lifecycle management (ephemeral/durable),
9
9
  * runtime catalog (React Query CRUD), lifecycle/catalog stores,
10
- * and the AI Agents REST API.
10
+ * the AI Agents REST API, and the agent-runtime WebSocket stream.
11
11
  *
12
- * @module hooks/useAgents
12
+ * @module hooks/useAgentRuntimes
13
13
  */
14
14
  import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
15
15
  import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
@@ -17,7 +17,8 @@ import { create } from 'zustand';
17
17
  import { persist, createJSONStorage } from 'zustand/middleware';
18
18
  import { useCoreStore, useDatalayer } from '@datalayer/core';
19
19
  import { useIAMStore } from '@datalayer/core/lib/state';
20
- import { useAgentStore, useAgentRuntime, useAgentStatus, useAgentError, useIsLaunching, } from '../stores/agentsStore';
20
+ import { agentRuntimeStore, useAgentRuntimeStore, useAgentRuntimeConnection, useAgentRuntimeStatus, useAgentRuntimeError, useAgentRuntimeIsLaunching, } from '../stores/agentRuntimeStore';
21
+ import { parseAgentStreamMessage, } from '../types/stream';
21
22
  import { DEFAULT_AGENT_CONFIG } from '../types/config';
22
23
  // ═══════════════════════════════════════════════════════════════════════════
23
24
  // Constants
@@ -103,18 +104,18 @@ function toAgentRuntimeData(raw) {
103
104
  * });
104
105
  * ```
105
106
  */
106
- export function useAgents(options = {}) {
107
+ export function useAgentRuntimes(options = {}) {
107
108
  const { agentSpecId, agentConfig, autoCreateAgent = true, autoStart = false, agentSpec, } = options;
108
109
  // Base store state
109
- const runtime = useAgentRuntime();
110
- const baseStatus = useAgentStatus();
111
- const storeError = useAgentError();
112
- const isLaunching = useIsLaunching();
110
+ const runtime = useAgentRuntimeConnection();
111
+ const baseStatus = useAgentRuntimeStatus();
112
+ const storeError = useAgentRuntimeError();
113
+ const isLaunching = useAgentRuntimeIsLaunching();
113
114
  // Store actions
114
- const storeLaunchAgent = useAgentStore(state => state.launchAgent);
115
- const storeConnectAgent = useAgentStore(state => state.connectAgent);
116
- const storeCreateAgent = useAgentStore(state => state.createAgent);
117
- const storeDisconnect = useAgentStore(state => state.disconnect);
115
+ const storeLaunchAgent = useAgentRuntimeStore(state => state.launchAgent);
116
+ const storeConnectAgent = useAgentRuntimeStore(state => state.connectAgent);
117
+ const storeCreateAgent = useAgentRuntimeStore(state => state.createAgent);
118
+ const storeDisconnect = useAgentRuntimeStore(state => state.disconnect);
118
119
  // Lifecycle local state
119
120
  const [lifecycleStatus, setLifecycleStatus] = useState('idle');
120
121
  const [lifecycleError, setLifecycleError] = useState(null);
@@ -408,7 +409,7 @@ export function useAgents(options = {}) {
408
409
  * The backend returns active runtimes from the operator **plus** paused
409
410
  * runtimes synthesised from Solr checkpoint records (with ``status="paused"``).
410
411
  */
411
- export function useAgentRuntimes() {
412
+ export function useAgentRuntimesQuery() {
412
413
  const { configuration } = useCoreStore();
413
414
  const { requestDatalayer } = useDatalayer({ notifyOnError: false });
414
415
  const { user } = useIAMStore();
@@ -607,7 +608,7 @@ export const useAgentLifecycleStore = create()(persist((set, get) => ({
607
608
  * Consolidated runtime list and mutations.
608
609
  */
609
610
  export function useAgentsRuntimes() {
610
- const runtimesQuery = useAgentRuntimes();
611
+ const runtimesQuery = useAgentRuntimesQuery();
611
612
  const createRuntimeMutation = useCreateAgentRuntime();
612
613
  const deleteRuntimeMutation = useDeleteAgentRuntime();
613
614
  const refreshRuntimes = useRefreshAgentRuntimes();
@@ -631,3 +632,112 @@ export function useAgentsRuntimes() {
631
632
  deleteRuntimeMutation,
632
633
  ]);
633
634
  }
635
+ const DEFAULT_WS_PATH = '/api/v1/tool-approvals/ws';
636
+ const DEFAULT_RECONNECT_DELAY_MS = 3_000;
637
+ /**
638
+ * Connect to the agent-runtime monitoring WebSocket.
639
+ *
640
+ * The hook writes all incoming data into the `useAgentRuntimeStore` Zustand
641
+ * store. Components that need approvals, MCP status, context snapshots, or
642
+ * full-context data simply read from the store.
643
+ *
644
+ * Mount this hook **once** near the top of your component tree (e.g. in
645
+ * the example root or in `ChatBase`). All other components read from the
646
+ * store — no extra WebSocket connections needed.
647
+ */
648
+ export function useAgentRuntimeWebSocket(options) {
649
+ const { enabled = true, baseUrl, authToken, agentId, autoReconnect = true, reconnectDelayMs = DEFAULT_RECONNECT_DELAY_MS, maxReconnectAttempts, } = options;
650
+ const onMessageRef = useRef(options.onMessage);
651
+ onMessageRef.current = options.onMessage;
652
+ useEffect(() => {
653
+ if (!enabled || !baseUrl) {
654
+ agentRuntimeStore.getState().setWsState('closed');
655
+ return;
656
+ }
657
+ let disposed = false;
658
+ let reconnectAttempts = 0;
659
+ let reconnectTimer = null;
660
+ function buildWsUrl() {
661
+ const httpUrl = `${baseUrl}${DEFAULT_WS_PATH}`;
662
+ const url = new URL(httpUrl.replace(/^http/, 'ws'));
663
+ if (authToken) {
664
+ url.searchParams.set('token', authToken);
665
+ }
666
+ if (agentId) {
667
+ url.searchParams.set('agent_id', agentId);
668
+ }
669
+ return url.toString();
670
+ }
671
+ function connect() {
672
+ if (disposed)
673
+ return;
674
+ const wsUrl = buildWsUrl();
675
+ agentRuntimeStore.getState().setWsState('connecting');
676
+ const ws = new WebSocket(wsUrl);
677
+ agentRuntimeStore.getState().setWs(ws, agentId);
678
+ ws.onopen = () => {
679
+ reconnectAttempts = 0;
680
+ agentRuntimeStore.getState().setWsState('connected');
681
+ };
682
+ ws.onmessage = (ev) => {
683
+ let raw;
684
+ try {
685
+ raw = JSON.parse(String(ev.data));
686
+ }
687
+ catch {
688
+ return;
689
+ }
690
+ const parsed = parseAgentStreamMessage(raw);
691
+ onMessageRef.current?.({
692
+ type: parsed?.type,
693
+ payload: parsed?.payload,
694
+ raw,
695
+ });
696
+ if (!parsed)
697
+ return;
698
+ const state = agentRuntimeStore.getState();
699
+ if (parsed.type === 'agent.snapshot') {
700
+ state.applySnapshot(parsed.payload);
701
+ return;
702
+ }
703
+ };
704
+ ws.onclose = () => {
705
+ agentRuntimeStore.getState().setWs(null, agentId);
706
+ agentRuntimeStore.getState().setWsState('closed');
707
+ if (disposed || !autoReconnect)
708
+ return;
709
+ reconnectAttempts += 1;
710
+ if (typeof maxReconnectAttempts === 'number' &&
711
+ reconnectAttempts > maxReconnectAttempts) {
712
+ return;
713
+ }
714
+ const delay = typeof reconnectDelayMs === 'function'
715
+ ? reconnectDelayMs(reconnectAttempts)
716
+ : reconnectDelayMs;
717
+ reconnectTimer = setTimeout(connect, Math.max(0, delay));
718
+ };
719
+ ws.onerror = () => {
720
+ if (ws.readyState === WebSocket.CONNECTING ||
721
+ ws.readyState === WebSocket.OPEN) {
722
+ ws.close();
723
+ }
724
+ };
725
+ }
726
+ connect();
727
+ return () => {
728
+ disposed = true;
729
+ if (reconnectTimer)
730
+ clearTimeout(reconnectTimer);
731
+ agentRuntimeStore.getState().setWs(null, agentId);
732
+ agentRuntimeStore.getState().resetWs();
733
+ };
734
+ }, [
735
+ enabled,
736
+ baseUrl,
737
+ authToken,
738
+ agentId,
739
+ autoReconnect,
740
+ reconnectDelayMs,
741
+ maxReconnectAttempts,
742
+ ]);
743
+ }
@@ -3,7 +3,7 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  /**
6
- * Agent catalog hooks.
6
+ * Agents catalog hooks.
7
7
  *
8
8
  * Includes the Zustand catalog store and the agent registry hook.
9
9
  *
@@ -4,7 +4,7 @@ export type RequestOptions = {
4
4
  };
5
5
  export type RoomType = 'notebook_persist' | 'notebook_memory' | 'doc_memory';
6
6
  /**
7
- * @deprecated Use useAgents instead
7
+ * @deprecated Use useAgentRuntimes instead
8
8
  */
9
9
  export declare const useAgentsService: (baseUrlOverride?: string) => {
10
10
  createAgent: (documentId: string, documentType: RoomType, ingress?: string, token?: string, kernelId?: string, { signal, baseUrl }?: RequestOptions) => Promise<any>;
@@ -17,6 +17,6 @@ export declare const useAgentsService: (baseUrlOverride?: string) => {
17
17
  * Get the notebook AI agent if any.
18
18
  *
19
19
  * This performs a periodic liveness check and keeps the local store in sync.
20
- * @deprecated Use useAgents instead
20
+ * @deprecated Use useAgentRuntimes instead
21
21
  */
22
22
  export declare function useNotebookAgents(notebookId: string): import("..").AgentRegistryEntry | undefined;
@@ -11,12 +11,12 @@
11
11
  import { useEffect } from 'react';
12
12
  import { useCoreStore, useDatalayer } from '@datalayer/core';
13
13
  import { URLExt } from '@jupyterlab/coreutils';
14
- import { useAgentStore } from '../stores/agentsStore';
14
+ import { useAgentRuntimeStore } from '../stores/agentRuntimeStore';
15
15
  // ═══════════════════════════════════════════════════════════════════════════
16
16
  // Agents Service REST API hook.
17
17
  // ═══════════════════════════════════════════════════════════════════════════
18
18
  /**
19
- * @deprecated Use useAgents instead
19
+ * @deprecated Use useAgentRuntimes instead
20
20
  */
21
21
  export const useAgentsService = (baseUrlOverride = 'api/ai-agents/v1') => {
22
22
  const { configuration } = useCoreStore();
@@ -86,14 +86,14 @@ export const useAgentsService = (baseUrlOverride = 'api/ai-agents/v1') => {
86
86
  * Get the notebook AI agent if any.
87
87
  *
88
88
  * This performs a periodic liveness check and keeps the local store in sync.
89
- * @deprecated Use useAgents instead
89
+ * @deprecated Use useAgentRuntimes instead
90
90
  */
91
91
  export function useNotebookAgents(notebookId) {
92
92
  const { getAgent } = useAgentsService();
93
- const agents = useAgentStore(state => state.agents);
94
- const upsertAgent = useAgentStore(state => state.upsertAgent);
95
- const deleteAgent = useAgentStore(state => state.deleteAgent);
96
- const getAgentById = useAgentStore(state => state.getAgentById);
93
+ const agents = useAgentRuntimeStore(state => state.agents);
94
+ const upsertAgent = useAgentRuntimeStore(state => state.upsertAgent);
95
+ const deleteAgent = useAgentRuntimeStore(state => state.deleteAgent);
96
+ const getAgentById = useAgentRuntimeStore(state => state.getAgentById);
97
97
  useEffect(() => {
98
98
  let abortController;
99
99
  const refreshAIAgent = async () => {
@@ -14,7 +14,7 @@ import { useMemo, useState, useCallback } from 'react';
14
14
  import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
15
15
  import { useIAMStore } from '@datalayer/core/lib/state';
16
16
  import { useCoreStore, useDatalayer } from '@datalayer/core';
17
- import { agentQueryKeys, AGENT_QUERY_OPTIONS } from './useAgents';
17
+ import { agentQueryKeys, AGENT_QUERY_OPTIONS } from './useAgentRuntimes';
18
18
  // ═══════════════════════════════════════════════════════════════════════════
19
19
  // Query hooks
20
20
  // ═══════════════════════════════════════════════════════════════════════════
@@ -3,9 +3,12 @@ import type { RemoteConfig } from '../types/config';
3
3
  * Hook to safely use query when QueryClient is available.
4
4
  * Returns a mock result if no QueryClientProvider is present.
5
5
  */
6
- export declare function useConfig(enabled: boolean, configEndpoint?: string, authToken?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPendingResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<RemoteConfig, Error> | {
6
+ export declare function useConfig(enabled: boolean, configEndpoint?: string, authToken?: string, agentId?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPendingResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<RemoteConfig, Error> | {
7
7
  data: undefined;
8
8
  isLoading: boolean;
9
9
  isError: boolean;
10
10
  error: null;
11
+ refetch: () => Promise<{
12
+ data: undefined;
13
+ }>;
11
14
  };
@@ -9,7 +9,7 @@ import { requestAPI } from '../api/handler';
9
9
  * Hook to safely use query when QueryClient is available.
10
10
  * Returns a mock result if no QueryClientProvider is present.
11
11
  */
12
- export function useConfig(enabled, configEndpoint, authToken) {
12
+ export function useConfig(enabled, configEndpoint, authToken, agentId) {
13
13
  const queryClient = useContext(QueryClientContext);
14
14
  if (!queryClient) {
15
15
  return {
@@ -17,6 +17,7 @@ export function useConfig(enabled, configEndpoint, authToken) {
17
17
  isLoading: false,
18
18
  isError: false,
19
19
  error: null,
20
+ refetch: () => Promise.resolve({ data: undefined }),
20
21
  };
21
22
  }
22
23
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -30,7 +31,13 @@ export function useConfig(enabled, configEndpoint, authToken) {
30
31
  if (authToken) {
31
32
  headers['Authorization'] = `Bearer ${authToken}`;
32
33
  }
33
- const response = await fetch(configEndpoint, { headers });
34
+ let endpoint = configEndpoint;
35
+ if (agentId) {
36
+ const url = new URL(configEndpoint, window.location.origin);
37
+ url.searchParams.set('agent_id', agentId);
38
+ endpoint = url.toString();
39
+ }
40
+ const response = await fetch(endpoint, { headers });
34
41
  if (!response.ok) {
35
42
  throw new Error(`Config fetch failed: ${response.statusText}`);
36
43
  }
@@ -39,7 +46,7 @@ export function useConfig(enabled, configEndpoint, authToken) {
39
46
  // Otherwise use Jupyter requestAPI.
40
47
  return requestAPI('configure');
41
48
  },
42
- queryKey: ['models', configEndpoint || 'jupyter'],
49
+ queryKey: ['models', configEndpoint || 'jupyter', agentId || 'global'],
43
50
  enabled,
44
51
  retry: 1,
45
52
  });
@@ -1,10 +1,15 @@
1
1
  import type { ContextSnapshotData } from '../types/context';
2
2
  /**
3
- * Hook to poll agent context-snapshot from the backend.
4
- * Returns cumulative token usage (input/output breakdown) tracked by the agent server.
3
+ * Hook that previously polled agent context-snapshot from the backend.
4
+ *
5
+ * The REST endpoint has been removed — context snapshot data is now
6
+ * delivered via the WebSocket stream (`agent.snapshot` messages).
7
+ * This hook is kept as a no-op so existing call-sites compile without
8
+ * changes; the token-usage bar simply stays hidden until a WS-based
9
+ * replacement is wired in.
5
10
  */
6
- export declare function useContextSnapshot(enabled: boolean, configEndpoint?: string, agentId?: string, authToken?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<ContextSnapshotData, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<ContextSnapshotData, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<ContextSnapshotData, Error> | import("@tanstack/query-core").QueryObserverPendingResult<ContextSnapshotData, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<ContextSnapshotData, Error> | {
7
- data: undefined;
11
+ export declare function useContextSnapshot(_enabled: boolean, _configEndpoint?: string, _agentId?: string, _authToken?: string): {
12
+ data: ContextSnapshotData | undefined;
8
13
  isLoading: boolean;
9
14
  isError: boolean;
10
15
  error: null;
@@ -2,43 +2,15 @@
2
2
  * Copyright (c) 2025-2026 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import { useContext } from 'react';
6
- import { useQuery, QueryClientContext } from '@tanstack/react-query';
7
- import { getApiBaseFromConfig } from '../utils';
8
5
  /**
9
- * Hook to poll agent context-snapshot from the backend.
10
- * Returns cumulative token usage (input/output breakdown) tracked by the agent server.
6
+ * Hook that previously polled agent context-snapshot from the backend.
7
+ *
8
+ * The REST endpoint has been removed — context snapshot data is now
9
+ * delivered via the WebSocket stream (`agent.snapshot` messages).
10
+ * This hook is kept as a no-op so existing call-sites compile without
11
+ * changes; the token-usage bar simply stays hidden until a WS-based
12
+ * replacement is wired in.
11
13
  */
12
- export function useContextSnapshot(enabled, configEndpoint, agentId, authToken) {
13
- const queryClient = useContext(QueryClientContext);
14
- if (!queryClient) {
15
- return { data: undefined, isLoading: false, isError: false, error: null };
16
- }
17
- const snapshotUrl = configEndpoint && agentId
18
- ? `${getApiBaseFromConfig(configEndpoint)}/configure/agents/${encodeURIComponent(agentId)}/context-snapshot`
19
- : undefined;
20
- // eslint-disable-next-line react-hooks/rules-of-hooks
21
- return useQuery({
22
- queryKey: ['context-snapshot-header', agentId, snapshotUrl],
23
- queryFn: async () => {
24
- if (!snapshotUrl) {
25
- throw new Error('No context-snapshot URL available');
26
- }
27
- const headers = { 'Content-Type': 'application/json' };
28
- if (authToken) {
29
- headers['Authorization'] = `Bearer ${authToken}`;
30
- }
31
- const response = await fetch(snapshotUrl, { headers });
32
- if (!response.ok) {
33
- throw new Error(`Context snapshot fetch failed: ${response.statusText}`);
34
- }
35
- return response.json();
36
- },
37
- enabled: enabled && !!snapshotUrl,
38
- // Poll every 10s, but stop after an error (e.g. runtime terminated).
39
- refetchInterval: query => (query.state.status === 'error' ? false : 10_000),
40
- refetchOnMount: 'always',
41
- staleTime: 0,
42
- retry: 1,
43
- });
14
+ export function useContextSnapshot(_enabled, _configEndpoint, _agentId, _authToken) {
15
+ return { data: undefined, isLoading: false, isError: false, error: null };
44
16
  }
@@ -25,6 +25,9 @@ export function toMetricValue(row) {
25
25
  return 0;
26
26
  }
27
27
  export async function fetchOtelMetricRows({ metric, serviceName, runUrl, apiKey, limit = 500, }) {
28
+ if (!runUrl || !apiKey) {
29
+ return [];
30
+ }
28
31
  const client = createOtelClient({
29
32
  baseUrl: runUrl,
30
33
  token: apiKey,
@@ -1,12 +1,24 @@
1
1
  import type { SandboxStatusData } from '../types/context';
2
2
  /**
3
- * Hook to poll sandbox execution status from the backend.
4
- * Returns whether a sandbox is available and if code is currently executing.
3
+ * Subscribe to the sandbox execution status via the
4
+ * `/api/v1/configure/sandbox/ws` WebSocket.
5
+ *
6
+ * This hook replaces the previous REST-polling implementation — the server
7
+ * now pushes status updates in real time and accepts interrupt requests over
8
+ * the same connection.
9
+ *
10
+ * @param enabled Whether to open the WebSocket connection.
11
+ * @param configEndpoint Base `configEndpoint` used by other chat hooks
12
+ * (e.g. `http://localhost:8765/api/v1/configure/config`).
13
+ * @param authToken Optional bearer token (passed as `?token=` query param
14
+ * because browsers cannot set headers on WebSocket).
15
+ * @param agentId Optional agent id; the backend returns an
16
+ * agent-scoped status when provided.
17
+ * @returns `{ data, interrupt }` where `data` is the latest status (or
18
+ * `undefined` until the first message) and `interrupt()` sends an
19
+ * `{ action: 'interrupt' }` message over the same WebSocket.
5
20
  */
6
- export declare function useSandbox(enabled: boolean, configEndpoint?: string, authToken?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<SandboxStatusData, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<SandboxStatusData, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<SandboxStatusData, Error> | import("@tanstack/query-core").QueryObserverPendingResult<SandboxStatusData, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<SandboxStatusData, Error> | {
7
- data: undefined;
8
- isLoading: boolean;
9
- isError: boolean;
10
- error: null;
11
- refetch: () => Promise<any>;
21
+ export declare function useSandbox(enabled: boolean, configEndpoint?: string, authToken?: string, agentId?: string): {
22
+ data: SandboxStatusData | undefined;
23
+ interrupt: () => void;
12
24
  };
@@ -2,48 +2,113 @@
2
2
  * Copyright (c) 2025-2026 Datalayer, Inc.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import { useContext } from 'react';
6
- import { useQuery, QueryClientContext } from '@tanstack/react-query';
5
+ import { useCallback, useEffect, useRef, useState } from 'react';
7
6
  import { getApiBaseFromConfig } from '../utils';
7
+ const RECONNECT_BASE_MS = 1000;
8
+ const RECONNECT_MAX_MS = 30000;
9
+ function isRetryableCloseCode(code) {
10
+ // Avoid reconnect loops for policy/auth/protocol closures.
11
+ const nonRetryable = new Set([1002, 1003, 1007, 1008, 4401, 4403]);
12
+ return !nonRetryable.has(code);
13
+ }
8
14
  /**
9
- * Hook to poll sandbox execution status from the backend.
10
- * Returns whether a sandbox is available and if code is currently executing.
15
+ * Subscribe to the sandbox execution status via the
16
+ * `/api/v1/configure/sandbox/ws` WebSocket.
17
+ *
18
+ * This hook replaces the previous REST-polling implementation — the server
19
+ * now pushes status updates in real time and accepts interrupt requests over
20
+ * the same connection.
21
+ *
22
+ * @param enabled Whether to open the WebSocket connection.
23
+ * @param configEndpoint Base `configEndpoint` used by other chat hooks
24
+ * (e.g. `http://localhost:8765/api/v1/configure/config`).
25
+ * @param authToken Optional bearer token (passed as `?token=` query param
26
+ * because browsers cannot set headers on WebSocket).
27
+ * @param agentId Optional agent id; the backend returns an
28
+ * agent-scoped status when provided.
29
+ * @returns `{ data, interrupt }` where `data` is the latest status (or
30
+ * `undefined` until the first message) and `interrupt()` sends an
31
+ * `{ action: 'interrupt' }` message over the same WebSocket.
11
32
  */
12
- export function useSandbox(enabled, configEndpoint, authToken) {
13
- const queryClient = useContext(QueryClientContext);
14
- if (!queryClient) {
15
- return {
16
- data: undefined,
17
- isLoading: false,
18
- isError: false,
19
- error: null,
20
- refetch: () => Promise.resolve({}),
33
+ export function useSandbox(enabled, configEndpoint, authToken, agentId) {
34
+ const [data, setData] = useState(undefined);
35
+ const wsRef = useRef(null);
36
+ useEffect(() => {
37
+ if (!enabled || !configEndpoint) {
38
+ setData(undefined);
39
+ return;
40
+ }
41
+ const apiBase = getApiBaseFromConfig(configEndpoint);
42
+ if (!apiBase)
43
+ return;
44
+ const wsBase = apiBase.replace(/^http/, 'ws');
45
+ const params = [];
46
+ if (agentId) {
47
+ params.push(`agent_id=${encodeURIComponent(agentId)}`);
48
+ }
49
+ if (authToken) {
50
+ // WebSocket API cannot set custom headers — pass token via query param.
51
+ params.push(`token=${encodeURIComponent(authToken)}`);
52
+ }
53
+ const url = `${wsBase}/configure/sandbox/ws${params.length ? `?${params.join('&')}` : ''}`;
54
+ let disposed = false;
55
+ let reconnectTimer;
56
+ let reconnectAttempts = 0;
57
+ const scheduleReconnect = (code) => {
58
+ if (disposed || !isRetryableCloseCode(code))
59
+ return;
60
+ const delay = Math.min(RECONNECT_BASE_MS * 2 ** reconnectAttempts, RECONNECT_MAX_MS);
61
+ reconnectAttempts += 1;
62
+ reconnectTimer = setTimeout(connect, delay);
63
+ };
64
+ const connect = () => {
65
+ if (disposed)
66
+ return;
67
+ const ws = new WebSocket(url);
68
+ wsRef.current = ws;
69
+ ws.onopen = () => {
70
+ reconnectAttempts = 0;
71
+ };
72
+ ws.onmessage = event => {
73
+ try {
74
+ const msg = JSON.parse(event.data);
75
+ if (msg && msg.action === 'interrupt')
76
+ return;
77
+ const variant = typeof msg?.variant === 'string' ? msg.variant : '';
78
+ setData({
79
+ available: variant !== 'unavailable' && variant !== 'error',
80
+ sandbox_running: Boolean(msg?.sandbox_running),
81
+ is_executing: Boolean(msg?.is_executing),
82
+ variant,
83
+ });
84
+ }
85
+ catch {
86
+ // Ignore malformed messages.
87
+ }
88
+ };
89
+ ws.onclose = event => {
90
+ wsRef.current = null;
91
+ scheduleReconnect(event.code);
92
+ };
93
+ ws.onerror = () => {
94
+ ws.close();
95
+ };
96
+ };
97
+ connect();
98
+ return () => {
99
+ disposed = true;
100
+ if (reconnectTimer)
101
+ clearTimeout(reconnectTimer);
102
+ wsRef.current?.close();
103
+ wsRef.current = null;
104
+ setData(undefined);
21
105
  };
22
- }
23
- const statusUrl = configEndpoint
24
- ? `${getApiBaseFromConfig(configEndpoint)}/configure/sandbox-status`
25
- : undefined;
26
- // eslint-disable-next-line react-hooks/rules-of-hooks
27
- return useQuery({
28
- queryKey: ['sandbox-status', statusUrl],
29
- queryFn: async () => {
30
- if (!statusUrl) {
31
- throw new Error('No sandbox status URL available');
32
- }
33
- const headers = { 'Content-Type': 'application/json' };
34
- if (authToken) {
35
- headers['Authorization'] = `Bearer ${authToken}`;
36
- }
37
- const response = await fetch(statusUrl, { headers });
38
- if (!response.ok) {
39
- throw new Error(`Sandbox status fetch failed: ${response.statusText}`);
40
- }
41
- return response.json();
42
- },
43
- enabled: enabled && !!statusUrl,
44
- refetchInterval: query => (query.state.status === 'error' ? false : 2_000),
45
- refetchOnMount: 'always',
46
- staleTime: 0,
47
- retry: 1,
48
- });
106
+ }, [enabled, configEndpoint, authToken, agentId]);
107
+ const interrupt = useCallback(() => {
108
+ const ws = wsRef.current;
109
+ if (ws && ws.readyState === WebSocket.OPEN) {
110
+ ws.send(JSON.stringify({ action: 'interrupt' }));
111
+ }
112
+ }, []);
113
+ return { data, interrupt };
49
114
  }
@@ -1,13 +1,31 @@
1
- import type { SkillsResponse } from '../types/skills';
1
+ import type { SkillInfo } from '../types/skills';
2
2
  /**
3
- * Hook to fetch available skills from backend.
3
+ * Derive the list of skills from the WS-pushed `codemodeStatus`.
4
+ *
5
+ * The server-side SkillsArea pushes per-skill status (`available`,
6
+ * `enabled`, `loaded`) via the monitoring WebSocket inside the
7
+ * `codemodeStatus.skills` array. This hook reads from the Zustand
8
+ * store — no REST call is made.
4
9
  */
5
- export declare function useSkills(enabled: boolean, baseEndpoint?: string, authToken?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<SkillsResponse, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<SkillsResponse, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<SkillsResponse, Error> | import("@tanstack/query-core").QueryObserverPendingResult<SkillsResponse, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<SkillsResponse, Error> | {
6
- data: undefined;
10
+ export declare function useSkills(_enabled: boolean, _baseEndpoint?: string, _authToken?: string): {
11
+ data: {
12
+ skills: SkillInfo[];
13
+ total: number;
14
+ } | undefined;
7
15
  isLoading: boolean;
8
16
  isError: boolean;
9
17
  error: null;
10
18
  refetch: () => Promise<{
11
- data: undefined;
19
+ data: {
20
+ skills: SkillInfo[];
21
+ total: number;
22
+ } | undefined;
12
23
  }>;
13
24
  };
25
+ export declare function useSkillActions(agentId?: string): {
26
+ enableSkill: (skillId: string) => boolean;
27
+ disableSkill: (skillId: string) => boolean;
28
+ approveSkill: (skillId: string) => boolean;
29
+ unapproveSkill: (skillId: string) => boolean;
30
+ };
31
+ export { useAgentRuntimeLoadedSkills } from '../stores';