Skip to content

Load attention and plugin tools on search - #1329

Merged
baxen merged 3 commits into
mainfrom
mbot/tool-groups
Oct 20, 2026
Merged

baxen merged 3 commits into
mainfrom
mbot/tool-groups

Conversation

@baxen

@baxen baxen commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

What

All agent tools stay on one buzz server, and each tool has a load of always or search. The thread on this PR settled on this design (one server, a flag per tool, and plugins can only use search).

  • Up front (always): the 15 core Buzz tools (send, read, react, …).
  • On search: the 11 attention tools.
  • Plugin tools: always on search. Only the core Buzz tools can be always, and the plugin contract (AddedTool) doesn't change. So installing plugins never adds to what every turn carries.
  • Hint: sessionHint tells the model what it can search for: attention, plus the names of any plugin tools.
Harness How the flag is delivered
Claude One in-process SDK server with no server-level alwaysLoad. tools/list marks each up-front tool with _meta["anthropic/alwaysLoad"], and the server's instructions is the hint.
Codex One buzz dynamicTools namespace. Searched tools get deferLoading, and the namespace description is the hint.
goose Unchanged: every tool up front and no hint, because goose can't load tools on demand.

Tool names don't depend on when a tool loads. Claude always sees mcp__buzz__watch_add, and Codex always sees buzz.watch_add. Plugin tool names share one space: they should start with the plugin's name (notes_*), and addTool already rejects a name that a Buzz tool or another plugin has.

Two prompt changes go with this:

  • Attention guidance: it is no longer in BUZZ_PROMPT. It now lives in the attention tools' own descriptions (interest_set, watch_add and the others), so a session pays for it only after it loads those tools.
  • End-of-turn note: an agent with attention on but no Interests now gets a one-line "you have no Interests" note instead of the full review. It doesn't have to search just to find nothing.

Live checks (real harnesses, probe scripts outside the repo, tool lists dumped from this branch)

  • Claude 2.1.296: send was called directly. interest_list was called after one ToolSearch (select:mcp__buzz__interest_list).
  • Codex 0.162 on gpt-6.1-sol: send was called directly. The model found the deferred interest_list and called it in namespace buzz.
  • Startup input tokens for a one-word reply:
    • Claude: 27.5k → 22.2k.
    • Codex: 22.2k → 19.5k.
    • These are measured against the same branch with every tool up front, so the ~1.2k-token attention prompt is not in either number.

Compatibility

  • Old Codex threads: a thread saved before this change is resumed as it is today. It keeps its tools, all up front with the old short attention descriptions, and its calls are still answered under buzz. It also gets the new system prompt, which has no ## Attention section, so until that thread is replaced it has neither form of the attention guidance. The binding key covers only plugin tools. Fixing this means keying on the whole tool list, which would start every Codex agent on a fresh thread once now and again whenever a Buzz tool changes. I left that out; it's a call for review.
  • Claude: each spawn passes the server config again, so resumed sessions pick up the per-tool flags.

Known gaps

  • Codex models without tool search: such a model would not see deferred tools. Every model in Codex 0.162's catalog has supports_search_tool, but a custom provider model might not.
  • Plugin tools on main: no plugin on main adds tools yet, so plugin tools on search are only covered by tests.

Checks

  • tsc and biome are clean.
  • Vitest passes for src/buzz-mcp, src/bundled, src/features/agents, src/features/agent-harness and src/plugins (238 files, 3,509 tests).

🤖 Generated with Claude Code

@salman1993 salman1993 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • [P2] Plugin namespaces can change without invalidating saved sessions. ToolGroup naming depends on registration order, while addedKey ignores that order. With valid plugin IDs foo.bar, foo-bar, and foo.bar.2, reordering registration removes the previously allocated foo_bar_2_2 namespace. Codex resumes the existing thread, then rejects its plugin calls with “No active Buzz tool for this thread and turn.” Fix: allocate names in a deterministic plugin-ID order and cover reordered registration through session resume.

