@datalayer/agent-runtimes 1.0.4 → 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 (267) hide show
  1. package/README.md +34 -0
  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 -106
  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 +1083 -157
  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 +108 -113
  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 +0 -18
  46. package/lib/client/AgentsMixin.js +6 -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 +5 -1
  54. package/lib/config/AgentConfiguration.js +3 -3
  55. package/lib/context/ContextDistribution.d.ts +3 -1
  56. package/lib/context/ContextDistribution.js +8 -27
  57. package/lib/context/ContextInspector.d.ts +3 -1
  58. package/lib/context/ContextInspector.js +19 -67
  59. package/lib/context/ContextPanel.d.ts +3 -1
  60. package/lib/context/ContextPanel.js +104 -64
  61. package/lib/context/ContextUsage.d.ts +3 -1
  62. package/lib/context/ContextUsage.js +3 -3
  63. package/lib/context/CostTracker.d.ts +9 -3
  64. package/lib/context/CostTracker.js +26 -47
  65. package/lib/context/CostUsageChart.d.ts +12 -0
  66. package/lib/context/CostUsageChart.js +378 -0
  67. package/lib/context/GraphFlowChart.d.ts +16 -0
  68. package/lib/context/GraphFlowChart.js +182 -0
  69. package/lib/context/TokenUsageChart.d.ts +8 -1
  70. package/lib/context/TokenUsageChart.js +349 -211
  71. package/lib/context/TurnGraphChart.d.ts +39 -0
  72. package/lib/context/TurnGraphChart.js +538 -0
  73. package/lib/context/otelWsPool.d.ts +20 -0
  74. package/lib/context/otelWsPool.js +69 -0
  75. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  76. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  77. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  78. package/lib/examples/A2UiContactCardExample.js +154 -411
  79. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  80. package/lib/examples/A2UiRestaurantExample.js +114 -212
  81. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  82. package/lib/examples/A2UiViewerExample.js +283 -532
  83. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  84. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  85. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  86. package/lib/examples/AgentCheckpointsExample.js +13 -27
  87. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  88. package/lib/examples/AgentCodemodeExample.js +591 -169
  89. package/lib/examples/AgentEvalsExample.js +12 -16
  90. package/lib/examples/AgentGuardrailsExample.js +370 -64
  91. package/lib/examples/AgentHooksExample.d.ts +3 -0
  92. package/lib/examples/AgentHooksExample.js +104 -0
  93. package/lib/examples/AgentMCPExample.d.ts +3 -0
  94. package/lib/examples/AgentMCPExample.js +480 -0
  95. package/lib/examples/AgentMemoryExample.js +13 -17
  96. package/lib/examples/AgentMonitoringExample.js +260 -199
  97. package/lib/examples/AgentNotificationsExample.js +49 -17
  98. package/lib/examples/AgentOtelExample.js +2 -3
  99. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  100. package/lib/examples/AgentOutputsExample.js +382 -81
  101. package/lib/examples/AgentParametersExample.d.ts +3 -0
  102. package/lib/examples/AgentParametersExample.js +246 -0
  103. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  104. package/lib/examples/AgentSandboxExample.js +68 -40
  105. package/lib/examples/AgentSkillsExample.js +91 -99
  106. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  107. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  108. package/lib/examples/AgentSubagentsExample.js +228 -0
  109. package/lib/examples/AgentToolApprovalsExample.js +29 -557
  110. package/lib/examples/AgentTriggersExample.js +819 -565
  111. package/lib/examples/ChatCustomExample.js +11 -24
  112. package/lib/examples/ChatExample.js +7 -24
  113. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  114. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  115. package/lib/examples/HomeExample.d.ts +15 -0
  116. package/lib/examples/HomeExample.js +77 -0
  117. package/lib/examples/Lexical2Example.js +4 -2
  118. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  119. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  120. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  121. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  122. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  123. package/lib/examples/NotebookAgentExample.js +192 -0
  124. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  125. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  126. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  127. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  128. package/lib/examples/NotebookExample.d.ts +4 -7
  129. package/lib/examples/NotebookExample.js +14 -146
  130. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  131. package/lib/examples/components/AuthRequiredView.js +33 -0
  132. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  133. package/lib/examples/components/ExampleWrapper.js +25 -6
  134. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  135. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  136. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  137. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  138. package/lib/examples/components/index.d.ts +3 -0
  139. package/lib/examples/components/index.js +4 -0
  140. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  142. package/lib/examples/example-selector.d.ts +17 -4
  143. package/lib/examples/example-selector.js +107 -41
  144. package/lib/examples/index.d.ts +9 -6
  145. package/lib/examples/index.js +9 -6
  146. package/lib/examples/main.js +217 -27
  147. package/lib/examples/utils/a2ui.d.ts +18 -0
  148. package/lib/examples/utils/a2ui.js +69 -0
  149. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  150. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  151. package/lib/examples/utils/agentId.d.ts +18 -0
  152. package/lib/examples/utils/agentId.js +54 -0
  153. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  154. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  155. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  156. package/lib/examples/utils/agents/stock-market.json +11 -11
  157. package/lib/examples/utils/examplesStore.js +82 -27
  158. package/lib/hooks/index.d.ts +8 -8
  159. package/lib/hooks/index.js +7 -7
  160. package/lib/hooks/useA2A.d.ts +2 -3
  161. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  162. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  163. package/lib/hooks/useAcp.d.ts +1 -2
  164. package/lib/hooks/useAgUi.d.ts +1 -1
  165. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  166. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  167. package/lib/hooks/useAgentsCatalog.js +1 -1
  168. package/lib/hooks/useAgentsService.d.ts +2 -2
  169. package/lib/hooks/useAgentsService.js +7 -7
  170. package/lib/hooks/useCheckpoints.js +1 -1
  171. package/lib/hooks/useConfig.d.ts +4 -1
  172. package/lib/hooks/useConfig.js +10 -3
  173. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  174. package/lib/hooks/useContextSnapshot.js +9 -37
  175. package/lib/hooks/useMonitoring.js +3 -0
  176. package/lib/hooks/useSandbox.d.ts +20 -8
  177. package/lib/hooks/useSandbox.js +105 -40
  178. package/lib/hooks/useSkills.d.ts +23 -5
  179. package/lib/hooks/useSkills.js +94 -39
  180. package/lib/hooks/useToolApprovals.d.ts +60 -36
  181. package/lib/hooks/useToolApprovals.js +318 -69
  182. package/lib/hooks/useVercelAI.d.ts +1 -1
  183. package/lib/index.d.ts +2 -1
  184. package/lib/index.js +1 -0
  185. package/lib/inference/index.d.ts +0 -1
  186. package/lib/middleware/index.d.ts +0 -1
  187. package/lib/protocols/AGUIAdapter.js +6 -0
  188. package/lib/protocols/VercelAIAdapter.d.ts +7 -0
  189. package/lib/protocols/VercelAIAdapter.js +59 -7
  190. package/lib/specs/agents/agents.d.ts +10 -0
  191. package/lib/specs/agents/agents.js +2139 -262
  192. package/lib/specs/agents/index.js +3 -1
  193. package/lib/specs/envvars.d.ts +1 -0
  194. package/lib/specs/envvars.js +38 -20
  195. package/lib/specs/evals.js +6 -6
  196. package/lib/specs/events.d.ts +3 -10
  197. package/lib/specs/events.js +127 -84
  198. package/lib/specs/frontendTools.js +2 -2
  199. package/lib/specs/guardrails.d.ts +0 -7
  200. package/lib/specs/guardrails.js +240 -159
  201. package/lib/specs/index.d.ts +1 -0
  202. package/lib/specs/index.js +1 -0
  203. package/lib/specs/mcpServers.js +35 -6
  204. package/lib/specs/memory.d.ts +0 -2
  205. package/lib/specs/memory.js +4 -17
  206. package/lib/specs/models.js +25 -5
  207. package/lib/specs/notifications.js +102 -18
  208. package/lib/specs/outputs.js +15 -9
  209. package/lib/specs/personas.d.ts +41 -0
  210. package/lib/specs/personas.js +168 -0
  211. package/lib/specs/skills.d.ts +2 -1
  212. package/lib/specs/skills.js +41 -23
  213. package/lib/specs/teams/index.js +3 -1
  214. package/lib/specs/teams/teams.js +468 -348
  215. package/lib/specs/tools.js +4 -4
  216. package/lib/specs/triggers.js +61 -11
  217. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  218. package/lib/stores/agentRuntimeStore.js +636 -0
  219. package/lib/stores/index.d.ts +1 -1
  220. package/lib/stores/index.js +1 -1
  221. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  222. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  223. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  224. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  225. package/lib/tools/index.d.ts +0 -2
  226. package/lib/tools/index.js +0 -1
  227. package/lib/types/agentspecs.d.ts +50 -1
  228. package/lib/types/chat.d.ts +309 -8
  229. package/lib/types/context.d.ts +27 -0
  230. package/lib/types/cost.d.ts +2 -2
  231. package/lib/types/index.d.ts +2 -0
  232. package/lib/types/index.js +2 -0
  233. package/lib/types/mcp.d.ts +8 -0
  234. package/lib/types/models.d.ts +2 -2
  235. package/lib/types/personas.d.ts +25 -0
  236. package/lib/types/personas.js +5 -0
  237. package/lib/types/skills.d.ts +43 -1
  238. package/lib/types/stream.d.ts +110 -0
  239. package/lib/types/stream.js +36 -0
  240. package/lib/utils/utils.d.ts +9 -5
  241. package/lib/utils/utils.js +9 -5
  242. package/package.json +13 -9
  243. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  244. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  245. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  246. package/scripts/codegen/generate_agents.py +102 -6
  247. package/scripts/codegen/generate_events.py +35 -13
  248. package/scripts/codegen/generate_personas.py +319 -0
  249. package/scripts/codegen/generate_skills.py +9 -9
  250. package/scripts/sync-jupyter.sh +26 -7
  251. package/lib/api/tool-approvals.d.ts +0 -62
  252. package/lib/api/tool-approvals.js +0 -145
  253. package/lib/examples/LexicalSidebarExample.js +0 -163
  254. package/lib/examples/NotebookSidebarExample.js +0 -119
  255. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  256. package/lib/examples/NotebookSimpleExample.js +0 -22
  257. package/lib/examples/ag-ui/index.d.ts +0 -10
  258. package/lib/examples/ag-ui/index.js +0 -16
  259. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  260. package/lib/hooks/useAgentsRegistry.js +0 -20
  261. package/lib/stores/agentsStore.d.ts +0 -123
  262. package/lib/stores/agentsStore.js +0 -270
  263. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  264. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  265. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  266. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  267. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -0,0 +1,636 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Unified Zustand store for the agent-runtime layer.
