Skip to content

Prototype discoverable RPC for provider usage sources - #3449

Draft
ymichael wants to merge 20 commits into
mainfrom
bb/improve-plugin-surface-compatibility-thr_2iguhd9c6n
Draft

Prototype discoverable RPC for provider usage sources#3449
ymichael wants to merge 20 commits into
mainfrom
bb/improve-plugin-surface-compatibility-thr_2iguhd9c6n

Conversation

@ymichael

@ymichael ymichael commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Human comments

What was wrong

Plugins could call schema-validated RPC methods but could not discover published contracts. Usage displays also had no common way to list pooled and machine-local accounts, fetch only visible resources, or distinguish duplicate observations from distinct accounts.

What changed

  • Add opt-in RPC publication with experimental_discoverable, registration/method experimental_description, portable schemas, SDK discovery, and CLI list/inspect/call. Internal registrations retain existing behavior. Discovery does not authorize calls or negotiate compatibility.
  • Provider Usage owns a two-method defineRpcContract convention: cheap provider-usage.v1.listResources({}) inventory and targeted provider-usage.v1.getResource({resourceId, refresh}) measurements. Sources and consumers copy contracts locally; there is no shared schema package.
  • Codex, Claude Code, and ACP explicitly implement the contract for their own providers using existing SDK maintenance APIs. ACP includes usage-capable agents such as Cursor. Account Pooler implements it for shared accounts, including an empty shared group when unconfigured. There is no extra adapter plugin or shared implementation package. Other providers must explicitly implement the contract; maintenance.usage alone does not publish RPC methods. The provider kit and core runtime do not import or interpret this contract.
  • Separate source-local resource IDs from nullable provider-issued account identities. Consumers deduplicate known identities within the selected location and never merge by email or sum quota percentages. Structured window/plan metadata normalizes labels while preserving custom provider labels. Codex and Claude enrich their existing passthrough maintenance metadata; older providers continue working without these extensions.
  • The sidebar preserves provider tabs/icons, compact account rows, and reset times. It fetches only the selected provider’s resources. Settings preserves its provider cards and fetches only the selected pool or machine. Shared groups are the default; explicit machine selections remain available. Unopened tabs have unknown usage rather than fabricated badges.
  • Preserve previous measurements on transport and collection failures. Handle empty sources, authentication states, missing limits, offline hosts, and removed resources. Shared display labels are independent of plugin manifest names.
  • Update Plugin Guide/API inventory, audit notes, CLI guidance, plugin skills, and the implementation plan. SDK minimum is 0.4.56. Existing passthrough maintenance transport is retained without changing protocol schemas. bb settings usage remains the direct host-maintenance view.

How you verified

  • Relevant app, server, display, and provider typechecks pass. Targeted suites pass: 17 settings tests, 13 Provider Usage tests, 276 Account Pooler tests, 271 Codex tests, 351 Claude Code tests, 84 ACP tests, and 31 builtin-plugin tests.
  • Tests cover cheap inventory, exact-resource fetching, rejection of foreign-provider resources, unknown metadata, cache/force/concurrent requests, disconnected hosts, removed resources, identity deduplication, structured labels, empty pools, and first-load/stale failures.
  • Live CLI inventory confirms Codex and Claude identities match corresponding pool accounts; Cursor remains unknown. Live discovery lists exactly Account Pooler, Codex, Claude Code, and ACP. Dev Browser verifies Cursor through ACP’s explicit implementation and targeted machine fetches.
  • Inspected current screenshots of pooled Codex/Claude cards, pool settings, and machine settings with Cursor. Earlier RPC publication checks and the 17-scenario consumer-state review also passed; those historical screenshots were not recaptured for every state in this follow-up.
  • Preview runs through pnpm start:worktree. JSON Schema refinement/transform fidelity remains an explicit experimental stabilization task.

Preview: https://ymichael-latest--25451.getbb.app/settings/usage

AGENT GENERATED

ymichael added a commit that referenced this pull request Sep 11, 2026
## Human comments

## What was wrong

The Provider Usage footer coverage put plugin import/registration, the
content-script preload and focus listener lifecycle, disclosure
rendering, two Radix machine-menu sessions, provider mouse and keyboard
navigation, disconnected state, dismiss, manual refresh, and disposal
inside one asynchronous test with the default 5-second budget.
Package-shard concurrency and Vitest worker oversubscription made that
serial UI sequence slow enough to expose the test architecture: the
unchanged test reproduced at 6.610 seconds under bounded Intel
contention and timed out at 5 seconds. The CI failure was therefore not
a deterministic regression in PR #3449, and scheduler contention was the
trigger rather than the root cause.

## What changed

`plugins/provider-usage/app.test.tsx` now loads and captures the plugin
registration once outside test clocks, reuses one response fixture, and
divides coverage into registration, content-script focus refresh,
disconnected/manual refresh, and connected machine/provider interaction
scenarios. Content-script disposal is protected by `finally`. The
disconnected case starts from the active Intel machine, removing a
second Radix menu lifecycle while the connected case still proves all
machines are aggregated and exercises machine selection plus provider
mouse and keyboard navigation. No assertions were disabled, no timeout
was increased, and there are no wire, CLI, or documentation changes.

## How you verified

- Before: on enrolled Intel host `host_nwqfteeqz4`, a warmed run with 12
bounded CPU competitors reproduced the exact failure: 6.610 seconds and
`Test timed out in 5000ms`.
- After: the same 12-worker warmed stress passed all four scenarios; the
slowest scenario was 833 ms.
- After: five fresh focused iterations under 12 CPU competitors passed
20/20 scenario executions; the slowest scenario was 1.202 seconds.
- `pnpm exec turbo run test --filter=bb-plugin-provider-usage` — 3 files
and 7 tests passed.
- `pnpm exec turbo run typecheck --filter=bb-plugin-provider-usage` —
passed.
- `pnpm exec turbo run build --filter=bb-plugin-provider-usage` — passed
the package's available upstream generator tasks; this package has no
build script.
- `bb plugin build` from `plugins/provider-usage` — emitted validated
server and app bundles.
- Every test/build/load command ran in a bounded process group; teardown
and the final process scan found no surviving Vitest, Turbo,
plugin-build, or load workers.

> AGENT GENERATED
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.

1 participant