Comment thread src/buzz-mcp/rpc.ts Outdated
tools: served?.tools ?? sessionTools(added),
tools: sessionTools(added).map(({ load, ...tool }) =>
search && load === "always"
? { ...tool, _meta: { "anthropic/alwaysLoad": true } }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can "anthropic/alwaysLoad": true go in bundled/claude-code/? buzz-mcp should be harness agnostic.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Done in 2f01c5a65. respond now takes a Listing from its harness: an optional instructions string, plus a function that shapes how each tool is listed. buzz-mcp only says which tools are always and which are search. The _meta["anthropic/alwaysLoad"] mark and the hint as server instructions now live in bundled/claude-code/runtime.ts.

@baxen
baxen marked this pull request as ready for review October 19, 2026 20:08
@baxen
baxen requested a review from a team as a code owner October 19, 2026 20:08
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T20:13:11.856587Z 348696f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 348696fd76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

type: "function",
...tool,
...(load === "search" ? { deferLoading: true } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Version Codex bindings before deferring shared tools

When upgrading an existing Codex conversation, this flag is never applied: thread/resume restores the thread's original tool definitions, while the resume check in runtime.ts only keys on addedKey(added), so a pre-release binding with no plugin tools still matches "". Consequently, existing conversations keep every attention tool and its old description eagerly loaded for their entire lifetime, preventing the main token/context reduction unless the workspace or plugin-tool set changes. Include a version or hash of the shared tool/load schema in the persisted binding key so each existing thread is recreated once.

AGENTS.md reference: AGENTS.md:L126-L129

Useful? React with 👍 / 👎.

@salman1993

Copy link
Copy Markdown
Contributor

lgtm!

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/flows) reviews.

Reviewed head 2f01c5a65bff8af3c5ad27668560943b63801387 against base/merge-base 7d50425b7fda7c0bfdccb897df0507a286d6bbac.

9/10 for the source change: no actionable source-demonstrated defects found. The single-server listing keeps harness-specific metadata in the adapters; plugin-name validation, attention authorization, and goose’s eager listing remain intact. Reviewed the 17-file diff and relevant callers, fresh/resumed/one-off sessions, attention toggles and error handling. No UI/focus transition changes were identified. The public PR description has no attached images; no disclosure issue found in that description or the reviewed commit messages.

Compatibility validation remains open: legacy Codex bindings retain their old tool schemas, while the PR description says resumed threads receive the new prompt without Attention guidance. However, src/bundled/codex/prompt.ts:34–35 and runtime.test.ts:2150 say the original developer instructions persist. The mocked test does not settle the upstream behavior. A resume check using a pre-change binding should establish which guidance the model actually receives; if it is lost, retaining compatibility guidance would avoid discarding conversation context. We have not established this as a runtime defect and do not recommend forcing fresh threads on this evidence alone.

Validation: source-only; no tests, builds, PR code, or live harnesses executed. One hosted-check snapshot showed CI required and its Linux/browser lanes passing; Windows native validation was skipped. Author-reported live probes and token savings were not independently reproduced. Native/live behavior, provider-version compatibility, performance measurements and human acceptance remain unverified. This COMMENT is not approval or merge authorization.

baxen and others added 3 commits October 19, 2026 20:34
Split the session tools into groups: `buzz` stays loaded up front, while
`buzz_attention` and one group per plugin load when the model searches for
them. Claude gets one in-process server per group (alwaysLoad only on
`buzz`, the group hint as server instructions); Codex gets one dynamicTools
namespace per group with deferLoading on searched groups. goose keeps one
flat server, since it cannot load tools on demand.

The attention guidance moves from the system prompt into the attention
tools' descriptions, and an agent with no Interests gets a short end-of-turn
line instead of the review, so it need not search to find nothing.

Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
Drop the tool groups for one `buzz` server where each tool has a `load` of
`always` or `search`. The Buzz tools load up front and the attention tools
on search; tools plugins add always load on search, so only Buzz decides
what every turn carries. Claude marks each up-front tool with
`_meta["anthropic/alwaysLoad"]`, Codex sets `deferLoading` on each searched
tool, and goose still gets them all. `sessionHint` tells the model what it
can search for. Tool names no longer depend on which group serves them.

Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
`respond` takes a `Listing` from its harness instead of a search flag, so
buzz-mcp stays harness-neutral: the Claude runtime marks up-front tools
with `_meta["anthropic/alwaysLoad"]` and gives the hint as instructions.

Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/flows) reviews.

Reviewed head 8b1020c286d4df72ff88c4a19c0a8d334f5e3917 against base 5992e69385474d5ee12fc542dc7a947c45ac725f.

9/10 for this rebase integration: no new actionable source defects found. Range-diff confirms all three feature patches are unchanged from the previously reviewed series ending at 2f01c5a6. We checked their integration with the new base’s storage, interruption/background-task lifecycle and media replies, including fresh, resumed, spare and one-off sessions. Tool dispatch authorization, plugin-name collision checks, Claude’s listing metadata and goose’s eager listing remain consistent with the shared contract. No UI/focus transition changes were identified. The public description has no attached images; no disclosure issue found in it or the three feature commit messages.

The prior review’s compatibility limitation remains unresolved: old Codex bindings retain their tool schemas, but source and mocked tests do not establish whether upstream resume retains the original attention guidance. No new evidence warrants a forced thread reset. Optional description clarification: qualify the “neither form” guidance claim as unverified, and identify the commit exercised by the reported live probes/tests.

Validation: source-only rebase/integration follow-up; no PR code, tests, builds, apps, live harnesses or performance probes executed. CI was not assessed this cycle. Prior author-reported tests/token savings were not independently reproduced at this head. Native/live compatibility, performance and human acceptance remain unverified. This COMMENT is not approval or merge authorization.

@baxen
baxen merged commit cb28028 into main Oct 20, 2026
33 checks passed
@baxen
baxen deleted the mbot/tool-groups branch October 20, 2026 03:52
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.

3 participants