Skip to content

feat: expose weighted routing configuration#325

Open
bagaking wants to merge 1 commit into
router-for-me:mainfrom
bagaking:feat/weighted-routing-ui
Open

feat: expose weighted routing configuration#325
bagaking wants to merge 1 commit into
router-for-me:mainfrom
bagaking:feat/weighted-routing-ui

Conversation

@bagaking

@bagaking bagaking commented Jun 20, 2026

Copy link
Copy Markdown

Summary

Exposes weighted routing controls in the management UI so operators can configure and inspect weighted-round-robin without editing YAML or auth JSON by hand.

The UI now supports selecting weighted-round-robin globally, editing provider-level and OpenAI-compatible per-key selection-weight, editing auth-file selection_weight, and seeing priority/weight metadata where quota and credential decisions are reviewed.

Backend Compatibility

Requires CLIProxyAPI with weighted routing support from router-for-me/CLIProxyAPI#3935, or a later backend release containing equivalent support, for full functionality. Against older backend builds, the panel can still load, but weighted-round-robin and selection-weight may be ignored, rejected, or absent from quota/auth-file responses.

Details

  • Adds weighted-round-robin to visual config editing, dashboard badges, search metadata, and i18n strings.
  • Adds selection-weight parsing and serialization for provider lists and OpenAI-compatible API key entries.
  • Adds provider/auth-file form controls with non-negative integer validation and default handling.
  • Shows priority and selection weight on quota cards so weighted routing can be checked alongside quota state.
  • Surfaces invalid auth-file selection weights as backend validation errors instead of silently ignoring the edited value.

Related

Validation

  • bun run type-check
  • bun run lint
  • bun run build
  • git diff --check

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for a new weighted-round-robin routing strategy, allowing users to configure and display a selection_weight for provider credentials, API key entries, and quota cards. The changes span configuration editors, hooks, API transformers, and translation files across multiple locales. A critical issue was identified in QuotaCard.tsx, where the newly added styles.scheduleMeta class is accessed but its CSS definition resides in QuotaPage.module.scss instead of the component's scoped stylesheet, which will prevent the styles from being applied at runtime.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +145 to +152
<div className={styles.scheduleMeta}>
<span>
{t('auth_files.priority_display')}: {priority}
</span>
<span>
{t('auth_files.selection_weight_display')}: {selectionWeight}
</span>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The CSS class scheduleMeta is defined in src/pages/QuotaPage.module.scss, but it is being accessed here via styles.scheduleMeta. Since QuotaCard.tsx is a reusable component located in src/components/quota/, it likely imports its own scoped stylesheet (e.g., QuotaCard.module.scss). Accessing styles.scheduleMeta will result in undefined at runtime, and the styles won't be applied due to CSS Modules scoping.

Please verify where QuotaCard.tsx imports styles from, and move the .scheduleMeta class definition from QuotaPage.module.scss to the appropriate stylesheet imported by QuotaCard.tsx (such as QuotaCard.module.scss).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Verified this path: QuotaCard.tsx imports styles from @/pages/QuotaPage.module.scss, and .scheduleMeta is declared in that same module. The class is therefore present in the imported CSS module at runtime; no code move is needed for this comment.

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

Copy link
Copy Markdown

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: 1aa6a48a59

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

const serializeVertexKey = (config: ProviderKeyConfig) => {
const payload: Record<string, unknown> = { 'api-key': config.apiKey };
if (config.priority !== undefined) payload.priority = config.priority;
if (config.selectionWeight !== undefined) payload['selection-weight'] = config.selectionWeight;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow clearing Vertex selection weights

When a Vertex key already has selection-weight and the operator clears the new selection-weight input, buildProviderKeyConfig sets selectionWeight to undefined and this serializer omits the field. However saveVertexConfigs merges that payload back over the raw config using VERTEX_KEY_FIELDS, which still does not include selection-weight, so mergeKnownFields preserves the old raw value; the UI appears cleared until the next refetch/reload brings the stale Vertex weight back. Add selection-weight to VERTEX_KEY_FIELDS so an omitted payload removes it like the other provider types.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in 0ef464d: selection-weight is now included in VERTEX_KEY_FIELDS, so clearing the Vertex selection weight removes the preserved raw field during merge just like the other provider types.

@bagaking bagaking force-pushed the feat/weighted-routing-ui branch from 1aa6a48 to 0ef464d Compare June 20, 2026 12:14

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

Copy link
Copy Markdown

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: 0ef464d636

ℹ️ 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 on lines +267 to +268
} else if (nextSelectionWeight === undefined) {
patch.selection_weight = -1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject invalid selection weights instead of saving -1

When the auth-file editor's new selection weight field contains any non-empty invalid value (for example abc or 1.5), parseSelectionWeightValue returns undefined and this branch sends selection_weight: -1 in both the preview and PATCH payload. Selection weights are otherwise constrained to non-negative integers (and the hint says empty means default 1), so a typo can attempt to persist an invalid negative routing weight instead of being ignored or blocked like the other validation errors.

Useful? React with 👍 / 👎.

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