Agent Fleet view: live status board for all owner agents - #3684
Closed
maxmoneycash wants to merge 3 commits into
Closed
Agent Fleet view: live status board for all owner agents#3684maxmoneycash wants to merge 3 commits into
maxmoneycash wants to merge 3 commits into
Conversation
…etric usage store New desktop/src/features/fleet/ module for the Agent Fleet board: - fleetAgents.ts: pure roster composition (managed agents + NIP-OA declared-owned relay agents, the same ownership rule the observer ingestion uses), with useFleetAgents.ts as the query-composing hook. - fleetStatus.ts: pure live-status/last-seen/headline derivations over the existing observer stores plus compact token/cost formatting. - turnMetrics.ts + turnMetricsStore.ts: NIP-AM (kind 44200) usage aggregation fed exclusively from existing data paths — the local SQLite archive (owner_p save subscription) and the relay's persisted, owner-addressed metric events, decrypted through the same decrypt_observer_event command the observer store uses. - FleetView/FleetAgentCard/FleetScreen: live status grid reusing AgentStatusBadge, the unified agent working signal, and useOpenAgentActivity (cards open the existing agent session panel). - Unit tests for every pure module. Addresses the fleet-view use case raised in block#2716. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Max Mohammadi <maxmohammadi@gmail.com>
- /fleet route (TanStack virtual file route + regenerated route tree) lazy-loading FleetScreen, mirroring the Agents route pattern. - Sidebar entry behind a new 'fleet' preview feature gate, consistent with Pulse/Projects/Workflows; goFleet navigation + selected-view derivation in AppShell.helpers. - resetFleetTurnMetricsStore() wired into resetCommunityState() per the community-switching singleton rules; AGENTS.md singleton list updated in the same PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Max Mohammadi <maxmohammadi@gmail.com>
- __BUZZ_E2E_SEED_TURN_METRICS__ bridge hook injecting decoded NIP-AM payloads into the fleet usage store, mirroring the observer-event seed hook. - fleet-screenshots.spec.ts (smoke): mixed-status board (working live turn, idle with transcript headline, crashed with friendly error copy, offline, and a declared-owned remote agent), aggregation assertions (cumulative series must not double-count), and the card-click ingress into the existing agent session panel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Max Mohammadi <maxmohammadi@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Owners running several agents — across channels, and increasingly across machines — have no single place to see what their fleet is doing. Today that means opening each agent's profile panel or channel one at a time to answer "which of my agents are working right now, which one crashed overnight, and what has all of this cost me?"
A commenter on #2716 describes building exactly this on top of kind 24200 ("I'm building a fleet view on top of kind:24200 and presence right now"). The desktop app is the natural home for that owner-side surface: it already holds the owner key, decrypts observer frames app-wide, and archives turn metrics locally.
What this adds
A new Agent Fleet view (
/fleet, sidebar entry behind a newfleetpreview feature, consistent with Pulse/Projects/Workflows) with one card per owned agent:activeAgentTurnsStore→ unifiedagentWorkingSignal), with the sameAgentStatusBadgeused on the Agents page.ManagedAgentRow(friendlyAgentLastError).Clicking a card opens the existing agent session panel via
useOpenAgentActivity— the same universal ingress the profile panel uses — no duplicated transcript UI.The roster is "all of the owner's agents": locally managed agents plus relay agents whose profile declares NIP-OA
ownerPubkey == me(the same ownership ruleuseAgentObserverIngestionalready uses), so agents running on another machine appear too.Data sources — existing paths only
No new HTTP endpoints, no new Rust, no new event kinds:
useAgentObserverIngestionbridge already ingests kind 24200 app-wide; the fleet view only readsobserverRelayStore/activeAgentTurnsStore/agentWorkingSignal.owner_psave subscription — the oneuseAgentMetricArchiveSeed/ the Local Archive settings card manage) plus the relay's persisted, owner-addressed copies via the existingrelayClientfetch/subscribe path. Decryption goes through the samedecrypt_observer_eventTauri command the observer store uses (44200 shares the NIP-44 agent→owner scheme).resetCommunityState()per the community-switching singleton rules (AGENTS.md list updated in this PR).This is complementary to #3068 (per-agent usage table on the Agents page, local log aggregates): that PR is per-agent local resource introspection; this one is the fleet-wide live board fed by relay-carried NIP-AM metrics.
Screenshots
Fleet board — mixed statuses
One working agent (live turn in #agents with elapsed counter), one idle with a transcript headline and cumulative usage, one crashed with friendly error copy, one offline, and a declared-owned agent running on another device.
Working card
Needs-attention card
Structured error copy (
friendlyAgentLastError), not the raw JSON error string.Card click → existing session panel
The card deep-links into the agent's working channel with the existing Activity pane open.
Default state (
just desktop-screenshot --name fleet-empty --route /fleet)Screenshots are hosted on a branch in my fork (
agent-screenshots/fleet) becausescripts/post-screenshots.shpushes toorigin, which fork contributors can't write to. Happy to re-post via the script once the PR exists if a maintainer prefers.Testing
node --testunit coverage for every pure module: NIP-AM aggregation (cumulative vs delta, unreliable deltas, null-vs-zero semantics), fleet status derivation, last-seen/headline selection, formatting, and roster composition (ownership gate, collision handling).fleet-screenshots.spec.ts: seeds a mixed fleet plus decoded 44200 payloads through a new__BUZZ_E2E_SEED_TURN_METRICS__bridge hook (mirrors the observer-event seed hook), asserts summary counts, per-card states, aggregation, the remote-owned roster path, and the card-click ingress into the existing session panel.just desktop-check,pnpm typecheck, full desktop unit suite (3757 passing),cargo fmt --check+ workspace clippy clean (no Rust touched).Diff is additive and confined to
desktop/src+ route/sidebar registration, the e2e spec, and thefleetentry inpreview-features.json.Related: #2716 (fleet-view comment), #3068 (complementary per-agent usage dashboard).
🤖 Generated with Claude Code