@datalayer/agent-runtimes 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -119
- 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 -104
- 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 +1118 -141
- 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 +110 -102
- 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 +48 -19
- package/lib/client/AgentsMixin.js +115 -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 +55 -26
- package/lib/components/OutputCard.js +21 -7
- package/lib/components/ToolApprovalCard.js +20 -2
- 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 +14 -34
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +591 -175
- package/lib/examples/AgentEvalsExample.js +13 -23
- package/lib/examples/AgentGuardrailsExample.js +371 -71
- 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 +14 -24
- package/lib/examples/AgentMonitoringExample.js +261 -206
- package/lib/examples/AgentNotificationsExample.js +50 -24
- package/lib/examples/AgentOtelExample.js +2 -3
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +383 -88
- 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 +69 -47
- package/lib/examples/AgentSkillsExample.js +92 -106
- 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 +30 -493
- package/lib/examples/AgentTriggersExample.js +1067 -246
- package/lib/examples/ChatCustomExample.js +11 -24
- package/lib/examples/ChatExample.js +9 -34
- 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/ErrorView.d.ts +14 -0
- package/lib/examples/components/ErrorView.js +20 -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 +5 -0
- package/lib/examples/components/index.js +5 -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.d.ts +1 -0
- package/lib/examples/main.js +218 -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 +9 -0
- package/lib/protocols/VercelAIAdapter.js +144 -26
- package/lib/shims/json5.d.ts +4 -0
- package/lib/shims/json5.js +8 -0
- package/lib/specs/agents/agents.d.ts +10 -0
- package/lib/specs/agents/agents.js +752 -24
- package/lib/specs/envvars.d.ts +1 -0
- package/lib/specs/envvars.js +11 -0
- package/lib/specs/events.d.ts +1 -0
- package/lib/specs/events.js +1 -0
- package/lib/specs/index.d.ts +1 -0
- package/lib/specs/index.js +1 -0
- 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 +23 -5
- package/lib/specs/tools.js +3 -0
- 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/types/tools.d.ts +2 -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 +106 -7
- package/scripts/codegen/generate_events.py +47 -17
- package/scripts/codegen/generate_personas.py +319 -0
- package/scripts/codegen/generate_skills.py +9 -9
- package/scripts/codegen/generate_tools.py +20 -0
- package/scripts/sync-jupyter.sh +26 -7
- package/style/primer-primitives.css +1 -6
- 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/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
- /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
|
@@ -16,141 +16,57 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
16
16
|
/// <reference types="vite/client" />
|
|
17
17
|
import { useEffect, useState, useCallback, useRef } from 'react';
|
|
18
18
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
19
|
-
import { Text,
|
|
20
|
-
import {
|
|
19
|
+
import { Text, Spinner, Heading, Label } from '@primer/react';
|
|
20
|
+
import { GraphIcon } from '@primer/octicons-react';
|
|
21
21
|
import { Box } from '@datalayer/primer-addons';
|
|
22
|
+
import { AuthRequiredView, ErrorView } from './components';
|
|
22
23
|
import { ThemedProvider } from './utils/themedProvider';
|
|
24
|
+
import { uniqueAgentId } from './utils/agentId';
|
|
25
|
+
import { ContextPanel, } from '../context/ContextPanel';
|
|
26
|
+
import { CostTracker } from '../context/CostTracker';
|
|
27
|
+
import { CostUsageChart } from '../context/CostUsageChart';
|
|
28
|
+
import { TokenUsageChart } from '../context/TokenUsageChart';
|
|
29
|
+
import { GraphFlowChart } from '../context/GraphFlowChart';
|
|
30
|
+
import { TurnGraphChart } from '../context/TurnGraphChart';
|
|
31
|
+
import { useAIAgentsWebSocket } from '../hooks';
|
|
32
|
+
import { parseAgentStreamMessage } from '../types/stream';
|
|
33
|
+
import { useCoreStore } from '@datalayer/core/lib/state';
|
|
23
34
|
const queryClient = new QueryClient();
|
|
24
35
|
import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
|
|
25
|
-
import { SignInSimple } from '@datalayer/core/lib/views/iam';
|
|
26
|
-
import { UserBadge } from '@datalayer/core/lib/views/profile';
|
|
27
36
|
import { Chat } from '../chat';
|
|
28
|
-
import { useAgents } from '../hooks/useAgents';
|
|
29
37
|
const AGENT_NAME = 'monitoring-demo-agent';
|
|
30
|
-
const AGENT_SPEC_ID = '
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
return Number.isFinite(n) ? n : fallback;
|
|
35
|
-
};
|
|
36
|
-
const randomOffset = (range) => (Math.random() - 0.5) * range;
|
|
37
|
-
const createSyntheticSnapshot = (previous) => {
|
|
38
|
-
const baseCpu = previous?.cpuPercent ?? 42;
|
|
39
|
-
const baseMemory = previous?.memoryPercent ?? 57;
|
|
40
|
-
const baseLatency = previous?.latencyMs ?? 320;
|
|
41
|
-
const baseErrorRate = previous?.errorRatePercent ?? 1.6;
|
|
42
|
-
const baseQueueDepth = previous?.queueDepth ?? 12;
|
|
43
|
-
const cpuPercent = clampPercent(baseCpu + randomOffset(10));
|
|
44
|
-
const memoryPercent = clampPercent(baseMemory + randomOffset(8));
|
|
45
|
-
const latencyMs = Math.max(30, baseLatency + randomOffset(120));
|
|
46
|
-
const errorRatePercent = clampPercent(baseErrorRate + randomOffset(0.8));
|
|
47
|
-
const queueDepth = Math.max(0, Math.round(baseQueueDepth + randomOffset(8)));
|
|
48
|
-
let status = 'healthy';
|
|
49
|
-
if (errorRatePercent > 4 || latencyMs > 1200 || cpuPercent > 90) {
|
|
50
|
-
status = 'critical';
|
|
51
|
-
}
|
|
52
|
-
else if (errorRatePercent > 2 || latencyMs > 700 || cpuPercent > 80) {
|
|
53
|
-
status = 'degraded';
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
timestamp: new Date().toISOString(),
|
|
57
|
-
cpuPercent,
|
|
58
|
-
memoryPercent,
|
|
59
|
-
latencyMs,
|
|
60
|
-
errorRatePercent,
|
|
61
|
-
queueDepth,
|
|
62
|
-
status,
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
const normalizeSnapshot = (raw, previous) => {
|
|
66
|
-
if (!raw || typeof raw !== 'object') {
|
|
67
|
-
return createSyntheticSnapshot(previous);
|
|
68
|
-
}
|
|
69
|
-
const data = raw;
|
|
70
|
-
const snapshot = createSyntheticSnapshot(previous);
|
|
71
|
-
const statusValue = String(data.status ?? snapshot.status).toLowerCase();
|
|
72
|
-
const status = statusValue === 'healthy' ||
|
|
73
|
-
statusValue === 'degraded' ||
|
|
74
|
-
statusValue === 'critical'
|
|
75
|
-
? statusValue
|
|
76
|
-
: 'unknown';
|
|
77
|
-
return {
|
|
78
|
-
timestamp: String(data.timestamp ?? new Date().toISOString()),
|
|
79
|
-
cpuPercent: clampPercent(toNumber(data.cpuPercent ?? data.cpu, snapshot.cpuPercent)),
|
|
80
|
-
memoryPercent: clampPercent(toNumber(data.memoryPercent ?? data.memory, snapshot.memoryPercent)),
|
|
81
|
-
latencyMs: Math.max(0, toNumber(data.latencyMs ?? data.latency, snapshot.latencyMs)),
|
|
82
|
-
errorRatePercent: clampPercent(toNumber(data.errorRatePercent ?? data.errorRate, snapshot.errorRatePercent)),
|
|
83
|
-
queueDepth: Math.max(0, Math.round(toNumber(data.queueDepth, snapshot.queueDepth))),
|
|
84
|
-
status,
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
const normalizeAlert = (raw, index) => {
|
|
88
|
-
if (!raw || typeof raw !== 'object') {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const data = raw;
|
|
92
|
-
const severityValue = String(data.severity ?? 'info').toLowerCase();
|
|
93
|
-
const severity = severityValue === 'warning' || severityValue === 'critical'
|
|
94
|
-
? severityValue
|
|
95
|
-
: 'info';
|
|
96
|
-
return {
|
|
97
|
-
id: String(data.id ?? `alert-${Date.now()}-${index}`),
|
|
98
|
-
title: String(data.title ?? 'Agent alert detected'),
|
|
99
|
-
severity,
|
|
100
|
-
timestamp: String(data.timestamp ?? new Date().toISOString()),
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
const statusVariant = (status) => {
|
|
104
|
-
if (status === 'healthy')
|
|
105
|
-
return 'success';
|
|
106
|
-
if (status === 'degraded')
|
|
107
|
-
return 'attention';
|
|
108
|
-
if (status === 'critical')
|
|
109
|
-
return 'danger';
|
|
110
|
-
return 'secondary';
|
|
111
|
-
};
|
|
112
|
-
const alertVariant = (severity) => {
|
|
113
|
-
if (severity === 'critical')
|
|
114
|
-
return 'danger';
|
|
115
|
-
if (severity === 'warning')
|
|
116
|
-
return 'attention';
|
|
117
|
-
return 'secondary';
|
|
118
|
-
};
|
|
119
|
-
const MetricRow = ({ label, value, percent }) => {
|
|
120
|
-
return (_jsxs(Box, { sx: { mb: 2 }, children: [_jsxs(Box, { sx: {
|
|
121
|
-
display: 'flex',
|
|
122
|
-
justifyContent: 'space-between',
|
|
123
|
-
alignItems: 'center',
|
|
124
|
-
mb: 1,
|
|
125
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: label }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold' }, children: value })] }), _jsx(Box, { sx: {
|
|
126
|
-
width: '100%',
|
|
127
|
-
height: 8,
|
|
128
|
-
bg: 'canvas.subtle',
|
|
129
|
-
borderRadius: 6,
|
|
130
|
-
overflow: 'hidden',
|
|
131
|
-
}, children: _jsx(Box, { sx: {
|
|
132
|
-
width: `${clampPercent(percent)}%`,
|
|
133
|
-
height: '100%',
|
|
134
|
-
bg: percent >= 85 ? 'danger.emphasis' : 'accent.emphasis',
|
|
135
|
-
transition: 'width 300ms ease-out',
|
|
136
|
-
} }) })] }));
|
|
137
|
-
};
|
|
38
|
+
const AGENT_SPEC_ID = 'demo-monitoring';
|
|
39
|
+
const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
|
|
40
|
+
const OTEL_BASE_URL_ENV = import.meta.env.VITE_OTEL_BASE_URL;
|
|
41
|
+
const DATALAYER_RUN_URL_ENV = import.meta.env.DATALAYER_RUN_URL;
|
|
138
42
|
const AgentMonitoringInner = ({ onLogout, }) => {
|
|
139
43
|
const { token } = useSimpleAuthStore();
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
const [snapshots, setSnapshots] = useState([]);
|
|
44
|
+
const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
|
|
45
|
+
const { configuration } = useCoreStore();
|
|
46
|
+
const [runtimeStatus, setRuntimeStatus] = useState('launching');
|
|
47
|
+
const [isReady, setIsReady] = useState(false);
|
|
48
|
+
const [hookError, setHookError] = useState(null);
|
|
49
|
+
const [agentId, setAgentId] = useState(agentName);
|
|
50
|
+
const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
|
|
150
51
|
const [alerts, setAlerts] = useState([]);
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
52
|
+
const [liveContext, setLiveContext] = useState(undefined);
|
|
53
|
+
const [liveContextSnapshot, setLiveContextSnapshot] = useState(undefined);
|
|
54
|
+
const [liveCost, setLiveCost] = useState(undefined);
|
|
55
|
+
const [liveMcpStatus, setLiveMcpStatus] = useState(undefined);
|
|
56
|
+
const [monitorLastSnapshotAt, setMonitorLastSnapshotAt] = useState(null);
|
|
57
|
+
const [liveGraphTelemetry, setLiveGraphTelemetry] = useState(undefined);
|
|
58
|
+
const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
|
|
59
|
+
const otelBaseUrl = configuration?.otelRunUrl ||
|
|
60
|
+
configuration?.runUrl ||
|
|
61
|
+
OTEL_BASE_URL_ENV ||
|
|
62
|
+
DATALAYER_RUN_URL_ENV ||
|
|
63
|
+
'https://prod1.datalayer.run';
|
|
64
|
+
const podName = agentId;
|
|
65
|
+
// The OTEL service_name resource attribute is 'agent-runtimes' (the
|
|
66
|
+
// application name), NOT the individual agent ID. Use the correct value
|
|
67
|
+
// so the TokenUsageChart WS filter and HTTP query match actual rows.
|
|
68
|
+
const otelServiceName = 'agent-runtimes';
|
|
69
|
+
const chatAuthToken = token === null ? undefined : token;
|
|
154
70
|
const authFetch = useCallback((url, opts = {}) => fetch(url, {
|
|
155
71
|
...opts,
|
|
156
72
|
headers: {
|
|
@@ -160,46 +76,137 @@ const AgentMonitoringInner = ({ onLogout, }) => {
|
|
|
160
76
|
},
|
|
161
77
|
}), [token]);
|
|
162
78
|
useEffect(() => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
79
|
+
let isCancelled = false;
|
|
80
|
+
const createLocalAgent = async () => {
|
|
81
|
+
setRuntimeStatus('launching');
|
|
82
|
+
setIsReady(false);
|
|
83
|
+
setHookError(null);
|
|
84
|
+
setIsReconnectedAgent(false);
|
|
168
85
|
try {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
: []
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
86
|
+
const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
|
|
87
|
+
method: 'POST',
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
name: agentName,
|
|
90
|
+
description: 'MCP monitoring demo – web crawling via Tavily with live cost/token metrics',
|
|
91
|
+
agent_library: 'pydantic-ai',
|
|
92
|
+
transport: 'vercel-ai',
|
|
93
|
+
agent_spec_id: AGENT_SPEC_ID,
|
|
94
|
+
enable_skills: true,
|
|
95
|
+
tools: [],
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
let resolvedAgentId = agentName;
|
|
99
|
+
let isAlreadyRunning = false;
|
|
100
|
+
if (response.ok) {
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
resolvedAgentId = data?.id || agentName;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const contentType = response.headers.get('content-type') || '';
|
|
106
|
+
let detail = '';
|
|
107
|
+
if (contentType.includes('application/json')) {
|
|
108
|
+
const data = await response.json().catch(() => null);
|
|
109
|
+
detail =
|
|
110
|
+
(typeof data?.detail === 'string' && data.detail) ||
|
|
111
|
+
(typeof data?.message === 'string' && data.message) ||
|
|
112
|
+
'';
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
detail = await response.text();
|
|
116
|
+
}
|
|
117
|
+
if (response.status === 409 || /already exists/i.test(detail || '')) {
|
|
118
|
+
isAlreadyRunning = true;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
throw new Error(detail || `Failed to create local agent: ${response.status}`);
|
|
185
122
|
}
|
|
186
|
-
|
|
123
|
+
}
|
|
124
|
+
if (!isCancelled) {
|
|
125
|
+
setAgentId(resolvedAgentId);
|
|
126
|
+
setIsReconnectedAgent(isAlreadyRunning);
|
|
127
|
+
setIsReady(true);
|
|
128
|
+
setRuntimeStatus('ready');
|
|
187
129
|
}
|
|
188
130
|
}
|
|
189
|
-
catch {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (prev.length > 0) {
|
|
194
|
-
return prev;
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (!isCancelled) {
|
|
133
|
+
setHookError(error instanceof Error ? error.message : 'Agent failed to start');
|
|
134
|
+
setRuntimeStatus('error');
|
|
195
135
|
}
|
|
196
|
-
|
|
197
|
-
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
void createLocalAgent();
|
|
139
|
+
return () => {
|
|
140
|
+
isCancelled = true;
|
|
198
141
|
};
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
142
|
+
}, [agentBaseUrl, authFetch]);
|
|
143
|
+
const handleMonitoringStreamMessage = useCallback((message) => {
|
|
144
|
+
try {
|
|
145
|
+
const stream = parseAgentStreamMessage(message?.raw ?? message);
|
|
146
|
+
if (!stream || stream.type !== 'agent.snapshot') {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const payload = stream.payload;
|
|
150
|
+
if (payload.contextSnapshot) {
|
|
151
|
+
setLiveContext(payload.contextSnapshot);
|
|
152
|
+
setLiveContextSnapshot(payload.contextSnapshot);
|
|
153
|
+
setMonitorLastSnapshotAt(Date.now());
|
|
154
|
+
}
|
|
155
|
+
if (payload.mcpStatus !== undefined) {
|
|
156
|
+
setLiveMcpStatus(payload.mcpStatus ?? undefined);
|
|
157
|
+
}
|
|
158
|
+
if (payload.graphTelemetry) {
|
|
159
|
+
setLiveGraphTelemetry(payload.graphTelemetry);
|
|
160
|
+
}
|
|
161
|
+
const snapshotCost = payload.contextSnapshot?.costUsage ?? payload.costUsage;
|
|
162
|
+
if (!snapshotCost) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
setLiveCost({
|
|
166
|
+
agentId,
|
|
167
|
+
lastTurnCostUsd: Number(snapshotCost.lastTurnCostUsd ?? 0),
|
|
168
|
+
cumulativeCostUsd: Number(snapshotCost.cumulativeCostUsd ?? 0),
|
|
169
|
+
perRunBudgetUsd: snapshotCost.perRunBudgetUsd == null
|
|
170
|
+
? null
|
|
171
|
+
: Number(snapshotCost.perRunBudgetUsd),
|
|
172
|
+
cumulativeBudgetUsd: snapshotCost.cumulativeBudgetUsd == null
|
|
173
|
+
? null
|
|
174
|
+
: Number(snapshotCost.cumulativeBudgetUsd),
|
|
175
|
+
requestCount: Number(snapshotCost.requestCount ?? 0),
|
|
176
|
+
totalTokensUsed: Number(snapshotCost.totalTokensUsed ?? 0),
|
|
177
|
+
modelBreakdown: Array.isArray(snapshotCost.modelBreakdown)
|
|
178
|
+
? snapshotCost.modelBreakdown.map(item => ({
|
|
179
|
+
model: String(item.model ?? 'unknown'),
|
|
180
|
+
inputTokens: Number(item.inputTokens ?? 0),
|
|
181
|
+
outputTokens: Number(item.outputTokens ?? 0),
|
|
182
|
+
costUsd: Number(item.costUsd ?? 0),
|
|
183
|
+
requests: Number(item.requests ?? 0),
|
|
184
|
+
}))
|
|
185
|
+
: [],
|
|
186
|
+
runs: Array.isArray(snapshotCost.runs)
|
|
187
|
+
? snapshotCost.runs.map(item => ({
|
|
188
|
+
pricingResolved: Boolean(item.pricingResolved),
|
|
189
|
+
}))
|
|
190
|
+
: undefined,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Ignore malformed stream payloads.
|
|
195
|
+
}
|
|
196
|
+
}, [agentId]);
|
|
197
|
+
const monitorSocket = useAIAgentsWebSocket({
|
|
198
|
+
enabled: isReady && Boolean(agentBaseUrl),
|
|
199
|
+
baseUrl: agentBaseUrl,
|
|
200
|
+
path: '/api/v1/tool-approvals/ws',
|
|
201
|
+
queryParams: { agent_id: agentId },
|
|
202
|
+
onMessage: handleMonitoringStreamMessage,
|
|
203
|
+
reconnectDelayMs: attempt => Math.min(1000 * 2 ** Math.max(0, attempt - 1), 10000),
|
|
204
|
+
});
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
// Monitoring alerts endpoint is optional and may return 404 in local mode.
|
|
207
|
+
// Keep the UI quiet and rely on stream snapshots for now.
|
|
208
|
+
setAlerts([]);
|
|
209
|
+
}, [isReady, agentId]);
|
|
203
210
|
if (!isReady && runtimeStatus !== 'error') {
|
|
204
211
|
return (_jsxs(Box, { sx: {
|
|
205
212
|
display: 'flex',
|
|
@@ -208,21 +215,11 @@ const AgentMonitoringInner = ({ onLogout, }) => {
|
|
|
208
215
|
justifyContent: 'center',
|
|
209
216
|
height: '100vh',
|
|
210
217
|
gap: 3,
|
|
211
|
-
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children:
|
|
212
|
-
? 'Launching runtime for monitoring agent…'
|
|
213
|
-
: 'Creating monitoring demo agent…' })] }));
|
|
218
|
+
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching local monitoring demo agent..." })] }));
|
|
214
219
|
}
|
|
215
220
|
if (runtimeStatus === 'error' || hookError) {
|
|
216
|
-
return (
|
|
217
|
-
display: 'flex',
|
|
218
|
-
flexDirection: 'column',
|
|
219
|
-
alignItems: 'center',
|
|
220
|
-
justifyContent: 'center',
|
|
221
|
-
height: '100vh',
|
|
222
|
-
gap: 3,
|
|
223
|
-
}, children: [_jsx(AlertIcon, { size: 48 }), _jsx(Text, { sx: { color: 'danger.fg' }, children: hookError || 'Agent failed to start' })] }));
|
|
221
|
+
return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
|
|
224
222
|
}
|
|
225
|
-
const latest = snapshots[0] ?? createSyntheticSnapshot();
|
|
226
223
|
return (_jsxs(Box, { sx: {
|
|
227
224
|
height: 'calc(100vh - 60px)',
|
|
228
225
|
display: 'flex',
|
|
@@ -236,46 +233,109 @@ const AgentMonitoringInner = ({ onLogout, }) => {
|
|
|
236
233
|
borderBottom: '1px solid',
|
|
237
234
|
borderColor: 'border.default',
|
|
238
235
|
flexShrink: 0,
|
|
239
|
-
}, children: [_jsx(GraphIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Monitoring \u2014 ", podName] }),
|
|
236
|
+
}, children: [_jsx(GraphIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Monitoring \u2014 ", podName] }), isReconnectedAgent && (_jsx(Label, { variant: "secondary", size: "small", children: "Reconnected" })), _jsxs(Label, { variant: monitorSocket.connectionState === 'connected'
|
|
237
|
+
? 'success'
|
|
238
|
+
: 'secondary', children: ["WS: ", monitorSocket.connectionState] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsxs(Box, { sx: {
|
|
239
|
+
width: 320,
|
|
240
|
+
minWidth: 280,
|
|
241
|
+
borderRight: '1px solid',
|
|
242
|
+
borderColor: 'border.default',
|
|
243
|
+
display: 'flex',
|
|
244
|
+
flexDirection: 'column',
|
|
245
|
+
overflow: 'auto',
|
|
246
|
+
'@media (max-width: 1680px)': {
|
|
247
|
+
width: 300,
|
|
248
|
+
minWidth: 260,
|
|
249
|
+
},
|
|
250
|
+
'@media (max-width: 1400px)': {
|
|
251
|
+
display: 'none',
|
|
252
|
+
},
|
|
253
|
+
}, children: [_jsxs(Box, { sx: {
|
|
254
|
+
p: 3,
|
|
255
|
+
borderBottom: '1px solid',
|
|
256
|
+
borderColor: 'border.default',
|
|
257
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Token Usage" }), _jsx(TokenUsageChart, { serviceName: otelServiceName, agentId: agentId, apiKey: token ?? undefined, runUrl: otelBaseUrl, liveSystemPromptTokens: liveContextSnapshot?.systemPromptTokens, liveUserMessageTokens: liveContextSnapshot?.userMessageTokens, liveAgentMessageTokens: liveContextSnapshot?.assistantMessageTokens, liveToolsUsageTokens: liveContextSnapshot?.toolTokens, liveTimestampMs: monitorLastSnapshotAt, height: 180 })] }), _jsxs(Box, { sx: {
|
|
258
|
+
p: 3,
|
|
259
|
+
borderBottom: '1px solid',
|
|
260
|
+
borderColor: 'border.default',
|
|
261
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Cost" }), _jsx(CostUsageChart, { serviceName: otelServiceName, agentId: agentId, apiKey: token ?? undefined, runUrl: otelBaseUrl, liveCumulativeUsd: liveCost?.cumulativeCostUsd, liveTimestampMs: monitorLastSnapshotAt, height: 180 })] }), _jsxs(Box, { sx: {
|
|
262
|
+
p: 3,
|
|
263
|
+
borderBottom: '1px solid',
|
|
264
|
+
borderColor: 'border.default',
|
|
265
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "LLM Cost Monitoring" }), liveCost ? (_jsx(CostTracker, { agentId: agentId, compact: false, liveData: liveCost })) : (_jsxs(Box, { children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Waiting for first websocket snapshot..." }), monitorSocket.lastClose?.detail && (_jsxs(Text, { sx: {
|
|
266
|
+
color: 'danger.fg',
|
|
267
|
+
fontSize: 0,
|
|
268
|
+
mt: 1,
|
|
269
|
+
display: 'block',
|
|
270
|
+
}, children: ["Last close: ", monitorSocket.lastClose.detail] }))] }))] })] }), _jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Monitoring Agent", placeholder: "Ask for cost, token usage, and turn-level monitoring insights...", description: `${alerts.length} active alert${alerts.length !== 1 ? 's' : ''}`, showHeader: true, showTokenUsage: true, showToolsMenu: true, showSkillsMenu: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
|
|
240
271
|
{
|
|
241
|
-
title: '
|
|
242
|
-
message: '
|
|
272
|
+
title: '▶ No-tool turn',
|
|
273
|
+
message: 'Briefly introduce yourself without calling any tool or skill — produces a linear Start → Model → Decision → End graph.',
|
|
243
274
|
},
|
|
244
275
|
{
|
|
245
|
-
title: '
|
|
246
|
-
message: '
|
|
276
|
+
title: '🔍 Single tool call',
|
|
277
|
+
message: 'Use the Tavily web search tool to find the latest news about pydantic-graph. Make a single search call.',
|
|
247
278
|
},
|
|
248
|
-
|
|
249
|
-
|
|
279
|
+
{
|
|
280
|
+
title: '🌀 Parallel tool fan-out',
|
|
281
|
+
message: 'Use Tavily to search the web in parallel for these three topics in the same turn: (1) OpenTelemetry traces, (2) agent observability, (3) LLM cost monitoring. Issue all three searches together so the turn graph fans out (Broadcast → Spread → Join).',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
title: '🧩 Skill call',
|
|
285
|
+
message: 'Use the datalayer-whoami skill to identify my profile, then summarize it.',
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
title: '😄 Joke skill',
|
|
289
|
+
message: 'Use the jokes skill to tell me a random dad joke, then wrap it in one-sentence commentary.',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
title: '🧪 Mixed tools + skills',
|
|
293
|
+
message: 'In one turn: (a) use Tavily to search for "OTEL traces best practices", (b) call the datalayer-whoami skill, (c) call the jokes skill. Summarize all three results together. This should produce a Broadcast → three Spread nodes → Join in the Turn Execution Graph.',
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
title: 'Monitoring summary',
|
|
297
|
+
message: 'Summarize my current token usage, cost status, and recent turn activity.',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
title: 'Turn usage analysis',
|
|
301
|
+
message: 'Analyze the last turn usage and explain which parts drove input and output tokens.',
|
|
302
|
+
},
|
|
303
|
+
], submitOnSuggestionClick: true, contextSnapshot: liveContextSnapshot, mcpStatusData: liveMcpStatus }) }), _jsxs(Box, { sx: {
|
|
304
|
+
width: 360,
|
|
305
|
+
minWidth: 320,
|
|
250
306
|
borderLeft: '1px solid',
|
|
251
307
|
borderColor: 'border.default',
|
|
252
308
|
display: 'flex',
|
|
253
309
|
flexDirection: 'column',
|
|
254
310
|
overflow: 'auto',
|
|
311
|
+
'@media (max-width: 1680px)': {
|
|
312
|
+
width: 340,
|
|
313
|
+
minWidth: 300,
|
|
314
|
+
},
|
|
315
|
+
'@media (max-width: 1100px)': {
|
|
316
|
+
width: 300,
|
|
317
|
+
minWidth: 260,
|
|
318
|
+
},
|
|
255
319
|
}, children: [_jsxs(Box, { sx: {
|
|
256
320
|
p: 3,
|
|
257
321
|
borderBottom: '1px solid',
|
|
258
322
|
borderColor: 'border.default',
|
|
259
|
-
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
justifyContent: 'space-between',
|
|
276
|
-
alignItems: 'center',
|
|
277
|
-
mb: 1,
|
|
278
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: alert.title }), _jsx(Label, { size: "small", variant: alertVariant(alert.severity), children: alert.severity })] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: new Date(alert.timestamp).toLocaleString() })] }, alert.id))))] })] })] })] }));
|
|
323
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Turn and Session Usage" }), liveContext ? (_jsx(ContextPanel, { agentId: agentId, apiBase: agentBaseUrl, liveData: liveContext, defaultView: "overview", chartHeight: "160px" })) : (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Waiting for first websocket snapshot..." })), _jsxs(Text, { sx: { mt: 2, color: 'fg.muted', fontSize: 0 }, children: ["Live monitoring uses websocket snapshots only.", monitorLastSnapshotAt
|
|
324
|
+
? ` Last snapshot ${new Date(monitorLastSnapshotAt).toLocaleTimeString()}.`
|
|
325
|
+
: '', monitorSocket.connectionState !== 'connected' &&
|
|
326
|
+
monitorSocket.reconnectAttempt > 0
|
|
327
|
+
? ` Reconnect attempt ${monitorSocket.reconnectAttempt}.`
|
|
328
|
+
: ''] })] }), liveGraphTelemetry && (_jsxs(Box, { sx: {
|
|
329
|
+
p: 3,
|
|
330
|
+
borderBottom: '1px solid',
|
|
331
|
+
borderColor: 'border.default',
|
|
332
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Graph Execution (live)" }), _jsx(GraphFlowChart, { data: liveGraphTelemetry, height: 240 }), _jsxs(Text, { sx: { mt: 1, color: 'fg.muted', fontSize: 0 }, children: [liveGraphTelemetry.totalNodesExecuted, " node(s) executed across", ' ', liveGraphTelemetry.runCount, " run(s)", liveGraphTelemetry.totalDurationMs
|
|
333
|
+
? ` — ${(liveGraphTelemetry.totalDurationMs / 1000).toFixed(2)}s total`
|
|
334
|
+
: ''] })] })), _jsxs(Box, { sx: {
|
|
335
|
+
p: 3,
|
|
336
|
+
borderBottom: '1px solid',
|
|
337
|
+
borderColor: 'border.default',
|
|
338
|
+
}, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Turn Execution Graph (OTEL traces)" }), _jsx(TurnGraphChart, { serviceName: otelServiceName, agentId: agentId, runUrl: otelBaseUrl, apiKey: token ?? undefined, autoRefreshMs: 10_000, height: 280 })] })] })] })] }));
|
|
279
339
|
};
|
|
280
340
|
const syncTokenToIamStore = (token) => {
|
|
281
341
|
import('@datalayer/core/lib/state').then(({ iamStore }) => {
|
|
@@ -283,7 +343,7 @@ const syncTokenToIamStore = (token) => {
|
|
|
283
343
|
});
|
|
284
344
|
};
|
|
285
345
|
const AgentMonitoringExample = () => {
|
|
286
|
-
const { token,
|
|
346
|
+
const { token, clearAuth } = useSimpleAuthStore();
|
|
287
347
|
const hasSynced = useRef(false);
|
|
288
348
|
useEffect(() => {
|
|
289
349
|
if (token && !hasSynced.current) {
|
|
@@ -291,11 +351,6 @@ const AgentMonitoringExample = () => {
|
|
|
291
351
|
syncTokenToIamStore(token);
|
|
292
352
|
}
|
|
293
353
|
}, [token]);
|
|
294
|
-
const handleSignIn = useCallback((newToken, handle) => {
|
|
295
|
-
setAuth(newToken, handle);
|
|
296
|
-
hasSynced.current = true;
|
|
297
|
-
syncTokenToIamStore(newToken);
|
|
298
|
-
}, [setAuth]);
|
|
299
354
|
const handleLogout = useCallback(() => {
|
|
300
355
|
clearAuth();
|
|
301
356
|
hasSynced.current = false;
|
|
@@ -304,7 +359,7 @@ const AgentMonitoringExample = () => {
|
|
|
304
359
|
});
|
|
305
360
|
}, [clearAuth]);
|
|
306
361
|
if (!token) {
|
|
307
|
-
return (_jsx(ThemedProvider, { children: _jsx(
|
|
362
|
+
return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
|
|
308
363
|
}
|
|
309
364
|
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentMonitoringInner, { onLogout: handleLogout }) }) }));
|
|
310
365
|
};
|