@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.
- package/README.md +34 -0
- package/lib/App.js +1 -1
- package/lib/agents/AgentDetails.d.ts +22 -1
- package/lib/agents/AgentDetails.js +34 -47
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +4 -2
- package/lib/chat/Chat.d.ts +5 -106
- package/lib/chat/Chat.js +4 -4
- package/lib/chat/ChatFloating.d.ts +7 -140
- package/lib/chat/ChatFloating.js +2 -2
- package/lib/chat/ChatPopupStandalone.d.ts +8 -47
- package/lib/chat/ChatPopupStandalone.js +3 -3
- package/lib/chat/ChatSidebar.d.ts +4 -69
- package/lib/chat/ChatSidebar.js +2 -2
- package/lib/chat/ChatStandalone.d.ts +4 -54
- package/lib/chat/ChatStandalone.js +3 -3
- package/lib/chat/base/ChatBase.js +1083 -157
- package/lib/chat/header/ChatHeaderBase.d.ts +11 -6
- package/lib/chat/header/ChatHeaderBase.js +18 -16
- package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
- package/lib/chat/indicators/McpStatusIndicator.js +7 -32
- package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
- package/lib/chat/indicators/SandboxStatusIndicator.js +9 -9
- package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
- package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
- package/lib/chat/indicators/index.d.ts +1 -0
- package/lib/chat/indicators/index.js +1 -0
- package/lib/chat/messages/ChatMessageList.d.ts +1 -1
- package/lib/chat/messages/ChatMessageList.js +108 -113
- package/lib/chat/prompt/InputFooter.d.ts +19 -6
- package/lib/chat/prompt/InputFooter.js +71 -18
- package/lib/chat/prompt/InputPrompt.d.ts +3 -1
- package/lib/chat/prompt/InputPrompt.js +4 -4
- package/lib/chat/prompt/InputPromptFooter.js +1 -1
- package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
- package/lib/chat/prompt/InputPromptLexical.js +12 -5
- package/lib/chat/prompt/InputPromptText.d.ts +3 -1
- package/lib/chat/prompt/InputPromptText.js +2 -2
- package/lib/chat/tools/ToolApprovalBanner.js +1 -1
- package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
- package/lib/chat/tools/ToolCallDisplay.js +2 -2
- package/lib/chat/usage/TokenUsageBar.js +20 -2
- package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
- package/lib/client/AgentRuntimesClientContext.js +55 -0
- package/lib/client/AgentsMixin.d.ts +0 -18
- package/lib/client/AgentsMixin.js +6 -30
- package/lib/client/IAgentRuntimesClient.d.ts +215 -0
- package/lib/client/IAgentRuntimesClient.js +5 -0
- package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
- package/lib/client/SdkAgentRuntimesClient.js +134 -0
- package/lib/client/index.d.ts +4 -1
- package/lib/client/index.js +3 -1
- package/lib/components/NotificationEventCard.js +5 -1
- package/lib/config/AgentConfiguration.js +3 -3
- package/lib/context/ContextDistribution.d.ts +3 -1
- package/lib/context/ContextDistribution.js +8 -27
- package/lib/context/ContextInspector.d.ts +3 -1
- package/lib/context/ContextInspector.js +19 -67
- package/lib/context/ContextPanel.d.ts +3 -1
- package/lib/context/ContextPanel.js +104 -64
- package/lib/context/ContextUsage.d.ts +3 -1
- package/lib/context/ContextUsage.js +3 -3
- package/lib/context/CostTracker.d.ts +9 -3
- package/lib/context/CostTracker.js +26 -47
- package/lib/context/CostUsageChart.d.ts +12 -0
- package/lib/context/CostUsageChart.js +378 -0
- package/lib/context/GraphFlowChart.d.ts +16 -0
- package/lib/context/GraphFlowChart.js +182 -0
- package/lib/context/TokenUsageChart.d.ts +8 -1
- package/lib/context/TokenUsageChart.js +349 -211
- package/lib/context/TurnGraphChart.d.ts +39 -0
- package/lib/context/TurnGraphChart.js +538 -0
- package/lib/context/otelWsPool.d.ts +20 -0
- package/lib/context/otelWsPool.js +69 -0
- package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
- package/lib/examples/A2UiComponentGalleryExample.js +315 -522
- package/lib/examples/A2UiContactCardExample.d.ts +0 -18
- package/lib/examples/A2UiContactCardExample.js +154 -411
- package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
- package/lib/examples/A2UiRestaurantExample.js +114 -212
- package/lib/examples/A2UiViewerExample.d.ts +0 -18
- package/lib/examples/A2UiViewerExample.js +283 -532
- package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
- package/lib/examples/AgentCheckpointsExample.js +13 -27
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +591 -169
- package/lib/examples/AgentEvalsExample.js +12 -16
- package/lib/examples/AgentGuardrailsExample.js +370 -64
- package/lib/examples/AgentHooksExample.d.ts +3 -0
- package/lib/examples/AgentHooksExample.js +104 -0
- package/lib/examples/AgentMCPExample.d.ts +3 -0
- package/lib/examples/AgentMCPExample.js +480 -0
- package/lib/examples/AgentMemoryExample.js +13 -17
- package/lib/examples/AgentMonitoringExample.js +260 -199
- package/lib/examples/AgentNotificationsExample.js +49 -17
- package/lib/examples/AgentOtelExample.js +2 -3
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +382 -81
- package/lib/examples/AgentParametersExample.d.ts +3 -0
- package/lib/examples/AgentParametersExample.js +246 -0
- package/lib/examples/AgentSandboxExample.d.ts +2 -2
- package/lib/examples/AgentSandboxExample.js +68 -40
- package/lib/examples/AgentSkillsExample.js +91 -99
- package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
- package/lib/examples/AgentSubagentsExample.d.ts +14 -0
- package/lib/examples/AgentSubagentsExample.js +228 -0
- package/lib/examples/AgentToolApprovalsExample.js +29 -557
- package/lib/examples/AgentTriggersExample.js +819 -565
- package/lib/examples/ChatCustomExample.js +11 -24
- package/lib/examples/ChatExample.js +7 -24
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/CopilotKitNotebookExample.js +2 -1
- package/lib/examples/HomeExample.d.ts +15 -0
- package/lib/examples/HomeExample.js +77 -0
- package/lib/examples/Lexical2Example.js +4 -2
- package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
- package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
- package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
- package/lib/examples/LexicalAgentSidebarExample.js +261 -0
- package/lib/examples/NotebookAgentExample.d.ts +9 -0
- package/lib/examples/NotebookAgentExample.js +192 -0
- package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
- package/lib/examples/NotebookAgentSidebarExample.js +221 -0
- package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
- package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
- package/lib/examples/NotebookExample.d.ts +4 -7
- package/lib/examples/NotebookExample.js +14 -146
- package/lib/examples/components/AuthRequiredView.d.ts +6 -0
- package/lib/examples/components/AuthRequiredView.js +33 -0
- package/lib/examples/components/ExampleWrapper.d.ts +7 -0
- package/lib/examples/components/ExampleWrapper.js +25 -6
- package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
- package/lib/examples/components/index.d.ts +3 -0
- package/lib/examples/components/index.js +4 -0
- package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
- package/lib/examples/example-selector.d.ts +17 -4
- package/lib/examples/example-selector.js +107 -41
- package/lib/examples/index.d.ts +9 -6
- package/lib/examples/index.js +9 -6
- package/lib/examples/main.js +217 -27
- package/lib/examples/utils/a2ui.d.ts +18 -0
- package/lib/examples/utils/a2ui.js +69 -0
- package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
- package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
- package/lib/examples/utils/agentId.d.ts +18 -0
- package/lib/examples/utils/agentId.js +54 -0
- package/lib/examples/utils/agents/earthquake-detector.json +11 -11
- package/lib/examples/utils/agents/sales-forecaster.json +11 -11
- package/lib/examples/utils/agents/social-post-generator.json +11 -11
- package/lib/examples/utils/agents/stock-market.json +11 -11
- package/lib/examples/utils/examplesStore.js +82 -27
- package/lib/hooks/index.d.ts +8 -8
- package/lib/hooks/index.js +7 -7
- package/lib/hooks/useA2A.d.ts +2 -3
- package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
- package/lib/hooks/useAIAgentsWebSocket.js +118 -12
- package/lib/hooks/useAcp.d.ts +1 -2
- package/lib/hooks/useAgUi.d.ts +1 -1
- package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
- package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
- package/lib/hooks/useAgentsCatalog.js +1 -1
- package/lib/hooks/useAgentsService.d.ts +2 -2
- package/lib/hooks/useAgentsService.js +7 -7
- package/lib/hooks/useCheckpoints.js +1 -1
- package/lib/hooks/useConfig.d.ts +4 -1
- package/lib/hooks/useConfig.js +10 -3
- package/lib/hooks/useContextSnapshot.d.ts +9 -4
- package/lib/hooks/useContextSnapshot.js +9 -37
- package/lib/hooks/useMonitoring.js +3 -0
- package/lib/hooks/useSandbox.d.ts +20 -8
- package/lib/hooks/useSandbox.js +105 -40
- package/lib/hooks/useSkills.d.ts +23 -5
- package/lib/hooks/useSkills.js +94 -39
- package/lib/hooks/useToolApprovals.d.ts +60 -36
- package/lib/hooks/useToolApprovals.js +318 -69
- package/lib/hooks/useVercelAI.d.ts +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/inference/index.d.ts +0 -1
- package/lib/middleware/index.d.ts +0 -1
- package/lib/protocols/AGUIAdapter.js +6 -0
- package/lib/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/protocols/VercelAIAdapter.js +59 -7
- package/lib/specs/agents/agents.d.ts +10 -0
- package/lib/specs/agents/agents.js +2139 -262
- package/lib/specs/agents/index.js +3 -1
- package/lib/specs/envvars.d.ts +1 -0
- package/lib/specs/envvars.js +38 -20
- package/lib/specs/evals.js +6 -6
- package/lib/specs/events.d.ts +3 -10
- package/lib/specs/events.js +127 -84
- package/lib/specs/frontendTools.js +2 -2
- package/lib/specs/guardrails.d.ts +0 -7
- package/lib/specs/guardrails.js +240 -159
- package/lib/specs/index.d.ts +1 -0
- package/lib/specs/index.js +1 -0
- package/lib/specs/mcpServers.js +35 -6
- package/lib/specs/memory.d.ts +0 -2
- package/lib/specs/memory.js +4 -17
- package/lib/specs/models.js +25 -5
- package/lib/specs/notifications.js +102 -18
- package/lib/specs/outputs.js +15 -9
- package/lib/specs/personas.d.ts +41 -0
- package/lib/specs/personas.js +168 -0
- package/lib/specs/skills.d.ts +2 -1
- package/lib/specs/skills.js +41 -23
- package/lib/specs/teams/index.js +3 -1
- package/lib/specs/teams/teams.js +468 -348
- package/lib/specs/tools.js +4 -4
- package/lib/specs/triggers.js +61 -11
- package/lib/stores/agentRuntimeStore.d.ts +204 -0
- package/lib/stores/agentRuntimeStore.js +636 -0
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
- package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
- package/lib/tools/index.d.ts +0 -2
- package/lib/tools/index.js +0 -1
- package/lib/types/agentspecs.d.ts +50 -1
- package/lib/types/chat.d.ts +309 -8
- package/lib/types/context.d.ts +27 -0
- package/lib/types/cost.d.ts +2 -2
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.js +2 -0
- package/lib/types/mcp.d.ts +8 -0
- package/lib/types/models.d.ts +2 -2
- package/lib/types/personas.d.ts +25 -0
- package/lib/types/personas.js +5 -0
- package/lib/types/skills.d.ts +43 -1
- package/lib/types/stream.d.ts +110 -0
- package/lib/types/stream.js +36 -0
- package/lib/utils/utils.d.ts +9 -5
- package/lib/utils/utils.js +9 -5
- package/package.json +13 -9
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +102 -6
- package/scripts/codegen/generate_events.py +35 -13
- package/scripts/codegen/generate_personas.py +319 -0
- package/scripts/codegen/generate_skills.py +9 -9
- package/scripts/sync-jupyter.sh +26 -7
- package/lib/api/tool-approvals.d.ts +0 -62
- package/lib/api/tool-approvals.js +0 -145
- package/lib/examples/LexicalSidebarExample.js +0 -163
- package/lib/examples/NotebookSidebarExample.js +0 -119
- package/lib/examples/NotebookSimpleExample.d.ts +0 -6
- package/lib/examples/NotebookSimpleExample.js +0 -22
- package/lib/examples/ag-ui/index.d.ts +0 -10
- package/lib/examples/ag-ui/index.js +0 -16
- package/lib/hooks/useAgentsRegistry.d.ts +0 -10
- package/lib/hooks/useAgentsRegistry.js +0 -20
- package/lib/stores/agentsStore.d.ts +0 -123
- package/lib/stores/agentsStore.js +0 -270
- /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
- /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
- /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;
|
package/lib/stores/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module store
|
|
5
5
|
*/
|
|
6
|
-
export {
|
|
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';
|
package/lib/stores/index.js
CHANGED
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module store
|
|
9
9
|
*/
|
|
10
|
-
export {
|
|
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
|
|
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
|
|
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 };
|