Repository navigation
Conversation
added 10 commits
October 6, 2026 20:43
Agents are plugins from the start: a type registers run, a card back, and tabs on ctx.agents2. Attention follows agent-attention/v1 in a local store behind a one-object-per-write interface. Identity keys stay native; run gets a stable agent handle and an AbortSignal (timeout or removal). Signed-off-by: hMurderbot <219c58afff8ac2c76e4e527a329aa61c2ebbb896786b1916d4f9cca5140ecd04@buzz.block.builderlab.xyz>
…alog The desktop catalog comes from plugin-manager's bundled list, so bundles missing there never activate in the app even though the web catalog has them. Signed-off-by: hMurderbot <219c58afff8ac2c76e4e527a329aa61c2ebbb896786b1916d4f9cca5140ecd04@buzz.block.builderlab.xyz>
…host The harness AgentHost holds an exclusive lock on its agent storage, so a second Buzz app (e.g. one running main alongside this branch) made every Agents2 create/delete/publish fail with "Another Buzz app owns this agent storage". Agents2 keys only need the OS credential store, whose bundle lock is per-operation and safe across processes, so AppAgentHost now holds its own PlatformCredentials. Also drops Option::take_if (MSRV 1.77).
Create asked the harness command agent_control_create_authorize for the owner's NIP-OA tag. That command checks the harness AgentHost's pending request, so it failed with the harness storage lock error while another Buzz app was open, and would have refused Agents2's key anyway. Add app_agent_create_authorize, which attests only the key Agents2 prepared, for the owner it was prepared for.
Drops the card flips. The page now has three frames: - Inventory: agents as tiles (portrait, name, the type's summary line) in a listbox. Click or arrow keys select; Enter or double-click opens; Esc clears. - Peek: a side panel beside the grid with identity, the type's Peek, what wakes the agent, and Open. - Build: an identity rail (inline rename, type, key, delete) and the type's tabs followed by the app's Attention tab. New agents are made in the side panel (name, type cards with descriptions) and go straight to Build. Attention is the app's: every Agents2 agent is woken through agent-attention/v1, so AttentionPanel (interests with their watches and timers, switches, forms, raw JSON fallback) replaces the plugin-hosted AttentionEditor. The profile panel gets the same Attention tab. Contract: `Back` becomes `Peek`, and types may add `summary(agent)`. Responder is updated to match.
Runtime - Only chat kinds (9, 40003, 40007, 46010) address an agent, so reactions to or deletions of its messages no longer wake it. DMs (kind 4) are no longer treated as mentions: run could neither read nor answer one. - One owner's agents no longer wake each other by replying: a sibling's event reaches another agent only as a fresh mention, never as a reply or a watch. - Runners are long-lived, one per saved agent. Edits no longer abort the in-flight run, drop the queue or reset the rate window; each job reads the agent and config as it starts, and watches recompile when attention changes. A run aborts only when its agent is removed or its type is replaced. - Agent state has one owner: timer run state moves into each record (so it goes with its slug or agent), seen/wrote live on the runner, and records whose key is gone are dropped when identities load. - create no longer fails after the agent exists when its profile publish fails. - The relay snapshot exposes the community origin, so create stops parsing the partition key. Native - App agent identities lock read-modify-write across app instances. - Pending creates are kept by pubkey, so concurrent creates don't collide. - list and publish read the identity file off the async runtime. Contract - Peek receives only the agent. Type tabs receive save(config): the app owns the name and attention. - Responder is written the way an external plugin must be: ctx.react and type-only imports, plain HTML controls. UI - agentSections() builds the type's tabs plus Attention for both the Build view and the profile panel. - Attention model helpers move to attention.ts; editing an existing watch is its JSON only, the forms add. - Key shown with formatPublicKey; "Copied" resets.
… of view - load() prunes only records that existed before it listed identities, and merges identities created while the list was in flight. - drain() pauses (without consuming jobs) while the agent is not visible; update() resumes queued runners after publishing the snapshot. A type that cannot run still drops the queue. - Disposal clears the shown agents without reconciling runners. - Document that tab save() replaces the type's whole config.
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.
Combines Logan's agent-attention/v1 coplan spec with the plugin agent-type idea from #621. It adds a new Agents2 page and leaves the existing harness agents untouched.
What's here
ctx.agents2:{ id, title, defaults, run, CardBack, tabs }.interest/<id>andwatch/<id>slugs, each{ value, modifiedAt }. Next to them is a plugin-ownedconfig. Each write changes exactly one object, behind a small interface, so a relay backend can replace localStorage later.mentiontrigger instead.armed_at, interval,max_occurrences,expires_at, and no burst catch-up. Timer state is stored separately from config.run({ trigger, agent, config, signal })gets one stable agent handle (pubkey,name,owner,publish) and anAbortSignalthat fires on timeout or agent removal. Runs execute one at a time per agent. There is no per-run identity fencing (unlike Add plugin agent types: agents a plugin defines and the app runs #621).crates/agent-controller/src/app_agent.rsplus the Tauri commands insrc-tauri/src/app_agents.rs.<relay>/events.CardBack.responderthat replies with configured text when a watch or mention fires.FOUNDATION files (edited per baxen's direction; please review closely)
src/app/services.ts: one service added.src/features/relay/session.ts:subscribeLive/LiveBatch, ported from Add plugin agent types: agents a plugin defines and the app runs #621.Checks
pnpm typecheckpasses, andbiome checkis clean.vitest runpasses.pages.integrationcounts were updated for the new page.cargo test -p buzz-agent-controllerpasses, including the new app_agent tests.cargo testfor src-tauri: everything passes except 3host_commandtests. Those failed only in the parallel run and pass when run alone; this PR doesn't touch them.Status: ready to try, not validated. Not done yet: an in-app run of create/flip/edit/responder, an independent agent review, and review of auth/signing.
Non-goals
Relay storage for attention, classifiers, and migrating harness agents.
Possible split
subscribeLive