Skip to content

Account Pool: route Codex accounts through the hub over WebSocket - #3056

Open
SawyerHood wants to merge 2 commits into
bb/plugin-websocket-routesfrom
bb/account-pool-codex
Open

Account Pool: route Codex accounts through the hub over WebSocket#3056
SawyerHood wants to merge 2 commits into
bb/plugin-websocket-routesfrom
bb/account-pool-codex

Conversation

@SawyerHood

Copy link
Copy Markdown
Collaborator

Stack layer 3 (Codex pool track). Prerequisites: #3053 and #3054 below it. Single-plugin design: Codex joins the existing Account Pool plugin as a provider adapter.

Human comments

What was wrong

Account Pool was coupled to Claude credentials, request rewriting, quota headers, and refresh behavior, so it could not select or maintain Codex OAuth accounts. Codex also attempts the Responses WebSocket protocol before HTTP SSE, while the Codex bridge launched codex app-server without applying provider-contributed per-thread base URL and hub authentication values. Pointing Codex at the hub therefore required both a provider-neutral pool core inside the plugin and a session-aware app-server launch path.

What changed

  • Added an internal provider-adapter contract in plugins/account-pool and preserved the existing Claude behavior behind its adapter.
  • Added Codex OAuth import from ~/.codex/auth.json, serialized pre-expiry refresh with write-back, ChatGPT account identity storage, and provider-scoped account selection.
  • Added Codex request/header rewriting for ChatGPT's Codex backend and parsed x-codex-primary-* / x-codex-secondary-* rate-limit observations and quota rejections.
  • Added authenticated HTTP POST /v1/responses, GET /v1/models, and WebSocket /v1/responses routes in the existing Account Pool /http/ namespace.
  • Implemented Codex's downstream envelope session behavior: local prewarm completion, incremental input expansion after a completed response, unknown-id failure plus close 1011, upstream HTTPS SSE forwarding as one JSON event per WebSocket frame, and rotation after quota rejection.
  • Made each WebSocket forward independently abortable. A downstream close now cancels the hub request signal and upstream fetch/body read, releases the account's in-flight slot, drops queued frames, and guards every send against a closing or closed socket.
  • Extended the single bb pool CLI and Account Pool settings section with Codex import, provider badges, shared machine tokens, Codex environment and health contributions, and provider-aware status.
  • Made the Codex bridge consume the resolved per-session pool environment, append in-memory -c openai_base_url=... configuration, add an environment-backed hub header without putting the token in process arguments, and rebuild a session when pool routing or token identity changes.
  • Updated the configuration reference, generated Guide source, and builtin bb CLI skill. The original two-plugin extraction plan was intentionally dropped after the scope decision to keep both providers in plugins/account-pool.

There is no server/host-daemon wire contract change, so HOST_DAEMON_PROTOCOL_VERSION does not need a bump. There is no new public Plugin SDK surface in this layer.

Not in this PR

  • Keeping model_provider="openai" while adding the machine-token header is not possible with Codex CLI 0.153.2: a live app-server launch rejects model_providers.openai because built-in provider IDs are reserved and cannot be overridden. The bridge therefore retains the custom bb-account-pool provider ID. That changes the provider recorded in newly pooled rollouts and may affect Codex's provider-keyed session grouping, remote compaction, and remote-control behavior. Compatibility for existing sessions was verified live: a rollout created with model_provider: "openai" completed a direct turn, Account Pool was enabled, and the same rollout resumed and completed a pooled WebSocket turn.

How you verified

The new focused regressions fail on the layer-A base because Codex is not an Account Pool provider there and the bridge ignores per-session pool configuration. They now cover import parsing, refresh persistence, HTTP credential/account-id rewrite, provider-scoped selection, Codex quota parsing and rotation, WebSocket authentication/prewarm/incremental/unknown-id/session streaming behavior, provider env/health, UI import and badges, and token-free app-server launch arguments.

  • pnpm exec turbo run typecheck test --filter=bb-plugin-account-pool --filter=bb-plugin-provider-codex --continue --force — 8/8 tasks passed; Account Pool 41/41 tests and Codex provider 261/261 tests passed; both typechecks passed. The added regression closes a downstream WebSocket during a non-terminating SSE response and proves the upstream abort signal fires, the account's in-flight count returns to zero, and no post-close frame is sent.
  • pnpm exec turbo run test typecheck --filter=@bb/server --filter=@bb/app --filter=@bb/templates --filter=@bb/cli --continue — 15/15 tasks passed; server 2,209, app 3,872, templates 43, and CLI 530 tests passed; 4 app tests skipped; all selected typechecks passed.
  • bb plugin build plugins/account-pool — production server and app bundles built successfully.
  • node scripts/check-provider-literal-ratchet.mjs — passed with all core provider literals allowlisted.
  • node .github/workflows/check-plugin-sdk-version.mjs — passed against the layer-A SDK surface/version state.
  • git diff --check — passed.
  • Live dev app with Codex CLI 0.153.2 and this machine's imported account: a pooled WebSocket turn returned BB93_POOL_WS_OK, emitted the Account Pool WebSocket transport marker, and updated five-hour utilization to 0.4% without fallback/retry noise. The resolved-env card showed the Account Pool base URL and masked token. After bb pool bypass, a direct turn returned BB93_DIRECT_OK while the pool observation timestamp stayed unchanged. Settings and timeline screenshots were inspected and attached to BB-93.
  • Review E2E with Codex CLI 0.153.2: the attempted built-in openai provider override failed with the reserved-provider validation error. With Account Pool disabled, rollout 01a06b6b-a3a4-7de2-9d07-d98af7bc5c90 recorded model_provider: "openai" and returned BB93_PREPOOL_OPENAI_OK; after enabling Account Pool, that same rollout returned BB93_RESUMED_THROUGH_POOL_OK over the plugin WebSocket route and advanced pool utilization from 0.40% to 0.41% with no account error.

Tracks BB-93 (layer B).

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