Skip to content

feat(agents2): show agents as typing while they work on a mention - #792

Closed
baxen wants to merge 2 commits into
mainfrom
art/agents2-typing
Closed

baxen wants to merge 2 commits into
mainfrom
art/agents2-typing

Conversation

@baxen

@baxen baxen commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Depends on block/buzz#8207. Until that relay change is deployed, the relay rejects every pulse. Each mention run then sends one failed pulse and stops, so nothing breaks, but no typing shows.

What it does

An Agents2 agent now shows as typing while it works on a mention, the same way buzz-acp agents do.

  • Host (Agents2Service.drain): when a mention starts a run, the host signs a kind 20002 typing pulse right away and another every 3 s. It goes in the mention's channel and thread, tagged where the agent's reply lands: e <thread root> root when the mention is already in a thread, plus e <mention> reply. Watch and timer runs send no typing, because they often post nothing.
  • Hook: Delivery.workingUntil(promise). A type that hands its work off and returns from run early can pass a promise for that work. Pulses then continue until run has returned and every promise passed in has settled. Claude Code (Claude Code agents on Agents2 #732) returns from run about 300 ms in, so it needs one call, workingUntil(done). That goes into Claude Code agents on Agents2 #732 when it rebases onto this.
  • When pulses stop: when the run ends (as above), when the agent is removed or its type is replaced, after 30 minutes, or after a pulse fails. Stopping on failure means a relay that refuses typing is asked once per run, not every 3 s.
  • Native: an agent may now sign kind 20002 (app_agent.rs KINDS). This part is ART's change.
  • Pulses never count as something the agent wrote. The host signs them through native directly, not the run handle's publish. The agent's own pulses that come back over the live stream are also kept out of wrote, so they can't push real messages out of the set that makes replies to the agent count as addressed.

Known gap

For a top-level mention the pulse is scoped to the thread the reply starts. That is the correct place, but you only see it with that thread open. The "agent working" indicator on the root message row (MessageRow.tsx useThreadAgents) and the sidebar dot only count session.agentChoices, and Agents2 agents aren't in it. Mentions inside an open thread show typing. Fixing the root-row and sidebar indicators means bringing Agents2 agents into shared agent selection, which is a separate change.

Testing

  • service.test.ts has 4 new cases using fake timers. They cover: the pulse tags for a thread mention and for a top-level mention; pulses continuing past run while handed-off work runs, then stopping; no typing for watch runs; stopping after a failed pulse and after the agent is removed; the 30-minute cap; and the agent's own echoed pulse not counting as something it wrote. I checked that the new tests fail when the hook or the wrote guard is removed.
  • The agents2 and bundled agents2 Vitest suites pass, and so do tsc and biome. cargo test -p buzz-agent-controller app_agent and clippy pass.
  • Live, against a local relay built from feat(relay): accept typing indicators over HTTP POST /events buzz#8207: I ran the real Agents2Service with native replaced by a stand-in that does what native does (attach the owner attestation, sign as the agent, NIP-98 POST /events with x-auth-tag). A channel member's WebSocket received pulses at 0.02 s, 3.0 s and 6.0 s during a 7 s workingUntil turn, and none after it ended. Each was tagged h + e <mention> reply + the attestation. No 20002 rows were stored.
  • Not done: the native desktop app (Keychain gate) and a human test.

To test by hand: run a local relay from block/buzz#8207 and point the desktop app at it. Mention an Agents2 agent inside a thread and open that thread. " is typing…" should appear within a moment and stay while the agent works. With #732 plus the workingUntil(done) line, it should last through Claude's whole turn and clear when the reply posts.

🤖 Generated with Claude Code

baxen and others added 2 commits October 9, 2026 13:45
The Agents2 host now sends a typing pulse (kind 20002) when a
mention-started run begins and every 3 s after, in the mention's channel
and threaded where the agent replies. Pulses stop when the run returns,
or, for a type that hands its work off and returns early, when every
promise it passed to the new `Delivery.workingUntil` has settled. They
also stop when the agent goes away, after 30 minutes, or after a pulse
fails, so a relay that refuses typing is asked once per run.

Native may now sign kind 20002 for an agent. Pulses are signed through
native directly and the agent's echoed pulses are not recorded as
something it wrote, so they cannot push real messages out of that set.

Needs the relay to accept typing over HTTP POST /events (block/buzz#8207).

Signed-off-by: Bradley Axen <baxen@squareup.com>
Co-authored-by: ART <ea39c1c8acf57180161ef4ba4ed68abf8589f5291956b909a5aa991fc66664ca@buzz.block.builderlab.xyz>
Co-authored-by: Honey <8e307ae0076a4dab6b94b036ea3edc7e08f823a625269c1e6919e881a048b4d2@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code's run returns as soon as the turn is handed to its session,
so typing stopped after the first pulse. Hand the turn's promise to
`workingUntil` so the pulses last until the turn settles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Honey <8e307ae0076a4dab6b94b036ea3edc7e08f823a625269c1e6919e881a048b4d2@buzz.block.builderlab.xyz>
@baxen

baxen commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Superseded by #860 (local typing while an agent works), which is in the merge stack. Relay-backed typing can come back once block/buzz#8207 lands.

@baxen baxen closed this Oct 11, 2026
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