@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
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @module hooks/useAIAgentsWebSocket
|
|
14
14
|
*/
|
|
15
|
-
import { useEffect, useRef } from 'react';
|
|
15
|
+
import { useEffect, useRef, useState } from 'react';
|
|
16
16
|
import { useQueryClient } from '@tanstack/react-query';
|
|
17
17
|
import { useCoreStore, useIAMStore } from '@datalayer/core/lib/state';
|
|
18
18
|
import { DEFAULT_SERVICE_URLS, API_BASE_PATHS, } from '@datalayer/core/lib/api/constants';
|
|
@@ -27,6 +27,8 @@ function useBaseUrl() {
|
|
|
27
27
|
}
|
|
28
28
|
// ─── Hook ────────────────────────────────────────────────────────────
|
|
29
29
|
const RECONNECT_DELAY_MS = 3_000;
|
|
30
|
+
const WS_DEFAULT_PATH = `${API_BASE_PATHS.AI_AGENTS}/ws`;
|
|
31
|
+
const isObject = (value) => !!value && typeof value === 'object';
|
|
30
32
|
/**
|
|
31
33
|
* Connect to the AI Agents generic WebSocket.
|
|
32
34
|
*
|
|
@@ -44,28 +46,68 @@ const RECONNECT_DELAY_MS = 3_000;
|
|
|
44
46
|
export function useAIAgentsWebSocket(options) {
|
|
45
47
|
const token = useAuthToken();
|
|
46
48
|
const baseUrl = useBaseUrl();
|
|
49
|
+
const configuredBaseUrl = options?.baseUrl ?? baseUrl;
|
|
50
|
+
const enabled = options?.enabled ?? true;
|
|
51
|
+
const wsPath = options?.path ?? WS_DEFAULT_PATH;
|
|
52
|
+
const queryParamsKey = JSON.stringify(options?.queryParams ?? {});
|
|
47
53
|
const queryClient = useQueryClient();
|
|
54
|
+
const [connectionState, setConnectionState] = useState('closed');
|
|
55
|
+
const [lastClose, setLastClose] = useState(null);
|
|
56
|
+
const [reconnectAttempt, setReconnectAttempt] = useState(0);
|
|
48
57
|
const wsRef = useRef(null);
|
|
49
58
|
const reconnectTimer = useRef(null);
|
|
50
59
|
// Keep a ref of channels so we can re-subscribe on reconnect without
|
|
51
60
|
// tearing down the socket when the array reference changes.
|
|
52
61
|
const channelsRef = useRef(options?.channels ?? []);
|
|
53
62
|
channelsRef.current = options?.channels ?? [];
|
|
63
|
+
const autoReconnectRef = useRef(options?.autoReconnect ?? true);
|
|
64
|
+
autoReconnectRef.current = options?.autoReconnect ?? true;
|
|
65
|
+
const maxReconnectAttemptsRef = useRef(options?.maxReconnectAttempts);
|
|
66
|
+
maxReconnectAttemptsRef.current = options?.maxReconnectAttempts;
|
|
67
|
+
const reconnectDelayRef = useRef(options?.reconnectDelayMs);
|
|
68
|
+
reconnectDelayRef.current = options?.reconnectDelayMs;
|
|
69
|
+
const onOpenRef = useRef(options?.onOpen);
|
|
70
|
+
onOpenRef.current = options?.onOpen;
|
|
54
71
|
const onMessageRef = useRef(options?.onMessage);
|
|
55
72
|
onMessageRef.current = options?.onMessage;
|
|
73
|
+
const onCloseRef = useRef(options?.onClose);
|
|
74
|
+
onCloseRef.current = options?.onClose;
|
|
56
75
|
useEffect(() => {
|
|
57
|
-
if (!token)
|
|
76
|
+
if (!enabled || !token) {
|
|
77
|
+
setConnectionState('closed');
|
|
58
78
|
return;
|
|
79
|
+
}
|
|
59
80
|
let disposed = false;
|
|
81
|
+
let reconnectAttempts = 0;
|
|
82
|
+
const toWsUrl = () => {
|
|
83
|
+
const httpUrl = wsPath.startsWith('http://') || wsPath.startsWith('https://')
|
|
84
|
+
? wsPath
|
|
85
|
+
: `${configuredBaseUrl}${wsPath.startsWith('/') ? '' : '/'}${wsPath}`;
|
|
86
|
+
const url = new URL(httpUrl.replace(/^http/, 'ws'));
|
|
87
|
+
url.searchParams.set('token', token);
|
|
88
|
+
const queryParams = JSON.parse(queryParamsKey);
|
|
89
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
90
|
+
if (value === null || value === undefined) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
url.searchParams.set(key, String(value));
|
|
94
|
+
});
|
|
95
|
+
return url.toString();
|
|
96
|
+
};
|
|
60
97
|
function connect() {
|
|
61
98
|
if (disposed)
|
|
62
99
|
return;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const wsUrl = httpUrl.replace(/^http/, 'ws') + `?token=${encodeURIComponent(token)}`;
|
|
100
|
+
const wsUrl = toWsUrl();
|
|
101
|
+
setConnectionState('connecting');
|
|
66
102
|
const ws = new WebSocket(wsUrl);
|
|
67
103
|
wsRef.current = ws;
|
|
68
104
|
ws.onopen = () => {
|
|
105
|
+
reconnectAttempts = 0;
|
|
106
|
+
setReconnectAttempt(0);
|
|
107
|
+
setConnectionState('connected');
|
|
108
|
+
setLastClose(null);
|
|
109
|
+
console.debug('[ws:connect] url=%s', wsUrl);
|
|
110
|
+
onOpenRef.current?.();
|
|
69
111
|
// Subscribe to extra channels.
|
|
70
112
|
const channels = channelsRef.current;
|
|
71
113
|
if (channels.length > 0) {
|
|
@@ -73,17 +115,33 @@ export function useAIAgentsWebSocket(options) {
|
|
|
73
115
|
}
|
|
74
116
|
};
|
|
75
117
|
ws.onmessage = ev => {
|
|
76
|
-
let
|
|
118
|
+
let raw;
|
|
77
119
|
try {
|
|
78
|
-
|
|
120
|
+
raw = JSON.parse(String(ev.data));
|
|
79
121
|
}
|
|
80
122
|
catch {
|
|
81
123
|
return;
|
|
82
124
|
}
|
|
125
|
+
const msg = isObject(raw)
|
|
126
|
+
? {
|
|
127
|
+
channel: typeof raw.channel === 'string' ? raw.channel : undefined,
|
|
128
|
+
event: typeof raw.event === 'string' ? raw.event : undefined,
|
|
129
|
+
data: isObject(raw.data)
|
|
130
|
+
? raw.data
|
|
131
|
+
: undefined,
|
|
132
|
+
type: typeof raw.type === 'string' ? raw.type : undefined,
|
|
133
|
+
payload: raw.payload,
|
|
134
|
+
raw,
|
|
135
|
+
}
|
|
136
|
+
: { raw };
|
|
83
137
|
// Fire optional callback.
|
|
138
|
+
console.debug('[ws:recv] type=%s', msg.type ?? msg.event ?? 'unknown');
|
|
84
139
|
onMessageRef.current?.(msg);
|
|
85
140
|
// Invalidate React Query caches based on the event type.
|
|
86
141
|
const { event } = msg;
|
|
142
|
+
if (typeof event !== 'string') {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
87
145
|
if (event.startsWith('event_')) {
|
|
88
146
|
queryClient.invalidateQueries({ queryKey: ['agent-events'] });
|
|
89
147
|
}
|
|
@@ -94,15 +152,43 @@ export function useAIAgentsWebSocket(options) {
|
|
|
94
152
|
queryClient.invalidateQueries({ queryKey: ['agent-notifications'] });
|
|
95
153
|
}
|
|
96
154
|
};
|
|
97
|
-
ws.onclose =
|
|
155
|
+
ws.onclose = event => {
|
|
98
156
|
wsRef.current = null;
|
|
99
|
-
|
|
100
|
-
|
|
157
|
+
setConnectionState('closed');
|
|
158
|
+
const closeInfo = {
|
|
159
|
+
code: event.code,
|
|
160
|
+
reason: event.reason,
|
|
161
|
+
wasClean: event.wasClean,
|
|
162
|
+
detail: `code ${event.code}${event.reason ? `: ${event.reason}` : ''}${event.wasClean ? ' (clean)' : ' (unclean)'}`,
|
|
163
|
+
};
|
|
164
|
+
setLastClose(closeInfo);
|
|
165
|
+
console.debug('[ws:disconnect] code=%d reason=%s', event.code, event.reason || '(none)');
|
|
166
|
+
onCloseRef.current?.(closeInfo);
|
|
167
|
+
if (disposed || !autoReconnectRef.current) {
|
|
168
|
+
return;
|
|
101
169
|
}
|
|
170
|
+
reconnectAttempts += 1;
|
|
171
|
+
setReconnectAttempt(reconnectAttempts);
|
|
172
|
+
const maxAttempts = maxReconnectAttemptsRef.current;
|
|
173
|
+
if (typeof maxAttempts === 'number' &&
|
|
174
|
+
Number.isFinite(maxAttempts) &&
|
|
175
|
+
reconnectAttempts > maxAttempts) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const configuredDelay = reconnectDelayRef.current;
|
|
179
|
+
const delay = typeof configuredDelay === 'function'
|
|
180
|
+
? configuredDelay(reconnectAttempts)
|
|
181
|
+
: typeof configuredDelay === 'number'
|
|
182
|
+
? configuredDelay
|
|
183
|
+
: RECONNECT_DELAY_MS;
|
|
184
|
+
reconnectTimer.current = setTimeout(connect, Math.max(0, delay));
|
|
102
185
|
};
|
|
103
186
|
ws.onerror = () => {
|
|
104
187
|
// onclose will fire after onerror; reconnect happens there.
|
|
105
|
-
ws.
|
|
188
|
+
if (ws.readyState === WebSocket.CONNECTING ||
|
|
189
|
+
ws.readyState === WebSocket.OPEN) {
|
|
190
|
+
ws.close();
|
|
191
|
+
}
|
|
106
192
|
};
|
|
107
193
|
}
|
|
108
194
|
connect();
|
|
@@ -110,11 +196,13 @@ export function useAIAgentsWebSocket(options) {
|
|
|
110
196
|
disposed = true;
|
|
111
197
|
if (reconnectTimer.current) {
|
|
112
198
|
clearTimeout(reconnectTimer.current);
|
|
199
|
+
reconnectTimer.current = null;
|
|
113
200
|
}
|
|
114
201
|
wsRef.current?.close();
|
|
115
202
|
wsRef.current = null;
|
|
203
|
+
setConnectionState('closed');
|
|
116
204
|
};
|
|
117
|
-
}, [token,
|
|
205
|
+
}, [token, configuredBaseUrl, wsPath, queryParamsKey, enabled, queryClient]);
|
|
118
206
|
// When the channel list changes, send subscribe/unsubscribe diffs.
|
|
119
207
|
const prevChannelsRef = useRef([]);
|
|
120
208
|
useEffect(() => {
|
|
@@ -133,4 +221,22 @@ export function useAIAgentsWebSocket(options) {
|
|
|
133
221
|
}
|
|
134
222
|
prevChannelsRef.current = [...channelsRef.current];
|
|
135
223
|
}, [options?.channels]);
|
|
224
|
+
return {
|
|
225
|
+
connectionState,
|
|
226
|
+
lastClose,
|
|
227
|
+
reconnectAttempt,
|
|
228
|
+
send: (payload) => {
|
|
229
|
+
const ws = wsRef.current;
|
|
230
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
ws.send(typeof payload === 'string' ? payload : JSON.stringify(payload));
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
};
|
|
136
242
|
}
|
package/lib/hooks/useAcp.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { type StopReason, type SessionUpdate, type AgentCapabilities, type
|
|
2
|
-
export type { StopReason, AgentCapabilities, ClientCapabilities, ToolCallUpdate, PermissionOption, };
|
|
1
|
+
import { type StopReason, type SessionUpdate, type AgentCapabilities, type PermissionOption, type ToolCallUpdate } from '@agentclientprotocol/sdk';
|
|
3
2
|
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
4
3
|
export type SessionUpdateType = SessionUpdate extends {
|
|
5
4
|
sessionUpdate: infer T;
|
package/lib/hooks/useAgUi.d.ts
CHANGED
|
@@ -98,14 +98,14 @@ export declare const agentQueryKeys: {
|
|
|
98
98
|
* });
|
|
99
99
|
* ```
|
|
100
100
|
*/
|
|
101
|
-
export declare function
|
|
101
|
+
export declare function useAgentRuntimes(options?: UseAgentOptions): UseAgentReturn;
|
|
102
102
|
/**
|
|
103
103
|
* Hook to fetch user's agent runtimes (running agent instances).
|
|
104
104
|
*
|
|
105
105
|
* The backend returns active runtimes from the operator **plus** paused
|
|
106
106
|
* runtimes synthesised from Solr checkpoint records (with ``status="paused"``).
|
|
107
107
|
*/
|
|
108
|
-
export declare function
|
|
108
|
+
export declare function useAgentRuntimesQuery(): import("@tanstack/react-query").UseQueryResult<AgentRuntimeData[], Error>;
|
|
109
109
|
/**
|
|
110
110
|
* Hook to fetch a single agent runtime by pod name.
|
|
111
111
|
*/
|
|
@@ -150,3 +150,40 @@ export interface UseAgentsRuntimesReturn {
|
|
|
150
150
|
* Consolidated runtime list and mutations.
|
|
151
151
|
*/
|
|
152
152
|
export declare function useAgentsRuntimes(): UseAgentsRuntimesReturn;
|
|
153
|
+
export interface UseAgentRuntimeWebSocketOptions {
|
|
154
|
+
/** Enable/disable the connection. Defaults to `true`. */
|
|
155
|
+
enabled?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* Base URL of the agent-runtime server
|
|
158
|
+
* (e.g. `http://localhost:8765`). The WS path is appended automatically.
|
|
159
|
+
*/
|
|
160
|
+
baseUrl: string;
|
|
161
|
+
/** Auth token passed as `?token=` query parameter. */
|
|
162
|
+
authToken?: string;
|
|
163
|
+
/** Optional `agent_id` query parameter to scope the stream. */
|
|
164
|
+
agentId?: string;
|
|
165
|
+
/** Auto-reconnect on unexpected disconnects. Defaults to `true`. */
|
|
166
|
+
autoReconnect?: boolean;
|
|
167
|
+
/** Delay between reconnection attempts (ms). Defaults to 3 000. */
|
|
168
|
+
reconnectDelayMs?: number | ((attempt: number) => number);
|
|
169
|
+
/** Maximum reconnect attempts. Unbounded by default. */
|
|
170
|
+
maxReconnectAttempts?: number;
|
|
171
|
+
/** Additional callback fired for every incoming WS message. */
|
|
172
|
+
onMessage?: (msg: {
|
|
173
|
+
type?: string;
|
|
174
|
+
payload?: unknown;
|
|
175
|
+
raw: unknown;
|
|
176
|
+
}) => void;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Connect to the agent-runtime monitoring WebSocket.
|
|
180
|
+
*
|
|
181
|
+
* The hook writes all incoming data into the `useAgentRuntimeStore` Zustand
|
|
182
|
+
* store. Components that need approvals, MCP status, context snapshots, or
|
|
183
|
+
* full-context data simply read from the store.
|
|
184
|
+
*
|
|
185
|
+
* Mount this hook **once** near the top of your component tree (e.g. in
|
|
186
|
+
* the example root or in `ChatBase`). All other components read from the
|
|
187
|
+
* store — no extra WebSocket connections needed.
|
|
188
|
+
*/
|
|
189
|
+
export declare function useAgentRuntimeWebSocket(options: UseAgentRuntimeWebSocketOptions): void;
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* Unified hook for managing
|
|
6
|
+
* Unified hook for managing agent runtimes.
|
|
7
7
|
*
|
|
8
8
|
* Combines agent lifecycle management (ephemeral/durable),
|
|
9
9
|
* runtime catalog (React Query CRUD), lifecycle/catalog stores,
|
|
10
|
-
*
|
|
10
|
+
* the AI Agents REST API, and the agent-runtime WebSocket stream.
|
|
11
11
|
*
|
|
12
|
-
* @module hooks/
|
|
12
|
+
* @module hooks/useAgentRuntimes
|
|
13
13
|
*/
|
|
14
14
|
import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
15
15
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
@@ -17,7 +17,8 @@ import { create } from 'zustand';
|
|
|
17
17
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
18
18
|
import { useCoreStore, useDatalayer } from '@datalayer/core';
|
|
19
19
|
import { useIAMStore } from '@datalayer/core/lib/state';
|
|
20
|
-
import {
|
|
20
|
+
import { agentRuntimeStore, useAgentRuntimeStore, useAgentRuntimeConnection, useAgentRuntimeStatus, useAgentRuntimeError, useAgentRuntimeIsLaunching, } from '../stores/agentRuntimeStore';
|
|
21
|
+
import { parseAgentStreamMessage, } from '../types/stream';
|
|
21
22
|
import { DEFAULT_AGENT_CONFIG } from '../types/config';
|
|
22
23
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
24
|
// Constants
|
|
@@ -103,18 +104,18 @@ function toAgentRuntimeData(raw) {
|
|
|
103
104
|
* });
|
|
104
105
|
* ```
|
|
105
106
|
*/
|
|
106
|
-
export function
|
|
107
|
+
export function useAgentRuntimes(options = {}) {
|
|
107
108
|
const { agentSpecId, agentConfig, autoCreateAgent = true, autoStart = false, agentSpec, } = options;
|
|
108
109
|
// Base store state
|
|
109
|
-
const runtime =
|
|
110
|
-
const baseStatus =
|
|
111
|
-
const storeError =
|
|
112
|
-
const isLaunching =
|
|
110
|
+
const runtime = useAgentRuntimeConnection();
|
|
111
|
+
const baseStatus = useAgentRuntimeStatus();
|
|
112
|
+
const storeError = useAgentRuntimeError();
|
|
113
|
+
const isLaunching = useAgentRuntimeIsLaunching();
|
|
113
114
|
// Store actions
|
|
114
|
-
const storeLaunchAgent =
|
|
115
|
-
const storeConnectAgent =
|
|
116
|
-
const storeCreateAgent =
|
|
117
|
-
const storeDisconnect =
|
|
115
|
+
const storeLaunchAgent = useAgentRuntimeStore(state => state.launchAgent);
|
|
116
|
+
const storeConnectAgent = useAgentRuntimeStore(state => state.connectAgent);
|
|
117
|
+
const storeCreateAgent = useAgentRuntimeStore(state => state.createAgent);
|
|
118
|
+
const storeDisconnect = useAgentRuntimeStore(state => state.disconnect);
|
|
118
119
|
// Lifecycle local state
|
|
119
120
|
const [lifecycleStatus, setLifecycleStatus] = useState('idle');
|
|
120
121
|
const [lifecycleError, setLifecycleError] = useState(null);
|
|
@@ -408,7 +409,7 @@ export function useAgents(options = {}) {
|
|
|
408
409
|
* The backend returns active runtimes from the operator **plus** paused
|
|
409
410
|
* runtimes synthesised from Solr checkpoint records (with ``status="paused"``).
|
|
410
411
|
*/
|
|
411
|
-
export function
|
|
412
|
+
export function useAgentRuntimesQuery() {
|
|
412
413
|
const { configuration } = useCoreStore();
|
|
413
414
|
const { requestDatalayer } = useDatalayer({ notifyOnError: false });
|
|
414
415
|
const { user } = useIAMStore();
|
|
@@ -607,7 +608,7 @@ export const useAgentLifecycleStore = create()(persist((set, get) => ({
|
|
|
607
608
|
* Consolidated runtime list and mutations.
|
|
608
609
|
*/
|
|
609
610
|
export function useAgentsRuntimes() {
|
|
610
|
-
const runtimesQuery =
|
|
611
|
+
const runtimesQuery = useAgentRuntimesQuery();
|
|
611
612
|
const createRuntimeMutation = useCreateAgentRuntime();
|
|
612
613
|
const deleteRuntimeMutation = useDeleteAgentRuntime();
|
|
613
614
|
const refreshRuntimes = useRefreshAgentRuntimes();
|
|
@@ -631,3 +632,112 @@ export function useAgentsRuntimes() {
|
|
|
631
632
|
deleteRuntimeMutation,
|
|
632
633
|
]);
|
|
633
634
|
}
|
|
635
|
+
const DEFAULT_WS_PATH = '/api/v1/tool-approvals/ws';
|
|
636
|
+
const DEFAULT_RECONNECT_DELAY_MS = 3_000;
|
|
637
|
+
/**
|
|
638
|
+
* Connect to the agent-runtime monitoring WebSocket.
|
|
639
|
+
*
|
|
640
|
+
* The hook writes all incoming data into the `useAgentRuntimeStore` Zustand
|
|
641
|
+
* store. Components that need approvals, MCP status, context snapshots, or
|
|
642
|
+
* full-context data simply read from the store.
|
|
643
|
+
*
|
|
644
|
+
* Mount this hook **once** near the top of your component tree (e.g. in
|
|
645
|
+
* the example root or in `ChatBase`). All other components read from the
|
|
646
|
+
* store — no extra WebSocket connections needed.
|
|
647
|
+
*/
|
|
648
|
+
export function useAgentRuntimeWebSocket(options) {
|
|
649
|
+
const { enabled = true, baseUrl, authToken, agentId, autoReconnect = true, reconnectDelayMs = DEFAULT_RECONNECT_DELAY_MS, maxReconnectAttempts, } = options;
|
|
650
|
+
const onMessageRef = useRef(options.onMessage);
|
|
651
|
+
onMessageRef.current = options.onMessage;
|
|
652
|
+
useEffect(() => {
|
|
653
|
+
if (!enabled || !baseUrl) {
|
|
654
|
+
agentRuntimeStore.getState().setWsState('closed');
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
let disposed = false;
|
|
658
|
+
let reconnectAttempts = 0;
|
|
659
|
+
let reconnectTimer = null;
|
|
660
|
+
function buildWsUrl() {
|
|
661
|
+
const httpUrl = `${baseUrl}${DEFAULT_WS_PATH}`;
|
|
662
|
+
const url = new URL(httpUrl.replace(/^http/, 'ws'));
|
|
663
|
+
if (authToken) {
|
|
664
|
+
url.searchParams.set('token', authToken);
|
|
665
|
+
}
|
|
666
|
+
if (agentId) {
|
|
667
|
+
url.searchParams.set('agent_id', agentId);
|
|
668
|
+
}
|
|
669
|
+
return url.toString();
|
|
670
|
+
}
|
|
671
|
+
function connect() {
|
|
672
|
+
if (disposed)
|
|
673
|
+
return;
|
|
674
|
+
const wsUrl = buildWsUrl();
|
|
675
|
+
agentRuntimeStore.getState().setWsState('connecting');
|
|
676
|
+
const ws = new WebSocket(wsUrl);
|
|
677
|
+
agentRuntimeStore.getState().setWs(ws, agentId);
|
|
678
|
+
ws.onopen = () => {
|
|
679
|
+
reconnectAttempts = 0;
|
|
680
|
+
agentRuntimeStore.getState().setWsState('connected');
|
|
681
|
+
};
|
|
682
|
+
ws.onmessage = (ev) => {
|
|
683
|
+
let raw;
|
|
684
|
+
try {
|
|
685
|
+
raw = JSON.parse(String(ev.data));
|
|
686
|
+
}
|
|
687
|
+
catch {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const parsed = parseAgentStreamMessage(raw);
|
|
691
|
+
onMessageRef.current?.({
|
|
692
|
+
type: parsed?.type,
|
|
693
|
+
payload: parsed?.payload,
|
|
694
|
+
raw,
|
|
695
|
+
});
|
|
696
|
+
if (!parsed)
|
|
697
|
+
return;
|
|
698
|
+
const state = agentRuntimeStore.getState();
|
|
699
|
+
if (parsed.type === 'agent.snapshot') {
|
|
700
|
+
state.applySnapshot(parsed.payload);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
ws.onclose = () => {
|
|
705
|
+
agentRuntimeStore.getState().setWs(null, agentId);
|
|
706
|
+
agentRuntimeStore.getState().setWsState('closed');
|
|
707
|
+
if (disposed || !autoReconnect)
|
|
708
|
+
return;
|
|
709
|
+
reconnectAttempts += 1;
|
|
710
|
+
if (typeof maxReconnectAttempts === 'number' &&
|
|
711
|
+
reconnectAttempts > maxReconnectAttempts) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
const delay = typeof reconnectDelayMs === 'function'
|
|
715
|
+
? reconnectDelayMs(reconnectAttempts)
|
|
716
|
+
: reconnectDelayMs;
|
|
717
|
+
reconnectTimer = setTimeout(connect, Math.max(0, delay));
|
|
718
|
+
};
|
|
719
|
+
ws.onerror = () => {
|
|
720
|
+
if (ws.readyState === WebSocket.CONNECTING ||
|
|
721
|
+
ws.readyState === WebSocket.OPEN) {
|
|
722
|
+
ws.close();
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
connect();
|
|
727
|
+
return () => {
|
|
728
|
+
disposed = true;
|
|
729
|
+
if (reconnectTimer)
|
|
730
|
+
clearTimeout(reconnectTimer);
|
|
731
|
+
agentRuntimeStore.getState().setWs(null, agentId);
|
|
732
|
+
agentRuntimeStore.getState().resetWs();
|
|
733
|
+
};
|
|
734
|
+
}, [
|
|
735
|
+
enabled,
|
|
736
|
+
baseUrl,
|
|
737
|
+
authToken,
|
|
738
|
+
agentId,
|
|
739
|
+
autoReconnect,
|
|
740
|
+
reconnectDelayMs,
|
|
741
|
+
maxReconnectAttempts,
|
|
742
|
+
]);
|
|
743
|
+
}
|
|
@@ -4,7 +4,7 @@ export type RequestOptions = {
|
|
|
4
4
|
};
|
|
5
5
|
export type RoomType = 'notebook_persist' | 'notebook_memory' | 'doc_memory';
|
|
6
6
|
/**
|
|
7
|
-
* @deprecated Use
|
|
7
|
+
* @deprecated Use useAgentRuntimes instead
|
|
8
8
|
*/
|
|
9
9
|
export declare const useAgentsService: (baseUrlOverride?: string) => {
|
|
10
10
|
createAgent: (documentId: string, documentType: RoomType, ingress?: string, token?: string, kernelId?: string, { signal, baseUrl }?: RequestOptions) => Promise<any>;
|
|
@@ -17,6 +17,6 @@ export declare const useAgentsService: (baseUrlOverride?: string) => {
|
|
|
17
17
|
* Get the notebook AI agent if any.
|
|
18
18
|
*
|
|
19
19
|
* This performs a periodic liveness check and keeps the local store in sync.
|
|
20
|
-
* @deprecated Use
|
|
20
|
+
* @deprecated Use useAgentRuntimes instead
|
|
21
21
|
*/
|
|
22
22
|
export declare function useNotebookAgents(notebookId: string): import("..").AgentRegistryEntry | undefined;
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
import { useEffect } from 'react';
|
|
12
12
|
import { useCoreStore, useDatalayer } from '@datalayer/core';
|
|
13
13
|
import { URLExt } from '@jupyterlab/coreutils';
|
|
14
|
-
import {
|
|
14
|
+
import { useAgentRuntimeStore } from '../stores/agentRuntimeStore';
|
|
15
15
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
16
|
// Agents Service REST API hook.
|
|
17
17
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
18
18
|
/**
|
|
19
|
-
* @deprecated Use
|
|
19
|
+
* @deprecated Use useAgentRuntimes instead
|
|
20
20
|
*/
|
|
21
21
|
export const useAgentsService = (baseUrlOverride = 'api/ai-agents/v1') => {
|
|
22
22
|
const { configuration } = useCoreStore();
|
|
@@ -86,14 +86,14 @@ export const useAgentsService = (baseUrlOverride = 'api/ai-agents/v1') => {
|
|
|
86
86
|
* Get the notebook AI agent if any.
|
|
87
87
|
*
|
|
88
88
|
* This performs a periodic liveness check and keeps the local store in sync.
|
|
89
|
-
* @deprecated Use
|
|
89
|
+
* @deprecated Use useAgentRuntimes instead
|
|
90
90
|
*/
|
|
91
91
|
export function useNotebookAgents(notebookId) {
|
|
92
92
|
const { getAgent } = useAgentsService();
|
|
93
|
-
const agents =
|
|
94
|
-
const upsertAgent =
|
|
95
|
-
const deleteAgent =
|
|
96
|
-
const getAgentById =
|
|
93
|
+
const agents = useAgentRuntimeStore(state => state.agents);
|
|
94
|
+
const upsertAgent = useAgentRuntimeStore(state => state.upsertAgent);
|
|
95
|
+
const deleteAgent = useAgentRuntimeStore(state => state.deleteAgent);
|
|
96
|
+
const getAgentById = useAgentRuntimeStore(state => state.getAgentById);
|
|
97
97
|
useEffect(() => {
|
|
98
98
|
let abortController;
|
|
99
99
|
const refreshAIAgent = async () => {
|
|
@@ -14,7 +14,7 @@ import { useMemo, useState, useCallback } from 'react';
|
|
|
14
14
|
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
|
|
15
15
|
import { useIAMStore } from '@datalayer/core/lib/state';
|
|
16
16
|
import { useCoreStore, useDatalayer } from '@datalayer/core';
|
|
17
|
-
import { agentQueryKeys, AGENT_QUERY_OPTIONS } from './
|
|
17
|
+
import { agentQueryKeys, AGENT_QUERY_OPTIONS } from './useAgentRuntimes';
|
|
18
18
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
19
19
|
// Query hooks
|
|
20
20
|
// ═══════════════════════════════════════════════════════════════════════════
|
package/lib/hooks/useConfig.d.ts
CHANGED
|
@@ -3,9 +3,12 @@ import type { RemoteConfig } from '../types/config';
|
|
|
3
3
|
* Hook to safely use query when QueryClient is available.
|
|
4
4
|
* Returns a mock result if no QueryClientProvider is present.
|
|
5
5
|
*/
|
|
6
|
-
export declare function useConfig(enabled: boolean, configEndpoint?: string, authToken?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPendingResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<RemoteConfig, Error> | {
|
|
6
|
+
export declare function useConfig(enabled: boolean, configEndpoint?: string, authToken?: string, agentId?: string): import("@tanstack/query-core").QueryObserverRefetchErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverSuccessResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverLoadingErrorResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPendingResult<RemoteConfig, Error> | import("@tanstack/query-core").QueryObserverPlaceholderResult<RemoteConfig, Error> | {
|
|
7
7
|
data: undefined;
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
isError: boolean;
|
|
10
10
|
error: null;
|
|
11
|
+
refetch: () => Promise<{
|
|
12
|
+
data: undefined;
|
|
13
|
+
}>;
|
|
11
14
|
};
|
package/lib/hooks/useConfig.js
CHANGED
|
@@ -9,7 +9,7 @@ import { requestAPI } from '../api/handler';
|
|
|
9
9
|
* Hook to safely use query when QueryClient is available.
|
|
10
10
|
* Returns a mock result if no QueryClientProvider is present.
|
|
11
11
|
*/
|
|
12
|
-
export function useConfig(enabled, configEndpoint, authToken) {
|
|
12
|
+
export function useConfig(enabled, configEndpoint, authToken, agentId) {
|
|
13
13
|
const queryClient = useContext(QueryClientContext);
|
|
14
14
|
if (!queryClient) {
|
|
15
15
|
return {
|
|
@@ -17,6 +17,7 @@ export function useConfig(enabled, configEndpoint, authToken) {
|
|
|
17
17
|
isLoading: false,
|
|
18
18
|
isError: false,
|
|
19
19
|
error: null,
|
|
20
|
+
refetch: () => Promise.resolve({ data: undefined }),
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -30,7 +31,13 @@ export function useConfig(enabled, configEndpoint, authToken) {
|
|
|
30
31
|
if (authToken) {
|
|
31
32
|
headers['Authorization'] = `Bearer ${authToken}`;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
let endpoint = configEndpoint;
|
|
35
|
+
if (agentId) {
|
|
36
|
+
const url = new URL(configEndpoint, window.location.origin);
|
|
37
|
+
url.searchParams.set('agent_id', agentId);
|
|
38
|
+
endpoint = url.toString();
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(endpoint, { headers });
|
|
34
41
|
if (!response.ok) {
|
|
35
42
|
throw new Error(`Config fetch failed: ${response.statusText}`);
|
|
36
43
|
}
|
|
@@ -39,7 +46,7 @@ export function useConfig(enabled, configEndpoint, authToken) {
|
|
|
39
46
|
// Otherwise use Jupyter requestAPI.
|
|
40
47
|
return requestAPI('configure');
|
|
41
48
|
},
|
|
42
|
-
queryKey: ['models', configEndpoint || 'jupyter'],
|
|
49
|
+
queryKey: ['models', configEndpoint || 'jupyter', agentId || 'global'],
|
|
43
50
|
enabled,
|
|
44
51
|
retry: 1,
|
|
45
52
|
});
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { ContextSnapshotData } from '../types/context';
|
|
2
2
|
/**
|
|
3
|
-
* Hook
|
|
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;
|