@datalayer/agent-runtimes 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -1
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/App.js +1 -1
- package/lib/agent-node/themeStore.d.ts +3 -0
- package/lib/agent-node/themeStore.js +156 -0
- package/lib/agent-node-main.d.ts +1 -0
- package/lib/agent-node-main.js +14 -0
- package/lib/agents/AgentDetails.d.ts +22 -1
- package/lib/agents/AgentDetails.js +34 -47
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +4 -2
- package/lib/chat/Chat.d.ts +5 -106
- package/lib/chat/Chat.js +20 -14
- package/lib/chat/ChatFloating.d.ts +7 -140
- package/lib/chat/ChatFloating.js +3 -3
- package/lib/chat/ChatPopupStandalone.d.ts +8 -47
- package/lib/chat/ChatPopupStandalone.js +3 -3
- package/lib/chat/ChatSidebar.d.ts +4 -69
- package/lib/chat/ChatSidebar.js +83 -51
- package/lib/chat/ChatStandalone.d.ts +4 -54
- package/lib/chat/ChatStandalone.js +3 -3
- package/lib/chat/base/ChatBase.js +1414 -174
- package/lib/chat/display/FloatingBrandButton.js +8 -1
- package/lib/chat/header/ChatHeader.d.ts +3 -1
- package/lib/chat/header/ChatHeader.js +15 -12
- package/lib/chat/header/ChatHeaderBase.d.ts +30 -5
- package/lib/chat/header/ChatHeaderBase.js +41 -16
- package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
- package/lib/chat/indicators/McpStatusIndicator.js +7 -32
- package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
- package/lib/chat/indicators/SandboxStatusIndicator.js +91 -56
- package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
- package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
- package/lib/chat/indicators/index.d.ts +1 -0
- package/lib/chat/indicators/index.js +1 -0
- package/lib/chat/messages/ChatMessageList.d.ts +1 -1
- package/lib/chat/messages/ChatMessageList.js +154 -114
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +21 -6
- package/lib/chat/prompt/InputFooter.js +76 -20
- package/lib/chat/prompt/InputPrompt.d.ts +5 -1
- package/lib/chat/prompt/InputPrompt.js +4 -4
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
- package/lib/chat/prompt/InputPromptLexical.js +12 -5
- package/lib/chat/prompt/InputPromptText.d.ts +3 -1
- package/lib/chat/prompt/InputPromptText.js +2 -2
- package/lib/chat/tools/ToolApprovalBanner.js +1 -1
- package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
- package/lib/chat/tools/ToolCallDisplay.js +2 -2
- package/lib/chat/usage/TokenUsageBar.js +20 -2
- package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
- package/lib/client/AgentRuntimesClientContext.js +55 -0
- package/lib/client/AgentsMixin.d.ts +0 -18
- package/lib/client/AgentsMixin.js +20 -30
- package/lib/client/IAgentRuntimesClient.d.ts +215 -0
- package/lib/client/IAgentRuntimesClient.js +5 -0
- package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
- package/lib/client/SdkAgentRuntimesClient.js +134 -0
- package/lib/client/index.d.ts +4 -1
- package/lib/client/index.js +3 -1
- package/lib/components/NotificationEventCard.js +5 -1
- package/lib/config/AgentConfiguration.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- package/lib/context/ContextDistribution.d.ts +3 -1
- package/lib/context/ContextDistribution.js +8 -27
- package/lib/context/ContextInspector.d.ts +3 -1
- package/lib/context/ContextInspector.js +19 -67
- package/lib/context/ContextPanel.d.ts +3 -1
- package/lib/context/ContextPanel.js +104 -64
- package/lib/context/ContextUsage.d.ts +3 -1
- package/lib/context/ContextUsage.js +3 -3
- package/lib/context/CostTracker.d.ts +9 -3
- package/lib/context/CostTracker.js +26 -47
- package/lib/context/CostUsageChart.d.ts +12 -0
- package/lib/context/CostUsageChart.js +378 -0
- package/lib/context/GraphFlowChart.d.ts +16 -0
- package/lib/context/GraphFlowChart.js +182 -0
- package/lib/context/TokenUsageChart.d.ts +8 -1
- package/lib/context/TokenUsageChart.js +349 -211
- package/lib/context/TurnGraphChart.d.ts +39 -0
- package/lib/context/TurnGraphChart.js +538 -0
- package/lib/context/otelWsPool.d.ts +20 -0
- package/lib/context/otelWsPool.js +69 -0
- package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
- package/lib/examples/A2UiComponentGalleryExample.js +315 -522
- package/lib/examples/A2UiContactCardExample.d.ts +0 -18
- package/lib/examples/A2UiContactCardExample.js +154 -411
- package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
- package/lib/examples/A2UiRestaurantExample.js +114 -212
- package/lib/examples/A2UiViewerExample.d.ts +0 -18
- package/lib/examples/A2UiViewerExample.js +283 -532
- package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
- package/lib/examples/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +14 -28
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +603 -169
- package/lib/examples/AgentEvalsExample.js +339 -53
- package/lib/examples/AgentGuardrailsExample.js +383 -66
- package/lib/examples/AgentHooksExample.d.ts +3 -0
- package/lib/examples/AgentHooksExample.js +122 -0
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.d.ts +3 -0
- package/lib/examples/AgentMCPExample.js +481 -0
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +78 -33
- package/lib/examples/AgentMonitoringExample.js +261 -200
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +114 -33
- package/lib/examples/AgentOtelExample.js +32 -42
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +433 -81
- package/lib/examples/AgentParametersExample.d.ts +3 -0
- package/lib/examples/AgentParametersExample.js +248 -0
- package/lib/examples/AgentSandboxExample.d.ts +3 -3
- package/lib/examples/AgentSandboxExample.js +74 -45
- package/lib/examples/AgentSkillsExample.js +95 -103
- package/lib/examples/AgentSubagentsExample.d.ts +14 -0
- package/lib/examples/AgentSubagentsExample.js +228 -0
- package/lib/examples/AgentToolApprovalsExample.js +49 -561
- package/lib/examples/AgentTriggersExample.js +823 -569
- package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +16 -28
- package/lib/examples/ChatExample.js +13 -29
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/CopilotKitNotebookExample.js +2 -1
- package/lib/examples/HomeExample.d.ts +15 -0
- package/lib/examples/HomeExample.js +77 -0
- package/lib/examples/Lexical2Example.js +4 -2
- package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
- package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +66 -17
- package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
- package/lib/examples/LexicalAgentSidebarExample.js +261 -0
- package/lib/examples/NotebookAgentExample.d.ts +9 -0
- package/lib/examples/NotebookAgentExample.js +192 -0
- package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
- package/lib/examples/NotebookAgentSidebarExample.js +221 -0
- package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
- package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
- package/lib/examples/NotebookExample.d.ts +4 -7
- package/lib/examples/NotebookExample.js +14 -146
- package/lib/examples/components/AuthRequiredView.d.ts +6 -0
- package/lib/examples/components/AuthRequiredView.js +33 -0
- package/lib/examples/components/ExampleWrapper.d.ts +9 -3
- package/lib/examples/components/ExampleWrapper.js +45 -9
- package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
- package/lib/examples/components/index.d.ts +3 -0
- package/lib/examples/components/index.js +4 -0
- package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
- package/lib/examples/example-selector.d.ts +17 -4
- package/lib/examples/example-selector.js +108 -41
- package/lib/examples/index.d.ts +10 -6
- package/lib/examples/index.js +10 -6
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +257 -27
- package/lib/examples/utils/a2ui.d.ts +18 -0
- package/lib/examples/utils/a2ui.js +69 -0
- package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
- package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
- package/lib/examples/utils/agentId.d.ts +18 -0
- package/lib/examples/utils/agentId.js +54 -0
- package/lib/examples/utils/agents/earthquake-detector.json +11 -11
- package/lib/examples/utils/agents/sales-forecaster.json +11 -11
- package/lib/examples/utils/agents/social-post-generator.json +11 -11
- package/lib/examples/utils/agents/stock-market.json +11 -11
- package/lib/examples/utils/examplesStore.js +82 -27
- package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- package/lib/hooks/index.d.ts +8 -8
- package/lib/hooks/index.js +7 -7
- package/lib/hooks/useA2A.d.ts +2 -3
- package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
- package/lib/hooks/useAIAgentsWebSocket.js +153 -12
- package/lib/hooks/useAcp.d.ts +1 -2
- package/lib/hooks/useAgUi.d.ts +1 -1
- package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +70 -4
- package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
- package/lib/hooks/useAgentsCatalog.js +1 -1
- package/lib/hooks/useAgentsService.d.ts +2 -2
- package/lib/hooks/useAgentsService.js +7 -7
- package/lib/hooks/useCheckpoints.js +1 -1
- package/lib/hooks/useConfig.d.ts +4 -1
- package/lib/hooks/useConfig.js +10 -3
- package/lib/hooks/useContextSnapshot.d.ts +9 -4
- package/lib/hooks/useContextSnapshot.js +9 -37
- package/lib/hooks/useMonitoring.js +3 -0
- package/lib/hooks/useSandbox.d.ts +20 -8
- package/lib/hooks/useSandbox.js +105 -40
- package/lib/hooks/useSkills.d.ts +23 -5
- package/lib/hooks/useSkills.js +94 -39
- package/lib/hooks/useToolApprovals.d.ts +60 -36
- package/lib/hooks/useToolApprovals.js +318 -69
- package/lib/hooks/useVercelAI.d.ts +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/inference/index.d.ts +0 -1
- package/lib/middleware/index.d.ts +0 -1
- package/lib/protocols/AGUIAdapter.js +6 -0
- package/lib/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/protocols/VercelAIAdapter.js +59 -7
- package/lib/specs/agents/agents.d.ts +21 -4
- package/lib/specs/agents/agents.js +2879 -316
- package/lib/specs/agents/index.js +3 -1
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.js +27 -20
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- package/lib/specs/events.d.ts +3 -10
- package/lib/specs/events.js +127 -84
- package/lib/specs/frontendTools.js +2 -2
- package/lib/specs/guardrails.d.ts +0 -7
- package/lib/specs/guardrails.js +240 -159
- package/lib/specs/mcpServers.js +35 -6
- package/lib/specs/memory.d.ts +0 -2
- package/lib/specs/memory.js +4 -17
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +20 -15
- package/lib/specs/notifications.js +102 -18
- package/lib/specs/outputs.js +15 -9
- package/lib/specs/personas.d.ts +41 -0
- package/lib/specs/personas.js +168 -0
- package/lib/specs/skills.d.ts +1 -1
- package/lib/specs/skills.js +23 -23
- package/lib/specs/teams/index.js +3 -1
- package/lib/specs/teams/teams.js +468 -348
- package/lib/specs/tools.js +4 -4
- package/lib/specs/triggers.js +61 -11
- package/lib/stores/agentRuntimeStore.d.ts +208 -0
- package/lib/stores/agentRuntimeStore.js +650 -0
- package/lib/stores/conversationStore.js +2 -2
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
- package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
- package/lib/tools/index.d.ts +0 -2
- package/lib/tools/index.js +0 -1
- package/lib/types/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +54 -1
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +325 -8
- package/lib/types/context.d.ts +27 -0
- package/lib/types/cost.d.ts +2 -2
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.js +3 -0
- package/lib/types/mcp.d.ts +8 -0
- package/lib/types/models.d.ts +2 -2
- package/lib/types/personas.d.ts +25 -0
- package/lib/types/personas.js +5 -0
- package/lib/types/skills.d.ts +43 -1
- package/lib/types/stream.d.ts +110 -0
- package/lib/types/stream.js +36 -0
- package/lib/utils/utils.d.ts +9 -5
- package/lib/utils/utils.js +9 -5
- package/package.json +19 -11
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +187 -45
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +35 -14
- package/scripts/codegen/generate_personas.py +319 -0
- package/scripts/codegen/generate_skills.py +9 -9
- package/scripts/sync-jupyter.sh +26 -7
- package/lib/api/tool-approvals.d.ts +0 -62
- package/lib/api/tool-approvals.js +0 -145
- package/lib/examples/AgentspecExample.js +0 -705
- package/lib/examples/LexicalSidebarExample.js +0 -163
- package/lib/examples/NotebookSidebarExample.js +0 -119
- package/lib/examples/NotebookSimpleExample.d.ts +0 -6
- package/lib/examples/NotebookSimpleExample.js +0 -22
- package/lib/examples/ag-ui/index.d.ts +0 -10
- package/lib/examples/ag-ui/index.js +0 -16
- package/lib/hooks/useAgentsRegistry.d.ts +0 -10
- package/lib/hooks/useAgentsRegistry.js +0 -20
- package/lib/stores/agentsStore.d.ts +0 -123
- package/lib/stores/agentsStore.js +0 -270
- /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
|
@@ -6,18 +6,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
6
6
|
*/
|
|
7
7
|
import { Box, Text, Spinner, Button } from '@primer/react';
|
|
8
8
|
import { ListUnorderedIcon } from '@primer/octicons-react';
|
|
9
|
-
import { useQuery } from '@tanstack/react-query';
|
|
10
9
|
import ReactECharts from 'echarts-for-react';
|
|
11
10
|
import { useState } from 'react';
|
|
12
|
-
function getLocalApiBase() {
|
|
13
|
-
if (typeof window === 'undefined') {
|
|
14
|
-
return '';
|
|
15
|
-
}
|
|
16
|
-
const host = window.location.hostname;
|
|
17
|
-
return host === 'localhost' || host === '127.0.0.1'
|
|
18
|
-
? 'http://127.0.0.1:8765'
|
|
19
|
-
: '';
|
|
20
|
-
}
|
|
21
11
|
/**
|
|
22
12
|
* Format token count for display
|
|
23
13
|
*/
|
|
@@ -33,23 +23,14 @@ function formatTokens(tokens) {
|
|
|
33
23
|
/**
|
|
34
24
|
* ContextDistribution component displays context distribution as a treemap.
|
|
35
25
|
*/
|
|
36
|
-
export function ContextDistribution({ agentId, height = '250px', }) {
|
|
26
|
+
export function ContextDistribution({ agentId, height = '250px', liveData, }) {
|
|
37
27
|
const [showDetails, setShowDetails] = useState(false);
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new Error('Failed to fetch context snapshot');
|
|
45
|
-
}
|
|
46
|
-
return response.json();
|
|
47
|
-
},
|
|
48
|
-
refetchInterval: 10000, // Refresh every 10 seconds
|
|
49
|
-
refetchOnMount: 'always',
|
|
50
|
-
staleTime: 0,
|
|
51
|
-
});
|
|
52
|
-
if (isLoading) {
|
|
28
|
+
const hasLiveData = liveData !== undefined;
|
|
29
|
+
// REST polling removed — data comes exclusively via WS `agent.snapshot`.
|
|
30
|
+
const snapshotData = liveData;
|
|
31
|
+
const showLoading = !hasLiveData;
|
|
32
|
+
const hasError = false;
|
|
33
|
+
if (showLoading) {
|
|
53
34
|
return (_jsxs(Box, { sx: {
|
|
54
35
|
p: 3,
|
|
55
36
|
display: 'flex',
|
|
@@ -58,7 +39,7 @@ export function ContextDistribution({ agentId, height = '250px', }) {
|
|
|
58
39
|
height,
|
|
59
40
|
}, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { ml: 2, fontSize: 1, color: 'fg.muted' }, children: "Loading context distribution..." })] }));
|
|
60
41
|
}
|
|
61
|
-
if (
|
|
42
|
+
if (hasError || !snapshotData) {
|
|
62
43
|
return (_jsx(Box, { sx: {
|
|
63
44
|
p: 3,
|
|
64
45
|
bg: 'canvas.subtle',
|
|
@@ -73,9 +73,11 @@ export interface ContextInspectorProps {
|
|
|
73
73
|
agentId: string;
|
|
74
74
|
/** API base URL for fetching context data */
|
|
75
75
|
apiBase?: string;
|
|
76
|
+
/** Live full-context data from WS — bypasses REST polling when provided */
|
|
77
|
+
liveData?: FullContextResponse | null;
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
80
|
* ContextInspector component displays full detailed context snapshot.
|
|
79
81
|
*/
|
|
80
|
-
export declare function ContextInspector({ agentId, apiBase }: ContextInspectorProps): import("react/jsx-runtime").JSX.Element;
|
|
82
|
+
export declare function ContextInspector({ agentId, apiBase, liveData, }: ContextInspectorProps): import("react/jsx-runtime").JSX.Element;
|
|
81
83
|
export default ContextInspector;
|
|
@@ -5,29 +5,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
5
5
|
* ContextInspector component - Shows detailed context snapshot with full tool schemas,
|
|
6
6
|
* message history with in_context flags, and model configuration.
|
|
7
7
|
*/
|
|
8
|
-
import { Text,
|
|
8
|
+
import { Text, Button, Label, ProgressBar } from '@primer/react';
|
|
9
9
|
import { Box } from '@datalayer/primer-addons';
|
|
10
10
|
import { AiModelIcon, TerminalIcon, CommentDiscussionIcon, DatabaseIcon, KeyIcon, CodeIcon, CheckCircleIcon, XCircleIcon, ChevronDownIcon, ChevronRightIcon, InfoIcon, } from '@primer/octicons-react';
|
|
11
|
-
import {
|
|
12
|
-
import React, { useState, useMemo, useEffect } from 'react';
|
|
13
|
-
const RETRY_INTERVAL_SECONDS = 5;
|
|
11
|
+
import React, { useState, useMemo } from 'react';
|
|
14
12
|
/**
|
|
15
13
|
* Get the API base URL for fetching context data.
|
|
16
14
|
* If apiBase prop is provided, use it.
|
|
17
15
|
* Otherwise, fall back to localhost for local development.
|
|
18
16
|
*/
|
|
19
|
-
function getApiBase(apiBase) {
|
|
20
|
-
if (apiBase) {
|
|
21
|
-
return apiBase;
|
|
22
|
-
}
|
|
23
|
-
if (typeof window === 'undefined') {
|
|
24
|
-
return '';
|
|
25
|
-
}
|
|
26
|
-
const host = window.location.hostname;
|
|
27
|
-
return host === 'localhost' || host === '127.0.0.1'
|
|
28
|
-
? 'http://127.0.0.1:8765'
|
|
29
|
-
: '';
|
|
30
|
-
}
|
|
31
17
|
/**
|
|
32
18
|
* Format token count for display
|
|
33
19
|
*/
|
|
@@ -143,34 +129,10 @@ function MessageDetailView({ message }) {
|
|
|
143
129
|
/**
|
|
144
130
|
* ContextInspector component displays full detailed context snapshot.
|
|
145
131
|
*/
|
|
146
|
-
export function ContextInspector({ agentId, apiBase }) {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
queryFn: async () => {
|
|
151
|
-
const base = getApiBase(apiBase);
|
|
152
|
-
const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/full-context`);
|
|
153
|
-
if (!response.ok) {
|
|
154
|
-
throw new Error('Failed to fetch full context');
|
|
155
|
-
}
|
|
156
|
-
return response.json();
|
|
157
|
-
},
|
|
158
|
-
refetchInterval: RETRY_INTERVAL_SECONDS * 1000,
|
|
159
|
-
refetchOnMount: 'always',
|
|
160
|
-
staleTime: 0,
|
|
161
|
-
});
|
|
162
|
-
const hasRetryError = Boolean(error) || Boolean(contextData?.error);
|
|
163
|
-
useEffect(() => {
|
|
164
|
-
if (!hasRetryError) {
|
|
165
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
169
|
-
const timer = window.setInterval(() => {
|
|
170
|
-
setRetryCountdown(prev => prev <= 1 ? RETRY_INTERVAL_SECONDS : prev - 1);
|
|
171
|
-
}, 1000);
|
|
172
|
-
return () => window.clearInterval(timer);
|
|
173
|
-
}, [hasRetryError]);
|
|
132
|
+
export function ContextInspector({ agentId, apiBase, liveData, }) {
|
|
133
|
+
const hasLiveData = liveData !== undefined;
|
|
134
|
+
// REST polling removed — data comes exclusively via WS `agent.snapshot`.
|
|
135
|
+
const contextData = liveData;
|
|
174
136
|
// Separate messages by in_context status
|
|
175
137
|
const { inContextMessages, outOfContextMessages } = useMemo(() => {
|
|
176
138
|
if (!contextData?.messages) {
|
|
@@ -181,30 +143,28 @@ export function ContextInspector({ agentId, apiBase }) {
|
|
|
181
143
|
outOfContextMessages: contextData.messages.filter(m => !m.inContext),
|
|
182
144
|
};
|
|
183
145
|
}, [contextData?.messages]);
|
|
184
|
-
|
|
185
|
-
|
|
146
|
+
const messageHistoryTokens = useMemo(() => {
|
|
147
|
+
if (!contextData?.messages) {
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
return contextData.messages.reduce((sum, message) => sum + (message.estimatedTokens || 0), 0);
|
|
151
|
+
}, [contextData?.messages]);
|
|
152
|
+
if (!hasLiveData) {
|
|
153
|
+
return (_jsx(Box, { sx: {
|
|
186
154
|
p: 3,
|
|
187
155
|
display: 'flex',
|
|
188
156
|
alignItems: 'center',
|
|
189
157
|
justifyContent: 'center',
|
|
190
|
-
}, children:
|
|
158
|
+
}, children: _jsx(Text, { sx: { color: 'fg.muted' }, children: "Waiting for context data from WebSocket stream..." }) }));
|
|
191
159
|
}
|
|
192
|
-
if (
|
|
160
|
+
if (!contextData) {
|
|
193
161
|
return (_jsx(Box, { sx: {
|
|
194
162
|
p: 3,
|
|
195
163
|
bg: 'attention.subtle',
|
|
196
164
|
borderRadius: 2,
|
|
197
165
|
border: '1px solid',
|
|
198
166
|
borderColor: 'attention.muted',
|
|
199
|
-
}, children:
|
|
200
|
-
display: 'flex',
|
|
201
|
-
alignItems: 'center',
|
|
202
|
-
justifyContent: 'space-between',
|
|
203
|
-
gap: 2,
|
|
204
|
-
}, children: [_jsxs(Text, { sx: { color: 'attention.fg' }, children: ["Service not available for context snapshot. Retrying in", ' ', retryCountdown, " second", retryCountdown === 1 ? '' : 's', "..."] }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
|
|
205
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
206
|
-
void refetch();
|
|
207
|
-
}, children: "Retry now" })] }) }));
|
|
167
|
+
}, children: _jsx(Text, { sx: { color: 'attention.fg' }, children: "No context data available." }) }));
|
|
208
168
|
}
|
|
209
169
|
if (contextData.error) {
|
|
210
170
|
return (_jsx(Box, { sx: {
|
|
@@ -213,15 +173,7 @@ export function ContextInspector({ agentId, apiBase }) {
|
|
|
213
173
|
borderRadius: 2,
|
|
214
174
|
border: '1px solid',
|
|
215
175
|
borderColor: 'attention.muted',
|
|
216
|
-
}, children:
|
|
217
|
-
display: 'flex',
|
|
218
|
-
alignItems: 'center',
|
|
219
|
-
justifyContent: 'space-between',
|
|
220
|
-
gap: 2,
|
|
221
|
-
}, children: [_jsx(Text, { sx: { color: 'attention.fg' }, children: `${contextData.error} Retrying in ${retryCountdown} second${retryCountdown === 1 ? '' : 's'}...` }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
|
|
222
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
223
|
-
void refetch();
|
|
224
|
-
}, children: "Retry now" })] }) }));
|
|
176
|
+
}, children: _jsx(Text, { sx: { color: 'attention.fg' }, children: contextData.error }) }));
|
|
225
177
|
}
|
|
226
178
|
const { tokenSummary, modelConfiguration } = contextData;
|
|
227
179
|
return (_jsxs(Box, { children: [_jsxs(Box, { sx: { mb: 3 }, children: [_jsxs(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: ["Total usage: ", formatTokens(tokenSummary.total), " /", ' ', formatTokens(tokenSummary.contextWindow), " (", Math.round(tokenSummary.usagePercent), "%)"] }), _jsx(ProgressBar, { progress: Math.min(tokenSummary.usagePercent, 100), sx: { mt: 2, height: 8 }, bg: tokenSummary.usagePercent > 90
|
|
@@ -258,7 +210,7 @@ export function ContextInspector({ agentId, apiBase }) {
|
|
|
258
210
|
wordBreak: 'break-word',
|
|
259
211
|
maxHeight: 200,
|
|
260
212
|
overflow: 'auto',
|
|
261
|
-
}, children: prompt.content })] }, idx)))) }), _jsx(CollapsibleSection, { title: "
|
|
213
|
+
}, children: prompt.content })] }, idx)))) }), _jsx(CollapsibleSection, { title: "Tool Definitions", icon: TerminalIcon, count: contextData.tools.length, tokens: contextData.toolTokens, children: contextData.tools.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No tools configured" })) : (contextData.tools.map((tool, idx) => (_jsx(ToolDetailView, { tool: tool }, idx)))) }), _jsx(CollapsibleSection, { title: "Message History", icon: CommentDiscussionIcon, count: contextData.messages.length, tokens: messageHistoryTokens, children: contextData.messages.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No messages yet" })) : (_jsxs(_Fragment, { children: [outOfContextMessages.length > 0 && (_jsxs(Box, { sx: { mb: 3 }, children: [_jsxs(Text, { sx: {
|
|
262
214
|
fontWeight: 'semibold',
|
|
263
215
|
fontSize: 1,
|
|
264
216
|
color: 'fg.muted',
|
|
@@ -98,6 +98,8 @@ export interface ContextPanelProps {
|
|
|
98
98
|
agentId: string;
|
|
99
99
|
/** API base URL for fetching context data */
|
|
100
100
|
apiBase?: string;
|
|
101
|
+
/** Live context snapshot pushed by websocket; skips internal polling when provided */
|
|
102
|
+
liveData?: ContextSnapshotResponse | null;
|
|
101
103
|
/** Number of messages in conversation (from chat store) */
|
|
102
104
|
messageCount?: number;
|
|
103
105
|
/** Default view mode */
|
|
@@ -108,5 +110,5 @@ export interface ContextPanelProps {
|
|
|
108
110
|
/**
|
|
109
111
|
* ContextPanel component - unified context usage display.
|
|
110
112
|
*/
|
|
111
|
-
export declare function ContextPanel({ agentId, apiBase, messageCount, defaultView, chartHeight, }: ContextPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
113
|
+
export declare function ContextPanel({ agentId, apiBase, liveData, messageCount, defaultView, chartHeight, }: ContextPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
112
114
|
export default ContextPanel;
|
|
@@ -7,12 +7,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* - Token distribution treemap
|
|
8
8
|
* - Historic usage time-series chart
|
|
9
9
|
*/
|
|
10
|
-
import { CommentDiscussionIcon, DatabaseIcon, FileIcon, ToolsIcon, ClockIcon, GraphIcon, ListUnorderedIcon, } from '@primer/octicons-react';
|
|
10
|
+
import { CommentDiscussionIcon, DatabaseIcon, FileIcon, ToolsIcon, ClockIcon, GraphIcon, AppsIcon, ListUnorderedIcon, DownloadIcon, } from '@primer/octicons-react';
|
|
11
11
|
import { Heading, Text, ProgressBar, Spinner, Button, SegmentedControl, } from '@primer/react';
|
|
12
12
|
import { Box } from '@datalayer/primer-addons';
|
|
13
|
-
import { useQuery } from '@tanstack/react-query';
|
|
14
13
|
import ReactECharts from 'echarts-for-react';
|
|
15
|
-
import { useState, useMemo
|
|
14
|
+
import { useState, useMemo } from 'react';
|
|
16
15
|
/**
|
|
17
16
|
* Format token count for display
|
|
18
17
|
*/
|
|
@@ -29,8 +28,11 @@ function formatTokens(tokens) {
|
|
|
29
28
|
* Format duration
|
|
30
29
|
*/
|
|
31
30
|
function formatDuration(seconds) {
|
|
31
|
+
if (!Number.isFinite(seconds) || Number.isNaN(seconds) || seconds < 0) {
|
|
32
|
+
return '0ms';
|
|
33
|
+
}
|
|
32
34
|
if (seconds < 1) {
|
|
33
|
-
return `${Math.round(seconds * 1000)}ms`;
|
|
35
|
+
return `${Math.max(0, Math.round(seconds * 1000))}ms`;
|
|
34
36
|
}
|
|
35
37
|
if (seconds < 60) {
|
|
36
38
|
return `${seconds.toFixed(1)}s`;
|
|
@@ -39,6 +41,89 @@ function formatDuration(seconds) {
|
|
|
39
41
|
const secs = Math.round(seconds % 60);
|
|
40
42
|
return `${minutes}m ${secs}s`;
|
|
41
43
|
}
|
|
44
|
+
function csvCell(value) {
|
|
45
|
+
const text = String(value ?? '');
|
|
46
|
+
if (/[",\n]/.test(text)) {
|
|
47
|
+
return `"${text.replace(/"/g, '""')}"`;
|
|
48
|
+
}
|
|
49
|
+
return text;
|
|
50
|
+
}
|
|
51
|
+
function downloadContextUsageAsCSV(data) {
|
|
52
|
+
const rows = [];
|
|
53
|
+
rows.push(['Context Usage Snapshot for Agent', data.agentId]);
|
|
54
|
+
rows.push(['Generated At', new Date().toISOString()]);
|
|
55
|
+
rows.push([]);
|
|
56
|
+
rows.push(['Summary']);
|
|
57
|
+
rows.push(['Total Tokens', data.totalTokens]);
|
|
58
|
+
rows.push(['Context Window', data.contextWindow]);
|
|
59
|
+
rows.push(['System Prompt Tokens', data.systemPromptTokens]);
|
|
60
|
+
rows.push(['Tool Tokens', data.toolTokens]);
|
|
61
|
+
rows.push(['History Tokens', data.historyTokens]);
|
|
62
|
+
rows.push(['Current Message Tokens', data.currentMessageTokens]);
|
|
63
|
+
rows.push(['User Message Tokens', data.userMessageTokens]);
|
|
64
|
+
rows.push(['Assistant Message Tokens', data.assistantMessageTokens]);
|
|
65
|
+
rows.push([]);
|
|
66
|
+
if (data.sessionUsage) {
|
|
67
|
+
rows.push(['Session Usage']);
|
|
68
|
+
rows.push(['Input Tokens', data.sessionUsage.inputTokens]);
|
|
69
|
+
rows.push(['Output Tokens', data.sessionUsage.outputTokens]);
|
|
70
|
+
rows.push(['Requests', data.sessionUsage.requests]);
|
|
71
|
+
rows.push(['Tool Calls', data.sessionUsage.toolCalls]);
|
|
72
|
+
rows.push(['Turns', data.sessionUsage.turns]);
|
|
73
|
+
rows.push(['Duration Seconds', data.sessionUsage.durationSeconds]);
|
|
74
|
+
rows.push([]);
|
|
75
|
+
}
|
|
76
|
+
if (data.turnUsage) {
|
|
77
|
+
rows.push(['Last Turn Usage']);
|
|
78
|
+
rows.push(['Input Tokens', data.turnUsage.inputTokens]);
|
|
79
|
+
rows.push(['Output Tokens', data.turnUsage.outputTokens]);
|
|
80
|
+
rows.push(['Requests', data.turnUsage.requests]);
|
|
81
|
+
rows.push(['Tool Calls', data.turnUsage.toolCalls]);
|
|
82
|
+
rows.push(['Duration Seconds', data.turnUsage.durationSeconds]);
|
|
83
|
+
rows.push([]);
|
|
84
|
+
}
|
|
85
|
+
rows.push(['Distribution']);
|
|
86
|
+
rows.push(['Category', 'Tokens']);
|
|
87
|
+
for (const category of data.distribution?.children ?? []) {
|
|
88
|
+
rows.push([category.name, category.value]);
|
|
89
|
+
}
|
|
90
|
+
rows.push([]);
|
|
91
|
+
if (data.perRequestUsage.length > 0) {
|
|
92
|
+
rows.push(['Per Request Usage']);
|
|
93
|
+
rows.push([
|
|
94
|
+
'Request #',
|
|
95
|
+
'Input Tokens',
|
|
96
|
+
'Output Tokens',
|
|
97
|
+
'Duration Ms',
|
|
98
|
+
'Tool Names',
|
|
99
|
+
'Timestamp',
|
|
100
|
+
'Turn ID',
|
|
101
|
+
]);
|
|
102
|
+
for (const request of data.perRequestUsage) {
|
|
103
|
+
rows.push([
|
|
104
|
+
request.requestNum,
|
|
105
|
+
request.inputTokens,
|
|
106
|
+
request.outputTokens,
|
|
107
|
+
request.durationMs,
|
|
108
|
+
request.toolNames.join('; '),
|
|
109
|
+
request.timestamp ?? '',
|
|
110
|
+
request.turnId ?? '',
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const csv = rows.map(row => row.map(csvCell).join(',')).join('\n');
|
|
115
|
+
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
|
116
|
+
const url = URL.createObjectURL(blob);
|
|
117
|
+
const link = document.createElement('a');
|
|
118
|
+
link.href = url;
|
|
119
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
120
|
+
link.download = `context-usage-${data.agentId}-${ts}.csv`;
|
|
121
|
+
link.style.display = 'none';
|
|
122
|
+
document.body.appendChild(link);
|
|
123
|
+
link.click();
|
|
124
|
+
document.body.removeChild(link);
|
|
125
|
+
URL.revokeObjectURL(url);
|
|
126
|
+
}
|
|
42
127
|
/**
|
|
43
128
|
* Get icon for context category
|
|
44
129
|
*/
|
|
@@ -59,56 +144,17 @@ function getCategoryIcon(name) {
|
|
|
59
144
|
return ClockIcon;
|
|
60
145
|
}
|
|
61
146
|
}
|
|
62
|
-
const RETRY_INTERVAL_SECONDS = 5;
|
|
63
|
-
/**
|
|
64
|
-
* Get the API base URL for fetching context data.
|
|
65
|
-
* If apiBase prop is provided, use it.
|
|
66
|
-
* Otherwise, fall back to localhost for local development.
|
|
67
|
-
*/
|
|
68
|
-
function getApiBase(apiBase) {
|
|
69
|
-
if (apiBase) {
|
|
70
|
-
return apiBase;
|
|
71
|
-
}
|
|
72
|
-
if (typeof window === 'undefined') {
|
|
73
|
-
return '';
|
|
74
|
-
}
|
|
75
|
-
const host = window.location.hostname;
|
|
76
|
-
return host === 'localhost' || host === '127.0.0.1'
|
|
77
|
-
? 'http://127.0.0.1:8765'
|
|
78
|
-
: '';
|
|
79
|
-
}
|
|
80
147
|
/**
|
|
81
148
|
* ContextPanel component - unified context usage display.
|
|
82
149
|
*/
|
|
83
|
-
export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView = 'overview', chartHeight = '200px', }) {
|
|
150
|
+
export function ContextPanel({ agentId, apiBase, liveData, messageCount = 0, defaultView = 'overview', chartHeight = '200px', }) {
|
|
84
151
|
const [viewMode, setViewMode] = useState(defaultView);
|
|
85
152
|
const [showDetails, setShowDetails] = useState(false);
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/context-snapshot`);
|
|
92
|
-
if (!response.ok) {
|
|
93
|
-
throw new Error('Failed to fetch context snapshot');
|
|
94
|
-
}
|
|
95
|
-
return response.json();
|
|
96
|
-
},
|
|
97
|
-
refetchInterval: RETRY_INTERVAL_SECONDS * 1000,
|
|
98
|
-
refetchOnMount: 'always',
|
|
99
|
-
staleTime: 0,
|
|
100
|
-
});
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
if (!error) {
|
|
103
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
107
|
-
const timer = window.setInterval(() => {
|
|
108
|
-
setRetryCountdown(prev => prev <= 1 ? RETRY_INTERVAL_SECONDS : prev - 1);
|
|
109
|
-
}, 1000);
|
|
110
|
-
return () => window.clearInterval(timer);
|
|
111
|
-
}, [error]);
|
|
153
|
+
const hasLiveData = liveData !== undefined;
|
|
154
|
+
// REST polling removed — data comes exclusively via WS `agent.snapshot`.
|
|
155
|
+
const snapshotData = liveData;
|
|
156
|
+
const showLoading = !hasLiveData;
|
|
157
|
+
const hasError = false;
|
|
112
158
|
// Build historic usage chart data from perRequestUsage
|
|
113
159
|
const historyChartOption = useMemo(() => {
|
|
114
160
|
if (!snapshotData?.perRequestUsage ||
|
|
@@ -251,7 +297,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
251
297
|
};
|
|
252
298
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
253
299
|
}, [snapshotData?.distribution]);
|
|
254
|
-
if (
|
|
300
|
+
if (showLoading) {
|
|
255
301
|
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
|
|
256
302
|
fontSize: 1,
|
|
257
303
|
fontWeight: 'semibold',
|
|
@@ -268,7 +314,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
268
314
|
gap: 2,
|
|
269
315
|
}, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading context details..." })] })] }));
|
|
270
316
|
}
|
|
271
|
-
if (
|
|
317
|
+
if (hasError || !snapshotData) {
|
|
272
318
|
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
|
|
273
319
|
fontSize: 1,
|
|
274
320
|
fontWeight: 'semibold',
|
|
@@ -280,19 +326,13 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
280
326
|
borderRadius: 2,
|
|
281
327
|
border: '1px solid',
|
|
282
328
|
borderColor: 'attention.muted',
|
|
283
|
-
}, children:
|
|
284
|
-
display: 'flex',
|
|
285
|
-
alignItems: 'center',
|
|
286
|
-
justifyContent: 'space-between',
|
|
287
|
-
gap: 2,
|
|
288
|
-
}, children: [_jsxs(Text, { sx: { fontSize: 1, color: 'attention.fg' }, children: ["Service not available for context usage. Retrying in", ' ', retryCountdown, " second", retryCountdown === 1 ? '' : 's', "..."] }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => {
|
|
289
|
-
setRetryCountdown(RETRY_INTERVAL_SECONDS);
|
|
290
|
-
void refetch();
|
|
291
|
-
}, children: "Retry now" })] }) })] }));
|
|
329
|
+
}, children: _jsx(Text, { sx: { fontSize: 1, color: 'attention.fg' }, children: "Waiting for context data from WebSocket stream..." }) })] }));
|
|
292
330
|
}
|
|
293
331
|
const { totalTokens, contextWindow, sessionUsage, turnUsage, distribution } = snapshotData;
|
|
332
|
+
const sentMessageCount = messageCount > 0
|
|
333
|
+
? messageCount
|
|
334
|
+
: Math.max(sessionUsage?.turns ?? 0, snapshotData.perRequestUsage?.length > 0 ? 1 : 0);
|
|
294
335
|
const hasDistributionData = distribution?.children && distribution.children.length > 0;
|
|
295
|
-
const hasHistoryData = snapshotData.perRequestUsage && snapshotData.perRequestUsage.length > 0;
|
|
296
336
|
return (_jsxs(Box, { children: [_jsxs(Box, { sx: {
|
|
297
337
|
display: 'flex',
|
|
298
338
|
justifyContent: 'space-between',
|
|
@@ -302,7 +342,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
302
342
|
fontSize: 1,
|
|
303
343
|
fontWeight: 'semibold',
|
|
304
344
|
color: 'fg.muted',
|
|
305
|
-
}, children: "Context Usage" }),
|
|
345
|
+
}, children: "Context Usage" }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [sentMessageCount > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [sentMessageCount, ' ', sentMessageCount === 1 ? 'message sent' : 'messages sent'] })), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => downloadContextUsageAsCSV(snapshotData), children: "Download" })] })] }), _jsxs(Box, { sx: {
|
|
306
346
|
p: 3,
|
|
307
347
|
bg: 'canvas.subtle',
|
|
308
348
|
borderRadius: 2,
|
|
@@ -337,7 +377,7 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
337
377
|
}, children: [_jsxs(SegmentedControl, { "aria-label": "View mode", size: "small", onChange: index => {
|
|
338
378
|
const modes = ['overview', 'distribution', 'history'];
|
|
339
379
|
setViewMode(modes[index]);
|
|
340
|
-
}, children: [_jsx(SegmentedControl.
|
|
380
|
+
}, children: [_jsx(SegmentedControl.IconButton, { "aria-label": "Overview", selected: viewMode === 'overview', icon: ListUnorderedIcon }), _jsx(SegmentedControl.IconButton, { "aria-label": "Distribution", selected: viewMode === 'distribution', icon: AppsIcon, disabled: !hasDistributionData }), _jsx(SegmentedControl.IconButton, { "aria-label": "History", selected: viewMode === 'history', icon: GraphIcon })] }), viewMode === 'overview' && (_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowDetails(!showDetails), children: showDetails ? 'Less' : 'More' }))] }), viewMode === 'overview' && (_jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [hasDistributionData &&
|
|
341
381
|
distribution.children.map(category => {
|
|
342
382
|
const CategoryIcon = getCategoryIcon(category.name);
|
|
343
383
|
const categoryPercent = (category.value / contextWindow) * 100;
|
|
@@ -384,6 +424,6 @@ export function ContextPanel({ agentId, apiBase, messageCount = 0, defaultView =
|
|
|
384
424
|
py: 1,
|
|
385
425
|
borderBottom: idx < 9 ? '1px solid' : 'none',
|
|
386
426
|
borderColor: 'border.muted',
|
|
387
|
-
}, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', minWidth: 30 }, children: ["#", req.requestNum] }), _jsxs(Text, { sx: { color: '#3B82F6' }, children: ["\u2193", formatTokens(req.inputTokens)] }), _jsxs(Text, { sx: { color: '#10B981' }, children: ["\u2191", formatTokens(req.outputTokens)] }), req.toolNames.length > 0 && (_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["\uD83D\uDD27 ", req.toolNames.join(', ')] }))] }, req.requestNum))) }))] }))] })] }));
|
|
427
|
+
}, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', minWidth: 30 }, children: ["#", req.requestNum] }), _jsxs(Text, { sx: { color: '#3B82F6' }, children: ["\u2193", formatTokens(req.inputTokens)] }), _jsxs(Text, { sx: { color: '#10B981' }, children: ["\u2191", formatTokens(req.outputTokens)] }), req.toolNames.length > 0 && (_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["\uD83D\uDD27 ", req.toolNames.join(', ')] }))] }, req.requestNum))) }))] })), viewMode === 'history' && !historyChartOption && (_jsx(Box, { sx: { py: 3 }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No history" }) }))] })] }));
|
|
388
428
|
}
|
|
389
429
|
export default ContextPanel;
|
|
@@ -25,9 +25,11 @@ export interface ContextDetailsResponse {
|
|
|
25
25
|
export interface ContextUsageProps {
|
|
26
26
|
/** Agent ID for fetching context details (required) */
|
|
27
27
|
agentId: string;
|
|
28
|
+
/** Optional base URL override (defaults to local 8765 or same-origin) */
|
|
29
|
+
baseUrl?: string;
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* ContextUsage component displays token usage breakdown by category.
|
|
31
33
|
*/
|
|
32
|
-
export declare function ContextUsage({ agentId }: ContextUsageProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function ContextUsage({ agentId, baseUrl }: ContextUsageProps): import("react/jsx-runtime").JSX.Element;
|
|
33
35
|
export default ContextUsage;
|
|
@@ -52,11 +52,11 @@ function getCategoryIcon(name) {
|
|
|
52
52
|
/**
|
|
53
53
|
* ContextUsage component displays token usage breakdown by category.
|
|
54
54
|
*/
|
|
55
|
-
export function ContextUsage({ agentId }) {
|
|
55
|
+
export function ContextUsage({ agentId, baseUrl }) {
|
|
56
56
|
const { data: contextData, isLoading, error, } = useQuery({
|
|
57
|
-
queryKey: ['context-details', agentId],
|
|
57
|
+
queryKey: ['context-details', agentId, baseUrl],
|
|
58
58
|
queryFn: async () => {
|
|
59
|
-
const apiBase = getLocalApiBase();
|
|
59
|
+
const apiBase = baseUrl || getLocalApiBase();
|
|
60
60
|
const response = await fetch(`${apiBase}/api/v1/configure/agents/${encodeURIComponent(agentId)}/context-details`);
|
|
61
61
|
if (!response.ok) {
|
|
62
62
|
throw new Error('Failed to fetch context details');
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export interface CostUsageResponse {
|
|
5
5
|
agentId: string;
|
|
6
|
-
/** Cost for the
|
|
7
|
-
|
|
6
|
+
/** Cost for the last completed turn in USD */
|
|
7
|
+
lastTurnCostUsd: number;
|
|
8
8
|
/** Total cumulative cost in USD */
|
|
9
9
|
cumulativeCostUsd: number;
|
|
10
10
|
/** Per-run budget limit (from guardrails) */
|
|
@@ -23,15 +23,21 @@ export interface CostUsageResponse {
|
|
|
23
23
|
costUsd: number;
|
|
24
24
|
requests: number;
|
|
25
25
|
}>;
|
|
26
|
+
/** Optional run traces with pricing resolution info */
|
|
27
|
+
runs?: Array<{
|
|
28
|
+
pricingResolved: boolean;
|
|
29
|
+
}>;
|
|
26
30
|
}
|
|
27
31
|
export interface CostTrackerProps {
|
|
28
32
|
/** Agent ID for fetching cost data */
|
|
29
33
|
agentId: string;
|
|
30
34
|
/** Compact mode — show only the summary bar */
|
|
31
35
|
compact?: boolean;
|
|
36
|
+
/** Live cost data pushed by websocket (single source of truth). */
|
|
37
|
+
liveData?: CostUsageResponse | null;
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
40
|
* Displays running cost and budget utilization for an agent.
|
|
35
41
|
*/
|
|
36
|
-
export declare function CostTracker({ agentId, compact }: CostTrackerProps): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
export declare function CostTracker({ agentId: _agentId, compact, liveData, }: CostTrackerProps): import("react/jsx-runtime").JSX.Element;
|
|
37
43
|
export default CostTracker;
|