@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
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
|
+
import ReactECharts from 'echarts-for-react';
|
|
8
|
+
import { buildOtelWebSocketUrl } from '@datalayer/core/lib/otel';
|
|
9
|
+
import { toMetricValue } from '../hooks/useMonitoring';
|
|
10
|
+
import { subscribeOtelWs } from './otelWsPool';
|
|
11
|
+
import { agentRuntimeStore, getMonitoringCacheKey, useAgentRuntimeStore, } from '../stores/agentRuntimeStore';
|
|
12
|
+
const COST_RUN_METRIC = 'agent_runtimes.capability.cost.run.usd';
|
|
13
|
+
const COST_CUMULATIVE_METRIC = 'agent_runtimes.capability.cost.cumulative.usd';
|
|
14
|
+
function resolveMonitoringEntry(monitoringCache, serviceName, agentId) {
|
|
15
|
+
const direct = monitoringCache[getMonitoringCacheKey(serviceName, agentId)];
|
|
16
|
+
if (direct)
|
|
17
|
+
return direct;
|
|
18
|
+
if (agentId) {
|
|
19
|
+
const byAgent = Object.entries(monitoringCache).find(([key, entry]) => {
|
|
20
|
+
return key.endsWith(`::${agentId}`) && entry.costPoints.length > 0;
|
|
21
|
+
});
|
|
22
|
+
if (byAgent)
|
|
23
|
+
return byAgent[1];
|
|
24
|
+
}
|
|
25
|
+
if (serviceName) {
|
|
26
|
+
const byService = Object.entries(monitoringCache).find(([key, entry]) => {
|
|
27
|
+
return key.startsWith(`${serviceName}::`) && entry.costPoints.length > 0;
|
|
28
|
+
});
|
|
29
|
+
if (byService)
|
|
30
|
+
return byService[1];
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
function localPointToCostPoint(point) {
|
|
35
|
+
return {
|
|
36
|
+
timestampKey: String(point.timestampMs),
|
|
37
|
+
timestampMs: point.timestampMs,
|
|
38
|
+
costUsd: 0,
|
|
39
|
+
cumulativeUsd: point.cumulativeUsd,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Parse attributes that may arrive as a JSON string (WS) or object (HTTP). */
|
|
43
|
+
function parseAttributes(attrs) {
|
|
44
|
+
if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) {
|
|
45
|
+
return attrs;
|
|
46
|
+
}
|
|
47
|
+
if (typeof attrs === 'string') {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(attrs);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
/** Convert metric row timestamp to milliseconds. */
|
|
58
|
+
function rowTimestampMs(row) {
|
|
59
|
+
const nanoTs = row.timestamp_unix_nano ?? row.observed_timestamp_unix_nano;
|
|
60
|
+
if (typeof nanoTs === 'number' && nanoTs > 0)
|
|
61
|
+
return nanoTs / 1_000_000;
|
|
62
|
+
if (typeof nanoTs === 'string' && nanoTs.length > 0) {
|
|
63
|
+
const parsed = Number(nanoTs);
|
|
64
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
65
|
+
return parsed / 1_000_000;
|
|
66
|
+
}
|
|
67
|
+
const isoTs = row.timestamp;
|
|
68
|
+
if (typeof isoTs === 'string' && isoTs.length > 0) {
|
|
69
|
+
const ms = new Date(isoTs).getTime();
|
|
70
|
+
if (Number.isFinite(ms) && ms > 0)
|
|
71
|
+
return ms;
|
|
72
|
+
}
|
|
73
|
+
return Date.now();
|
|
74
|
+
}
|
|
75
|
+
function rowTimestampKey(row) {
|
|
76
|
+
const nano = row.timestamp_unix_nano;
|
|
77
|
+
if (typeof nano === 'number' && nano > 0)
|
|
78
|
+
return String(nano);
|
|
79
|
+
if (typeof nano === 'string' && nano.length > 0)
|
|
80
|
+
return nano;
|
|
81
|
+
const iso = row.timestamp;
|
|
82
|
+
if (typeof iso === 'string' && iso.length > 0)
|
|
83
|
+
return iso;
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
/** Extract cost points from cost metrics rows. */
|
|
87
|
+
function extractCostPoints(rows, agentId) {
|
|
88
|
+
let filtered = rows.filter(row => {
|
|
89
|
+
const metricName = row.metric_name;
|
|
90
|
+
return (metricName === COST_CUMULATIVE_METRIC || metricName === COST_RUN_METRIC);
|
|
91
|
+
});
|
|
92
|
+
if (agentId) {
|
|
93
|
+
filtered = filtered.filter(row => extractAgentId(row) === agentId);
|
|
94
|
+
}
|
|
95
|
+
const byTimestamp = new Map();
|
|
96
|
+
for (const row of filtered) {
|
|
97
|
+
const ts = rowTimestampKey(row);
|
|
98
|
+
if (!ts)
|
|
99
|
+
continue;
|
|
100
|
+
const group = byTimestamp.get(ts) ?? [];
|
|
101
|
+
group.push(row);
|
|
102
|
+
byTimestamp.set(ts, group);
|
|
103
|
+
}
|
|
104
|
+
const points = [];
|
|
105
|
+
const sorted = [...byTimestamp.entries()].sort((a, b) => {
|
|
106
|
+
const na = Number(a[0]);
|
|
107
|
+
const nb = Number(b[0]);
|
|
108
|
+
if (Number.isFinite(na) && Number.isFinite(nb))
|
|
109
|
+
return na - nb;
|
|
110
|
+
return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
|
|
111
|
+
});
|
|
112
|
+
for (const [, groupRows] of sorted) {
|
|
113
|
+
const cumulativeRows = groupRows.filter(r => r.metric_name === COST_CUMULATIVE_METRIC);
|
|
114
|
+
if (cumulativeRows.length === 0)
|
|
115
|
+
continue;
|
|
116
|
+
const runRows = groupRows.filter(r => r.metric_name === COST_RUN_METRIC);
|
|
117
|
+
// Cumulative metric values represent the running total. Repeated snapshot
|
|
118
|
+
// rows for the same timestamp should not be summed; keep the highest value.
|
|
119
|
+
const cumulativeUsd = cumulativeRows.reduce((max, row) => Math.max(max, toMetricValue(row)), 0);
|
|
120
|
+
const costUsd = runRows.reduce((sum, row) => sum + toMetricValue(row), 0);
|
|
121
|
+
if (!Number.isFinite(cumulativeUsd) || !Number.isFinite(costUsd))
|
|
122
|
+
continue;
|
|
123
|
+
const timestampKey = rowTimestampKey(cumulativeRows[0]);
|
|
124
|
+
if (!timestampKey)
|
|
125
|
+
continue;
|
|
126
|
+
points.push({
|
|
127
|
+
timestampKey,
|
|
128
|
+
timestampMs: rowTimestampMs(cumulativeRows[0]),
|
|
129
|
+
costUsd,
|
|
130
|
+
cumulativeUsd,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
points.sort((a, b) => a.timestampMs - b.timestampMs);
|
|
134
|
+
return points;
|
|
135
|
+
}
|
|
136
|
+
function extractServiceName(row) {
|
|
137
|
+
const directCandidates = [row.service_name, row.service, row.serviceName];
|
|
138
|
+
for (const candidate of directCandidates) {
|
|
139
|
+
if (typeof candidate === 'string' && candidate.length > 0) {
|
|
140
|
+
return candidate;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const resourceAttributes = row.resource_attributes;
|
|
144
|
+
if (resourceAttributes && typeof resourceAttributes === 'object') {
|
|
145
|
+
const nested = resourceAttributes['service.name'];
|
|
146
|
+
if (typeof nested === 'string' && nested.length > 0) {
|
|
147
|
+
return nested;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
/** Extract `agent.id` from span/trace attributes. */
|
|
153
|
+
function extractAgentId(row) {
|
|
154
|
+
const attrs = parseAttributes(row.attributes);
|
|
155
|
+
const aid = attrs['agent.id'];
|
|
156
|
+
if (typeof aid === 'string')
|
|
157
|
+
return aid;
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
export function CostUsageChart({ serviceName, agentId, apiKey, runUrl, wsRunUrl, liveCumulativeUsd, liveTimestampMs, height = 160, }) {
|
|
161
|
+
const monitoringCache = useAgentRuntimeStore(s => s.monitoringCache);
|
|
162
|
+
const mergeCostPoints = useAgentRuntimeStore(s => s.mergeCostPoints);
|
|
163
|
+
const upsertLocalCostPoint = useAgentRuntimeStore(s => s.upsertLocalCostPoint);
|
|
164
|
+
const cachedEntry = useMemo(() => resolveMonitoringEntry(monitoringCache, serviceName, agentId), [agentId, monitoringCache, serviceName]);
|
|
165
|
+
const [points, setPoints] = useState([]);
|
|
166
|
+
const initialTimestampMsRef = useRef(Date.now());
|
|
167
|
+
const mergePoints = (existing, incoming) => {
|
|
168
|
+
const byTimestamp = new Map();
|
|
169
|
+
for (const point of existing) {
|
|
170
|
+
byTimestamp.set(point.timestampKey, point);
|
|
171
|
+
}
|
|
172
|
+
for (const point of incoming) {
|
|
173
|
+
const prev = byTimestamp.get(point.timestampKey);
|
|
174
|
+
if (!prev) {
|
|
175
|
+
byTimestamp.set(point.timestampKey, point);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
byTimestamp.set(point.timestampKey, {
|
|
179
|
+
...prev,
|
|
180
|
+
timestampMs: Math.max(prev.timestampMs, point.timestampMs),
|
|
181
|
+
costUsd: Math.max(prev.costUsd, point.costUsd),
|
|
182
|
+
cumulativeUsd: Math.max(prev.cumulativeUsd, point.cumulativeUsd),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
const merged = Array.from(byTimestamp.values()).sort((a, b) => a.timestampMs - b.timestampMs);
|
|
186
|
+
// Cumulative cost should never decrease; guard against out-of-order or
|
|
187
|
+
// duplicate snapshots by enforcing a monotonic series.
|
|
188
|
+
let runningMax = 0;
|
|
189
|
+
return merged.map(point => {
|
|
190
|
+
runningMax = Math.max(runningMax, point.cumulativeUsd);
|
|
191
|
+
return {
|
|
192
|
+
...point,
|
|
193
|
+
cumulativeUsd: runningMax,
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
// ── Reset state on source switch ──────────────────────────────
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
if (!serviceName) {
|
|
200
|
+
setPoints([]);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
setPoints((cachedEntry?.costPoints ?? []).map(localPointToCostPoint));
|
|
204
|
+
initialTimestampMsRef.current = Date.now();
|
|
205
|
+
}, [agentId, cachedEntry, serviceName]);
|
|
206
|
+
// Apply immediate post-turn updates from the monitoring websocket snapshot.
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
if (!serviceName)
|
|
209
|
+
return;
|
|
210
|
+
if (typeof liveCumulativeUsd !== 'number' ||
|
|
211
|
+
!Number.isFinite(liveCumulativeUsd)) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const timestampMs = typeof liveTimestampMs === 'number' && Number.isFinite(liveTimestampMs)
|
|
215
|
+
? liveTimestampMs
|
|
216
|
+
: Date.now();
|
|
217
|
+
const livePoint = {
|
|
218
|
+
timestampKey: `live-${timestampMs}`,
|
|
219
|
+
timestampMs,
|
|
220
|
+
costUsd: 0,
|
|
221
|
+
cumulativeUsd: Math.max(0, liveCumulativeUsd),
|
|
222
|
+
};
|
|
223
|
+
upsertLocalCostPoint({
|
|
224
|
+
serviceName,
|
|
225
|
+
agentId,
|
|
226
|
+
timestampMs,
|
|
227
|
+
cumulativeUsd: livePoint.cumulativeUsd,
|
|
228
|
+
});
|
|
229
|
+
const mergedEntry = resolveMonitoringEntry(agentRuntimeStore.getState().monitoringCache, serviceName, agentId);
|
|
230
|
+
if (mergedEntry) {
|
|
231
|
+
setPoints(mergedEntry.costPoints.map(localPointToCostPoint));
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
setPoints(prev => mergePoints(prev, [livePoint]));
|
|
235
|
+
}
|
|
236
|
+
}, [
|
|
237
|
+
agentId,
|
|
238
|
+
liveCumulativeUsd,
|
|
239
|
+
liveTimestampMs,
|
|
240
|
+
serviceName,
|
|
241
|
+
upsertLocalCostPoint,
|
|
242
|
+
]);
|
|
243
|
+
// ── WebSocket subscription (shared connection pool) ─────────
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
if (!serviceName || !apiKey)
|
|
246
|
+
return;
|
|
247
|
+
const rawBaseUrl = wsRunUrl ||
|
|
248
|
+
runUrl ||
|
|
249
|
+
(typeof window !== 'undefined' ? window.location.origin : '');
|
|
250
|
+
if (!rawBaseUrl)
|
|
251
|
+
return;
|
|
252
|
+
const baseWithProtocol = rawBaseUrl.startsWith('http://') ||
|
|
253
|
+
rawBaseUrl.startsWith('https://') ||
|
|
254
|
+
rawBaseUrl.startsWith('ws://') ||
|
|
255
|
+
rawBaseUrl.startsWith('wss://')
|
|
256
|
+
? rawBaseUrl
|
|
257
|
+
: `${typeof window !== 'undefined' &&
|
|
258
|
+
window.location.protocol === 'https:'
|
|
259
|
+
? 'https:'
|
|
260
|
+
: 'http:'}//${typeof window !== 'undefined' ? window.location.host : ''}${rawBaseUrl}`;
|
|
261
|
+
let wsUrl;
|
|
262
|
+
try {
|
|
263
|
+
wsUrl = buildOtelWebSocketUrl({
|
|
264
|
+
baseUrl: baseWithProtocol,
|
|
265
|
+
token: apiKey,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const unsubscribe = subscribeOtelWs(wsUrl, msg => {
|
|
272
|
+
if (msg.signal !== 'metrics')
|
|
273
|
+
return;
|
|
274
|
+
const rows = Array.isArray(msg.data) ? msg.data : [];
|
|
275
|
+
let matchingRows = rows.filter(row => extractServiceName(row) === serviceName);
|
|
276
|
+
// Filter by agent.id when specified.
|
|
277
|
+
if (agentId) {
|
|
278
|
+
matchingRows = matchingRows.filter(row => extractAgentId(row) === agentId);
|
|
279
|
+
}
|
|
280
|
+
if (matchingRows.length === 0)
|
|
281
|
+
return;
|
|
282
|
+
const newPoints = extractCostPoints(matchingRows, agentId);
|
|
283
|
+
if (newPoints.length > 0) {
|
|
284
|
+
mergeCostPoints({
|
|
285
|
+
serviceName,
|
|
286
|
+
agentId,
|
|
287
|
+
points: newPoints.map(point => ({
|
|
288
|
+
timestampMs: point.timestampMs,
|
|
289
|
+
cumulativeUsd: point.cumulativeUsd,
|
|
290
|
+
})),
|
|
291
|
+
});
|
|
292
|
+
const mergedEntry = resolveMonitoringEntry(agentRuntimeStore.getState().monitoringCache, serviceName, agentId);
|
|
293
|
+
if (mergedEntry) {
|
|
294
|
+
setPoints(mergedEntry.costPoints.map(localPointToCostPoint));
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
setPoints(prev => mergePoints(prev, newPoints));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
return unsubscribe;
|
|
302
|
+
}, [agentId, apiKey, mergeCostPoints, runUrl, serviceName, wsRunUrl]);
|
|
303
|
+
// ── Chart options ─────────────────────────────────────────────
|
|
304
|
+
const option = useMemo(() => {
|
|
305
|
+
const chartData = points.length > 0
|
|
306
|
+
? [
|
|
307
|
+
[points[0].timestampMs, 0],
|
|
308
|
+
...points.map(p => [p.timestampMs, p.cumulativeUsd]),
|
|
309
|
+
]
|
|
310
|
+
: [[initialTimestampMsRef.current, 0]];
|
|
311
|
+
return {
|
|
312
|
+
animation: false,
|
|
313
|
+
animationDuration: 0,
|
|
314
|
+
animationDurationUpdate: 0,
|
|
315
|
+
tooltip: {
|
|
316
|
+
trigger: 'axis',
|
|
317
|
+
textStyle: { fontSize: 10 },
|
|
318
|
+
confine: true,
|
|
319
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
320
|
+
formatter: (params) => {
|
|
321
|
+
if (!Array.isArray(params) || params.length === 0)
|
|
322
|
+
return '';
|
|
323
|
+
const lines = params.map((p) => `${p.marker} ${p.seriesName}: $${p.value[1].toFixed(6)}`);
|
|
324
|
+
return lines.join('<br/>');
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
legend: {
|
|
328
|
+
data: ['Cumulative cost'],
|
|
329
|
+
top: 0,
|
|
330
|
+
textStyle: { fontSize: 9 },
|
|
331
|
+
itemWidth: 10,
|
|
332
|
+
itemHeight: 8,
|
|
333
|
+
itemGap: 6,
|
|
334
|
+
},
|
|
335
|
+
grid: {
|
|
336
|
+
left: 50,
|
|
337
|
+
right: 15,
|
|
338
|
+
top: 24,
|
|
339
|
+
bottom: 20,
|
|
340
|
+
},
|
|
341
|
+
xAxis: {
|
|
342
|
+
type: 'time',
|
|
343
|
+
min: 'dataMin',
|
|
344
|
+
max: 'dataMax',
|
|
345
|
+
axisLabel: { fontSize: 9 },
|
|
346
|
+
axisLine: { lineStyle: { color: '#d0d7de' } },
|
|
347
|
+
},
|
|
348
|
+
yAxis: {
|
|
349
|
+
type: 'value',
|
|
350
|
+
min: 0,
|
|
351
|
+
axisLabel: {
|
|
352
|
+
fontSize: 9,
|
|
353
|
+
formatter: (v) => `$${v.toFixed(4)}`,
|
|
354
|
+
},
|
|
355
|
+
splitLine: {
|
|
356
|
+
show: true,
|
|
357
|
+
lineStyle: { color: '#f0f0f0' },
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
series: [
|
|
361
|
+
{
|
|
362
|
+
name: 'Cumulative cost',
|
|
363
|
+
type: 'line',
|
|
364
|
+
smooth: false,
|
|
365
|
+
lineStyle: { width: 2 },
|
|
366
|
+
areaStyle: { opacity: 0.15 },
|
|
367
|
+
symbol: 'circle',
|
|
368
|
+
symbolSize: 4,
|
|
369
|
+
itemStyle: { color: '#cf222e' },
|
|
370
|
+
data: chartData,
|
|
371
|
+
animation: false,
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
};
|
|
375
|
+
}, [points]);
|
|
376
|
+
return (_jsx(ReactECharts, { option: option, style: { height, width: '100%' }, opts: { renderer: 'canvas' }, notMerge: true, lazyUpdate: true }));
|
|
377
|
+
}
|
|
378
|
+
export default CostUsageChart;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphFlowChart — ECharts graph visualisation of pydantic-graph execution.
|
|
3
|
+
*
|
|
4
|
+
* Renders a force-directed graph showing:
|
|
5
|
+
* - Static topology (nodes + edges from the graph definition)
|
|
6
|
+
* - Dynamic execution trace (which nodes were visited, with timing)
|
|
7
|
+
*/
|
|
8
|
+
import { type CSSProperties } from 'react';
|
|
9
|
+
import type { GraphTelemetryData } from '../types/stream';
|
|
10
|
+
export interface GraphFlowChartProps {
|
|
11
|
+
data: GraphTelemetryData;
|
|
12
|
+
height?: number | string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
export declare const GraphFlowChart: React.FC<GraphFlowChartProps>;
|
|
16
|
+
export default GraphFlowChart;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* GraphFlowChart — ECharts graph visualisation of pydantic-graph execution.
|
|
8
|
+
*
|
|
9
|
+
* Renders a force-directed graph showing:
|
|
10
|
+
* - Static topology (nodes + edges from the graph definition)
|
|
11
|
+
* - Dynamic execution trace (which nodes were visited, with timing)
|
|
12
|
+
*/
|
|
13
|
+
import { useMemo } from 'react';
|
|
14
|
+
import ReactECharts from 'echarts-for-react';
|
|
15
|
+
/** Category definitions for ECharts graph. */
|
|
16
|
+
const CATEGORIES = [
|
|
17
|
+
{ name: 'start', itemStyle: { color: '#58a6ff' } },
|
|
18
|
+
{ name: 'step', itemStyle: { color: '#3fb950' } },
|
|
19
|
+
{ name: 'end', itemStyle: { color: '#f85149' } },
|
|
20
|
+
{ name: 'end_or_continue', itemStyle: { color: '#d29922' } },
|
|
21
|
+
{ name: 'join', itemStyle: { color: '#bc8cff' } },
|
|
22
|
+
{ name: 'decision', itemStyle: { color: '#f0883e' } },
|
|
23
|
+
{ name: 'error', itemStyle: { color: '#da3633' } },
|
|
24
|
+
{ name: 'parallel', itemStyle: { color: '#79c0ff' } },
|
|
25
|
+
];
|
|
26
|
+
const CATEGORY_INDEX = {};
|
|
27
|
+
CATEGORIES.forEach((c, i) => {
|
|
28
|
+
CATEGORY_INDEX[c.name] = i;
|
|
29
|
+
});
|
|
30
|
+
function getCategoryIndex(category) {
|
|
31
|
+
return CATEGORY_INDEX[category] ?? CATEGORY_INDEX['step'];
|
|
32
|
+
}
|
|
33
|
+
/** Map node events to a lookup for fast access. */
|
|
34
|
+
function buildEventLookup(events) {
|
|
35
|
+
const map = new Map();
|
|
36
|
+
for (const evt of events) {
|
|
37
|
+
const existing = map.get(evt.nodeId);
|
|
38
|
+
if (existing) {
|
|
39
|
+
existing.push(evt);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
map.set(evt.nodeId, [evt]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return map;
|
|
46
|
+
}
|
|
47
|
+
function formatDuration(ms) {
|
|
48
|
+
if (ms == null)
|
|
49
|
+
return '—';
|
|
50
|
+
if (ms < 1)
|
|
51
|
+
return '<1ms';
|
|
52
|
+
if (ms < 1000)
|
|
53
|
+
return `${ms.toFixed(1)}ms`;
|
|
54
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
55
|
+
}
|
|
56
|
+
export const GraphFlowChart = ({ data, height = 320, style, }) => {
|
|
57
|
+
const option = useMemo(() => {
|
|
58
|
+
const eventLookup = buildEventLookup(data.events);
|
|
59
|
+
// Build ECharts nodes
|
|
60
|
+
const echartsNodes = data.nodes.map((node) => {
|
|
61
|
+
const nodeEvents = eventLookup.get(node.id) || [];
|
|
62
|
+
const lastEvent = nodeEvents[nodeEvents.length - 1];
|
|
63
|
+
const hitCount = nodeEvents.filter(e => e.status === 'completed').length;
|
|
64
|
+
const hasError = nodeEvents.some(e => e.status === 'error');
|
|
65
|
+
const totalDuration = nodeEvents.reduce((sum, e) => sum + (e.durationMs ?? 0), 0);
|
|
66
|
+
// Size based on hit count (bigger = more visits)
|
|
67
|
+
const baseSize = 30;
|
|
68
|
+
const symbolSize = baseSize + Math.min(hitCount * 8, 40);
|
|
69
|
+
// Determine visual category
|
|
70
|
+
let visualCategory = node.category;
|
|
71
|
+
if (hasError)
|
|
72
|
+
visualCategory = 'error';
|
|
73
|
+
return {
|
|
74
|
+
id: node.id,
|
|
75
|
+
name: node.name === '__start__'
|
|
76
|
+
? 'Start'
|
|
77
|
+
: node.name === '__end__'
|
|
78
|
+
? 'End'
|
|
79
|
+
: node.name,
|
|
80
|
+
symbolSize,
|
|
81
|
+
category: getCategoryIndex(visualCategory),
|
|
82
|
+
value: hitCount,
|
|
83
|
+
itemStyle: hitCount > 0 ? { borderWidth: 3, borderColor: '#e3b341' } : undefined,
|
|
84
|
+
label: {
|
|
85
|
+
show: true,
|
|
86
|
+
fontSize: 11,
|
|
87
|
+
color: '#c9d1d9',
|
|
88
|
+
},
|
|
89
|
+
tooltip: {
|
|
90
|
+
formatter: () => {
|
|
91
|
+
const lines = [
|
|
92
|
+
`<b>${node.name}</b>`,
|
|
93
|
+
`Category: ${node.category}`,
|
|
94
|
+
`Executions: ${hitCount}`,
|
|
95
|
+
];
|
|
96
|
+
if (totalDuration > 0) {
|
|
97
|
+
lines.push(`Total duration: ${formatDuration(totalDuration)}`);
|
|
98
|
+
}
|
|
99
|
+
if (lastEvent?.status === 'error' && lastEvent.error) {
|
|
100
|
+
lines.push(`<span style="color:#f85149">Error: ${lastEvent.error}</span>`);
|
|
101
|
+
}
|
|
102
|
+
return lines.join('<br/>');
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
// Build ECharts edges (links)
|
|
108
|
+
const echartsLinks = data.edges.map((edge) => {
|
|
109
|
+
// Check if this edge was traversed in the execution trace
|
|
110
|
+
const wasTraversed = data.events.some(e => e.nodeId === edge.target && e.parentNodeId === edge.source);
|
|
111
|
+
return {
|
|
112
|
+
source: edge.source,
|
|
113
|
+
target: edge.target,
|
|
114
|
+
label: edge.label
|
|
115
|
+
? {
|
|
116
|
+
show: true,
|
|
117
|
+
formatter: edge.label,
|
|
118
|
+
fontSize: 9,
|
|
119
|
+
color: '#8b949e',
|
|
120
|
+
}
|
|
121
|
+
: undefined,
|
|
122
|
+
lineStyle: {
|
|
123
|
+
color: wasTraversed ? '#e3b341' : '#484f58',
|
|
124
|
+
width: wasTraversed ? 3 : 1.5,
|
|
125
|
+
curveness: 0.2,
|
|
126
|
+
type: edge.edgeType === 'parallel'
|
|
127
|
+
? 'dashed'
|
|
128
|
+
: 'solid',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
tooltip: {
|
|
134
|
+
trigger: 'item',
|
|
135
|
+
backgroundColor: '#161b22',
|
|
136
|
+
borderColor: '#30363d',
|
|
137
|
+
textStyle: { color: '#c9d1d9', fontSize: 12 },
|
|
138
|
+
},
|
|
139
|
+
legend: {
|
|
140
|
+
data: CATEGORIES.map(c => c.name),
|
|
141
|
+
top: 4,
|
|
142
|
+
textStyle: { color: '#8b949e', fontSize: 10 },
|
|
143
|
+
itemWidth: 12,
|
|
144
|
+
itemHeight: 12,
|
|
145
|
+
},
|
|
146
|
+
series: [
|
|
147
|
+
{
|
|
148
|
+
type: 'graph',
|
|
149
|
+
layout: 'force',
|
|
150
|
+
roam: true,
|
|
151
|
+
draggable: true,
|
|
152
|
+
categories: CATEGORIES,
|
|
153
|
+
data: echartsNodes,
|
|
154
|
+
links: echartsLinks,
|
|
155
|
+
force: {
|
|
156
|
+
repulsion: 200,
|
|
157
|
+
edgeLength: [80, 160],
|
|
158
|
+
gravity: 0.1,
|
|
159
|
+
},
|
|
160
|
+
edgeSymbol: ['none', 'arrow'],
|
|
161
|
+
edgeSymbolSize: [0, 8],
|
|
162
|
+
emphasis: {
|
|
163
|
+
focus: 'adjacency',
|
|
164
|
+
lineStyle: { width: 4 },
|
|
165
|
+
},
|
|
166
|
+
label: {
|
|
167
|
+
show: true,
|
|
168
|
+
position: 'bottom',
|
|
169
|
+
fontSize: 10,
|
|
170
|
+
},
|
|
171
|
+
lineStyle: {
|
|
172
|
+
opacity: 0.7,
|
|
173
|
+
},
|
|
174
|
+
animation: true,
|
|
175
|
+
animationDuration: 500,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
}, [data]);
|
|
180
|
+
return (_jsx(ReactECharts, { option: option, style: { height, width: '100%', ...style }, opts: { renderer: 'canvas' }, notMerge: true }));
|
|
181
|
+
};
|
|
182
|
+
export default GraphFlowChart;
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
export interface TokenUsageChartProps {
|
|
2
2
|
serviceName?: string;
|
|
3
|
+
agentId?: string;
|
|
3
4
|
apiKey?: string;
|
|
4
5
|
runUrl?: string;
|
|
5
6
|
wsRunUrl?: string;
|
|
7
|
+
liveSystemPromptTokens?: number;
|
|
8
|
+
liveToolsDescriptionTokens?: number;
|
|
9
|
+
liveUserMessageTokens?: number;
|
|
10
|
+
liveAgentMessageTokens?: number;
|
|
11
|
+
liveToolsUsageTokens?: number;
|
|
12
|
+
liveTimestampMs?: number | null;
|
|
6
13
|
height?: number;
|
|
7
14
|
days?: number;
|
|
8
15
|
}
|
|
9
|
-
export declare function TokenUsageChart({ serviceName, apiKey, runUrl, wsRunUrl,
|
|
16
|
+
export declare function TokenUsageChart({ serviceName, agentId, apiKey, runUrl, wsRunUrl, liveSystemPromptTokens, liveToolsDescriptionTokens, liveUserMessageTokens, liveAgentMessageTokens, liveToolsUsageTokens, liveTimestampMs, height, }: TokenUsageChartProps): import("react/jsx-runtime").JSX.Element;
|
|
10
17
|
export default TokenUsageChart;
|