Skip to content

feat(proxy): add fill-first routing strategy#831

Open
ramhaidar wants to merge 6 commits into
Soju06:mainfrom
ramhaidar:feat/fill-first-routing-strategy
Open

feat(proxy): add fill-first routing strategy#831
ramhaidar wants to merge 6 commits into
Soju06:mainfrom
ramhaidar:feat/fill-first-routing-strategy

Conversation

@ramhaidar
Copy link
Copy Markdown

Summary

Add a new fill_first routing strategy that deterministically picks the eligible account with the lowest primary 5h used_percent, tiebroken by account_id ascending. Operators get a single-account-at-a-time mode for prompt-cache locality and predictable cost attribution, without changing the default routing strategy.

Type of change

  • feat: — new user-facing feature or capability

Linked issue:

OpenSpec

  • This PR includes / updates an OpenSpec change

Change directory: openspec/changes/add-fill-first-routing-strategy/

The change adds:

  • proposal.md — problem, solution, scope, impact
  • tasks.md — implementation breakdown (T1–T19)
  • specs/proxy-admission-control/spec.md## ADDED Requirements delta with normative scenarios for deterministic ranking, stable selection, transition-on-pool-exit, and account_id tiebreak

Changes

  • app/core/balancer/logic.py: extend RoutingStrategy literal to include "fill_first"; add _fill_first_sort_key and _select_fill_first helpers; add new dispatch branch in select_account() that applies _prefer_earlier_reset_candidates the same way as capacity_weighted. Determinism is a hard property — no randomness, only (used_percent, account_id).
  • app/modules/proxy/service.py: extend _routing_strategy() to propagate the new value to LoadBalancer.select_account(). Without this, the dashboard would accept fill_first but the proxy would silently fall back to capacity_weighted.
  • app/modules/settings/schemas.py: widen Pydantic regex on both response and update models.
  • frontend/src/features/settings/schemas.ts: extend RoutingStrategySchema; align the optional default with the backend (capacity_weighted).
  • frontend/src/features/settings/components/routing-settings.tsx: add <SelectItem value="fill_first">Fill first</SelectItem> directly under "Capacity weighted"; widen the onValueChange literal cast.
  • frontend/src/components/layout/status-bar.tsx: widen getRoutingLabel(...) to render fill_first with sticky / prefer-earlier-reset compositions.
  • frontend/src/utils/constants.ts: add fill_first: "fill first" to ROUTING_LABELS.
  • frontend/src/test/mocks/handlers.ts: widen the routing-strategy Zod enum.
  • Tests: 11 new backend unit tests, 1 new backend integration test (cycle through accounts as they saturate), 2 new settings-API round-trip tests, plus frontend assertions in routing-settings.test.tsx, schemas.test.ts, and constants.test.ts.

No alembic migration: dashboard_settings.routing_strategy is a free-form String column with app-level Pydantic validation only; the existing column accepts the new value as-is. Default routing strategy is unchanged (capacity_weighted).

Test plan

uvx ruff check .                                          # All checks passed
uvx ruff format --check .                                 # 499 files clean
uv run ty check                                           # All checks passed

uv run pytest tests/unit/test_load_balancer.py -q
# 93 passed (includes 11 new fill_first tests)

uv run pytest tests/integration/test_settings_api.py -q
# 3 passed (includes new fill_first round-trip + rejection)

uv run pytest tests/integration/test_load_balancer_integration.py::test_load_balancer_fill_first_cycles_through_accounts -q
# 1 passed

uv run pytest tests/unit -q --timeout=60
# 2076 passed, 40 skipped, 3 unrelated Windows-only failures in
# tests/unit/test_conversation_archive.py that reproduce on main

cd frontend
bun run lint        # clean
bun run typecheck   # clean
bun run test        # 449 tests across 76 files, all passing

Checklist

  • Title is in Conventional Commits format.
  • Added or updated tests covering the change.
  • Did not edit CHANGELOG.md by hand.
  • OpenSpec change folder included for the new behavior.
  • Default routing strategy unchanged.
  • openspec validate --specs will run in CI; the local CLI was unavailable in the dev environment.

@ramhaidar ramhaidar force-pushed the feat/fill-first-routing-strategy branch from e94fd6f to 119acee Compare May 27, 2026 10:44
@Soju06
Copy link
Copy Markdown
Owner

Soju06 commented May 27, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented May 31, 2026

@codex review

1 similar comment
@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented May 31, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 119aceed59

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

Comment thread app/core/balancer/logic.py Outdated
@Soju06 Soju06 added the 🤖 codex: needs work [@codex review] raised an issue label May 31, 2026
@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented May 31, 2026

@codex review

@Soju06 Soju06 removed the 🤖 codex: needs work [@codex review] raised an issue label May 31, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9231178ffb

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

Comment thread app/core/balancer/logic.py
@Soju06 Soju06 added 🤖 codex: needs work [@codex review] raised an issue and removed 🤖 codex: needs work [@codex review] raised an issue labels May 31, 2026
@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented May 31, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

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

ramhaidar and others added 5 commits June 1, 2026 11:10
Add a new `fill_first` routing strategy that deterministically picks the
eligible account with the lowest primary 5h `used_percent`, tiebreaking on
`account_id` ascending. The 'fill' behavior emerges naturally from the
existing `effective_pool` ladder: an account stays selected while it remains
the lowest-usage candidate, and traffic only moves once the upstream marks
that account rate-limited or quota-exceeded (or it transitions to draining).

Touches:
- balancer: extend `RoutingStrategy`, add `_select_fill_first`, dispatch
- settings: widen Pydantic regex; `_routing_strategy()` propagates `fill_first`
- frontend: schema, dropdown, status-bar label, mocks
- tests: unit, integration, settings-API round-trip, frontend
- openspec: change folder + proxy-admission-control delta

No alembic migration: `dashboard_settings.routing_strategy` is a free-form
String column with app-level Pydantic validation only.

Default routing strategy unchanged (capacity_weighted).
@Komzpa Komzpa force-pushed the feat/fill-first-routing-strategy branch from 3c122cf to 56e3555 Compare June 1, 2026 07:19
@Soju06
Copy link
Copy Markdown
Owner

Soju06 commented Jun 1, 2026

@codex review

1 similar comment
@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented Jun 1, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56e3555970

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

Comment thread app/core/balancer/logic.py Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56e3555970

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

Comment thread app/core/balancer/logic.py Outdated
@Komzpa Komzpa added the 🤖 codex: needs work [@codex review] raised an issue label Jun 1, 2026
@Soju06 Soju06 removed the 🤖 codex: needs work [@codex review] raised an issue label Jun 1, 2026
@Soju06
Copy link
Copy Markdown
Owner

Soju06 commented Jun 1, 2026

@codex review

1 similar comment
@Komzpa
Copy link
Copy Markdown
Collaborator

Komzpa commented Jun 1, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 060783be27

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

Comment thread app/core/balancer/logic.py Outdated
@Komzpa Komzpa added the 🤖 codex: needs work [@codex review] raised an issue label Jun 1, 2026
@Komzpa Komzpa force-pushed the feat/fill-first-routing-strategy branch from 060783b to 45a10fc Compare June 1, 2026 08:06
@Soju06 Soju06 removed the 🤖 codex: needs work [@codex review] raised an issue label Jun 1, 2026
@Soju06
Copy link
Copy Markdown
Owner

Soju06 commented Jun 1, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

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

@Soju06 Soju06 added the 🤖 codex: ok [@codex review] says no issues found. label Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 codex: ok [@codex review] says no issues found.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants