Skip to content

feat(routing): add configurable per-prompt model routing - #1422

Draft
mounir0672230294-alt wants to merge 2 commits into
lidge-jun:devfrom
mounir0672230294-alt:feat/smart-model-router
Draft

feat(routing): add configurable per-prompt model routing#1422
mounir0672230294-alt wants to merge 2 commits into
lidge-jun:devfrom
mounir0672230294-alt:feat/smart-model-router

Conversation

@mounir0672230294-alt

@mounir0672230294-alt mounir0672230294-alt commented Aug 10, 2026

Copy link
Copy Markdown

Summary

  • Add opt-in, deterministic per-prompt classification into fast, balanced, and powerful task tiers.
  • Let routing-profile candidates declare the task tiers they can serve, while preserving the existing health, quota, capability, cost, and fallback constraints.
  • Reclassify the latest user prompt on every request made through the selected routing-profile alias, without an extra model call and without persisting raw prompt text.
  • Add Routing Profiles GUI controls, management dry-run and CLI support, explainability traces, localized copy, documentation, and regression tests.
  • Keep the feature provider-agnostic so configured OpenAI, DeepSeek, Qwen, Kimi, GLM, and other provider models can participate in the same profile.

Verification

  • bun run typecheck
  • bun run test tests/prompt-classifier.test.ts tests/request-evidence.test.ts tests/routing-profile.test.ts tests/policy-execution.test.ts tests/route-explainability.test.ts tests/routing-profile-editor-data.test.ts
    • 71 pass, 0 fail
  • cd gui && bun test tests/routing-profiles.test.tsx ../tests/routing-profile-editor-data.test.ts
    • 20 pass, 0 fail
  • cd gui && bun run lint
  • cd gui && bun run lint:i18n
  • cd gui && bun run build
  • cd docs-site && bun run build
  • bun x --yes react-doctor@0.9.11 --verbose --scope changed --base origin/dev --no-telemetry
    • 10 changed GUI files scanned, no issues found
  • bun run privacy:scan
  • Full bun run test
    • 10,656 pass, 7 skip, 7 timeout failures across 10,670 tests
    • The suite took 1,196 seconds versus the runner's approximately 210-second idle baseline.
    • All six files containing the seven unrelated timeout failures passed when rerun in isolation: 141 pass, 0 fail.

Screenshot

Automatic prompt routing with fast, balanced, and powerful model tiers

Live local dashboard capture from opencodex v2.10.2 showing Automatic prompt routing enabled, the auto alias, and explicit fast / balanced / powerful candidate assignments. The profile was also dry-run locally for all three tiers plus image input.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • New Features
    • Added automatic prompt routing that classifies requests into fast, balanced, or powerful task tiers.
    • Routing profiles can assign models to supported task tiers and filter candidates accordingly.
    • Added task-tier controls, configuration, and dry-run testing in the routing profile editor.
    • Added --task-tier support to policy dry runs and evaluation commands.
  • Documentation
    • Updated routing guides and configuration references with prompt-routing setup and examples.
    • Added multilingual documentation and interface translations for task-tier routing.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Prompt routing adds deterministic classification into fast, balanced, and powerful tiers. Profiles assign candidates to tiers, routing filters candidates by the classified tier, and APIs, CLI tools, GUI controls, tests, and documentation expose the new behavior.

Changes

Prompt routing policy

Layer / File(s) Summary
Task-tier contracts and policy evaluation
src/types.ts, src/routing/profile.ts, src/routing/evaluator.ts, tests/routing-profile.test.ts
Adds task-tier types, profile validation and normalization, tier coverage requirements, candidate filtering, mismatch exclusions, and prompt-tier trace reasons.
Prompt classification and request evidence
src/routing/prompt-classifier.ts, src/routing/request-evidence.ts, tests/prompt-classifier.test.ts, tests/request-evidence.test.ts, tests/policy-execution.test.ts
Classifies the latest user prompt using deterministic signals and reasoning effort. Classification is enabled only for models with enabled prompt-routing profiles.
Server routing integration
src/server/chat-completions.ts, src/server/claude-messages.ts, src/server/responses/compact.ts, src/server/responses/core.ts
Uses model-aware request evidence for initial and fallback routing across supported request handlers.
Management API and CLI evidence
src/server/management/routing-profile-routes.ts, src/cli/route-policy.ts, tests/route-explainability.test.ts, tests/routing-profile.test.ts
Exposes prompt-routing metadata, validates task-tier evidence, and adds --task-tier to route dry-run and evaluate commands.
Profile editor and supporting content
gui/src/pages/RoutingProfiles.tsx, gui/src/routing-profile-editor-data.ts, gui/tests/routing-profiles.test.tsx, gui/src/i18n/*, docs-site/src/content/docs/...
Adds prompt-routing controls, candidate tier selection, dry-run tier input, localized messages, and configuration and editor documentation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RequestHandler
  participant evidenceForModelRequest
  participant classifyPromptComplexity
  participant PolicyEvaluator
  participant ModelProvider
  Client->>RequestHandler: Send model request
  RequestHandler->>evidenceForModelRequest: config, model, request body
  evidenceForModelRequest->>classifyPromptComplexity: Extract latest user prompt
  classifyPromptComplexity-->>evidenceForModelRequest: Task tier and signals
  evidenceForModelRequest->>PolicyEvaluator: Submit routing evidence
  PolicyEvaluator->>ModelProvider: Select eligible candidate
  ModelProvider-->>Client: Return model response
Loading

Possibly related PRs

Suggested reviewers: wibias, ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: configurable per-prompt model routing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This PR stays in draft until every box above is ticked.

@mounir0672230294-alt mounir0672230294-alt changed the title feat(routing): add per-prompt smart model selection feat(routing): add configurable per-prompt model routing Aug 11, 2026
@mounir0672230294-alt
mounir0672230294-alt marked this pull request as ready for review August 11, 2026 08:25
@github-actions
github-actions Bot marked this pull request as draft August 11, 2026 08:26

@coderabbitai coderabbitai 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.

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 `@gui/src/i18n/en.ts`:
- Line 78: Update the routing.promptRoutingHelp locale strings to clarify that
prompt classification applies only to requests using the selected profile with
prompt routing enabled. Change the English entry in gui/src/i18n/en.ts at lines
78-78 and add the equivalent Japanese condition in gui/src/i18n/ja.ts at lines
35-35.

In `@src/server/management/routing-profile-routes.ts`:
- Around line 62-67: Update parseEvidence to return a specific parse error code
or message when taskTier is unsupported, rather than only marking validation as
failed. Propagate that error through the dry-run handler so invalid taskTier
requests report the taskTier issue instead of “evidence must be an object,” and
add a management-route test covering taskTier value “huge”.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: 0c00d217-2333-4561-855d-09282616b061

📥 Commits

Reviewing files that changed from the base of the PR and between 0de4fd2 and 7d25ccd.

⛔ Files ignored due to path filters (1)
  • docs-site/public/pr-screenshots/1422-smart-prompt-routing.png is excluded by !**/*.png
📒 Files selected for processing (30)
  • docs-site/src/content/docs/guides/routing-profile-editor.md
  • docs-site/src/content/docs/reference/configuration/routing.md
  • docs-site/src/content/docs/zh-cn/reference/configuration/routing.md
  • gui/src/i18n/de.ts
  • gui/src/i18n/en.ts
  • gui/src/i18n/ja.ts
  • gui/src/i18n/ko.ts
  • gui/src/i18n/ru.ts
  • gui/src/i18n/tr.ts
  • gui/src/i18n/zh.ts
  • gui/src/pages/RoutingProfiles.tsx
  • gui/src/routing-profile-editor-data.ts
  • gui/tests/routing-profiles.test.tsx
  • src/cli/route-policy.ts
  • src/routing/evaluator.ts
  • src/routing/profile.ts
  • src/routing/prompt-classifier.ts
  • src/routing/request-evidence.ts
  • src/server/chat-completions.ts
  • src/server/claude-messages.ts
  • src/server/management/routing-profile-routes.ts
  • src/server/responses/compact.ts
  • src/server/responses/core.ts
  • src/types.ts
  • tests/policy-execution.test.ts
  • tests/prompt-classifier.test.ts
  • tests/request-evidence.test.ts
  • tests/route-explainability.test.ts
  • tests/routing-profile-editor-data.test.ts
  • tests/routing-profile.test.ts

Comment thread gui/src/i18n/en.ts
"routing.removeCandidate": "Remove candidate {provider}/{model}",
"routing.candidates": "Candidates",
"routing.promptRouting": "Automatic prompt routing",
"routing.promptRoutingHelp": "Classify each latest user prompt locally and select an eligible task tier for every request.",

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Scope the prompt-routing help text to enabled profiles.

Both locale strings imply that classification runs for every request. The runtime only generates task-tier evidence when prompt routing is enabled for the selected profile.

  • gui/src/i18n/en.ts#L78-L78: change the wording to state that classification applies to requests using this profile.
  • gui/src/i18n/ja.ts#L35-L35: add the equivalent Japanese condition.
📍 Affects 2 files
  • gui/src/i18n/en.ts#L78-L78 (this comment)
  • gui/src/i18n/ja.ts#L35-L35
🤖 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 `@gui/src/i18n/en.ts` at line 78, Update the routing.promptRoutingHelp locale
strings to clarify that prompt classification applies only to requests using the
selected profile with prompt routing enabled. Change the English entry in
gui/src/i18n/en.ts at lines 78-78 and add the equivalent Japanese condition in
gui/src/i18n/ja.ts at lines 35-35.

Comment on lines +62 to +67
if (record.taskTier !== undefined) {
if (record.taskTier !== "fast" && record.taskTier !== "balanced" && record.taskTier !== "powerful") {
return { evidence: {}, ok: false };
}
evidence.taskTier = record.taskTier;
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return an accurate validation error for an invalid task tier.

Line 64 rejects an unsupported taskTier, but Line 378 always returns "evidence must be an object". A request with { "taskTier": "huge" } has a valid evidence object, so the response directs the caller to fix the wrong field.

Return a parse error code or message from parseEvidence. Propagate it from the dry-run handler. Add a management-route test for an unsupported taskTier.

🤖 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 `@src/server/management/routing-profile-routes.ts` around lines 62 - 67, Update
parseEvidence to return a specific parse error code or message when taskTier is
unsupported, rather than only marking validation as failed. Propagate that error
through the dry-run handler so invalid taskTier requests report the taskTier
issue instead of “evidence must be an object,” and add a management-route test
covering taskTier value “huge”.

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The direction is valuable, and I found no credential or destination-boundary problem in the submitted diff. I rechecked exact head 7d25ccde: the six focused suites pass 71/71, typecheck passes, and privacy scan passes. I am requesting changes because the execution boundary is not yet safe for a model-routing feature.

  1. src/routing/request-evidence.ts:74-79 synthesizes balanced whenever a request contains no user-text item, and src/server/responses/core.ts:1494-1499 immediately uses that synthesized tier for route selection. A real Responses continuation can contain only previous_response_id plus function_call_output. On this head, an initial complex request selects the powerful candidate, while the tool-result continuation selects balanced. If local replay is unavailable but the selected API-key Responses provider can forward native continuation state, the prior response id can therefore be sent to a different model or provider. Preserve the prior tier/selected route for a continuation with no new user prompt, or fail closed when that affinity cannot be proved; do not invent a new balanced turn. Add server-level regressions for replay hit, native replay miss, tool-result-only input, and compact/continuation behavior.

  2. src/routing/prompt-classifier.ts:16-25,52-54 recognizes intent only in English and Chinese, while short length alone subtracts enough to classify an otherwise unknown prompt as fast. I reproduced fast for short, clearly repository-wide security work in Korean, Japanese, German, Russian, and Turkish—all languages exposed by this GUI. A short prompt is not positive evidence of simplicity. Make unmatched/unsupported-language input default conservatively to at least balanced unless a positive simple-intent or explicit low-effort signal exists, and add regressions across the shipped locales. Expanding a brittle keyword list is not required if the fallback contract is conservative.

  3. classifyPromptComplexity() computes bounded signal ids and a score, but request-evidence.ts:75-78 discards both and persists only the tier. The PR describes explainability, yet ocx logs explain can show only prompt-tier-*, not why that tier was chosen. Either carry the bounded non-content signal ids/score through the route trace and dry-run contract, or narrow the product/docs claim. Do not persist raw prompt text.

  4. This is a new heuristic policy that changes provider selection, cost, and possibly continuation ownership, but there is no repository [Decision Log]. Document the intent, alternatives, multilingual fallback, continuation/turn-stability rule, heuristic/versioning contract, and tradeoffs in the applicable structure/ document. The two current CodeRabbit threads also remain unresolved.

Finally, the head is 148 commits behind current dev@20c513198, the readiness checklist is 0/4, and there is no exact-head full CI. Rebase after the behavior blockers are fixed, rerun the focused GUI/runtime/docs checks, then require full exact-head CI before marking ready. This should remain a draft until those gates are complete.

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.

2 participants