Skip to content

fix(model-router): enforce public model aliases - #2991

Open
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/model-router-validate-public-alias
Open

fix(model-router): enforce public model aliases#2991
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/model-router-validate-public-alias

Conversation

@tang-vu

@tang-vu tang-vu commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Why this matters

The model router publishes exactly ods/current and default from /v1/models, but its forwarding route accepted any model value and silently mapped it to the active runtime. Clients could believe a concrete or misspelled model was honored while ODS served a different model and rewrote the response back to the unsupported name.

Root cause and invariant

The request body used str(payload.get(model) or PUBLIC_ALIASES[0]), coercing arbitrary strings, numbers, booleans, and containers into apparent aliases. The invariant is that the forwarding boundary accepts only aliases the discovery endpoint advertises; the existing missing/empty-model compatibility default remains ods/current.

Unsupported values now receive an OpenAI-shaped 400 before queue admission or any upstream request.

Overlap check

Searched open and closed PRs for model router unsupported alias, public model alias validation, and the changed production file. Open same-file PRs are #2843 (MLX runtime family) and #2719 (internal-key auth); neither validates the public model contract. No semantic match was found.

Regression coverage

The FastAPI contract suite now submits a concrete runtime ID, an unknown string, a number, a boolean, and a list. Each must return 400 invalid_request_error and the mock upstream must receive zero calls. Existing coverage proves both advertised aliases continue to route and rewrite correctly.

Validation

  • pytest -q ods/extensions/services/model-router/tests/test_router.py -x — 53 passed
  • python -m py_compile ods/extensions/services/model-router/app/main.py ods/extensions/services/model-router/tests/test_router.py
  • git diff --check

Tradeoffs and rollback

This deliberately closes an undocumented permissive behavior. Clients selecting a concrete runtime must use the switchboard/control plane, then call the stable alias. Revert restores permissive alias coercion; no state or config migration is involved.

@tang-vu

tang-vu commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Batch compatibility receipt (2026-08-23)

Validated merge order: #2989 ? #2990 ? #2993 ? #2991 ? #2992 ? #2994 ? #2995 ? #2996 ? #2997 ? #2998. The changes are independently useful; this order only reconciles shared model-router and magic-link files.

Synthetic integration head: origin/batch/quality-ten-20260822-round2-integration at 91eb730d. The only textual conflict was the two model-router tests inserting at the same class boundary; the integration resolution retains both contracts. Magic-link changes merged cleanly.

Combined validation on that exact head:

  • remote-provider egress contract: 16 passed
  • Token Spy suites: 22 passed, 1 skipped (live PostgreSQL availability)
  • model-router suite: 55 passed
  • APE suite: 29 passed
  • dashboard OAuth + magic-link suites: 118 passed, 2 platform skips
  • Brave Search loopback E2E: all checks passed
  • git diff --check: passed

All required GitHub checks are green across the batch. #2992 initially hit a transient openSUSE repository/mirror failure while installing rsync; a clearly labeled empty retry commit reran the unchanged tree, and openSUSE plus the full matrix passed.

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