feat: add model-specific account pools#200
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
📝 WalkthroughWalkthroughAdds ChangesModel account pool routing
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant RequestLoop
participant Config
participant AccountManager
participant AccountRotation
participant RoutingVisibility
RequestLoop->>Config: Resolve modelAccountPools
Config-->>RequestLoop: preferredAccountIds
RequestLoop->>AccountManager: Select account with preferred IDs
AccountManager->>AccountRotation: Apply strategy and selection pool
AccountRotation-->>AccountManager: Preferred account or general fallback
AccountManager-->>RequestLoop: Selected account
RequestLoop->>RoutingVisibility: Record pool mode and configured size
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
index.ts (1)
1948-1949: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueExtract the configuration lookup from the retry loop.
getModelAccountPoolparses the configuration and constructs a new array every time it is called. SincepluginConfigandmodeldo not change within the innerattempted.sizeloop (model fallback mutations trigger abreakout of this loop and restart the outerwhile (true)loop entirely), hoisting this call just outside the inner loop will avoid unnecessary configuration re-evaluations for each candidate account attempt.♻️ Proposed refactor
+ const preferredAccountIds = getModelAccountPool(pluginConfig, model); while (attempted.size < Math.max(1, accountCount)) { - const preferredAccountIds = getModelAccountPool(pluginConfig, model); const selectionExplainability = accountManager.getSelectionExplainability(🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@index.ts` around lines 1948 - 1949, Move the getModelAccountPool(pluginConfig, model) call out of the attempted.size retry loop and compute preferredAccountIds once before entering it. Reuse that array for each candidate-account attempt, while preserving the existing outer-loop restart behavior when model fallback changes the model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/accounts/rotation.ts`:
- Around line 56-72: Add a falsy-account guard at the start of the filter
callback in getPreferredSelectableIndices before accessing account.accountId,
while preserving the existing preferred-ID and isSelectable checks for valid
accounts.
---
Nitpick comments:
In `@index.ts`:
- Around line 1948-1949: Move the getModelAccountPool(pluginConfig, model) call
out of the attempted.size retry loop and compute preferredAccountIds once before
entering it. Reuse that array for each candidate-account attempt, while
preserving the existing outer-loop restart behavior when model fallback changes
the model.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4d585bcd-3953-4fe0-8516-7d5dc76674c2
📒 Files selected for processing (11)
README.mddocs/configuration.mddocs/development/CONFIG_FIELDS.mdindex.tslib/accounts.tslib/accounts/rotation.tslib/config.tslib/runtime.tslib/schemas.tstest/index.test.tstest/rotation-strategy.test.ts
|
Addressed automated review feedback in
Validation: |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/architecture.md`:
- Line 76: Synchronize both architecture inventories with the 24-tool registry:
in docs/architecture.md lines 76-76, change both 21 counts to 24 and add
codex-warm to daily account use; in docs/development/ARCHITECTURE.md lines
187-187, change both 23 counts to 24 and add codex-warm to the daily-account
group. Keep both documents consistent with the current subsystem map.
In `@lib/config.ts`:
- Around line 167-173: Update the model account pool mutation flow around
modelAccountPoolMutationQueue and performModelAccountPoolMutation to coordinate
the complete config read-modify-write across processes sharing CONFIG_PATH. Add
an inter-process lock or equivalent CAS/retry mechanism that protects reading,
applying the mutation, and writing/renaming the config, while retaining the
existing in-process queue serialization.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 074e39f7-eb89-4eec-8433-19f8bbac347d
📒 Files selected for processing (17)
AGENTS.mdREADME.mddocs/architecture.mddocs/configuration.mddocs/development/ARCHITECTURE.mddocs/development/CONFIG_FIELDS.mdlib/AGENTS.mdlib/config.tslib/tools/AGENTS.mdlib/tools/codex-help.tslib/tools/codex-pool.tslib/tools/index.tstest/doc-parity.test.tstest/index-retry.test.tstest/index.test.tstest/model-pool-config.test.tstest/tools-codex-pool.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- README.md
- test/index.test.ts
Summary
modelAccountPoolsfor routing effective model IDs through preferred stable account IDs.codex-poolto inspect and manage those pools with 1-based account numbers while persisting stable account IDs.status,set,add,remove,clear,dryRun, and redacted JSON output.Testing
npm run typechecknpm run lintnpm test(113 files, 2,796 tests)npm run buildnpm run audit:ciCompliance Confirmation
Notes
codex-pool; persistedmodelAccountPoolsvalues remain stable account IDs.Summary by CodeRabbit
modelAccountPoolsto route requests to preferred, healthy accounts per normalized model.codex-pooltool for viewing and mutating per-model preferred account pools.accountPoolMode(preferred,general,general-fallback) andconfiguredAccountPoolSizein both text and TUI views.note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
adds
modelAccountPoolsconfig to route requests for a given model through a preferred subset of healthy accounts, with automatic fallback to the general pool. introduces thecodex-pooltool for 1-based account-number management that persists stable account IDs.lib/accounts/rotation.ts):getPreferredSelectableIndicesbuilds a healthy preferred set at selection time and returnsnullwhen empty, transparently falling back to the full general pool across all three strategies (sticky, round-robin, hybrid).lib/config.ts): mutations are serialized in-process via a promise queue and cross-process viaproper-lockfile; atomic writes use the existingrenameWithWindowsRetryhelper, preserving all unrelated config keys.index.ts,lib/runtime.ts):accountPoolMode(general|preferred|general-fallback) andconfiguredAccountPoolSizeare added to both the text and TUI routing diagnostics snapshots.Confidence Score: 5/5
safe to merge — the core routing, serialization, and fallback paths are all correct and well-tested.
the promise-queue + file-lock concurrency model is sound,
isSelectablecorrectly rejects disabled accounts before they enter the preferred set, atomic writes use the establishedrenameWithWindowsRetrypath, and all three fallback modes are exercised by the new integration tests. no incorrect behavior was found in the changed paths.lib/tools/codex-pool.ts — the accounts schema accepts floats; minor fix only.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[request arrives with model] --> B[getModelAccountPool\nfrom pluginConfig] B -->|preferredAccountIds.length === 0| C[general pool] B -->|preferredAccountIds populated| D[getPreferredSelectableIndices] D -->|≥1 healthy preferred account| E[preferred pool\naccountPoolMode: preferred] D -->|all preferred unhealthy / unknown\nreturns null| F[fallback to general pool\naccountPoolMode: general-fallback] C --> G[getAccountForStrategy\nsticky / round-robin / hybrid] E --> G F --> G G -->|account selected| H[attempt request] H -->|success| I[snapshot: accountPoolMode\nconfiguredAccountPoolSize] H -->|retry| G style E fill:#d4edda style F fill:#fff3cd style C fill:#cce5ff%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A[request arrives with model] --> B[getModelAccountPool\nfrom pluginConfig] B -->|preferredAccountIds.length === 0| C[general pool] B -->|preferredAccountIds populated| D[getPreferredSelectableIndices] D -->|≥1 healthy preferred account| E[preferred pool\naccountPoolMode: preferred] D -->|all preferred unhealthy / unknown\nreturns null| F[fallback to general pool\naccountPoolMode: general-fallback] C --> G[getAccountForStrategy\nsticky / round-robin / hybrid] E --> G F --> G G -->|account selected| H[attempt request] H -->|success| I[snapshot: accountPoolMode\nconfiguredAccountPoolSize] H -->|retry| G style E fill:#d4edda style F fill:#fff3cd style C fill:#cce5ffReviews (4): Last reviewed commit: "fix: serialize model pool config across ..." | Re-trigger Greptile