Repository navigation
Conversation
A board refresh walked the thread tree with one threads.list call per
node, read every thread's timeline one at a time, then made up to four
more reads per thread in a second serial loop. On a 24-thread tree that
was 69 requests with at most 2 in flight.
- Read the tree with one experimental_listDescendants call plus one
batched threads.list({ threadIds }) row read, and run each thread's
timeline, model, output, event and queue reads in parallel (six
threads at a time). partial is now only set when a thread was left out.
- Match threads the board has not seen (for example a grandchild created
between refreshes) to their root with one batched
experimental_listAncestors read per tick instead of a threads.get per
thread that only matched direct children.
- Read board and global snapshots with experimental_useRpcQuery and
invalidate their tags from the watcher; the host handles refetch,
races and reconnects.
- Drive the watcher, Redteam and Fleet pollers and the global page's
20-second discovery refresh from bb.rpc.experimental_whileWatched
instead of 90-second leases, so they stop when the view closes.
- Register the board with app.slots.experimental_tab; threadPanelAction
is retired.
- Read the Codex goal from the timeline's extension state (BB 0.49
removed the timeline goal field), falling back to the old field.
- Require BB 0.47 / plugin SDK 0.6.73 for these APIs; develop against
SDK 0.6.132.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Human comments
What was wrong
Each board refresh did its BB reads one at a time. The tree walk made one
threads.list({ parentThreadId })call per thread, plus an extra probe at the depth limit. Each thread's timeline was then read in a serial loop, and a second serial loop made up to four more reads per thread (model, output, events, queued messages). On a 24-thread tree that came to 69 requests with at most 2 in flight, repeated on every invalidation. The board was also marked partial whenever it reached 24 threads, even when nothing was left out.The watcher looked up unseen threads with one
threads.geteach and only matched direct children of known threads, so a grandchild created between refreshes was missed. The Redteam and Fleet pollers ran on 90-second leases, so they kept running after the board closed. The global page also had a 20-second timer in the browser.Two of the APIs the plugin uses have since been retired in BB.
threadPanelActionis gone from SDK typings in favour ofexperimental_tab. BB 0.49 also removed the timelinegoalfield, so the board's goal line is blank on 0.49.What changed
lib/collect.ts): onebb.sdk.threads.experimental_listDescendantscall plus one batchedthreads.list({ threadIds })row read replace the per-node walk. A newplaceTreeapplies the same depth and count caps and keeps the same sibling order.partialis now true only when a reachable thread was actually left out. The 1-second tree cache is kept.mapWithConcurrency.lib/watch.ts,server.ts): threads the board hasn't seen are matched to their root withexperimental_listAncestors. Lookups made in the same tick are batched into one call of up to 200 ids. This covers grandchildren of threads the board hasn't seen yet, not just direct children.hooks/useBoard.ts,hooks/useGlobalDashboard.ts,contract/rpc.ts): the board and global page read their snapshots withexperimental_useRpcQuery. The contract tags themboard,board:<rootThreadId>andglobal-dashboard, and the watcher callsbb.rpc.experimental_invalidate. The host handles refetching, race guards and reconnects. Theagent-board-changedrealtime signal is still published for the Timeline dialog and the global page's health line. Dismissing attention items now invalidates the global tag on the server.lib/redteam-poll.ts,lib/fleet-poll.ts,server.ts): the watcher, Redteam and Fleet pollers and the global page's 20-second discovery refresh now start throughbb.rpc.experimental_whileWatched. They stop when the last client leaves or hides the tab, which replaces the 90-second leases and the browser timer.app.tsx):app.slots.experimental_tab({ context: { kind: "thread" }, availability: "action", ... })replacesthreadPanelAction. The idagent-boardis unchanged, so saved tabs keep working.lib/bb-source.ts): the goal is read from the timeline'sprovider-codex/goalextension state, falling back to the oldgoalfield on older BB. The contract's goal status now also acceptsblockedandusageLimited.engines.bbis>=0.47andengines.bbPluginSdkis>=0.6.73, the first versions with all of these APIs. Development types are now SDK 0.6.132; under that SDK,TimelineResponseis narrowed to the full-page result. README, PLUGIN_OVERVIEW, CONTRIBUTING anddocs/architecture.mdare updated to match.After a release, the Community marketplace description ("Requires BB 0.40+; BB 0.46.0 recommended") will need updating to BB 0.47+. To reach existing installs under the catalog's
^0.7.0range, the release should be a 0.7.x tag (for examplev0.7.1). Hosts older than BB 0.47 will refuse the update as incompatible and stay on 0.7.0.scripts/verify-package.mjsstill expects artifacts built with BB 0.46.0. It fails when built with any newer BB, with or without this change, so I left that pin for your next release.How you verified
npm run typecheckis clean andnpm testpasses (480 tests). New and updated tests cover:bb plugin buildsucceeds with no retired-API warnings.mainvs this branch:board_snapshotRPC withfresh: true, median / p90partialfor the exactly-24-thread treeThe cards and root summary were identical between the two versions; only
partialchanged. The remaining 48 requests are per-thread timeline and model reads, which BB has no batched API for.