Repository navigation
Conversation
Agents2 listened only to the selected community, and the Claude Code and Codex runtimes stopped the processes of agents that left that list, so switching communities killed work mid-turn and left the other community unheard. Agents2 now binds each joined community the viewer has an agent in (opened through a new Communities.open, without selecting it), delivers each community's live events only to its own agents, and exposes the running agents and each agent's community connection. The runtimes keep processes for every running agent and read conversations, names and memory from the agent's own community. Processes stop when the agent is deleted, its community is left or disconnected, or the viewer signs out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Honey <8e307ae0076a4dab6b94b036ea3edc7e08f823a625269c1e6919e881a048b4d2@buzz.block.builderlab.xyz>
A first connect that fails leaves the session in error, and only the selected community has a Retry the viewer can press. Agents2 now tries an unselected community's failed connection again every 30 seconds, so its agents recover without the viewer opening it. Also covers Communities.open directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Honey <8e307ae0076a4dab6b94b036ea3edc7e08f823a625269c1e6919e881a048b4d2@buzz.block.builderlab.xyz>
Each Claude Code agent kept its own warm `claude` process and up to six processes in all. With agents in many communities kept running, that is one idle ~300 MB process per agent. Starting the process is what a spare saves (time to turn start ~530ms cold vs ~45ms warm, measured against claude 2.1.296); sending `initialize` costs almost nothing. So the spare is now spawned without `initialize`, fixing only its folder and model, and the agent that takes it sends its own prompt and installs its own tool handler. One spare serves every agent; it follows the latest new conversation, and is replaced when no agent runs where it was started. The per-agent process cap is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
A conversation whose launch finished after its last agent was removed took the spare and started a replacement, which then stayed with no agents. Taking the spare now refills it only where the runtime wants one, so stopping the last agent (`warm()` with no places) is final. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
- A native agent list still being read when Agents2 stops is now stale, so it cannot reopen agent communities after teardown. - Codex follows `running` whatever the inventory status, as Claude Code does, so a failed refresh no longer keeps a stopped agent's server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Codex agents each kept their own `codex app-server` (~300-400 MB with its MCP children) until the agent stopped running. With agents now running in every joined community, that cost grew with every Codex agent used. Everything agent-specific already travels with the thread: cwd, developer instructions and dynamic tools go in thread/start, and tool calls carry their threadId. So the runtime now owns one server, opened on first use in ~/.buzz, and finds a tool call's agent by thread and turn across all agents. Entries keep their conversations and saved bindings but no longer own a process. A stopped agent can no longer take its process down with it, so it interrupts its own turns, then cleans the background shells its threads left (a dev server from a finished turn, say). Starting the same agent again waits for that, so it never resumes a thread mid-teardown. The server ends with the last Codex agent, on dispose, or on a crash (the next mention reopens it). live.mjs passed the relay as an object since the per-agent relay change; it now passes a function, expands ~ like the desktop host, and checks two agents on one real server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
`bin/node scripts/session-debug.mjs '<thread>'` serves a loopback page that follows a Codex or Claude Code transcript as it is written. The left rail is a vertical wall-time chart: inference, tool waits and their overlap, gaps nobody is accounted for, and idle time between runs, with each call's new tokens marked beside it. A grey band shows which part of the session is on screen. The conversation shows one harness/model/effort line, compact tool rows, and messages posted to Buzz as cards, so text the agent never sent stands out. Claude Code's zero-usage `<synthetic>` resume replies and queue bookkeeping no longer count as activity, which had been inflating inference time. The standalone exporters pick up the same tool rows and posted-message cards. Started by codex00; chart and conversation design by claude00. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Squashed-from: baxen/session-debug Squashed-head: 84d70727ddf9db15c352f070634ab47f7adb682f Signed-off-by: Bradley Axen <baxen@squareup.com>
The session page hid every instructions entry, so even Codex's recorded base instructions and dynamic tools never appeared. Model-visible context now shows as quiet collapsed rows where it was recorded, without a proxy: - Claude: the system prompt and tool schemas from Claude Code's `prompt_snapshot` records, one disclosure per tool. Each snapshot pair counts as one, and repeats only show when the prompt or tools change. Every injected reminder (environment, skills, CLAUDE.md, hook context) is shown with its rendered text and role. - Codex: base instructions, dynamic tools per tool, run settings from `turn_context` whenever they change, and developer/AGENTS.md context named by its tag. A one-line reminder also shows inline, such as the token count. Request framing, Claude's deferred tool schemas and Codex's native tool schemas are not recorded, and the page says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Squashed-from: baxen/session-debug Squashed-head: d7e8a3c248cdbbb693fdba2ef4c9262e412f21d8 Signed-off-by: Bradley Axen <baxen@squareup.com>
baxen
force-pushed
the
baxen/agent-presence
branch
from
October 11, 2026 21:52
a849850 to
8e39587
Compare
baxen
force-pushed
the
baxen/agent-working-reactions
branch
from
October 11, 2026 23:11
71f044f to
737b32d
Compare
baxen
force-pushed
the
baxen/agent-presence
branch
from
October 11, 2026 23:11
8e39587 to
3c33201
Compare
…page Browser fixtures scan every HTML file under the repo root, and scripts/session-debug.html imported "client.js", which only the inspector's own server maps to a real file. The scan failed, Vite skipped pre-bundling and re-optimized mid-test, and the reloads broke browser journeys across both engines. The page now names its files as they are on disk and the server serves them under those names, so the vite.config.ts exclusion (which fixture servers never read) goes away. Co-authored-by: claude00 <fb8b76a01257932b8ca35060862c29bd09b2137638573731c2d5074fc02c5385@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Mentioning your own Claude Code or Codex agent shows a gauge in the composer. Its popover is an effort slider with the model name in the slider's tab; the name opens a compact menu of the agent's models. The pick rides on that message as `model` and `effort` tags for that agent, and the host honors them only from the owner and only for listed models and levels. - Codex passes the pick to `turn/start` for that turn only. - Claude Code lists models from `initialize`, sends `set_model` and `apply_flag_settings` ahead of the picked turn, and restores its own on the next unpicked one. - The slider opens at the effort an unpicked run uses (Claude Code's session effort, Codex's configured effort or the model's default); moving back to it is no pick. - A configured Codex model its CLI does not list keeps the picker, with the listed models still pickable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Squashed-from: baxen/model Squashed-head: 053cee0dba93bb946f544c0c87804ceee90a49ef Signed-off-by: Bradley Axen <baxen@squareup.com> Co-authored-by: Codex <noreply@openai.com>
baxen
force-pushed
the
baxen/agent-working-reactions
branch
from
October 11, 2026 23:55
737b32d to
84e88c1
Compare
baxen
force-pushed
the
baxen/agent-presence
branch
from
October 11, 2026 23:56
3c33201 to
d52ccdb
Compare
Composer model controls also use a popup class. Select the completion-specific data-mention variant instead of whichever CSS module loads first. Preserves all token and geometry assertions; reproduced before and passed in Chromium and WebKit after. Co-authored-by: codex00 <6922125dbee102fcf02d2b32441fd56927c1298ac16119167f82f72529d13676@buzz.block.builderlab.xyz> Signed-off-by: Bradley Axen <baxen@squareup.com>
Store optional picture and about fields on Agents2 identities and publish them with the name. Track accepted metadata so updates and clears publish even without a rename. Preserve compatibility with older rows and publication receipts. Implemented with goose AI assistance. Human acceptance: green confirmed working. Signed-off-by: Bradley Axen <baxen@squareup.com>
Agents2 can now take over an identity that the harness controller or old Buzz (installed or dev) saved on this machine. It keeps the key, name and picture, and leaves the instructions and settings behind. Neither old store is written. - port.rs lists both stores as one flat list, one entry per key. The harness copy wins because its key is already in this app's store. It also re-reads an identity and its key at take-over time. - AppAgents::adopt is prepare with an existing key. When a harness agent saved for the same community already holds the key under the same credential ID, commit shares that key and never adds or withdraws it. Without this, a failed add would have deleted the harness copy. - An adopted agent keeps the profile its community already has. Without one, it publishes the name and picture it brought. If the read fails, it overwrites nothing until the agent is renamed. Agents2 profiles gain an optional picture. - Adds a "Bring over" side panel on the Agents2 page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Adapt adoption to the metadata layer so accepted pictures and descriptions are recorded with the name. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Erase kept only the earlier agent registry: "keep agents" wiped agents2/identities.json, orphaning its keys, and "remove agents" deleted only keys listed in the earlier registry. Both registries are now kept, and removing agents deletes the keys of both. A rename republished an adopted agent's profile with only its name, bot flag and picture, dropping about, banner, NIP-05 and the rest. It now reads the community's current profile and changes only the name and bot flag, adding the picture only where there is none. The Agents2 grid, peek and build view now show the picture an agent brought over instead of only its initials. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Import authored descriptions and retained pictures from legacy and harness records. Publish ordinary stored metadata and track accepted picture/about changes without a persistent adopted flag or community-profile preservation path. Retain transient shared-key custody protections and compatibility with saved adoption flags. Implemented with goose AI assistance. Validated on tail with 46 controller unit tests, 5 integration tests, 4 native host tests, formatting and diff checks. Live tail acceptance remains deferred. Signed-off-by: Bradley Axen <baxen@squareup.com>
Agents2 had no way to set a picture, and its grid, peek and build view
passed raw relay media URLs straight to <img>, which community media
refuses without the media proxy, so even agents brought over with a
picture showed initials.
AppAgents::set_picture (app_agent_set_picture) saves or clears an HTTPS
picture; Agents2.save takes { picture } and republishes the profile
through the existing refresh. The build view's identity rail uses the
shared AvatarEditor (uploads as the owner, like your own profile), and
every agent portrait goes through useAvatarPreview.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
…d agent-mention popups Delete the bundled Agents and Channel templates plugins and every v1 mention popup: wake notices, owner-review requests, the mention attach path in agent control, and snapshot previews. Adding an agent to a channel no longer starts it. Settings > Agents keeps only "Remember mentioned agents" and the saved activity archive. The shell's collapsible-sidebar, retry and icon special cases move from the v1 Agents page to Agents2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Keep the Profiles panel for people and Agents2 agents, and drop only what served v1 agents: Runtime, Instances, harness log, start/stop/restart, archive, Memories, Add to channel, exact-instance targets and the kind-10100 Agent type and Capabilities rows. Human profiles render as before. Agents2 agents keep their type's tabs and Delete, and Message for an agent follows the Agents2 LocalAgents snapshot. Browser fixtures use LocalAgents instead of AgentControl; v1-only cases are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
…g and security With the v1 Agents page, Profiles and Channel templates gone, the services behind them have no consumer. Delete v1 AgentControl and its native bridge, AgentSecurity, agent snapshots and snapshot sharing, team bundles and import, the community catalog, the agent-management request lease, and the channel kit's team payload/text write paths. Names, mentions and New message now read a LocalAgents snapshot published by Agents2 (the viewer's own live identities) instead of v1 native control, so Agents2 agents stay "managed" for DMs and mention invitations. The plugin author API no longer exports the AgentControl or AgentSecurity types. Docs drop agent-control.md and agent-security.md and describe the remaining agent surfaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Templates & teams was the only TemplateProviders contributor, so with it gone the extension point only rendered empty slots and "templates are off" notes. Remove ctx.channelTemplates and its editor, group-default and save-as slots from Create channel, the channel menu, Channel settings and Personal groups. Create now sends name, privacy, duration and destination group only. The channel kit model and session setup stay: groups and Canvas depend on them, and frozen setup receipts saved by earlier builds still retry with their original agents and Canvas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Nothing in the frontend drives the v1 agent controller any more. Delete AgentHost and every agent_control_* command, agent_security, native model discovery (agent/codex/goose/pi models), harness installers and managed npm, media_snapshot_read, the kit team-catalog reader and the agent supervisor dispatch, with their build.rs, capability and permission-test entries, plus the orphaned authorize-agent route in native-api and the dev broker. Drop the now-unused buzz-agent dependency. Agents2's app_agent_* commands are unchanged; app_agents.rs now owns the NIP-98 header helper it borrowed from the v1 module. Quit, update restart and sign-out no longer wait on a native agent host: Agents2 agents are plugin host processes that stop when Buzz exits. Sign-out still deletes keys listed in the v1 agent registry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Stop building and shipping the unused v1 agent runtime. Keep desktop launch, application signing, installer verification and AppImage launch repairs. Trim the controller crate to Agents2 identities, credentials, profile signing and legacy import. Preserve legacy key deletion with bounded registry reads, identity validation and controller locking, without retaining the v1 runtime. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
…e it is used With the v1 controller gone, credential locking is its only caller, and that is compiled only on macOS and in tests. Linux and Windows lint failed on the now-unused function. Co-authored-by: claude00 <fb8b76a01257932b8ca35060862c29bd09b2137638573731c2d5074fc02c5385@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Until Agents2 agents show as typing, the host reacts to a mention as the agent with 👀 and 💬 when its run starts, and deletes both once the run and the work it handed off have settled (at most the longest run allowed). Plugins return from `run` early and finish their turns in the background, so `Delivery.workingUntil(done)` lets them say when that work settles. Claude Code and Codex now call it. The reactions live in working-reactions.ts and its one call in the service, so they can be deleted once typing indicators ship; `workingUntil` stays for those. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
STOPGAP until agents' typing pulses reach the relay: the host shows a mention's agent typing in the mention's thread on this device only, for as long as the run counts as working. Every 3 s it feeds a pulse into the session's existing typing store through a new `typing.local`, so expiry and the agent's reply ending it work as they do for live pulses. Every piece is tagged STOPGAP(agent-local-typing); grep for it and delete what it marks to retire this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Codex makes one more model call after a final send before its turn ends, so the request's working handoff, and with it the agent's working reactions and typing, outlasted its reply by about 3s. The handoff now settles at the final send, for every request the turn has taken in by then. The turn itself still ends on its own: interrupting it would leave a <turn_aborted> note in Codex's history after every reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
baxen
force-pushed
the
baxen/agent-working-reactions
branch
from
October 12, 2026 00:12
84e88c1 to
ba9b31b
Compare
App-hosted agents have no socket of their own, so they always read as offline, and an owner cannot tell from another device whether the laptop running them is awake. Each origin now sends one owner-signed kind 20003 batch for the agents this copy holds and runs: on a new session, when the set changes, and every minute otherwise (presence expires after three minutes). Agents it stops running are said offline, unless another copy has taken them over. A refused send is retried after 30 seconds rather than every tick. Relays without kind 20003 ignore it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
baxen
force-pushed
the
baxen/agent-presence
branch
from
October 12, 2026 00:14
d52ccdb to
31a8ded
Compare
matt2e
force-pushed
the
baxen/agent-working-reactions
branch
from
October 12, 2026 05:51
ba9b31b to
04c3944
Compare
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.
Summary
Stacked on #860. Needs block/buzz#8261 (kind 20003) on the relay; until that deploys, relays ignore these events and nothing changes.
App-hosted agents have no socket of their own, so they always read as offline — and an owner can't tell from their phone whether the laptop running them is awake.
RelaySession.publishAgentPresence(status, agents, signal): signs one kind 20003 event (content = status, aptag per agent) and publishes it on the live socket. Ephemeral: never queued or retried by the outbox.Agents2Service.announce(), per origin, from the 5s tick and after each update:mayHold, after its claim was answered) and runs, with a live binding.yielded), so a handoff doesn't flash offline.Testing
service.test.ts: online every minute + on a new session + offline on removal; an agent held by another copy is never said online or offline; a refused send is retried after 30s. Mutation-checked (ownership/yield/backoff removal each fail a test).vitest run src/features/agents2 src/features/relay src/bundled/agents2: 112 files, 2047 tests pass.tscclean.🤖 Generated with Claude Code