agent-relay 2.0.21 → 2.0.23
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/bin/relay-pty-linux-arm64 +0 -0
- package/dist/src/cli/index.d.ts +3 -3
- package/dist/src/cli/index.js +31 -100
- package/package.json +22 -29
- package/packages/api-types/package.json +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/cli-tester/package.json +1 -1
- package/packages/cloud/dist/server.js +25 -4
- package/packages/cloud/package.json +6 -6
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/dist/orchestrator.js +21 -1
- package/packages/daemon/dist/router.d.ts +5 -0
- package/packages/daemon/dist/router.js +31 -0
- package/packages/daemon/dist/server.d.ts +5 -0
- package/packages/daemon/dist/server.js +131 -1
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/client.d.ts +15 -0
- package/packages/mcp/dist/client.js +9 -0
- package/packages/mcp/dist/server.js +13 -1
- package/packages/mcp/dist/tools/index.d.ts +2 -0
- package/packages/mcp/dist/tools/index.js +2 -0
- package/packages/mcp/dist/tools/relay-connected.d.ts +17 -0
- package/packages/mcp/dist/tools/relay-connected.js +40 -0
- package/packages/mcp/dist/tools/relay-remove-agent.d.ts +20 -0
- package/packages/mcp/dist/tools/relay-remove-agent.js +50 -0
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +46 -1
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/client.d.ts +22 -1
- package/packages/sdk/dist/client.js +31 -0
- package/packages/sdk/dist/protocol/index.d.ts +1 -1
- package/packages/sdk/dist/protocol/types.d.ts +35 -1
- package/packages/sdk/package.json +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/dist/adapter.d.ts +4 -0
- package/packages/storage/dist/sqlite-adapter.d.ts +10 -0
- package/packages/storage/dist/sqlite-adapter.js +26 -0
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/dist/update-checker.js +4 -0
- package/packages/utils/package.json +1 -1
- package/packages/wrapper/package.json +6 -6
- package/deploy/workspace/codex.config.toml +0 -20
- package/deploy/workspace/entrypoint-browser.sh +0 -118
- package/deploy/workspace/entrypoint.sh +0 -612
- package/deploy/workspace/gh-credential-relay +0 -90
- package/deploy/workspace/gh-relay +0 -156
- package/deploy/workspace/git-credential-relay +0 -330
- package/deploy/workspace/git-credential-relay.test.sh +0 -230
- package/dist/dashboard/out/404.html +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +0 -1
- package/dist/dashboard/out/_next/static/css/6892f8422896ef7a.css +0 -1
- package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +0 -45
- package/dist/dashboard/out/alt-logos/logo.svg +0 -38
- package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo.svg +0 -38
- package/dist/dashboard/out/app/onboarding.html +0 -1
- package/dist/dashboard/out/app/onboarding.txt +0 -7
- package/dist/dashboard/out/app.html +0 -1
- package/dist/dashboard/out/app.txt +0 -7
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/cloud/link.html +0 -1
- package/dist/dashboard/out/cloud/link.txt +0 -7
- package/dist/dashboard/out/complete-profile.html +0 -5
- package/dist/dashboard/out/complete-profile.txt +0 -7
- package/dist/dashboard/out/connect-repos.html +0 -1
- package/dist/dashboard/out/connect-repos.txt +0 -7
- package/dist/dashboard/out/history.html +0 -1
- package/dist/dashboard/out/history.txt +0 -7
- package/dist/dashboard/out/index.html +0 -1
- package/dist/dashboard/out/index.txt +0 -7
- package/dist/dashboard/out/login.html +0 -5
- package/dist/dashboard/out/login.txt +0 -7
- package/dist/dashboard/out/metrics.html +0 -1
- package/dist/dashboard/out/metrics.txt +0 -7
- package/dist/dashboard/out/pricing.html +0 -13
- package/dist/dashboard/out/pricing.txt +0 -7
- package/dist/dashboard/out/providers/setup/claude.html +0 -1
- package/dist/dashboard/out/providers/setup/claude.txt +0 -8
- package/dist/dashboard/out/providers/setup/codex.html +0 -1
- package/dist/dashboard/out/providers/setup/codex.txt +0 -8
- package/dist/dashboard/out/providers/setup/cursor.html +0 -1
- package/dist/dashboard/out/providers/setup/cursor.txt +0 -8
- package/dist/dashboard/out/providers.html +0 -1
- package/dist/dashboard/out/providers.txt +0 -7
- package/dist/dashboard/out/signup.html +0 -6
- package/dist/dashboard/out/signup.txt +0 -7
- package/dist/src/dashboard-server/index.d.ts +0 -8
- package/dist/src/dashboard-server/index.js +0 -8
- package/packages/dashboard/README.md +0 -48
- package/packages/dashboard/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard/dist/health-worker-manager.js +0 -144
- package/packages/dashboard/dist/health-worker.d.ts +0 -9
- package/packages/dashboard/dist/health-worker.js +0 -79
- package/packages/dashboard/dist/index.d.ts +0 -20
- package/packages/dashboard/dist/index.js +0 -19
- package/packages/dashboard/dist/metrics.d.ts +0 -105
- package/packages/dashboard/dist/metrics.js +0 -193
- package/packages/dashboard/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard/dist/needs-attention.js +0 -78
- package/packages/dashboard/dist/server.d.ts +0 -25
- package/packages/dashboard/dist/server.js +0 -5270
- package/packages/dashboard/dist/start.d.ts +0 -6
- package/packages/dashboard/dist/start.js +0 -13
- package/packages/dashboard/dist/types/threading.d.ts +0 -8
- package/packages/dashboard/dist/types/threading.js +0 -2
- package/packages/dashboard/dist/user-bridge.d.ts +0 -154
- package/packages/dashboard/dist/user-bridge.js +0 -372
- package/packages/dashboard/package.json +0 -65
- package/packages/dashboard/ui/app/app/onboarding/page.tsx +0 -394
- package/packages/dashboard/ui/app/app/page.tsx +0 -667
- package/packages/dashboard/ui/app/apple-icon.png +0 -0
- package/packages/dashboard/ui/app/cloud/link/page.tsx +0 -464
- package/packages/dashboard/ui/app/complete-profile/page.tsx +0 -204
- package/packages/dashboard/ui/app/connect-repos/page.tsx +0 -410
- package/packages/dashboard/ui/app/favicon.png +0 -0
- package/packages/dashboard/ui/app/globals.css +0 -59
- package/packages/dashboard/ui/app/history/page.tsx +0 -658
- package/packages/dashboard/ui/app/layout.tsx +0 -25
- package/packages/dashboard/ui/app/login/page.tsx +0 -424
- package/packages/dashboard/ui/app/metrics/page.tsx +0 -751
- package/packages/dashboard/ui/app/page.tsx +0 -59
- package/packages/dashboard/ui/app/pricing/page.tsx +0 -7
- package/packages/dashboard/ui/app/providers/page.tsx +0 -193
- package/packages/dashboard/ui/app/providers/setup/[provider]/ProviderSetupClient.tsx +0 -148
- package/packages/dashboard/ui/app/providers/setup/[provider]/constants.ts +0 -35
- package/packages/dashboard/ui/app/providers/setup/[provider]/page.tsx +0 -42
- package/packages/dashboard/ui/app/signup/page.tsx +0 -533
- package/packages/dashboard/ui/index.ts +0 -49
- package/packages/dashboard/ui/landing/LandingPage.tsx +0 -713
- package/packages/dashboard/ui/landing/PricingPage.tsx +0 -559
- package/packages/dashboard/ui/landing/index.ts +0 -6
- package/packages/dashboard/ui/landing/styles.css +0 -2850
- package/packages/dashboard/ui/lib/agent-merge.ts +0 -35
- package/packages/dashboard/ui/lib/api.ts +0 -1155
- package/packages/dashboard/ui/lib/cloudApi.ts +0 -877
- package/packages/dashboard/ui/lib/colors.ts +0 -218
- package/packages/dashboard/ui/lib/hierarchy.ts +0 -242
- package/packages/dashboard/ui/lib/stuckDetection.ts +0 -142
- package/packages/dashboard/ui/next-env.d.ts +0 -5
- package/packages/dashboard/ui/next.config.js +0 -41
- package/packages/dashboard/ui/package-lock.json +0 -2882
- package/packages/dashboard/ui/package.json +0 -33
- package/packages/dashboard/ui/postcss.config.js +0 -5
- package/packages/dashboard/ui/react-components/ActivityFeed.tsx +0 -216
- package/packages/dashboard/ui/react-components/AddWorkspaceModal.tsx +0 -170
- package/packages/dashboard/ui/react-components/AgentCard.tsx +0 -587
- package/packages/dashboard/ui/react-components/AgentList.tsx +0 -411
- package/packages/dashboard/ui/react-components/AgentProfilePanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/App.tsx +0 -3033
- package/packages/dashboard/ui/react-components/BillingPanel.tsx +0 -922
- package/packages/dashboard/ui/react-components/BillingResult.tsx +0 -447
- package/packages/dashboard/ui/react-components/BroadcastComposer.tsx +0 -690
- package/packages/dashboard/ui/react-components/ChannelAdminPanel.tsx +0 -773
- package/packages/dashboard/ui/react-components/ChannelBrowser.tsx +0 -385
- package/packages/dashboard/ui/react-components/ChannelChat.tsx +0 -261
- package/packages/dashboard/ui/react-components/ChannelSidebar.tsx +0 -399
- package/packages/dashboard/ui/react-components/CloudSessionProvider.tsx +0 -130
- package/packages/dashboard/ui/react-components/CommandPalette.tsx +0 -815
- package/packages/dashboard/ui/react-components/ConfirmationDialog.tsx +0 -133
- package/packages/dashboard/ui/react-components/ConversationHistory.tsx +0 -518
- package/packages/dashboard/ui/react-components/CoordinatorPanel.tsx +0 -944
- package/packages/dashboard/ui/react-components/DecisionQueue.tsx +0 -717
- package/packages/dashboard/ui/react-components/DirectMessageView.tsx +0 -164
- package/packages/dashboard/ui/react-components/FileAutocomplete.tsx +0 -368
- package/packages/dashboard/ui/react-components/FleetOverview.tsx +0 -278
- package/packages/dashboard/ui/react-components/LogViewer.tsx +0 -310
- package/packages/dashboard/ui/react-components/LogViewerPanel.tsx +0 -482
- package/packages/dashboard/ui/react-components/Logo.tsx +0 -284
- package/packages/dashboard/ui/react-components/MentionAutocomplete.tsx +0 -384
- package/packages/dashboard/ui/react-components/MessageComposer.tsx +0 -457
- package/packages/dashboard/ui/react-components/MessageList.tsx +0 -649
- package/packages/dashboard/ui/react-components/MessageSenderName.tsx +0 -91
- package/packages/dashboard/ui/react-components/MessageStatusIndicator.tsx +0 -142
- package/packages/dashboard/ui/react-components/NewConversationModal.tsx +0 -400
- package/packages/dashboard/ui/react-components/NotificationToast.tsx +0 -488
- package/packages/dashboard/ui/react-components/OnlineUsersIndicator.tsx +0 -164
- package/packages/dashboard/ui/react-components/Pagination.tsx +0 -124
- package/packages/dashboard/ui/react-components/PricingPlans.tsx +0 -386
- package/packages/dashboard/ui/react-components/ProjectList.tsx +0 -625
- package/packages/dashboard/ui/react-components/ProviderAuthFlow.tsx +0 -853
- package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +0 -378
- package/packages/dashboard/ui/react-components/ProvisioningProgress.tsx +0 -730
- package/packages/dashboard/ui/react-components/RepoAccessPanel.tsx +0 -549
- package/packages/dashboard/ui/react-components/ServerCard.tsx +0 -202
- package/packages/dashboard/ui/react-components/SessionExpiredModal.tsx +0 -128
- package/packages/dashboard/ui/react-components/SpawnModal.tsx +0 -804
- package/packages/dashboard/ui/react-components/TaskAssignmentUI.tsx +0 -375
- package/packages/dashboard/ui/react-components/TerminalProviderSetup.tsx +0 -608
- package/packages/dashboard/ui/react-components/ThemeProvider.tsx +0 -325
- package/packages/dashboard/ui/react-components/ThinkingIndicator.tsx +0 -231
- package/packages/dashboard/ui/react-components/ThreadList.tsx +0 -198
- package/packages/dashboard/ui/react-components/ThreadPanel.tsx +0 -346
- package/packages/dashboard/ui/react-components/TrajectoryViewer.tsx +0 -698
- package/packages/dashboard/ui/react-components/TypingIndicator.tsx +0 -69
- package/packages/dashboard/ui/react-components/UsageBanner.tsx +0 -231
- package/packages/dashboard/ui/react-components/UserProfilePanel.tsx +0 -233
- package/packages/dashboard/ui/react-components/WorkspaceContext.tsx +0 -107
- package/packages/dashboard/ui/react-components/WorkspaceSelector.tsx +0 -234
- package/packages/dashboard/ui/react-components/WorkspaceStatusIndicator.tsx +0 -370
- package/packages/dashboard/ui/react-components/XTermInteractive.tsx +0 -510
- package/packages/dashboard/ui/react-components/XTermLogViewer.tsx +0 -719
- package/packages/dashboard/ui/react-components/channels/ChannelDialogs.tsx +0 -1411
- package/packages/dashboard/ui/react-components/channels/ChannelHeader.tsx +0 -317
- package/packages/dashboard/ui/react-components/channels/ChannelMessageList.tsx +0 -463
- package/packages/dashboard/ui/react-components/channels/ChannelViewV1.tsx +0 -146
- package/packages/dashboard/ui/react-components/channels/MessageInput.tsx +0 -288
- package/packages/dashboard/ui/react-components/channels/SearchInput.tsx +0 -172
- package/packages/dashboard/ui/react-components/channels/SearchResults.tsx +0 -336
- package/packages/dashboard/ui/react-components/channels/api.ts +0 -697
- package/packages/dashboard/ui/react-components/channels/index.ts +0 -76
- package/packages/dashboard/ui/react-components/channels/mockApi.ts +0 -344
- package/packages/dashboard/ui/react-components/channels/types.ts +0 -566
- package/packages/dashboard/ui/react-components/hooks/index.ts +0 -57
- package/packages/dashboard/ui/react-components/hooks/useAgentLogs.ts +0 -394
- package/packages/dashboard/ui/react-components/hooks/useAgents.ts +0 -127
- package/packages/dashboard/ui/react-components/hooks/useBroadcastDedup.ts +0 -86
- package/packages/dashboard/ui/react-components/hooks/useChannelAdmin.ts +0 -329
- package/packages/dashboard/ui/react-components/hooks/useChannelBrowser.ts +0 -239
- package/packages/dashboard/ui/react-components/hooks/useChannelCommands.ts +0 -138
- package/packages/dashboard/ui/react-components/hooks/useChannels.ts +0 -328
- package/packages/dashboard/ui/react-components/hooks/useDebounce.ts +0 -29
- package/packages/dashboard/ui/react-components/hooks/useDirectMessage.ts +0 -141
- package/packages/dashboard/ui/react-components/hooks/useMessages.ts +0 -309
- package/packages/dashboard/ui/react-components/hooks/useOrchestrator.ts +0 -364
- package/packages/dashboard/ui/react-components/hooks/usePinnedAgents.ts +0 -140
- package/packages/dashboard/ui/react-components/hooks/usePresence.ts +0 -340
- package/packages/dashboard/ui/react-components/hooks/useRecentRepos.ts +0 -130
- package/packages/dashboard/ui/react-components/hooks/useSession.ts +0 -209
- package/packages/dashboard/ui/react-components/hooks/useTrajectory.ts +0 -265
- package/packages/dashboard/ui/react-components/hooks/useWebSocket.ts +0 -169
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceMembers.ts +0 -120
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceRepos.ts +0 -73
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceStatus.ts +0 -237
- package/packages/dashboard/ui/react-components/index.ts +0 -81
- package/packages/dashboard/ui/react-components/layout/Header.tsx +0 -355
- package/packages/dashboard/ui/react-components/layout/RepoContextHeader.tsx +0 -361
- package/packages/dashboard/ui/react-components/layout/Sidebar.archive.test.tsx +0 -126
- package/packages/dashboard/ui/react-components/layout/Sidebar.test.tsx +0 -691
- package/packages/dashboard/ui/react-components/layout/Sidebar.tsx +0 -930
- package/packages/dashboard/ui/react-components/layout/index.ts +0 -7
- package/packages/dashboard/ui/react-components/settings/BillingSettingsPanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/settings/SettingsPage.tsx +0 -544
- package/packages/dashboard/ui/react-components/settings/TeamSettingsPanel.tsx +0 -560
- package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +0 -1386
- package/packages/dashboard/ui/react-components/settings/index.ts +0 -11
- package/packages/dashboard/ui/react-components/settings/types.ts +0 -53
- package/packages/dashboard/ui/react-components/utils/messageFormatting.tsx +0 -370
- package/packages/dashboard/ui/tailwind.config.js +0 -148
- package/packages/dashboard/ui/types/index.ts +0 -304
- package/packages/dashboard/ui/types/threading.ts +0 -7
- package/packages/dashboard/ui-dist/404.html +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/packages/dashboard/ui-dist/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/packages/dashboard/ui-dist/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/4034f236dd1a3178.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/6892f8422896ef7a.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo.svg +0 -45
- package/packages/dashboard/ui-dist/alt-logos/logo.svg +0 -38
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo.svg +0 -38
- package/packages/dashboard/ui-dist/app/onboarding.html +0 -1
- package/packages/dashboard/ui-dist/app/onboarding.txt +0 -7
- package/packages/dashboard/ui-dist/app.html +0 -1
- package/packages/dashboard/ui-dist/app.txt +0 -7
- package/packages/dashboard/ui-dist/apple-icon.png +0 -0
- package/packages/dashboard/ui-dist/cloud/link.html +0 -1
- package/packages/dashboard/ui-dist/cloud/link.txt +0 -7
- package/packages/dashboard/ui-dist/complete-profile.html +0 -5
- package/packages/dashboard/ui-dist/complete-profile.txt +0 -7
- package/packages/dashboard/ui-dist/connect-repos.html +0 -1
- package/packages/dashboard/ui-dist/connect-repos.txt +0 -7
- package/packages/dashboard/ui-dist/history.html +0 -1
- package/packages/dashboard/ui-dist/history.txt +0 -7
- package/packages/dashboard/ui-dist/index.html +0 -1
- package/packages/dashboard/ui-dist/index.txt +0 -7
- package/packages/dashboard/ui-dist/login.html +0 -5
- package/packages/dashboard/ui-dist/login.txt +0 -7
- package/packages/dashboard/ui-dist/metrics.html +0 -1
- package/packages/dashboard/ui-dist/metrics.txt +0 -7
- package/packages/dashboard/ui-dist/pricing.html +0 -13
- package/packages/dashboard/ui-dist/pricing.txt +0 -7
- package/packages/dashboard/ui-dist/providers/setup/claude.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/codex.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/cursor.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.txt +0 -8
- package/packages/dashboard/ui-dist/providers.html +0 -1
- package/packages/dashboard/ui-dist/providers.txt +0 -7
- package/packages/dashboard/ui-dist/signup.html +0 -6
- package/packages/dashboard/ui-dist/signup.txt +0 -7
- package/packages/dashboard-server/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard-server/dist/health-worker-manager.js +0 -144
- package/packages/dashboard-server/dist/health-worker.d.ts +0 -9
- package/packages/dashboard-server/dist/health-worker.js +0 -79
- package/packages/dashboard-server/dist/index.d.ts +0 -18
- package/packages/dashboard-server/dist/index.js +0 -17
- package/packages/dashboard-server/dist/metrics.d.ts +0 -105
- package/packages/dashboard-server/dist/metrics.js +0 -193
- package/packages/dashboard-server/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard-server/dist/needs-attention.js +0 -78
- package/packages/dashboard-server/dist/server.d.ts +0 -25
- package/packages/dashboard-server/dist/server.js +0 -5158
- package/packages/dashboard-server/dist/start.d.ts +0 -6
- package/packages/dashboard-server/dist/start.js +0 -13
- package/packages/dashboard-server/dist/types/threading.d.ts +0 -8
- package/packages/dashboard-server/dist/types/threading.js +0 -2
- package/packages/dashboard-server/dist/user-bridge.d.ts +0 -158
- package/packages/dashboard-server/dist/user-bridge.js +0 -390
- package/packages/dashboard-server/package.json +0 -55
|
@@ -1,751 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard V2 - Metrics Page
|
|
3
|
-
*
|
|
4
|
-
* System metrics view showing agent health, throughput, and session lifecycle.
|
|
5
|
-
* Refined "mission control" aesthetic with Tailwind CSS.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use client';
|
|
9
|
-
|
|
10
|
-
import React, { useState, useEffect } from 'react';
|
|
11
|
-
import Link from 'next/link';
|
|
12
|
-
import { getApiUrl, initializeWorkspaceId } from '../../lib/api';
|
|
13
|
-
|
|
14
|
-
interface AgentMetric {
|
|
15
|
-
name: string;
|
|
16
|
-
messagesSent: number;
|
|
17
|
-
messagesReceived: number;
|
|
18
|
-
firstSeen: string;
|
|
19
|
-
lastSeen: string;
|
|
20
|
-
uptimeSeconds: number;
|
|
21
|
-
isOnline: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface SessionMetric {
|
|
25
|
-
agentName: string;
|
|
26
|
-
startedAt: string;
|
|
27
|
-
endedAt?: string;
|
|
28
|
-
messageCount: number;
|
|
29
|
-
closedBy?: 'agent' | 'disconnect' | 'error';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface Metrics {
|
|
33
|
-
timestamp: string;
|
|
34
|
-
totalAgents: number;
|
|
35
|
-
onlineAgents: number;
|
|
36
|
-
offlineAgents: number;
|
|
37
|
-
totalMessages: number;
|
|
38
|
-
throughput: {
|
|
39
|
-
messagesLastMinute: number;
|
|
40
|
-
messagesLastHour: number;
|
|
41
|
-
messagesLast24Hours: number;
|
|
42
|
-
avgMessagesPerMinute: number;
|
|
43
|
-
};
|
|
44
|
-
agents: AgentMetric[];
|
|
45
|
-
sessions?: {
|
|
46
|
-
totalSessions: number;
|
|
47
|
-
activeSessions: number;
|
|
48
|
-
closedByAgent: number;
|
|
49
|
-
closedByDisconnect: number;
|
|
50
|
-
closedByError: number;
|
|
51
|
-
errorRate: number;
|
|
52
|
-
recentSessions: SessionMetric[];
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface AgentMemoryMetric {
|
|
57
|
-
name: string;
|
|
58
|
-
pid?: number;
|
|
59
|
-
status: string;
|
|
60
|
-
rssBytes?: number;
|
|
61
|
-
heapUsedBytes?: number;
|
|
62
|
-
cpuPercent?: number;
|
|
63
|
-
trend?: 'growing' | 'stable' | 'shrinking' | 'unknown';
|
|
64
|
-
trendRatePerMinute?: number;
|
|
65
|
-
alertLevel?: 'normal' | 'warning' | 'critical' | 'oom_imminent';
|
|
66
|
-
highWatermark?: number;
|
|
67
|
-
averageRss?: number;
|
|
68
|
-
uptimeMs?: number;
|
|
69
|
-
startedAt?: string;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
interface MemoryMetrics {
|
|
73
|
-
agents: AgentMemoryMetric[];
|
|
74
|
-
system: {
|
|
75
|
-
totalMemory: number;
|
|
76
|
-
freeMemory: number;
|
|
77
|
-
heapUsed: number;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const COLORS = ['#4a9eff', '#b388ff', '#ff9e40', '#00e676', '#ff5c5c', '#00ffc8'];
|
|
82
|
-
|
|
83
|
-
function getAvatarColor(name: string): string {
|
|
84
|
-
let hash = 0;
|
|
85
|
-
for (let i = 0; i < name.length; i++) {
|
|
86
|
-
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
87
|
-
}
|
|
88
|
-
return COLORS[Math.abs(hash) % COLORS.length];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function getInitials(name: string): string {
|
|
92
|
-
return name.slice(0, 2).toUpperCase();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function formatDuration(seconds: number): string {
|
|
96
|
-
if (seconds < 60) return `${seconds}s`;
|
|
97
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
98
|
-
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
|
|
99
|
-
return `${Math.floor(seconds / 86400)}d ${Math.floor((seconds % 86400) / 3600)}h`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function formatTime(isoString: string): string {
|
|
103
|
-
return new Date(isoString).toLocaleTimeString('en-US', {
|
|
104
|
-
hour: '2-digit',
|
|
105
|
-
minute: '2-digit',
|
|
106
|
-
second: '2-digit',
|
|
107
|
-
hour12: false
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default function MetricsPage() {
|
|
112
|
-
const [metrics, setMetrics] = useState<Metrics | null>(null);
|
|
113
|
-
const [memoryMetrics, setMemoryMetrics] = useState<MemoryMetrics | null>(null);
|
|
114
|
-
const [error, setError] = useState<string | null>(null);
|
|
115
|
-
const [loading, setLoading] = useState(true);
|
|
116
|
-
const [_isCloudMode, setIsCloudMode] = useState(false);
|
|
117
|
-
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
// Initialize workspace ID from localStorage for cloud mode
|
|
120
|
-
const workspaceId = initializeWorkspaceId();
|
|
121
|
-
|
|
122
|
-
// Check if we're in cloud mode by checking for session endpoint
|
|
123
|
-
const checkCloudMode = async () => {
|
|
124
|
-
try {
|
|
125
|
-
const res = await fetch('/api/auth/session', { credentials: 'include' });
|
|
126
|
-
if (res.status !== 404) {
|
|
127
|
-
setIsCloudMode(true);
|
|
128
|
-
// In cloud mode without workspace, redirect to app to select one
|
|
129
|
-
if (!workspaceId) {
|
|
130
|
-
window.location.href = '/app';
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return true;
|
|
135
|
-
} catch {
|
|
136
|
-
return true; // Network error = local mode
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const fetchMetrics = async () => {
|
|
141
|
-
try {
|
|
142
|
-
// Check cloud mode first
|
|
143
|
-
const shouldContinue = await checkCloudMode();
|
|
144
|
-
if (!shouldContinue) return;
|
|
145
|
-
|
|
146
|
-
const [metricsRes, memoryRes] = await Promise.all([
|
|
147
|
-
fetch(getApiUrl('/api/metrics'), { credentials: 'include' }),
|
|
148
|
-
fetch(getApiUrl('/api/metrics/agents'), { credentials: 'include' }),
|
|
149
|
-
]);
|
|
150
|
-
|
|
151
|
-
if (!metricsRes.ok) throw new Error('Failed to fetch metrics');
|
|
152
|
-
const data = await metricsRes.json();
|
|
153
|
-
setMetrics(data);
|
|
154
|
-
|
|
155
|
-
if (memoryRes.ok) {
|
|
156
|
-
const memData = await memoryRes.json();
|
|
157
|
-
setMemoryMetrics(memData);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
setError(null);
|
|
161
|
-
} catch (err) {
|
|
162
|
-
setError(err instanceof Error ? err.message : 'Failed to load metrics');
|
|
163
|
-
} finally {
|
|
164
|
-
setLoading(false);
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
fetchMetrics();
|
|
169
|
-
const interval = setInterval(fetchMetrics, 5000);
|
|
170
|
-
return () => clearInterval(interval);
|
|
171
|
-
}, []);
|
|
172
|
-
|
|
173
|
-
if (loading) {
|
|
174
|
-
return (
|
|
175
|
-
<div className="min-h-screen bg-bg-primary text-text-primary font-sans">
|
|
176
|
-
<div className="flex flex-col items-center justify-center h-screen gap-4">
|
|
177
|
-
<div className="w-8 h-8 border-2 border-border border-t-accent rounded-full animate-spin" />
|
|
178
|
-
<p className="text-text-muted text-sm">Loading metrics...</p>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (error || !metrics) {
|
|
185
|
-
return (
|
|
186
|
-
<div className="min-h-screen bg-bg-primary text-text-primary font-sans">
|
|
187
|
-
<div className="flex flex-col items-center justify-center h-screen gap-4">
|
|
188
|
-
<div className="w-12 h-12 rounded-full bg-error/10 flex items-center justify-center">
|
|
189
|
-
<svg className="w-6 h-6 text-error" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
190
|
-
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
191
|
-
</svg>
|
|
192
|
-
</div>
|
|
193
|
-
<p className="text-text-secondary">{error || 'No metrics available'}</p>
|
|
194
|
-
<button
|
|
195
|
-
onClick={() => window.location.reload()}
|
|
196
|
-
className="px-5 py-2.5 bg-accent text-white rounded-lg text-sm font-medium transition-colors hover:bg-accent-hover"
|
|
197
|
-
>
|
|
198
|
-
Retry
|
|
199
|
-
</button>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const errorRateClass = (metrics.sessions?.errorRate ?? 0) <= 1 ? 'healthy' :
|
|
206
|
-
(metrics.sessions?.errorRate ?? 0) <= 5 ? 'warning' : 'critical';
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
<div className="min-h-screen bg-bg-primary text-text-primary font-sans">
|
|
210
|
-
{/* Header */}
|
|
211
|
-
<header className="sticky top-0 z-50 bg-sidebar-bg border-b border-sidebar-border px-4 md:px-8 py-4">
|
|
212
|
-
<div className="max-w-[1400px] mx-auto flex items-center justify-between">
|
|
213
|
-
<div className="flex items-center gap-4">
|
|
214
|
-
<Link
|
|
215
|
-
href="/app"
|
|
216
|
-
className="flex items-center gap-2 text-text-muted text-sm font-medium px-3 py-2 rounded-md transition-all hover:text-accent hover:bg-accent/10"
|
|
217
|
-
>
|
|
218
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
219
|
-
<path d="M19 12H5M12 19l-7-7 7-7"/>
|
|
220
|
-
</svg>
|
|
221
|
-
<span className="hidden sm:inline">Dashboard</span>
|
|
222
|
-
</Link>
|
|
223
|
-
<div className="flex items-center gap-3">
|
|
224
|
-
<div className="w-8 h-8 bg-gradient-to-br from-accent/80 to-accent rounded-lg flex items-center justify-center border border-accent/30">
|
|
225
|
-
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2">
|
|
226
|
-
<path d="M3 3v18h18"/>
|
|
227
|
-
<path d="M18 17V9"/>
|
|
228
|
-
<path d="M13 17V5"/>
|
|
229
|
-
<path d="M8 17v-3"/>
|
|
230
|
-
</svg>
|
|
231
|
-
</div>
|
|
232
|
-
<div className="text-lg font-semibold tracking-tight">
|
|
233
|
-
Agent <span className="text-accent">Metrics</span>
|
|
234
|
-
</div>
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
<div className="flex items-center gap-2 px-3 py-1.5 bg-success/10 border border-success/30 rounded-full">
|
|
238
|
-
<span className="w-2 h-2 bg-success rounded-full animate-pulse shadow-[0_0_8px_rgba(43,172,118,0.5)]" />
|
|
239
|
-
<span className="text-success text-xs font-semibold font-mono tracking-wide">LIVE</span>
|
|
240
|
-
</div>
|
|
241
|
-
</div>
|
|
242
|
-
</header>
|
|
243
|
-
|
|
244
|
-
{/* Main Content */}
|
|
245
|
-
<main className="max-w-[1400px] mx-auto px-4 md:px-8 py-6">
|
|
246
|
-
{/* Stats Overview */}
|
|
247
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
248
|
-
<StatCard
|
|
249
|
-
label="Total Agents"
|
|
250
|
-
value={metrics.totalAgents}
|
|
251
|
-
subtext={`${metrics.onlineAgents} online / ${metrics.offlineAgents} offline`}
|
|
252
|
-
accent="cyan"
|
|
253
|
-
/>
|
|
254
|
-
<StatCard
|
|
255
|
-
label="Online Now"
|
|
256
|
-
value={metrics.onlineAgents}
|
|
257
|
-
subtext={`${metrics.totalAgents > 0 ? Math.round((metrics.onlineAgents / metrics.totalAgents) * 100) : 0}% availability`}
|
|
258
|
-
accent="green"
|
|
259
|
-
/>
|
|
260
|
-
<StatCard
|
|
261
|
-
label="Total Messages"
|
|
262
|
-
value={metrics.totalMessages.toLocaleString()}
|
|
263
|
-
subtext="all time"
|
|
264
|
-
accent="purple"
|
|
265
|
-
/>
|
|
266
|
-
<StatCard
|
|
267
|
-
label="Avg. Throughput"
|
|
268
|
-
value={metrics.throughput.avgMessagesPerMinute}
|
|
269
|
-
subtext="messages / minute"
|
|
270
|
-
accent="orange"
|
|
271
|
-
/>
|
|
272
|
-
</div>
|
|
273
|
-
|
|
274
|
-
{/* Throughput Section */}
|
|
275
|
-
<section className="mb-6">
|
|
276
|
-
<SectionHeader title="Message Throughput" />
|
|
277
|
-
<div className="bg-bg-secondary border border-border rounded-lg p-6">
|
|
278
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
279
|
-
<ThroughputItem value={metrics.throughput.messagesLastMinute} label="Last Minute" max={10} />
|
|
280
|
-
<ThroughputItem value={metrics.throughput.messagesLastHour} label="Last Hour" max={100} />
|
|
281
|
-
<ThroughputItem value={metrics.throughput.messagesLast24Hours} label="Last 24 Hours" max={1000} />
|
|
282
|
-
<ThroughputItem value={metrics.throughput.avgMessagesPerMinute} label="Avg / Min" max={5} />
|
|
283
|
-
</div>
|
|
284
|
-
</div>
|
|
285
|
-
</section>
|
|
286
|
-
|
|
287
|
-
{/* Session Lifecycle Section */}
|
|
288
|
-
{metrics.sessions && (
|
|
289
|
-
<section className="mb-6">
|
|
290
|
-
<div className="flex items-center justify-between mb-3">
|
|
291
|
-
<SectionHeader title="Session Lifecycle" />
|
|
292
|
-
<ErrorRateIndicator rate={metrics.sessions.errorRate || 0} status={errorRateClass} />
|
|
293
|
-
</div>
|
|
294
|
-
<div className="bg-bg-secondary border border-border rounded-lg p-6">
|
|
295
|
-
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-5 mb-6">
|
|
296
|
-
<LifecycleItem value={metrics.sessions.totalSessions} label="Total Sessions" accent="purple" />
|
|
297
|
-
<LifecycleItem value={metrics.sessions.activeSessions} label="Active" accent="blue" />
|
|
298
|
-
<LifecycleItem value={metrics.sessions.closedByAgent} label="Clean Close" accent="green" />
|
|
299
|
-
<LifecycleItem value={metrics.sessions.closedByDisconnect} label="Disconnect" accent="orange" />
|
|
300
|
-
<LifecycleItem value={metrics.sessions.closedByError} label="Error" accent="red" />
|
|
301
|
-
</div>
|
|
302
|
-
|
|
303
|
-
{metrics.sessions.recentSessions && metrics.sessions.recentSessions.length > 0 && (
|
|
304
|
-
<div className="overflow-x-auto -mx-6 px-6">
|
|
305
|
-
<table className="w-full min-w-[500px]">
|
|
306
|
-
<thead>
|
|
307
|
-
<tr className="border-b border-border">
|
|
308
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Agent</th>
|
|
309
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Status</th>
|
|
310
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Messages</th>
|
|
311
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Started</th>
|
|
312
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Duration</th>
|
|
313
|
-
</tr>
|
|
314
|
-
</thead>
|
|
315
|
-
<tbody>
|
|
316
|
-
{metrics.sessions.recentSessions.slice(0, 5).map((session, i) => {
|
|
317
|
-
const started = new Date(session.startedAt);
|
|
318
|
-
const ended = session.endedAt ? new Date(session.endedAt) : new Date();
|
|
319
|
-
const durationSec = Math.floor((ended.getTime() - started.getTime()) / 1000);
|
|
320
|
-
|
|
321
|
-
return (
|
|
322
|
-
<tr key={i} className="border-b border-border/50 last:border-0">
|
|
323
|
-
<td className="py-3 px-4">
|
|
324
|
-
<AgentCell name={session.agentName} />
|
|
325
|
-
</td>
|
|
326
|
-
<td className="py-3 px-4">
|
|
327
|
-
<SessionStatusBadge closedBy={session.closedBy} />
|
|
328
|
-
</td>
|
|
329
|
-
<td className="py-3 px-4 font-mono text-sm text-accent">{session.messageCount}</td>
|
|
330
|
-
<td className="py-3 px-4 font-mono text-sm text-text-muted">{formatTime(session.startedAt)}</td>
|
|
331
|
-
<td className="py-3 px-4 font-mono text-sm text-text-muted">{formatDuration(durationSec)}</td>
|
|
332
|
-
</tr>
|
|
333
|
-
);
|
|
334
|
-
})}
|
|
335
|
-
</tbody>
|
|
336
|
-
</table>
|
|
337
|
-
</div>
|
|
338
|
-
)}
|
|
339
|
-
</div>
|
|
340
|
-
</section>
|
|
341
|
-
)}
|
|
342
|
-
|
|
343
|
-
{/* Agent Health Section */}
|
|
344
|
-
<section className="mb-6">
|
|
345
|
-
<SectionHeader title="Agent Health" />
|
|
346
|
-
<div className="bg-bg-secondary border border-border rounded-lg overflow-hidden">
|
|
347
|
-
{metrics.agents.length === 0 ? (
|
|
348
|
-
<div className="py-12 text-center">
|
|
349
|
-
<svg className="w-12 h-12 mx-auto mb-4 text-text-muted opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
|
|
350
|
-
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
|
|
351
|
-
<circle cx="12" cy="7" r="4"/>
|
|
352
|
-
</svg>
|
|
353
|
-
<p className="text-text-muted text-sm">No agents registered yet</p>
|
|
354
|
-
</div>
|
|
355
|
-
) : (
|
|
356
|
-
<div className="overflow-x-auto">
|
|
357
|
-
<table className="w-full min-w-[700px]">
|
|
358
|
-
<thead>
|
|
359
|
-
<tr className="bg-bg-tertiary border-b border-border">
|
|
360
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Agent</th>
|
|
361
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Status</th>
|
|
362
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Sent</th>
|
|
363
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Received</th>
|
|
364
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Uptime</th>
|
|
365
|
-
<th className="text-left py-3 px-4 text-xs font-semibold uppercase tracking-wider text-text-muted">Last Seen</th>
|
|
366
|
-
</tr>
|
|
367
|
-
</thead>
|
|
368
|
-
<tbody>
|
|
369
|
-
{metrics.agents.map((agent) => (
|
|
370
|
-
<tr key={agent.name} className="border-b border-border/50 last:border-0 transition-colors hover:bg-bg-hover">
|
|
371
|
-
<td className="py-3 px-4">
|
|
372
|
-
<AgentCell name={agent.name} />
|
|
373
|
-
</td>
|
|
374
|
-
<td className="py-3 px-4">
|
|
375
|
-
<OnlineStatusBadge isOnline={agent.isOnline} />
|
|
376
|
-
</td>
|
|
377
|
-
<td className="py-3 px-4 font-mono text-sm text-accent">{agent.messagesSent.toLocaleString()}</td>
|
|
378
|
-
<td className="py-3 px-4 font-mono text-sm text-[#a78bfa]">{agent.messagesReceived.toLocaleString()}</td>
|
|
379
|
-
<td className="py-3 px-4 font-mono text-sm text-text-muted">{formatDuration(agent.uptimeSeconds)}</td>
|
|
380
|
-
<td className="py-3 px-4 font-mono text-sm text-text-muted">{formatTime(agent.lastSeen)}</td>
|
|
381
|
-
</tr>
|
|
382
|
-
))}
|
|
383
|
-
</tbody>
|
|
384
|
-
</table>
|
|
385
|
-
</div>
|
|
386
|
-
)}
|
|
387
|
-
</div>
|
|
388
|
-
</section>
|
|
389
|
-
|
|
390
|
-
{/* Agent Memory Section */}
|
|
391
|
-
{memoryMetrics && memoryMetrics.agents.length > 0 && (
|
|
392
|
-
<section className="mb-6">
|
|
393
|
-
<div className="flex items-center justify-between mb-3">
|
|
394
|
-
<SectionHeader title="Agent Memory & Resources" />
|
|
395
|
-
<SystemMemoryIndicator system={memoryMetrics.system} />
|
|
396
|
-
</div>
|
|
397
|
-
<div className="bg-bg-secondary border border-border rounded-lg p-6">
|
|
398
|
-
{/* Memory Overview Cards */}
|
|
399
|
-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
400
|
-
<MemoryStatCard
|
|
401
|
-
label="Total Agents"
|
|
402
|
-
value={memoryMetrics.agents.length}
|
|
403
|
-
subtext="being monitored"
|
|
404
|
-
accent="cyan"
|
|
405
|
-
/>
|
|
406
|
-
<MemoryStatCard
|
|
407
|
-
label="Healthy"
|
|
408
|
-
value={memoryMetrics.agents.filter(a => a.alertLevel === 'normal').length}
|
|
409
|
-
subtext="normal memory"
|
|
410
|
-
accent="green"
|
|
411
|
-
/>
|
|
412
|
-
<MemoryStatCard
|
|
413
|
-
label="Warning"
|
|
414
|
-
value={memoryMetrics.agents.filter(a => a.alertLevel === 'warning').length}
|
|
415
|
-
subtext="elevated usage"
|
|
416
|
-
accent="orange"
|
|
417
|
-
/>
|
|
418
|
-
<MemoryStatCard
|
|
419
|
-
label="Critical"
|
|
420
|
-
value={memoryMetrics.agents.filter(a => a.alertLevel === 'critical' || a.alertLevel === 'oom_imminent').length}
|
|
421
|
-
subtext="needs attention"
|
|
422
|
-
accent="red"
|
|
423
|
-
/>
|
|
424
|
-
</div>
|
|
425
|
-
|
|
426
|
-
{/* Agent Memory Cards */}
|
|
427
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
428
|
-
{memoryMetrics.agents.map((agent) => (
|
|
429
|
-
<AgentMemoryCard key={agent.name} agent={agent} />
|
|
430
|
-
))}
|
|
431
|
-
</div>
|
|
432
|
-
</div>
|
|
433
|
-
</section>
|
|
434
|
-
)}
|
|
435
|
-
|
|
436
|
-
{/* Footer */}
|
|
437
|
-
<div className="text-center py-4 text-text-muted text-xs font-mono">
|
|
438
|
-
Last updated: {formatTime(metrics.timestamp)}
|
|
439
|
-
</div>
|
|
440
|
-
</main>
|
|
441
|
-
</div>
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/* ─────────────────────────────────────────────────────────────
|
|
446
|
-
Sub-components
|
|
447
|
-
───────────────────────────────────────────────────────────── */
|
|
448
|
-
|
|
449
|
-
function StatCard({ label, value, subtext, accent }: {
|
|
450
|
-
label: string;
|
|
451
|
-
value: string | number;
|
|
452
|
-
subtext: string;
|
|
453
|
-
accent: 'cyan' | 'green' | 'purple' | 'orange';
|
|
454
|
-
}) {
|
|
455
|
-
const accentColors = {
|
|
456
|
-
cyan: 'text-accent',
|
|
457
|
-
green: 'text-success',
|
|
458
|
-
purple: 'text-[#a78bfa]',
|
|
459
|
-
orange: 'text-warning',
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
return (
|
|
463
|
-
<div className="bg-bg-secondary border border-border rounded-lg p-5 transition-all hover:border-border-dark hover:bg-bg-tertiary group">
|
|
464
|
-
<div className="text-[11px] font-semibold uppercase tracking-wide text-text-muted mb-2">{label}</div>
|
|
465
|
-
<div className={`font-mono text-3xl font-bold ${accentColors[accent]} transition-transform group-hover:scale-105 origin-left`}>
|
|
466
|
-
{value}
|
|
467
|
-
</div>
|
|
468
|
-
<div className="text-xs text-text-muted font-mono mt-2">{subtext}</div>
|
|
469
|
-
</div>
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
function SectionHeader({ title }: { title: string }) {
|
|
474
|
-
return (
|
|
475
|
-
<h2 className="flex items-center gap-2.5 text-xs font-semibold uppercase tracking-wider text-text-muted mb-3">
|
|
476
|
-
<span className="w-[3px] h-3.5 bg-accent rounded-sm" />
|
|
477
|
-
{title}
|
|
478
|
-
</h2>
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
function ThroughputItem({ value, label, max }: { value: number; label: string; max: number }) {
|
|
483
|
-
const percentage = Math.min((value / max) * 100, 100);
|
|
484
|
-
|
|
485
|
-
return (
|
|
486
|
-
<div className="text-center">
|
|
487
|
-
<div className="font-mono text-4xl font-bold text-accent leading-none">{value}</div>
|
|
488
|
-
<div className="text-xs text-text-muted uppercase tracking-wide mt-2">{label}</div>
|
|
489
|
-
<div className="h-1 bg-border rounded-full mt-3 overflow-hidden">
|
|
490
|
-
<div
|
|
491
|
-
className="h-full bg-gradient-to-r from-accent to-[#6366f1] rounded-full transition-all duration-500"
|
|
492
|
-
style={{ width: `${percentage}%` }}
|
|
493
|
-
/>
|
|
494
|
-
</div>
|
|
495
|
-
</div>
|
|
496
|
-
);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
function LifecycleItem({ value, label, accent }: {
|
|
500
|
-
value: number;
|
|
501
|
-
label: string;
|
|
502
|
-
accent: 'purple' | 'blue' | 'green' | 'orange' | 'red';
|
|
503
|
-
}) {
|
|
504
|
-
const accentColors = {
|
|
505
|
-
purple: 'text-[#a78bfa]',
|
|
506
|
-
blue: 'text-accent',
|
|
507
|
-
green: 'text-success',
|
|
508
|
-
orange: 'text-warning',
|
|
509
|
-
red: 'text-error',
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
return (
|
|
513
|
-
<div className="text-center">
|
|
514
|
-
<div className={`font-mono text-3xl font-bold ${accentColors[accent]} leading-none`}>{value}</div>
|
|
515
|
-
<div className="text-[11px] text-text-muted uppercase tracking-wide mt-2">{label}</div>
|
|
516
|
-
</div>
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function ErrorRateIndicator({ rate, status }: { rate: number; status: string }) {
|
|
521
|
-
const statusStyles = {
|
|
522
|
-
healthy: 'bg-success/15 text-success border-success/30',
|
|
523
|
-
warning: 'bg-warning/15 text-warning border-warning/30',
|
|
524
|
-
critical: 'bg-error/15 text-error border-error/30',
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
return (
|
|
528
|
-
<span className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-semibold font-mono border ${statusStyles[status as keyof typeof statusStyles]}`}>
|
|
529
|
-
{rate.toFixed(1)}% error rate
|
|
530
|
-
</span>
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
function AgentCell({ name }: { name: string }) {
|
|
535
|
-
return (
|
|
536
|
-
<div className="flex items-center gap-3">
|
|
537
|
-
<div
|
|
538
|
-
className="w-8 h-8 rounded-md flex items-center justify-center text-white text-xs font-semibold"
|
|
539
|
-
style={{ backgroundColor: getAvatarColor(name) }}
|
|
540
|
-
>
|
|
541
|
-
{getInitials(name)}
|
|
542
|
-
</div>
|
|
543
|
-
<span className="font-semibold font-mono text-sm">{name}</span>
|
|
544
|
-
</div>
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function OnlineStatusBadge({ isOnline }: { isOnline: boolean }) {
|
|
549
|
-
return (
|
|
550
|
-
<span className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${
|
|
551
|
-
isOnline
|
|
552
|
-
? 'bg-success/15 text-success'
|
|
553
|
-
: 'bg-bg-hover text-text-muted'
|
|
554
|
-
}`}>
|
|
555
|
-
<span className={`w-1.5 h-1.5 rounded-full ${isOnline ? 'bg-success' : 'bg-text-muted'}`} />
|
|
556
|
-
{isOnline ? 'Online' : 'Offline'}
|
|
557
|
-
</span>
|
|
558
|
-
);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
function SessionStatusBadge({ closedBy }: { closedBy?: 'agent' | 'disconnect' | 'error' }) {
|
|
562
|
-
const statusConfig = {
|
|
563
|
-
agent: { label: 'Clean', className: 'bg-success/15 text-success' },
|
|
564
|
-
disconnect: { label: 'Disconnect', className: 'bg-warning/15 text-warning' },
|
|
565
|
-
error: { label: 'Error', className: 'bg-error/15 text-error' },
|
|
566
|
-
active: { label: 'Active', className: 'bg-accent/15 text-accent' },
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
const config = statusConfig[closedBy || 'active'];
|
|
570
|
-
|
|
571
|
-
return (
|
|
572
|
-
<span className={`inline-flex items-center px-2 py-0.5 rounded-lg text-[11px] font-medium ${config.className}`}>
|
|
573
|
-
{config.label}
|
|
574
|
-
</span>
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/* ─────────────────────────────────────────────────────────────
|
|
579
|
-
Memory Monitoring Components
|
|
580
|
-
───────────────────────────────────────────────────────────── */
|
|
581
|
-
|
|
582
|
-
function formatBytes(bytes: number): string {
|
|
583
|
-
if (bytes === 0) return '0 B';
|
|
584
|
-
const k = 1024;
|
|
585
|
-
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
586
|
-
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));
|
|
587
|
-
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function SystemMemoryIndicator({ system }: { system: { totalMemory: number; freeMemory: number; heapUsed: number } }) {
|
|
591
|
-
const usedPercent = Math.round(((system.totalMemory - system.freeMemory) / system.totalMemory) * 100);
|
|
592
|
-
|
|
593
|
-
return (
|
|
594
|
-
<div className="flex items-center gap-3 px-3 py-1.5 bg-bg-tertiary border border-border rounded-lg">
|
|
595
|
-
<div className="flex items-center gap-2">
|
|
596
|
-
<svg className="w-4 h-4 text-accent" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
597
|
-
<rect x="4" y="4" width="16" height="16" rx="2" />
|
|
598
|
-
<rect x="8" y="8" width="8" height="8" rx="1" fill="currentColor" opacity="0.3" />
|
|
599
|
-
</svg>
|
|
600
|
-
<span className="text-xs text-text-muted">System:</span>
|
|
601
|
-
</div>
|
|
602
|
-
<div className="flex items-center gap-2">
|
|
603
|
-
<div className="w-24 h-2 bg-border rounded-full overflow-hidden">
|
|
604
|
-
<div
|
|
605
|
-
className={`h-full rounded-full transition-all ${
|
|
606
|
-
usedPercent > 90 ? 'bg-error' : usedPercent > 70 ? 'bg-warning' : 'bg-accent'
|
|
607
|
-
}`}
|
|
608
|
-
style={{ width: `${usedPercent}%` }}
|
|
609
|
-
/>
|
|
610
|
-
</div>
|
|
611
|
-
<span className="text-xs font-mono text-text-muted">{usedPercent}%</span>
|
|
612
|
-
</div>
|
|
613
|
-
<span className="text-xs font-mono text-text-muted">
|
|
614
|
-
{formatBytes(system.freeMemory)} free
|
|
615
|
-
</span>
|
|
616
|
-
</div>
|
|
617
|
-
);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function MemoryStatCard({ label, value, subtext, accent }: {
|
|
621
|
-
label: string;
|
|
622
|
-
value: number;
|
|
623
|
-
subtext: string;
|
|
624
|
-
accent: 'cyan' | 'green' | 'orange' | 'red';
|
|
625
|
-
}) {
|
|
626
|
-
const accentColors = {
|
|
627
|
-
cyan: 'text-accent',
|
|
628
|
-
green: 'text-success',
|
|
629
|
-
orange: 'text-warning',
|
|
630
|
-
red: 'text-error',
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
return (
|
|
634
|
-
<div className="bg-bg-tertiary border border-border/50 rounded-lg p-4 text-center">
|
|
635
|
-
<div className={`font-mono text-3xl font-bold ${accentColors[accent]} leading-none`}>
|
|
636
|
-
{value}
|
|
637
|
-
</div>
|
|
638
|
-
<div className="text-[11px] text-text-muted uppercase tracking-wide mt-2">{label}</div>
|
|
639
|
-
<div className="text-xs text-text-muted mt-1">{subtext}</div>
|
|
640
|
-
</div>
|
|
641
|
-
);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
function AgentMemoryCard({ agent }: { agent: AgentMemoryMetric }) {
|
|
645
|
-
const memoryMB = agent.rssBytes ? agent.rssBytes / (1024 * 1024) : 0;
|
|
646
|
-
const maxMemoryMB = 2048; // 2GB max for visualization
|
|
647
|
-
const memoryPercent = Math.min((memoryMB / maxMemoryMB) * 100, 100);
|
|
648
|
-
|
|
649
|
-
const alertStyles = {
|
|
650
|
-
normal: { bg: 'bg-success/10', border: 'border-success/30', text: 'text-success', label: 'Healthy' },
|
|
651
|
-
warning: { bg: 'bg-warning/10', border: 'border-warning/30', text: 'text-warning', label: 'Warning' },
|
|
652
|
-
critical: { bg: 'bg-error/10', border: 'border-error/30', text: 'text-error', label: 'Critical' },
|
|
653
|
-
oom_imminent: { bg: 'bg-error/20', border: 'border-error/50', text: 'text-error', label: 'OOM Risk' },
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
const trendIcons = {
|
|
657
|
-
growing: { icon: '↑', color: 'text-warning', label: 'Growing' },
|
|
658
|
-
stable: { icon: '→', color: 'text-success', label: 'Stable' },
|
|
659
|
-
shrinking: { icon: '↓', color: 'text-accent', label: 'Shrinking' },
|
|
660
|
-
unknown: { icon: '?', color: 'text-text-muted', label: 'Unknown' },
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
const style = alertStyles[agent.alertLevel || 'normal'];
|
|
664
|
-
const trend = trendIcons[agent.trend || 'unknown'];
|
|
665
|
-
|
|
666
|
-
return (
|
|
667
|
-
<div className={`${style.bg} border ${style.border} rounded-lg p-4 transition-all hover:scale-[1.01]`}>
|
|
668
|
-
{/* Header */}
|
|
669
|
-
<div className="flex items-center justify-between mb-4">
|
|
670
|
-
<div className="flex items-center gap-3">
|
|
671
|
-
<div
|
|
672
|
-
className="w-10 h-10 rounded-lg flex items-center justify-center text-white text-sm font-semibold"
|
|
673
|
-
style={{ backgroundColor: getAvatarColor(agent.name) }}
|
|
674
|
-
>
|
|
675
|
-
{getInitials(agent.name)}
|
|
676
|
-
</div>
|
|
677
|
-
<div>
|
|
678
|
-
<div className="font-semibold font-mono text-sm text-text-primary">{agent.name}</div>
|
|
679
|
-
<div className="text-xs text-text-muted">
|
|
680
|
-
PID: {agent.pid || 'N/A'} • {agent.status}
|
|
681
|
-
</div>
|
|
682
|
-
</div>
|
|
683
|
-
</div>
|
|
684
|
-
<div className="flex items-center gap-2">
|
|
685
|
-
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium ${style.bg} ${style.text}`}>
|
|
686
|
-
{style.label}
|
|
687
|
-
</span>
|
|
688
|
-
</div>
|
|
689
|
-
</div>
|
|
690
|
-
|
|
691
|
-
{/* Memory Bar */}
|
|
692
|
-
<div className="mb-4">
|
|
693
|
-
<div className="flex items-center justify-between mb-1.5">
|
|
694
|
-
<span className="text-xs text-text-muted">Memory Usage</span>
|
|
695
|
-
<span className="text-sm font-mono font-semibold text-text-primary">
|
|
696
|
-
{formatBytes(agent.rssBytes || 0)}
|
|
697
|
-
</span>
|
|
698
|
-
</div>
|
|
699
|
-
<div className="h-3 bg-bg-primary rounded-full overflow-hidden">
|
|
700
|
-
<div
|
|
701
|
-
className={`h-full rounded-full transition-all duration-500 ${
|
|
702
|
-
(agent.alertLevel === 'critical' || agent.alertLevel === 'oom_imminent')
|
|
703
|
-
? 'bg-gradient-to-r from-error to-error/70'
|
|
704
|
-
: agent.alertLevel === 'warning'
|
|
705
|
-
? 'bg-gradient-to-r from-warning to-warning/70'
|
|
706
|
-
: 'bg-gradient-to-r from-accent to-[#6366f1]'
|
|
707
|
-
}`}
|
|
708
|
-
style={{ width: `${memoryPercent}%` }}
|
|
709
|
-
/>
|
|
710
|
-
</div>
|
|
711
|
-
<div className="flex items-center justify-between mt-1">
|
|
712
|
-
<span className="text-[10px] text-text-muted">0</span>
|
|
713
|
-
<span className="text-[10px] text-text-muted">2 GB</span>
|
|
714
|
-
</div>
|
|
715
|
-
</div>
|
|
716
|
-
|
|
717
|
-
{/* Stats Grid */}
|
|
718
|
-
<div className="grid grid-cols-3 gap-3">
|
|
719
|
-
<div className="text-center">
|
|
720
|
-
<div className="text-lg font-mono font-bold text-accent">
|
|
721
|
-
{agent.cpuPercent?.toFixed(1) || '0'}%
|
|
722
|
-
</div>
|
|
723
|
-
<div className="text-[10px] text-text-muted uppercase">CPU</div>
|
|
724
|
-
</div>
|
|
725
|
-
<div className="text-center">
|
|
726
|
-
<div className={`text-lg font-mono font-bold ${trend.color} flex items-center justify-center gap-1`}>
|
|
727
|
-
<span>{trend.icon}</span>
|
|
728
|
-
<span className="text-xs">{trend.label}</span>
|
|
729
|
-
</div>
|
|
730
|
-
<div className="text-[10px] text-text-muted uppercase">Trend</div>
|
|
731
|
-
</div>
|
|
732
|
-
<div className="text-center">
|
|
733
|
-
<div className="text-lg font-mono font-bold text-[#a78bfa]">
|
|
734
|
-
{formatBytes(agent.highWatermark || 0)}
|
|
735
|
-
</div>
|
|
736
|
-
<div className="text-[10px] text-text-muted uppercase">Peak</div>
|
|
737
|
-
</div>
|
|
738
|
-
</div>
|
|
739
|
-
|
|
740
|
-
{/* Uptime */}
|
|
741
|
-
{agent.uptimeMs && (
|
|
742
|
-
<div className="mt-3 pt-3 border-t border-border/30 flex items-center justify-between">
|
|
743
|
-
<span className="text-xs text-text-muted">Uptime</span>
|
|
744
|
-
<span className="text-xs font-mono text-text-muted">
|
|
745
|
-
{formatDuration(Math.floor(agent.uptimeMs / 1000))}
|
|
746
|
-
</span>
|
|
747
|
-
</div>
|
|
748
|
-
)}
|
|
749
|
-
</div>
|
|
750
|
-
);
|
|
751
|
-
}
|