7
+ *
8
+ * Manages three concerns in a single store:
9
+ *
10
+ * 1. **Agent Registry** (persisted) — URL-addressable agents that were
11
+ * previously connected. Each entry has a `baseUrl` + protocol pair.
12
+ *
13
+ * 2. **Runtime Connection** (ephemeral) — a single currently-connected pod
14
+ * (launch, connect, create agent, disconnect).
15
+ *
16
+ * 3. **WebSocket Stream** (ephemeral) — monitoring snapshot pushed by the
17
+ * agent-runtime server over `/api/v1/tool-approvals/ws` (tool approvals,
18
+ * context, MCP status, cost usage, codemode status, full context).
19
+ *
20
+ * @module stores/agentRuntimeStore
21
+ */
22
+ import { createStore } from 'zustand/vanilla';
23
+ import { useStore } from 'zustand';
24
+ import { persist, createJSONStorage, subscribeWithSelector, } from 'zustand/middleware';
25
+ export function getMonitoringCacheKey(serviceName, agentId) {
26
+ return `${serviceName || '__unknown_service__'}::${agentId || '__unknown_agent__'}`;
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // Helpers
30
+ // ---------------------------------------------------------------------------
31
+ function getTransportEndpoint(baseUrl, transport, agentId) {
32
+ switch (transport) {
33
+ case 'vercel-ai':
34
+ return `${baseUrl}/api/v1/vercel-ai/${agentId}`;
35
+ case 'a2a':
36
+ return `${baseUrl}/api/v1/a2a/agents/${agentId}/`;
37
+ case 'acp':
38
+ return `${baseUrl}/api/v1/acp/ws/${agentId}`;
39
+ case 'ag-ui':
40
+ default:
41
+ return `${baseUrl}/api/v1/ag-ui/${agentId}/`;
42
+ }
43
+ }
44
+ async function createAgentOnRuntime(agentBaseUrl, agentId, config = {}) {
45
+ if (!config.protocol) {
46
+ throw new Error('Agent protocol is required. Provide config.protocol from the selected spec/config.');
47
+ }
48
+ const transport = config.protocol;
49
+ if (!config.model) {
50
+ throw new Error('Agent model is required. Provide config.model from the selected spec/config.');
51
+ }
52
+ const response = await fetch(`${agentBaseUrl}/api/v1/agents`, {
53
+ method: 'POST',
54
+ headers: { 'Content-Type': 'application/json' },
55
+ body: JSON.stringify({
56
+ name: config.name || agentId,
57
+ description: config.description || 'AI assistant',
58
+ agent_library: config.agentLibrary || 'pydantic-ai',
59
+ transport,
60
+ model: config.model,
61
+ system_prompt: config.systemPrompt || 'You are a helpful AI assistant.',
62
+ }),
63
+ });
64
+ if (response.ok || response.status === 400) {
65
+ const endpoint = getTransportEndpoint(agentBaseUrl, transport, agentId);
66
+ return { agentId, endpoint, isReady: true };
67
+ }
68
+ const errorData = await response.json().catch(() => ({}));
69
+ throw new Error(errorData.detail || `Failed to create agent: ${response.status}`);
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Initial state
73
+ // ---------------------------------------------------------------------------
74
+ const initialRuntimeState = {
75
+ runtime: null,
76
+ status: 'idle',
77
+ error: null,
78
+ isLaunching: false,
79
+ };
80
+ const initialWsState = {
81
+ wsState: 'closed',
82
+ approvals: [],
83
+ pendingApprovalCount: 0,
84
+ contextSnapshot: null,
85
+ costUsage: null,
86
+ mcpStatus: null,
87
+ codemodeStatus: null,
88
+ fullContext: null,
89
+ monitoringCache: {},
90
+ loadedSkillsByAgentId: {},
91
+ };
92
+ // ---------------------------------------------------------------------------
93
+ // Store
94
+ // ---------------------------------------------------------------------------
95
+ /** Internal ref kept outside React to avoid re-renders on WS assignment. */
96
+ let _ws = null;
97
+ const _wsByAgentId = new Map();
98
+ function _resolveWs(agentId) {
99
+ const hasAgentScopedSockets = _wsByAgentId.size > 0;
100
+ if (agentId) {
101
+ const wsForAgent = _wsByAgentId.get(agentId);
102
+ if (wsForAgent && wsForAgent.readyState === WebSocket.OPEN) {
103
+ return wsForAgent;
104
+ }
105
+ // In multi-agent mode, avoid falling back to an arbitrary global socket.
106
+ if (hasAgentScopedSockets) {
107
+ return null;
108
+ }
109
+ }
110
+ // When any agent-scoped sockets are registered, require explicit routing.
111
+ if (hasAgentScopedSockets) {
112
+ return null;
113
+ }
114
+ if (_ws && _ws.readyState === WebSocket.OPEN) {
115
+ return _ws;
116
+ }
117
+ return null;
118
+ }
119
+ export const agentRuntimeStore = createStore()(subscribeWithSelector(persist((set, get) => ({
120
+ // ── Registry ──────────────────────────────────────────────────
121
+ agents: [],
122
+ upsertAgent: agentData => {
123
+ set(state => {
124
+ const existingIndex = state.agents.findIndex(a => a.id === agentData.id);
125
+ const now = Date.now();
126
+ if (existingIndex >= 0) {
127
+ const updatedAgents = [...state.agents];
128
+ updatedAgents[existingIndex] = {
129
+ ...updatedAgents[existingIndex],
130
+ ...agentData,
131
+ lastUpdated: now,
132
+ };
133
+ return { agents: updatedAgents };
134
+ }
135
+ const newAgent = {
136
+ name: agentData.name || agentData.id,
137
+ description: agentData.description || '',
138
+ status: agentData.status || 'initializing',
139
+ lastUpdated: now,
140
+ ...agentData,
141
+ };
142
+ return { agents: [...state.agents, newAgent] };
143
+ });
144
+ },
145
+ getAgentById: (id) => get().agents.find(a => a.id === id),
146
+ getAgentByUrl: (baseUrl, protocol) => get().agents.find(a => a.baseUrl === baseUrl && a.protocol === protocol),
147
+ updateAgentStatus: (id, status, error = null) => {
148
+ set(state => {
149
+ const index = state.agents.findIndex(a => a.id === id);
150
+ if (index >= 0) {
151
+ const updatedAgents = [...state.agents];
152
+ updatedAgents[index] = {
153
+ ...updatedAgents[index],
154
+ status,
155
+ error,
156
+ lastUpdated: Date.now(),
157
+ };
158
+ return { agents: updatedAgents };
159
+ }
160
+ return {};
161
+ });
162
+ },
163
+ toggleAgentStatus: (id) => {
164
+ set(state => {
165
+ const index = state.agents.findIndex(a => a.id === id);
166
+ if (index >= 0) {
167
+ const updatedAgents = [...state.agents];
168
+ const currentStatus = updatedAgents[index].status;
169
+ updatedAgents[index] = {
170
+ ...updatedAgents[index],
171
+ status: currentStatus === 'running' ? 'paused' : 'running',
172
+ lastUpdated: Date.now(),
173
+ };
174
+ return { agents: updatedAgents };
175
+ }
176
+ return {};
177
+ });
178
+ },
179
+ deleteAgent: (id) => {
180
+ set(state => {
181
+ const { [id]: _removed, ...remainingLoadedSkills } = state.loadedSkillsByAgentId;
182
+ return {
183
+ agents: state.agents.filter(a => a.id !== id),
184
+ loadedSkillsByAgentId: remainingLoadedSkills,
185
+ };
186
+ });
187
+ },
188
+ clearAgents: () => {
189
+ set({ agents: [] });
190
+ },
191
+ setLoadedSkillsForAgent: (agentId, skills) => {
192
+ set(state => ({
193
+ loadedSkillsByAgentId: {
194
+ ...state.loadedSkillsByAgentId,
195
+ [agentId]: skills,
196
+ },
197
+ }));
198
+ },
199
+ getLoadedSkillsForAgent: agentId => get().loadedSkillsByAgentId[agentId] ?? [],
200
+ clearLoadedSkillsForAgent: agentId => {
201
+ set(state => {
202
+ if (!(agentId in state.loadedSkillsByAgentId)) {
203
+ return {};
204
+ }
205
+ const { [agentId]: _removed, ...remaining } = state.loadedSkillsByAgentId;
206
+ return { loadedSkillsByAgentId: remaining };
207
+ });
208
+ },
209
+ // ── Runtime connection ────────────────────────────────────────
210
+ ...initialRuntimeState,
211
+ connectAgent: connection => {
212
+ const baseUrl = connection.jupyterBaseUrl ||
213
+ connection.serviceManager?.serverSettings.baseUrl;
214
+ if (!baseUrl) {
215
+ throw new Error('connectAgent requires either jupyterBaseUrl or serviceManager');
216
+ }
217
+ const agentBaseUrl = baseUrl.replace('/jupyter/server/', '/agent-runtimes/');
218
+ set({
219
+ runtime: {
220
+ podName: connection.podName,
221
+ environmentName: connection.environmentName,
222
+ jupyterBaseUrl: baseUrl,
223
+ agentBaseUrl,
224
+ serviceManager: connection.serviceManager,
225
+ status: 'ready',
226
+ kernelId: connection.kernelId,
227
+ },
228
+ status: 'ready',
229
+ error: null,
230
+ });
231
+ },
232
+ launchAgent: async (config) => {
233
+ set({ status: 'launching', error: null, isLaunching: true });
234
+ try {
235
+ const { createRuntime } = await import('@datalayer/core/lib/api');
236
+ const runtimePod = await createRuntime({
237
+ environmentName: config.environmentName,
238
+ creditsLimit: config.creditsLimit,
239
+ type: config.type || 'notebook',
240
+ givenName: config.givenName,
241
+ capabilities: config.capabilities,
242
+ snapshot: config.snapshot,
243
+ });
244
+ set({ status: 'connecting' });
245
+ const jupyterBaseUrl = runtimePod.ingress;
246
+ const agentBaseUrl = jupyterBaseUrl.replace('/jupyter/server/', '/agent-runtimes/');
247
+ const conn = {
248
+ podName: runtimePod.pod_name,
249
+ environmentName: runtimePod.environment_name,
250
+ jupyterBaseUrl,
251
+ agentBaseUrl,
252
+ status: 'ready',
253
+ };
254
+ set({ runtime: conn, status: 'ready', isLaunching: false });
255
+ return conn;
256
+ }
257
+ catch (err) {
258
+ const errorMessage = err instanceof Error ? err.message : 'Failed to launch runtime';
259
+ set({ status: 'error', error: errorMessage, isLaunching: false });
260
+ throw err;
261
+ }
262
+ },
263
+ createAgent: async (config = {}) => {
264
+ const { runtime } = get();
265
+ if (!runtime) {
266
+ throw new Error('No runtime connected. Launch or connect to a runtime first.');
267
+ }
268
+ try {
269
+ const agentId = config.name || runtime.podName;
270
+ const agentConnection = await createAgentOnRuntime(runtime.agentBaseUrl, agentId, config);
271
+ set({
272
+ runtime: {
273
+ ...runtime,
274
+ agentId: agentConnection.agentId,
275
+ endpoint: agentConnection.endpoint,
276
+ isReady: agentConnection.isReady,
277
+ },
278
+ });
279
+ return agentConnection;
280
+ }
281
+ catch (err) {
282
+ const errorMessage = err instanceof Error ? err.message : 'Failed to create agent';
283
+ set({ error: errorMessage });
284
+ throw err;
285
+ }
286
+ },
287
+ disconnect: () => {
288
+ set({ runtime: null, status: 'disconnected', error: null });
289
+ },
290
+ clearError: () => set({ error: null }),
291
+ setError: error => set({ error, status: 'error' }),
292
+ // ── WebSocket stream ──────────────────────────────────────────
293
+ ...initialWsState,
294
+ setWsState: wsState => set({ wsState }),
295
+ setWs: (ws, agentId) => {
296
+ _ws = ws;
297
+ if (agentId) {
298
+ if (ws) {
299
+ _wsByAgentId.set(agentId, ws);
300
+ }
301
+ else {
302
+ _wsByAgentId.delete(agentId);
303
+ }
304
+ }
305
+ },
306
+ applySnapshot: payload => set(state => ({
307
+ // Tool-approval list/count are sourced from ai-agents WS only.
308
+ approvals: state.approvals,
309
+ pendingApprovalCount: state.pendingApprovalCount,
310
+ contextSnapshot: payload.contextSnapshot ?? null,
311
+ costUsage: payload.costUsage ?? null,
312
+ mcpStatus: payload.mcpStatus ?? null,
313
+ codemodeStatus: payload.codemodeStatus ?? null,
314
+ fullContext: payload.fullContext ?? null,
315
+ })),
316
+ upsertApproval: approval => set(state => {
317
+ const filtered = state.approvals.filter(a => a.id !== approval.id);
318
+ const approvals = [approval, ...filtered];
319
+ return { approvals, pendingApprovalCount: approvals.length };
320
+ }),
321
+ removeApproval: approvalId => set(state => {
322
+ const approvals = state.approvals.filter(a => a.id !== approvalId);
323
+ return { approvals, pendingApprovalCount: approvals.length };
324
+ }),
325
+ sendDecision: (approvalId, approved, note, toolCallId, agentId) => {
326
+ const targetWs = _resolveWs(agentId);
327
+ if (!targetWs) {
328
+ return false;
329
+ }
330
+ targetWs.send(JSON.stringify({
331
+ type: 'tool_approval_decision',
332
+ approvalId,
333
+ approved,
334
+ ...(note ? { note } : {}),
335
+ ...(toolCallId ? { toolCallId } : {}),
336
+ }));
337
+ return true;
338
+ },
339
+ requestRefresh: agentId => {
340
+ const targetWs = _resolveWs(agentId);
341
+ if (!targetWs) {
342
+ return false;
343
+ }
344
+ targetWs.send(JSON.stringify({ type: 'request_snapshot' }));
345
+ targetWs.send(JSON.stringify({ type: 'request_otel_flush' }));
346
+ return true;
347
+ },
348
+ sendRawMessage: (payload, agentId) => {
349
+ const targetWs = _resolveWs(agentId);
350
+ if (!targetWs) {
351
+ return false;
352
+ }
353
+ targetWs.send(JSON.stringify(payload));
354
+ return true;
355
+ },
356
+ appendLocalTokenTurn: ({ serviceName, agentId, timestampMs, promptTokens, completionTokens, totalTokens, }) => {
357
+ set(state => {
358
+ const key = getMonitoringCacheKey(serviceName, agentId);
359
+ const existing = state.monitoringCache[key] ?? {
360
+ tokenTurns: [],
361
+ costPoints: [],
362
+ };
363
+ const tokenTurns = [...existing.tokenTurns];
364
+ const lastTurn = tokenTurns[tokenTurns.length - 1];
365
+ if (lastTurn &&
366
+ lastTurn.userMessageTokens === promptTokens &&
367
+ lastTurn.aiMessageTokens === completionTokens &&
368
+ lastTurn.systemPromptTokens === 0 &&
369
+ lastTurn.toolsDescriptionTokens === 0 &&
370
+ lastTurn.toolsUsageTokens === 0 &&
371
+ lastTurn.totalTokens === totalTokens) {
372
+ tokenTurns[tokenTurns.length - 1] = {
373
+ ...lastTurn,
374
+ timestampMs: Math.max(lastTurn.timestampMs, timestampMs),
375
+ };
376
+ return {
377
+ monitoringCache: {
378
+ ...state.monitoringCache,
379
+ [key]: {
380
+ ...existing,
381
+ tokenTurns,
382
+ },
383
+ },
384
+ };
385
+ }
386
+ const turnNumber = (lastTurn?.turnNumber ?? 0) + 1;
387
+ tokenTurns.push({
388
+ turnNumber,
389
+ timestampMs,
390
+ systemPromptTokens: 0,
391
+ toolsDescriptionTokens: 0,
392
+ userMessageTokens: promptTokens,
393
+ aiMessageTokens: completionTokens,
394
+ toolsUsageTokens: 0,
395
+ totalTokens,
396
+ });
397
+ return {
398
+ monitoringCache: {
399
+ ...state.monitoringCache,
400
+ [key]: {
401
+ ...existing,
402
+ tokenTurns,
403
+ },
404
+ },
405
+ };
406
+ });
407
+ },
408
+ mergeTokenTurns: ({ serviceName, agentId, turns }) => {
409
+ if (turns.length === 0)
410
+ return;
411
+ set(state => {
412
+ const key = getMonitoringCacheKey(serviceName, agentId);
413
+ const existing = state.monitoringCache[key] ?? {
414
+ tokenTurns: [],
415
+ costPoints: [],
416
+ };
417
+ const byTurn = new Map();
418
+ for (const turn of existing.tokenTurns) {
419
+ byTurn.set(turn.turnNumber, turn);
420
+ }
421
+ for (const turn of turns) {
422
+ byTurn.set(turn.turnNumber, turn);
423
+ }
424
+ const tokenTurns = Array.from(byTurn.values()).sort((a, b) => a.turnNumber - b.turnNumber);
425
+ return {
426
+ monitoringCache: {
427
+ ...state.monitoringCache,
428
+ [key]: {
429
+ ...existing,
430
+ tokenTurns,
431
+ },
432
+ },
433
+ };
434
+ });
435
+ },
436
+ appendLocalTokenTurnFull: ({ serviceName, agentId, timestampMs, systemPromptTokens, toolsDescriptionTokens, userMessageTokens, aiMessageTokens, toolsUsageTokens, totalTokens, }) => {
437
+ set(state => {
438
+ const key = getMonitoringCacheKey(serviceName, agentId);
439
+ const existing = state.monitoringCache[key] ?? {
440
+ tokenTurns: [],
441
+ costPoints: [],
442
+ };
443
+ const tokenTurns = [...existing.tokenTurns];
444
+ const lastTurn = tokenTurns[tokenTurns.length - 1];
445
+ if (lastTurn &&
446
+ lastTurn.systemPromptTokens === systemPromptTokens &&
447
+ lastTurn.toolsDescriptionTokens === toolsDescriptionTokens &&
448
+ lastTurn.userMessageTokens === userMessageTokens &&
449
+ lastTurn.aiMessageTokens === aiMessageTokens &&
450
+ lastTurn.toolsUsageTokens === toolsUsageTokens &&
451
+ lastTurn.totalTokens === totalTokens) {
452
+ tokenTurns[tokenTurns.length - 1] = {
453
+ ...lastTurn,
454
+ timestampMs: Math.max(lastTurn.timestampMs, timestampMs),
455
+ };
456
+ return {
457
+ monitoringCache: {
458
+ ...state.monitoringCache,
459
+ [key]: {
460
+ ...existing,
461
+ tokenTurns,
462
+ },
463
+ },
464
+ };
465
+ }
466
+ const turnNumber = (lastTurn?.turnNumber ?? 0) + 1;
467
+ tokenTurns.push({
468
+ turnNumber,
469
+ timestampMs,
470
+ systemPromptTokens,
471
+ toolsDescriptionTokens,
472
+ userMessageTokens,
473
+ aiMessageTokens,
474
+ toolsUsageTokens,
475
+ totalTokens,
476
+ });
477
+ return {
478
+ monitoringCache: {
479
+ ...state.monitoringCache,
480
+ [key]: {
481
+ ...existing,
482
+ tokenTurns,
483
+ },
484
+ },
485
+ };
486
+ });
487
+ },
488
+ upsertLocalCostPoint: ({ serviceName, agentId, timestampMs, cumulativeUsd, }) => {
489
+ set(state => {
490
+ const key = getMonitoringCacheKey(serviceName, agentId);
491
+ const existing = state.monitoringCache[key] ?? {
492
+ tokenTurns: [],
493
+ costPoints: [],
494
+ };
495
+ const costPoints = [...existing.costPoints];
496
+ const existingIdx = costPoints.findIndex(point => Math.abs(point.timestampMs - timestampMs) < 1);
497
+ if (existingIdx >= 0) {
498
+ costPoints[existingIdx] = {
499
+ ...costPoints[existingIdx],
500
+ cumulativeUsd: Math.max(costPoints[existingIdx].cumulativeUsd, cumulativeUsd),
501
+ };
502
+ }
503
+ else {
504
+ costPoints.push({ timestampMs, cumulativeUsd });
505
+ }
506
+ costPoints.sort((a, b) => a.timestampMs - b.timestampMs);
507
+ return {
508
+ monitoringCache: {
509
+ ...state.monitoringCache,
510
+ [key]: {
511
+ ...existing,
512
+ costPoints,
513
+ },
514
+ },
515
+ };
516
+ });
517
+ },
518
+ mergeCostPoints: ({ serviceName, agentId, points }) => {
519
+ if (points.length === 0)
520
+ return;
521
+ set(state => {
522
+ const key = getMonitoringCacheKey(serviceName, agentId);
523
+ const existing = state.monitoringCache[key] ?? {
524
+ tokenTurns: [],
525
+ costPoints: [],
526
+ };
527
+ const byTs = new Map();
528
+ for (const point of existing.costPoints) {
529
+ byTs.set(point.timestampMs, point);
530
+ }
531
+ for (const point of points) {
532
+ const prev = byTs.get(point.timestampMs);
533
+ if (!prev) {
534
+ byTs.set(point.timestampMs, point);
535
+ }
536
+ else {
537
+ byTs.set(point.timestampMs, {
538
+ timestampMs: point.timestampMs,
539
+ cumulativeUsd: Math.max(prev.cumulativeUsd, point.cumulativeUsd),
540
+ });
541
+ }
542
+ }
543
+ const costPoints = Array.from(byTs.values()).sort((a, b) => a.timestampMs - b.timestampMs);
544
+ return {
545
+ monitoringCache: {
546
+ ...state.monitoringCache,
547
+ [key]: {
548
+ ...existing,
549
+ costPoints,
550
+ },
551
+ },
552
+ };
553
+ });
554
+ },
555
+ // ── Reset ─────────────────────────────────────────────────────
556
+ reset: () => {
557
+ // Close any live WebSocket so the backend tears down its
558
+ // per-connection state (subscriptions, approvals, monitoring).
559
+ if (_ws) {
560
+ try {
561
+ _ws.close(1000, 'reset');
562
+ }
563
+ catch {
564
+ // Ignore close errors — socket may already be in a closing
565
+ // state or the runtime may have been killed.
566
+ }
567
+ }
568
+ _ws = null;
569
+ _wsByAgentId.clear();
570
+ set({ ...initialRuntimeState, ...initialWsState });
571
+ },
572
+ resetWs: () => {
573
+ if (_ws) {
574
+ try {
575
+ _ws.close(1000, 'reset');
576
+ }
577
+ catch {
578
+ // Ignore.
579
+ }
580
+ }
581
+ _ws = null;
582
+ _wsByAgentId.clear();
583
+ set(initialWsState);
584
+ },
585
+ }), {
586
+ name: 'agent-runtimes-storage',
587
+ storage: createJSONStorage(() => localStorage),
588
+ partialize: state => ({
589
+ agents: state.agents.map(agent => ({
590
+ id: agent.id,
591
+ name: agent.name,
592
+ description: agent.description,
593
+ baseUrl: agent.baseUrl,
594
+ transport: agent.protocol,
595
+ status: agent.status,
596
+ lastUpdated: agent.lastUpdated,
597
+ documentId: agent.documentId,
598
+ runtimeId: agent.runtimeId,
599
+ })),
600
+ monitoringCache: state.monitoringCache,
601
+ loadedSkillsByAgentId: state.loadedSkillsByAgentId,
602
+ }),
603
+ })));
604
+ export function useAgentRuntimeStore(selector) {
605
+ const resolvedSelector = selector
606
+ ? selector
607
+ : (state) => state;
608
+ return useStore(agentRuntimeStore, resolvedSelector);
609
+ }
610
+ const useAgentRuntimeStoreWithStatics = useAgentRuntimeStore;
611
+ useAgentRuntimeStoreWithStatics.getState = agentRuntimeStore.getState;
612
+ useAgentRuntimeStoreWithStatics.subscribe = agentRuntimeStore.subscribe;
613
+ // ---------------------------------------------------------------------------
614
+ // Selector hooks — Registry
615
+ // ---------------------------------------------------------------------------
616
+ export const useAgentRuntimeConnection = () => useAgentRuntimeStore(s => s.runtime);
617
+ export const useAgentRuntimeStatus = () => useAgentRuntimeStore(s => s.status);
618
+ export const useAgentRuntimeError = () => useAgentRuntimeStore(s => s.error);
619
+ export const useAgentRuntimeIsLaunching = () => useAgentRuntimeStore(s => s.isLaunching);
620
+ // ---------------------------------------------------------------------------
621
+ // Selector hooks — WebSocket stream
622
+ // ---------------------------------------------------------------------------
623
+ export const useAgentRuntimeApprovals = () => useAgentRuntimeStore(s => s.approvals);
624
+ export const useAgentRuntimePendingCount = () => useAgentRuntimeStore(s => s.pendingApprovalCount);
625
+ export const useAgentRuntimeMcpStatus = () => useAgentRuntimeStore(s => s.mcpStatus);
626
+ export const useAgentRuntimeFullContext = () => useAgentRuntimeStore(s => s.fullContext);
627
+ export const useAgentRuntimeContextSnapshot = () => useAgentRuntimeStore(s => s.contextSnapshot);
628
+ export const useAgentRuntimeCostUsage = () => useAgentRuntimeStore(s => s.costUsage);
629
+ export const useAgentRuntimeCodemodeStatus = () => useAgentRuntimeStore(s => s.codemodeStatus);
630
+ export const useAgentRuntimeWsState = () => useAgentRuntimeStore(s => s.wsState);
631
+ export const useAgentRuntimeLoadedSkills = (agentId) => useAgentRuntimeStore(s => agentId ? (s.loadedSkillsByAgentId[agentId] ?? []) : []);
632
+ // ---------------------------------------------------------------------------
633
+ // Non-React access
634
+ // ---------------------------------------------------------------------------
635
+ export const getAgentRuntimeState = () => agentRuntimeStore.getState();
636
+ export const subscribeToAgentRuntime = agentRuntimeStore.subscribe;
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * @module store
5
5
  */
6
- export { useAgentStore, useAgentRuntime, useAgentFromStore, useAgentStatus, useAgentError, useIsLaunching, getAgentState, subscribeToAgent, agentStore, type AgentRegistryEntry, type agentsStoreState, type agentsStoreActions, type agentsStore, type AgentRegistryState, type AgentState, } from './agentsStore';
6
+ export { agentRuntimeStore, useAgentRuntimeStore, useAgentRuntimeConnection, useAgentRuntimeStatus, useAgentRuntimeError, useAgentRuntimeIsLaunching, useAgentRuntimeApprovals, useAgentRuntimePendingCount, useAgentRuntimeMcpStatus, useAgentRuntimeFullContext, useAgentRuntimeContextSnapshot, useAgentRuntimeCostUsage, useAgentRuntimeCodemodeStatus, useAgentRuntimeWsState, useAgentRuntimeLoadedSkills, getAgentRuntimeState, subscribeToAgentRuntime, type AgentRegistryEntry, type AgentRuntimeWsState, type AgentRuntimeStoreState, type AgentRuntimeStoreActions, type AgentRuntimeStore, } from './agentRuntimeStore';
7
7
  export { useChatStore, useChatMessages, useChatLoading, useChatStreaming, useChatError, useChatTools, useChatOpen, useChatConfig, useChatReady, useChatInferenceProvider, useChatExtensionRegistry, defaultChatConfig, type ChatStore, type ChatState, type ChatActions, type ChatConfig, type ToolCallState, } from './chatStore';
8
8
  export { useConversationStore, useConversationMessages, useNeedsFetch, useIsFetching, type ConversationStore, type ConversationData, } from './conversationStore';
@@ -7,6 +7,6 @@
7
7
  *
8
8
  * @module store
9
9
  */
10
- export { useAgentStore, useAgentRuntime, useAgentFromStore, useAgentStatus, useAgentError, useIsLaunching, getAgentState, subscribeToAgent, agentStore, } from './agentsStore';
10
+ export { agentRuntimeStore, useAgentRuntimeStore, useAgentRuntimeConnection, useAgentRuntimeStatus, useAgentRuntimeError, useAgentRuntimeIsLaunching, useAgentRuntimeApprovals, useAgentRuntimePendingCount, useAgentRuntimeMcpStatus, useAgentRuntimeFullContext, useAgentRuntimeContextSnapshot, useAgentRuntimeCostUsage, useAgentRuntimeCodemodeStatus, useAgentRuntimeWsState, useAgentRuntimeLoadedSkills, getAgentRuntimeState, subscribeToAgentRuntime, } from './agentRuntimeStore';
11
11
  export { useChatStore, useChatMessages, useChatLoading, useChatStreaming, useChatError, useChatTools, useChatOpen, useChatConfig, useChatReady, useChatInferenceProvider, useChatExtensionRegistry, defaultChatConfig, } from './chatStore';
12
12
  export { useConversationStore, useConversationMessages, useNeedsFetch, useIsFetching, } from './conversationStore';
@@ -1,5 +1,5 @@
1
1
  import type { ToolExecutionContext } from '@datalayer/jupyter-react';
2
- import { createAllCopilotKitActions, ActionRegistrar, type UseFrontendToolFn } from './CopilotKitToolAdapter';
2
+ import { createAllCopilotKitActions } from './CopilotKitToolAdapter';
3
3
  /**
4
4
  * Hook that creates CopilotKit actions for lexical tools.
5
5
  * Returns stable actions array that won't cause re-renders.
@@ -24,4 +24,3 @@ import { createAllCopilotKitActions, ActionRegistrar, type UseFrontendToolFn } f
24
24
  * ```
25
25
  */
26
26
  export declare function useLexicalToolActions(documentId: string, contextOverrides?: Partial<Omit<ToolExecutionContext, 'executor' | 'documentId'>>): ReturnType<typeof createAllCopilotKitActions>;
27
- export { ActionRegistrar, type UseFrontendToolFn };
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { useMemo } from 'react';
12
12
  import { useLexicalStore, DefaultExecutor as LexicalDefaultExecutor, lexicalToolDefinitions, lexicalToolOperations, } from '@datalayer/jupyter-lexical';
13
- import { createAllCopilotKitActions, ActionRegistrar, } from './CopilotKitToolAdapter';
13
+ import { createAllCopilotKitActions } from './CopilotKitToolAdapter';
14
14
  /**
15
15
  * Hook that creates CopilotKit actions for lexical tools.
16
16
  * Returns stable actions array that won't cause re-renders.
@@ -55,5 +55,3 @@ export function useLexicalToolActions(documentId, contextOverrides) {
55
55
  const actions = useMemo(() => createAllCopilotKitActions(lexicalToolDefinitions, lexicalToolOperations, context), [context]);
56
56
  return actions;
57
57
  }
58
- // Re-export shared types and components for convenience
59
- export { ActionRegistrar };