Skip to content

feat(buzz-acp): publish the kind:10100 relay-agent directory entry - #6097

Open
Schnitzel wants to merge 1 commit into
block:mainfrom
Schnitzel:acp/publish-agent-directory
Open

feat(buzz-acp): publish the kind:10100 relay-agent directory entry#6097
Schnitzel wants to merge 1 commit into
block:mainfrom
Schnitzel:acp/publish-agent-directory

Conversation

@Schnitzel

Copy link
Copy Markdown

The problem

An agent run by buzz-acp never appears in Buzz Desktop's @ autocomplete, however healthy it is, and nothing anywhere reports why.

Desktop builds its mentionable set as managed agents ∪ relay agents (desktop/src/features/agents/knownAgentPubkeys.ts):

  • managed agents are the ones the desktop holds a key for and runs itself. An agent created in the app is in this set immediately and needs no relay event at all.
  • relay agents come from kind 10100, filtered by relayAgentCanRespondInChannel — the entry's channel_ids must contain the channel being typed in, and its respond_to must admit the person typing.

A harness-run agent can never be in the first set, so kind 10100 is its only route. buzz-acp never publishes one. channel_ids is then absent, agents_from_events defaults it to [], and the agent is eligible in no channel.

The failure is silent end to end: no client-side error, and a mention typed by hand goes out with no p tag, so it routes nowhere either. From the user's side a perfectly healthy bot simply cannot be mentioned.

examples/countdown-bot's README attributes mentionability to the role=bot self-add. In testing against a current relay and desktop that was not sufficient on its own; publishing kind 10100 was what made the agent appear.

The change

Publishes the entry from state the harness already holds — the channels it discovered and subscribed to, plus its own author gate — at startup, and again whenever a membership notification changes the channel set.

  • only subscribed channels are advertised, so the entry never offers a mention the agent would not actually receive
  • on membership change the channel set is re-read from the relay rather than trusted from local bookkeeping
  • best-effort: discoverability is not worth failing a startup or dropping a membership update over, so failures are logged and execution continues
  • kind 10100 is replaceable, so republishing supersedes rather than accumulating

Two new flags, so existing deployments that publish this entry themselves are unaffected:

Flag Env
--no-publish-directory BUZZ_ACP_NO_PUBLISH_DIRECTORY
--display-name BUZZ_ACP_DISPLAY_NAME

name is omitted when unset rather than guessed, so clients fall back to the agent's kind:0 profile name and then its npub, as they already do. respond_to_allowlist is emitted only in allowlist mode, mirroring the inbound author gate so the people who may prompt an agent are exactly the people whose client offers it.

Testing

  • 5 new unit tests on the entry body: only subscribed channels advertised, names positionally aligned with ids, allowlist only in allowlist mode, blank names omitted, output stable across builds (so a replaceable event is not rewritten without cause)
  • full buzz-acp suite: 783 passed, 0 failed
  • cargo clippy -p buzz-acp --all-targets clean, cargo fmt applied
  • built and exercised against a live self-hosted relay, where the published entry made a previously invisible agent mentionable

Question for maintainers

Kind 10100 does not appear in any NIP under docs/nips/, unlike the other agent-facing kinds (NIP-AP, NIP-AE, NIP-AO, NIP-AA). If it is intended to stay an internal convention I am happy to adjust; if it should be specified, I would be glad to draft it. Happy to change the default to opt-in if you would rather this not publish without being asked.

@Schnitzel
Schnitzel requested a review from a team as a code owner August 17, 2026 03:53
A harness-run agent cannot appear in Buzz Desktop's `@` autocomplete
today, however healthy it is, and nothing reports why.

Desktop builds its mentionable set as managed agents ∪ relay agents
(`desktop/src/features/agents/knownAgentPubkeys.ts`). Managed agents are
the ones the desktop holds a key for and runs itself, so an agent created
in the app qualifies immediately and needs no relay event at all. An
agent run by buzz-acp can never be in that set, which leaves the kind
10100 relay-agent directory entry as its only route — and buzz-acp never
publishes one. `relayAgentCanRespondInChannel` then fails on an absent
`channel_ids`, so the agent is silently offered nowhere.

The failure is quiet at every layer: no error client-side, and a mention
typed by hand goes out with no `p` tag, so it routes nowhere either.

This publishes the entry from state the harness already has — the
channels it discovered and subscribed to, plus its own author gate — at
startup and again whenever a membership notification changes the channel
set. Only subscribed channels are advertised, so the entry never offers a
mention the agent would not receive. On membership change the channel set
is re-read from the relay rather than trusted from local bookkeeping.

Publishing is best-effort: discoverability is never worth failing a
startup or dropping a membership update over, so failures are logged and
execution continues. Kind 10100 is replaceable, so republishing
supersedes rather than accumulating.

Two flags, both opt-out/opt-in rather than changing existing behaviour
for anyone who already publishes this entry themselves:

  --no-publish-directory / BUZZ_ACP_NO_PUBLISH_DIRECTORY
  --display-name / BUZZ_ACP_DISPLAY_NAME

`name` is omitted when unset rather than guessed, so clients fall back to
the agent's kind:0 profile name and then its npub, as they already do.
`respond_to_allowlist` is emitted only in allowlist mode, mirroring the
inbound author gate so the people who may prompt an agent are exactly the
people whose client offers it.

Tests cover the entry body: only subscribed channels are advertised,
names stay positionally aligned with ids, the allowlist appears only in
allowlist mode, blank names are omitted, and output is stable across
builds so a replaceable event is not rewritten without cause.

Signed-off-by: Michael Schmid <michael.schmid@amazee.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant