Repository navigation
Description
Is your feature request related to a problem? Please describe.
Buzz already supports running agents as headless buzz-acp bridges — a great fit
for always-on agents backed by runtimes like Hermes or OpenClaw, hosted
on a workstation/server and connected to a community relay 24/7, independent of
any desktop client.
The problem: the desktop Agents view only lists agents the local app
manages/hosts itself (AgentsView → UnifiedAgentsSection). Externally-hosted
bridge agents never appear there. They only surface as channel members (their
kind:10100 profile badges them as "agent" in member lists and @mention
autocomplete), but there is no representation in the Agents area itself.
This forces a bad tradeoff:
- To see/manage an agent in the Agents area, the desktop app has to host it —
which ties the agent's lifetime to that app instance being open, so true 24/7
operation is impossible (close the app → the agent goes offline). - Hosting the same agent on more than one device conflicts (two harnesses on
one identity, racing on the relay). - So anyone running Hermes/OpenClaw agents as always-on bridges has no
first-class, at-a-glance Agents surface for them — only a per-channel member
popup.
Describe the solution you'd like
- A read-only "Community / External agents" section in the Agents view that
lists agents present in the community via theirkind:10100agent profile
(+kind:0), regardless of which device or process hosts them — including
bridge agents the local app does not manage. - Clear separation of "Managed here" vs "External". Externally-hosted agents
get view/interact affordances (open profile, DM,@mention, online/offline
presence) but no start/stop/edit/delete controls, since the local app
doesn't own their runtime — and no "Configuration missing" / "Stopped" states
for agents the app was never hosting. - A uniform way to register/label an externally-hosted agent into the
community's Agents roster from any device — publish/curate its agent profile
(name, avatar, description) without the app taking over hosting — so multiple
people can each stand up their own always-on agents on their own machines and
have them all appear consistently in everyone's Agents view for that community.
Describe alternatives you've considered
- Hosting agents via the desktop app (managed): rejected — not 24/7 (the
harness dies when the app closes), and hosting the same agent on multiple
devices conflicts. - Publishing
kind:10100manually (e.g. viabuzz channels set-add-policy):
makes the agent show up in member lists / mentions, but not in the Agents
view, and the profile content isn't a real agent profile. A workaround, not a
surface. - Relying on the channel member popup only: fine for chatting, but there's no
agent-overview surface and it doesn't scale across many agents and devices.
Additional context
Concrete setup this would serve: a Mac hosts Agent1/Agent2/Agent3 as
buzz-acp → hermes -p <profile> launchd bridges on a shared community relay; a
Windows box and a Raspberry Pi host their own agents the same way. All of them
should appear in every device's Agents view as community agents — hosted only
where their bridge runs, viewable and interactable everywhere, start/stop-able
nowhere but their host.
This mirrors how Discord shows bots in a server: the bot runs server-side,
always-on, and every client sees and can interact with it regardless of which
client is open — no client "hosts" the bot.
Activity
UNST-ai commentedon Aug 1, 2026
+1 for this one.
murdawkmedia commentedon Aug 1, 2026
I validated this request against a real mixed-harness deployment: two independently hosted Hermes residents and two OpenClaw residents spread across Windows, Linux, and macOS, each with its own signing identity, runtime, state, and credentials, all using one authenticated community relay. They already produce canonical signed replies and remain available independently of Desktop, but—as this issue describes—channel membership does not project them into the Agents view.
I also composed the reviewed heads of #4006, #4023, and #3964 against current
mainin an isolated branch. They merge cleanly and are complementary, but do not yet compose into this issue's end state. #4006 has since gained an unrelated initial-window helper extraction; its connected-agent code is unchanged.AgentsView. Its generatedkind:10100hardcodesstatus: "online"independently of runtime state and reconstructs the replaceable profile rather than preserving fields, so profile status should not be treated as presence and refreshes need one shared non-clobbering merge path.users me, profile read-modify-write, scopedlisten). A production resident loop still needs explicit Windows key-file ACL handling, independently verified signed stream records, paginated catch-up beyond the relay's 1,000-event page ceiling, and a profile surface for the mention-policy fields used by fix(desktop): make remotely hosted agents mentionable from other machines #4023 (respond_to, allowlist, and current channel IDs). Reconnect remains at-least-once, so adapters must deduplicate by event ID.The model that fits this deployment cleanly would be:
kind:10100+kind:0, intersected/annotated with current community/channel membership, deduplicated by pubkey.This keeps the useful local-shortcut work in #4006, the cross-machine mention work in #4023, and the external CLI foundation in #3964 without conflating room membership, identity ownership, process custody, endpoint reachability, or conversational presence.
svenrawr-stock-well commentedon Aug 3, 2026
Additional source-level and prototype validation for this direction:
At exact Desktop tag
v0.5.2/ commit3e48f1b2365d326ee1c9582448d86a99b44ecd5d, the gap extends beyondAgentsViewinto first-class mention eligibility:desktop/src/features/messages/lib/useMentions.tsappliesisAgentIdentityInManagedList(...)before accepting an agent mention candidate.desktop/src/features/agents/lib/agentAutocompleteEligibility.tsaccepts an agent identity only when its pubkey is in the Desktop-local managed set.This creates a cross-client inconsistency: Mobile can mention an externally managed relay agent that Desktop omits. An honest relay-only workaround cannot fix unmodified Desktop without fabricating local ownership or misclassifying the identity.
We built a non-deployed Desktop v0.5.2 prototype to test a stricter projection. It admits an external identity only when signed
kind:10100metadata, active viewer membership, authoritativebotrole, advertised channel scope, and invocation policy agree. It keeps that identity outside managed persistence and every start/stop/edit/delete/configuration/reconciliation path, while enabling the existing pubkey for normal signed mentions and a read-only external-agent directory card.Validation completed:
The remaining design question is where Buzz wants the canonical authority contract resolved—relay/community API, shared client library, or per-client logic—and how replacement, freshness, revocation, archive/leave, and older-client behavior should work. We are intentionally holding the prototype rather than proposing code until maintainers confirm the preferred contract and implementation shape.
mikececco commentedon Aug 3, 2026
Opened #4537, which does the "derive online/offline from presence facts, not a static profile field" piece raised in this thread. It's only that piece — it deliberately doesn't touch the Agent View rendering, since several PRs are already in flight here and I didn't want to compete with them.
The specific defect:
agents_from_events(desktop/src-tauri/src/nostr_convert.rs) insertsstatus: "offline"whenever akind:10100profile carries no status string. Nothing in-tree ever writes that field — the only in-tree writer ofkind:10100iscmd_set_add_policy, which setschannel_add_policy— so the fallback is taken for every relay-discovered agent, andPulseViewbuilds its status map straight off it.Meanwhile real presence already exists (
kind:20001, 180s Redis TTL inbuzz-pubsub/src/presence.rs, exposed client-side viausePresenceQuery). The two were never joined.#4537 joins them, preferring presence where it has an entry and falling back to the incoming status otherwise (so locally-managed agents keep their process-handle status, and there's no flicker before the query resolves).
It should compose with whichever Agent View PR lands rather than conflict — the merge is a pure function in
agents/lib/agentPresenceStatus.ts, reusable by the other roster surfaces (useMentions,useNewMessageRecipients,useTrayMenu).ezrahill commentedon Aug 6, 2026
+1 for this
murdawkmedia commentedon Oct 3, 2026
Update to my August composition notes: #4006 has been closed, and #3964 was rewritten at
0ba5a866to generic CLI commands. It now verifies event IDs/signatures and preserves signatures in stream output; the earlier profile writer is absent. My old composed-head checks therefore do not validate the current branches or Desktop roster/mention flow. #4537 remains open and covers presence status only. I have not retested current Desktop behavior.ngoclt commentedon Oct 10, 2026
+1 for this.
Sometime the agents got stopped/stuck and there is no way for us to see what was happening.
murdawkmedia commentedon Oct 11, 2026
Follow-up on the latest stopped/stuck-agent report, with current source and tests rather than my old August composition.
At
main30873ba, externally hosted relay agents can now qualify for mentions throughgetMentionableAgentPubkeysand the ownership, invocation-policy and channel-membership rules. The earlier local-managed-only description is stale. In an isolated checkout using Node 24.15.0 and the existing test loader, the eligibility, active-turn store and working-signal test files passed all 131 checks. That includes same-owner agents across machines, channel admission, stale observer events and turn-liveness pruning. This was a focused source/test run, not a Desktop or deployed-fleet retest.The Agents view still feeds
agents.managedAgentsintoUnifiedAgentsSection, so the read-only community roster requested here remains a separate gap. Current profile/card availability code already reads relay presence; Pulse'sagentStatusMapstill reads the profile-deriveda.status. I also ran #4537's unchanged helper tests at3f6a437: all six pass, but that PR handles presence display rather than stalled work or the external roster.For the stuck case, it would help to show presence and last observed work/liveness separately. An online bridge can have a stuck turn; expired or unavailable observer data should not imply successful completion. This also fits
VISION_REMOTE_AGENTS.md: presence describes conversational availability, while unhealthy-substrate diagnostics remain host-owned. A roster should reuse the existing availability/observer signals without granting local lifecycle controls over external identities.