Skip to content

feat(auth): account pool round-robin and fill-first strategies - #593

Merged
Wibias merged 15 commits into
lidge-jun:devfrom
Wibias:feat/account-pool-round-robin
Jul 28, 2026
Merged

feat(auth): account pool round-robin and fill-first strategies#593
Wibias merged 15 commits into
lidge-jun:devfrom
Wibias:feat/account-pool-round-robin

Conversation

@Wibias

@Wibias Wibias commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add opt-in Codex/Anthropic account-pool rotation strategies: quota (default, unchanged), round-robin, and fill-first
  • Strategies apply to new sessions only; live thread/session affinity, cooldown, and reauth quarantine stay intact
  • Dashboard + management API controls (accountPoolStrategy / stickyLimit; Anthropic nested fields)
  • Docs + fairness regression tests

Fixes #592

Improvements (measured)

Fixture: 3 Codex pool accounts, equal quota, unbound new sessions.

Metric Baseline (quota) Round-robin Margin
New-session share max−min 100pp (100/0/0) 0pp (33/33/33) Fairness ↑ 100pp
Mid-thread affinity flips 0 0 (50 re-resolves) No regression
Operator control Threshold only Strategy + stickyLimit Parity with peer RR/Sticky, better affinity

vs 9Router / OmniRoute: session-granular RR (not request-granular), three composable strategies instead of a large menu, keeps existing generation/cooldown integrity.

Test plan

  • bun run typecheck
  • bun run privacy:scan
  • bun run lint:gui
  • Feature suites: codex-pool-rotation, anthropic-account-pool, account-pool-management-api, GUI strategy tests
  • CI Cross-platform green (ubuntu/mac/windows)
  • CodeRabbit + Codex review addressed
  • Security review (auth/routing) clean

Summary by CodeRabbit

  • New Features
    • Added account-pool rotation controls for Codex and experimental Anthropic OAuth pools.
    • You can now configure accountPoolStrategy (quota, round-robin, fill-first) and accountPoolStickyLimit for new sessions.
    • Rotation and failover behavior is now strategy-aware during quota/rate-limit events.
    • Updated the Codex/Anthropic account-pool settings UI to edit and save these options.
  • Documentation
    • Expanded getting-started and configuration docs to clarify new-session rebalancing, cooldown/re-auth skipping, and provider-enforcement limits (with details across languages).
  • Tests
    • Added and expanded automated coverage for settings UI, API persistence/validation, and rotation/failover behavior.

@coderabbitai

This comment was marked as outdated.

@github-actions github-actions Bot added the enhancement New feature or request label Jul 28, 2026
@Wibias

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

Wibias added 2 commits July 28, 2026 05:43
Seed RR on manual select, gate affinity re-eval to quota, validate before mutate, keep automatic picks in-memory, and advance fill-first/RR on 429.
Mock shared /active defaults and pool-strategy so CodexPoolStrategySetting no longer races the auto-switch harness.
@Wibias

This comment was marked as outdated.

@coderabbitai

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@Wibias

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@Wibias

This comment was marked as outdated.

@coderabbitai

This comment was marked as resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: a96d705d86

ℹ️ 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".

coderabbitai[bot]

This comment was marked as resolved.

Return 400 for null/array/scalar JSON instead of throwing 500, and use POOL_KEY_ANTHROPIC in the sticky-release test.
@Wibias

Wibias commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed remaining CodeRabbit nits in e6467e3:

  • Reject non-object pool-strategy / anthropic pool bodies with 400 (null/array/scalar)
  • Anthropic sticky-release test uses POOL_KEY_ANTHROPIC

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

commit="a96d705d"

echo '=== Commit metadata and changed files ==='
git show --no-ext-diff --format=fuller --stat "$commit"
git diff-tree --no-commit-id --name-only -r "$commit" | sort

echo '=== Source/test outlines for changed TypeScript files ==='
git diff-tree --no-commit-id --name-only -r "$commit" |
  while IFS= read -r file; do
    case "$file" in
      *.ts|*.tsx)
        echo "--- $file"
        ast-grep outline "$file" --items all 2>/dev/null || true
        ;;
    esac
  done

echo '=== Exact implementation/test patch ==='
git show --no-ext-diff --format= --find-renames "$commit" -- \
  src/codex/routing.ts \
  src/codex/auth-context.ts \
  src/server/responses/core.ts \
  src/oauth/anthropic-routing.ts \
  src/codex/pool-rotation.ts \
  tests/codex-pool-rotation.test.ts \
  tests/anthropic-account-pool.test.ts \
  tests/server-auth.test.ts

echo '=== Relevant code at the reviewed commit ==='
git show "$commit:src/codex/routing.ts" | nl -ba | sed -n '1,180p;500,720p;900,1060p'
git show "$commit:src/oauth/anthropic-routing.ts" | nl -ba | sed -n '140,260p;340,540p'
git show "$commit:src/server/responses/core.ts" | nl -ba | sed -n '260,360p'
git show "$commit:src/codex/pool-rotation.ts" | nl -ba | sed -n '80,190p'

echo '=== Focused regression-test sections at the reviewed commit ==='
git show "$commit:tests/codex-pool-rotation.test.ts" | nl -ba | sed -n '220,290p;360,500p'
git show "$commit:tests/anthropic-account-pool.test.ts" | nl -ba | sed -n '170,420p'
git show "$commit:tests/server-auth.test.ts" | nl -ba | sed -n '1650,1730p'

Length of output: 45280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

commit="a96d705d"

show_range() {
  local file="$1"
  local range="$2"
  echo "=== ${file}:${range} @ ${commit} ==="
  git show "${commit}:${file}" | cat -n | sed -n "${range}p"
}

echo '=== Complete commit patch (including auth API) ==='
git show --no-ext-diff --format= --find-renames "$commit"

show_range src/codex/routing.ts '470,750'
show_range src/codex/routing.ts '740,1035'
show_range src/oauth/anthropic-routing.ts '130,340'
show_range src/oauth/anthropic-routing.ts '330,525'
show_range src/codex/auth-api.ts '500,760'

echo '=== Exact relevant call sites at the reviewed commit ==='
git grep -n -E \
  'getEffectiveActiveCodexAccountId\(|promoteActiveCodexAccount\(|rememberActiveCodexAccount\(|setActiveCodexAccount\(|resolveAnthropicAccountForSession\(|getAnthropicPoolAccessToken\(|rotateAnthropicAccountOn429\(' \
  "$commit" -- src tests || true

echo '=== Full modified test files at the reviewed commit ==='
git show "$commit:tests/codex-pool-rotation.test.ts" | cat -n | sed -n '1,500p'
git show "$commit:tests/anthropic-account-pool.test.ts" | cat -n | sed -n '1,430p'

Length of output: 139947


@Wibias Reviewed a96d705d; no new correctness findings.

  • Quota 429 failover is restored without regressing RR behavior. In src/codex/routing.ts, Lines 984–1019 record the cooldown and reuse meta.promoteAccountId when the retry path already chose an alternate. This prevents a second RR selection. Lines 698–705 persist the promoted account for quota, while RR/fill-first only update the in-memory cursor.

  • Automatic strategies no longer overwrite the operator-selected config. src/codex/routing.ts Lines 677–705 separates runtimeActiveCodexAccountId from config.activeCodexAccountId; Lines 587–618 use the runtime cursor for committed RR/fill-first new-session picks. tests/codex-pool-rotation.test.ts Lines 363–378 verifies RR requests do not create or sync-write config.json.

  • Fill-first correctly bypasses known-drained successors. Both src/codex/routing.ts Lines 529–569 and src/oauth/anthropic-routing.ts Lines 188–215 traverse stable successor order and prefer an eligible account below the threshold, only falling back to a drained account if no eligible lower-usage alternative exists. The corresponding Codex and Anthropic regressions are at tests/codex-pool-rotation.test.ts Lines 261–272 and tests/anthropic-account-pool.test.ts Lines 325–335.

  • Keyless Anthropic requests retain active-account stability. src/oauth/anthropic-routing.ts Lines 360–381 preserves an eligible active account for null/empty keys under RR and fill-first. Identified new sessions still use strategy routing and create affinity, so the account-spreading behavior remains available where a session identity exists. This is covered by tests/anthropic-account-pool.test.ts Lines 215–225.

  • Manual selection remains authoritative. src/codex/routing.ts Lines 335–344 clears the automatic cursor during manual selection, and src/codex/auth-api.ts Lines 607–629 persists that explicit choice while reporting the effective active account.

The documented preview-reserve limitation remains properly constrained to the subagent fallback path and does not invalidate the routing changes in this commit.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Wibias Wibias linked an issue Jul 28, 2026 that may be closed by this pull request
5 tasks
@Wibias
Wibias merged commit c380ef7 into lidge-jun:dev Jul 28, 2026
11 checks passed
@Wibias
Wibias deleted the feat/account-pool-round-robin branch July 28, 2026 05:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Account pool round-robin / fill-first rotation strategies

1 participant