@datalayer/agent-runtimes 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -1
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/App.js +1 -1
- package/lib/agent-node/themeStore.d.ts +3 -0
- package/lib/agent-node/themeStore.js +156 -0
- package/lib/agent-node-main.d.ts +1 -0
- package/lib/agent-node-main.js +14 -0
- 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 +20 -14
- package/lib/chat/ChatFloating.d.ts +7 -140
- package/lib/chat/ChatFloating.js +3 -3
- 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 +83 -51
- package/lib/chat/ChatStandalone.d.ts +4 -54
- package/lib/chat/ChatStandalone.js +3 -3
- package/lib/chat/base/ChatBase.js +1414 -174
- package/lib/chat/display/FloatingBrandButton.js +8 -1
- package/lib/chat/header/ChatHeader.d.ts +3 -1
- package/lib/chat/header/ChatHeader.js +15 -12
- package/lib/chat/header/ChatHeaderBase.d.ts +30 -5
- package/lib/chat/header/ChatHeaderBase.js +41 -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 +91 -56
- 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 +154 -114
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +21 -6
- package/lib/chat/prompt/InputFooter.js +76 -20
- package/lib/chat/prompt/InputPrompt.d.ts +5 -1
- package/lib/chat/prompt/InputPrompt.js +4 -4
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- 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 +20 -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.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- 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/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +14 -28
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +603 -169
- package/lib/examples/AgentEvalsExample.js +339 -53
- package/lib/examples/AgentGuardrailsExample.js +383 -66
- package/lib/examples/AgentHooksExample.d.ts +3 -0
- package/lib/examples/AgentHooksExample.js +122 -0
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.d.ts +3 -0
- package/lib/examples/AgentMCPExample.js +481 -0
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +78 -33
- package/lib/examples/AgentMonitoringExample.js +261 -200
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +114 -33
- package/lib/examples/AgentOtelExample.js +32 -42
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +433 -81
- package/lib/examples/AgentParametersExample.d.ts +3 -0
- package/lib/examples/AgentParametersExample.js +248 -0
- package/lib/examples/AgentSandboxExample.d.ts +3 -3
- package/lib/examples/AgentSandboxExample.js +74 -45
- package/lib/examples/AgentSkillsExample.js +95 -103
- package/lib/examples/AgentSubagentsExample.d.ts +14 -0
- package/lib/examples/AgentSubagentsExample.js +228 -0
- package/lib/examples/AgentToolApprovalsExample.js +49 -561
- package/lib/examples/AgentTriggersExample.js +823 -569
- package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +16 -28
- package/lib/examples/ChatExample.js +13 -29
- 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} +66 -17
- 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 +9 -3
- package/lib/examples/components/ExampleWrapper.js +45 -9
- 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 +108 -41
- package/lib/examples/index.d.ts +10 -6
- package/lib/examples/index.js +10 -6
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +257 -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/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- 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 +153 -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} +70 -4
- package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
- 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 +21 -4
- package/lib/specs/agents/agents.js +2879 -316
- package/lib/specs/agents/index.js +3 -1
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.js +27 -20
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- 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/mcpServers.js +35 -6
- package/lib/specs/memory.d.ts +0 -2
- package/lib/specs/memory.js +4 -17
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +20 -15
- 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 +1 -1
- package/lib/specs/skills.js +23 -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 +208 -0
- package/lib/stores/agentRuntimeStore.js +650 -0
- package/lib/stores/conversationStore.js +2 -2
- 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/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +54 -1
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +325 -8
- package/lib/types/context.d.ts +27 -0
- package/lib/types/cost.d.ts +2 -2
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.js +3 -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 +19 -11
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.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 +187 -45
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +35 -14
- 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/AgentspecExample.js +0 -705
- 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/{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
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { ContextSnapshotData } from '../types/context';
|
|
2
2
|
/**
|
|
3
|
-
* Hook
|
|
4
|
-
*
|
|
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(
|
|
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
|
|
10
|
-
*
|
|
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(
|
|
13
|
-
|
|
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
|
-
*
|
|
4
|
-
*
|
|
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
|
|
7
|
-
data: undefined;
|
|
8
|
-
|
|
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
|
};
|
package/lib/hooks/useSandbox.js
CHANGED
|
@@ -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 {
|
|
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
|
-
*
|
|
10
|
-
*
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
}
|
package/lib/hooks/useSkills.d.ts
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SkillInfo } from '../types/skills';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
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(
|
|
6
|
-
data:
|
|
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:
|
|
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';
|
package/lib/hooks/useSkills.js
CHANGED
|
@@ -2,45 +2,100 @@
|
|
|
2
2
|
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { useCallback, useMemo } from 'react';
|
|
6
|
+
import { agentRuntimeStore, useAgentRuntimeCodemodeStatus } from '../stores';
|
|
7
|
+
function parseSkillStatus(value) {
|
|
8
|
+
if (value === 'available' || value === 'enabled' || value === 'loaded') {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return 'available';
|
|
12
|
+
}
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Skills from WS snapshot
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
7
16
|
/**
|
|
8
|
-
*
|
|
17
|
+
* Derive the list of skills from the WS-pushed `codemodeStatus`.
|
|
18
|
+
*
|
|
19
|
+
* The server-side SkillsArea pushes per-skill status (`available`,
|
|
20
|
+
* `enabled`, `loaded`) via the monitoring WebSocket inside the
|
|
21
|
+
* `codemodeStatus.skills` array. This hook reads from the Zustand
|
|
22
|
+
* store — no REST call is made.
|
|
9
23
|
*/
|
|
10
|
-
export function useSkills(
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
24
|
+
export function useSkills(_enabled, _baseEndpoint, _authToken) {
|
|
25
|
+
const codemodeStatus = useAgentRuntimeCodemodeStatus();
|
|
26
|
+
const data = useMemo(() => {
|
|
27
|
+
if (!codemodeStatus) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const skills = (codemodeStatus.skills ?? []).map(s => ({
|
|
31
|
+
id: s.id ?? s.name,
|
|
32
|
+
name: s.name,
|
|
33
|
+
description: s.description,
|
|
34
|
+
tags: s.tags,
|
|
35
|
+
has_scripts: s.has_scripts,
|
|
36
|
+
has_resources: s.has_resources,
|
|
37
|
+
status: parseSkillStatus(s.status),
|
|
38
|
+
approved: s.approved !== false,
|
|
39
|
+
skill_definition: s.skill_definition ?? null,
|
|
40
|
+
source_variant: s.source_variant,
|
|
41
|
+
module: s.module,
|
|
42
|
+
package: s.package,
|
|
43
|
+
method: s.method,
|
|
44
|
+
path: s.path,
|
|
45
|
+
}));
|
|
46
|
+
return { skills, total: skills.length };
|
|
47
|
+
}, [codemodeStatus]);
|
|
48
|
+
return {
|
|
49
|
+
data,
|
|
50
|
+
isLoading: false,
|
|
51
|
+
isError: false,
|
|
52
|
+
error: null,
|
|
53
|
+
refetch: () => Promise.resolve({ data }),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Skill enable / disable via WebSocket
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
export function useSkillActions(agentId) {
|
|
60
|
+
const enableSkill = useCallback((skillId) => {
|
|
61
|
+
const ok = agentRuntimeStore
|
|
62
|
+
.getState()
|
|
63
|
+
.sendRawMessage({ type: 'skill_enable', skillId }, agentId);
|
|
64
|
+
if (!ok) {
|
|
65
|
+
console.warn('[useSkillActions] skill_enable dropped: websocket not ready');
|
|
66
|
+
}
|
|
67
|
+
return ok;
|
|
68
|
+
}, [agentId]);
|
|
69
|
+
const disableSkill = useCallback((skillId) => {
|
|
70
|
+
const ok = agentRuntimeStore
|
|
71
|
+
.getState()
|
|
72
|
+
.sendRawMessage({ type: 'skill_disable', skillId }, agentId);
|
|
73
|
+
if (!ok) {
|
|
74
|
+
console.warn('[useSkillActions] skill_disable dropped: websocket not ready');
|
|
75
|
+
}
|
|
76
|
+
return ok;
|
|
77
|
+
}, [agentId]);
|
|
78
|
+
const approveSkill = useCallback((skillId) => {
|
|
79
|
+
const ok = agentRuntimeStore
|
|
80
|
+
.getState()
|
|
81
|
+
.sendRawMessage({ type: 'skill_approve', skillId }, agentId);
|
|
82
|
+
if (!ok) {
|
|
83
|
+
console.warn('[useSkillActions] skill_approve dropped: websocket not ready');
|
|
84
|
+
}
|
|
85
|
+
return ok;
|
|
86
|
+
}, [agentId]);
|
|
87
|
+
const unapproveSkill = useCallback((skillId) => {
|
|
88
|
+
const ok = agentRuntimeStore
|
|
89
|
+
.getState()
|
|
90
|
+
.sendRawMessage({ type: 'skill_unapprove', skillId }, agentId);
|
|
91
|
+
if (!ok) {
|
|
92
|
+
console.warn('[useSkillActions] skill_unapprove dropped: websocket not ready');
|
|
93
|
+
}
|
|
94
|
+
return ok;
|
|
95
|
+
}, [agentId]);
|
|
96
|
+
return { enableSkill, disableSkill, approveSkill, unapproveSkill };
|
|
46
97
|
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Loaded skills (kept for backward compat with AgentSkillsExample sidebar)
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
export { useAgentRuntimeLoadedSkills } from '../stores';
|
|
@@ -1,45 +1,69 @@
|
|
|
1
1
|
import type { ToolApprovalFilters } from '../types/tool-approvals';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Normalised approval record. Both snake_case (server-native) and
|
|
4
|
+
* camelCase (TypeScript-idiomatic) keys are present so existing UI
|
|
5
|
+
* consumers keep working regardless of which naming they read.
|
|
6
|
+
*/
|
|
7
|
+
export type ApprovalRecord = {
|
|
8
|
+
id: string;
|
|
9
|
+
agent_id: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
pod_name: string;
|
|
12
|
+
podName: string;
|
|
13
|
+
tool_name: string;
|
|
14
|
+
toolName: string;
|
|
15
|
+
tool_call_id?: string;
|
|
16
|
+
toolCallId?: string;
|
|
17
|
+
tool_args: Record<string, unknown>;
|
|
18
|
+
toolArgs: Record<string, unknown>;
|
|
19
|
+
status: string;
|
|
20
|
+
note?: string | null;
|
|
21
|
+
created_at: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
updated_at?: string;
|
|
24
|
+
updatedAt?: string;
|
|
25
|
+
read?: boolean;
|
|
26
|
+
};
|
|
27
|
+
interface ApprovalsQueryData {
|
|
28
|
+
approvals: ApprovalRecord[];
|
|
29
|
+
total: number;
|
|
30
|
+
}
|
|
31
|
+
interface MutationResult {
|
|
32
|
+
isPending: boolean;
|
|
33
|
+
mutate: (vars: {
|
|
34
|
+
id: string;
|
|
35
|
+
note?: string;
|
|
36
|
+
}) => void;
|
|
37
|
+
mutateAsync: (vars: {
|
|
38
|
+
id: string;
|
|
39
|
+
note?: string;
|
|
40
|
+
}) => Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export declare function useToolApprovalsQuery(filters?: ToolApprovalFilters): import("@tanstack/react-query").UseQueryResult<ApprovalsQueryData, Error>;
|
|
3
43
|
export declare function usePendingApprovalCount(): import("@tanstack/react-query").UseQueryResult<{
|
|
4
44
|
count: number;
|
|
5
45
|
}, Error>;
|
|
6
|
-
export declare function useApproveToolRequest():
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export declare function
|
|
18
|
-
id: string;
|
|
19
|
-
}, unknown>;
|
|
20
|
-
export declare function useDeleteToolApproval(): import("@tanstack/react-query").UseMutationResult<void, Error, {
|
|
21
|
-
id: string;
|
|
22
|
-
}, unknown>;
|
|
46
|
+
export declare function useApproveToolRequest(): MutationResult;
|
|
47
|
+
export declare function useRejectToolRequest(): MutationResult;
|
|
48
|
+
export declare function useMarkToolApprovalRead(): MutationResult;
|
|
49
|
+
export declare function useMarkToolApprovalUnread(): MutationResult;
|
|
50
|
+
/**
|
|
51
|
+
* Delete a tool approval.
|
|
52
|
+
*
|
|
53
|
+
* Sends a ``tool_approval_delete`` message over the shared websocket.
|
|
54
|
+
* The local cache is updated only after the server emits
|
|
55
|
+
* ``tool_approval_deleted``.
|
|
56
|
+
*/
|
|
57
|
+
export declare function useDeleteToolApproval(): MutationResult;
|
|
23
58
|
export declare function useToolApprovals(filters?: ToolApprovalFilters): {
|
|
24
|
-
approvalsQuery: import("@tanstack/react-query").UseQueryResult<
|
|
59
|
+
approvalsQuery: import("@tanstack/react-query").UseQueryResult<ApprovalsQueryData, Error>;
|
|
25
60
|
pendingCountQuery: import("@tanstack/react-query").UseQueryResult<{
|
|
26
61
|
count: number;
|
|
27
62
|
}, Error>;
|
|
28
|
-
approve:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
id: string;
|
|
34
|
-
note?: string;
|
|
35
|
-
}, unknown>;
|
|
36
|
-
markRead: import("@tanstack/react-query").UseMutationResult<void, Error, {
|
|
37
|
-
id: string;
|
|
38
|
-
}, unknown>;
|
|
39
|
-
markUnread: import("@tanstack/react-query").UseMutationResult<void, Error, {
|
|
40
|
-
id: string;
|
|
41
|
-
}, unknown>;
|
|
42
|
-
remove: import("@tanstack/react-query").UseMutationResult<void, Error, {
|
|
43
|
-
id: string;
|
|
44
|
-
}, unknown>;
|
|
63
|
+
approve: MutationResult;
|
|
64
|
+
reject: MutationResult;
|
|
65
|
+
markRead: MutationResult;
|
|
66
|
+
markUnread: MutationResult;
|
|
67
|
+
remove: MutationResult;
|
|
45
68
|
};
|
|
69
|
+
export {};
|