Bundle per-thread reads into GET /threads/:id?include= and seed the caches (B5) - #1903
Closed
SawyerHood wants to merge 3 commits into
Closed
Conversation
SawyerHood
force-pushed
the
bb/mobile-perf/sidebar-bootstrap-patch
branch
from
August 19, 2026 07:42
b8b9615 to
ec7b0fd
Compare
SawyerHood
force-pushed
the
bb/mobile-perf/thread-bootstrap-include
branch
from
August 19, 2026 07:42
61e0f29 to
93e1c49
Compare
Opening a thread issued the bootstrap read (include=environment,host) and then five more DB-only GETs gated on it: pending interactions, queued messages, prompt history, default execution options, and tabs. On a phone over the connect tunnel that second hop delayed the composer becoming ready by a full round-trip. Extend the include= option set with pendingInteractions, queuedMessages, promptHistory, defaultExecutionOptions and tabs. Each bundled field is present exactly when requested and is produced by the same reader as its stand-alone route (moved into services/threads/thread-detail-reads so the two surfaces cannot diverge). The stand-alone routes stay for the CLI and SDK. The plugin SDK declaration bundle is regenerated for the widened contract type. Server-to-browser only; no daemon protocol change. Co-Authored-By: Claude <noreply@anthropic.com>
The thread bootstrap now requests the bundled per-thread includes and ingestThreadDetailBootstrap seeds the pending-interactions, queued- messages, prompt-history, default-execution-options and tabs caches from the one response. Those hooks passed staleTime undefined, which TanStack treats as 0, so seeded rows were stale on arrival and every hook still refetched its own route on mount. Give them a shared 5 s seeded-freshness window (THREAD_DETAIL_SEEDED_STALE_TIME_MS). Realtime invalidation still refetches inside the window. Co-Authored-By: Claude <noreply@anthropic.com>
…strap The bundle seeds the tabs and pending-interaction caches, but both hooks mount in the same commit as the bootstrap (useFixedPanelTabsState in the thread-detail tree, the favicon probe in AppLayout), so useQuery decided to fetch before the bundle could seed them and the /tabs and /interactions requests still went out on every thread open. Wait for the bootstrap to settle before enabling those two reads; a failed bootstrap still lets them fetch on their own. Co-Authored-By: Claude <noreply@anthropic.com>
SawyerHood
force-pushed
the
bb/mobile-perf/sidebar-bootstrap-patch
branch
from
August 19, 2026 07:50
ec7b0fd to
d2b37f3
Compare
SawyerHood
force-pushed
the
bb/mobile-perf/thread-bootstrap-include
branch
from
August 19, 2026 07:50
93e1c49 to
c931531
Compare
SawyerHood
marked this pull request as ready for review
August 19, 2026 08:04
SawyerHood
marked this pull request as draft
August 19, 2026 15:09
Collaborator
Author
|
Closing: the maintainer decided to land only layers 1–22 of the mobile-perf stack (#1880–#1901). The branch stays on the remote for reference; it can be reopened and rebased later if the remaining big rocks (sidebar-bootstrap patching, thread bootstrap include=, composer draft push-down, timeline windowing, persisted cache, service worker) are picked up again. |
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.
What was wrong
Opening a thread issued
GET /threads/:id?include=environment,hostand then five more DB-only GETs gated on it: pending interactions, queued messages, prompt history, default execution options, and tabs. On a phone over the connect tunnel this second hop delayed composer readiness by a full round-trip (mobile perf audit B5).The per-thread hooks also passed
staleTime: undefined, which TanStack treats as 0, so any seeded cache row was stale on arrival and the hook refetched on mount anyway.What changed
packages/server-contract:threadIncludeOptionSchemagainspendingInteractions,queuedMessages,promptHistory,defaultExecutionOptions,tabs;threadWithIncludesResponseSchemagains the matching optional fields (present exactly when requested). SDK types follow from the contract; plugin SDK declaration bundle regenerated.apps/server:buildThreadResponsefills the new fields through shared readers inservices/threads/thread-detail-reads.ts; the stand-alone routes (/interactions,/queued-messages,/default-execution-options,/tabs) now call the same readers, so bundled and stand-alone responses cannot diverge. Stand-alone routes stay for CLI/SDK.apps/app: the thread bootstrap requests all includes;ingestThreadDetailBootstrapseeds the five per-thread caches;useThreadPendingInteractions,useThreadQueuedMessages,useThreadDefaultExecutionOptions,useThreadTabsdefault to a 5 sTHREAD_DETAIL_SEEDED_STALE_TIME_MSso seeded rows are fresh when the hooks mount. Realtime invalidation still refetches inside the window.No daemon protocol change (server<->browser only).
How you verified
apps/server/test/public/public-thread-data.test.ts"bundles per-thread reads through include= and matches the stand-alone routes": seeds a pending interaction, a queued message and tabs on an in-memory DB, asserts each bundled field deep-equals the stand-alone route response and that unrequested fields are absent. Fails before (400 invalid include).apps/app/src/hooks/queries/thread-queries.test.tsx"seeds the bundled per-thread caches so their hooks mount without extra requests": bootstrap resolves with bundled fields; the five hooks report data with zero calls to their SDK endpoints andisFetchingfalse. Verified it fails when the stale window is removed.pnpm exec turbo run typecheckfor @bb/app, @bb/server, @bb/server-contract, @bb/sdk, @bb/cli, @get-bb/plugin-sdk: pass.turbo run lint --filter=@bb/app: 0 errors. Server public thread data/tabs/interactions/defaults + prompt-history suites: 123 passed. App suites touching the bootstrap/hooks (ThreadDetailPromptArea, EmbeddedThreadChat, AppLayout, PluginThreadChat, useThreadFileTabs, cache-owners, thread-queries): pass. @bb/server-contract and @bb/sdk suites: pass.Fixes: part of the mobile / iOS Safari performance program (verified sweep report in the bb thread; no single issue).
Stack context
Layer 24 of 28 in the
bb/mobile-perf/*stack (bottom → top: quick wins first, big rocks last).bb/mobile-perf/sidebar-bootstrap-patch(Patch sidebar rows from change metadata; weak ETag; search keepPreviousData (B1, B27, E8) #1902).bb/mobile-perf/composer-draft-pushdown(Push the composer draft subscription below ThreadDetailPromptArea (D1) #1904).