feat: provider-neutral OpenRouter families + bump core to engine #22#26
Conversation
Reconstructed from Edgars Nemše's #24, carrying only the family half. The provider-adapter half is in its sibling PR; this one makes discovered OpenRouter marketplace families provider-neutral. What it does: - sources/openrouter.py: a discovered marketplace model's policy-facing family is the provider-neutral name (`openai/gpt-5-mini` -> `gpt-5-mini`), while `wire_model_id` keeps the exact OpenRouter slug for the wire. `service_aliases` (config) handle the canonicalization exceptions where stripping the vendor isn't the right family (dated/suffixed slugs). Curated families served by the static `openrouter` provider are deduped out, so a marketplace row never shadows a curated family. - This pairs with the engine's `provider_eq` (#18): family is the model, provider is a separate axis the algebra filters. It lets a single provider-agnostic policy span curated + marketplace routes for one model, which is the point of the router ("stop hardcoding models"). Core bump: `core` -> 97d0333 (unhardcoded-engine #22), which makes `served_model_id` the offer's wire id (`offer.wire_model_id or model_family`). With a neutral family + a distinct wire slug, the engine now wires the slug on both the curated and discovered paths without every adapter special-casing `wire_model_id`, and the replayable trace records the real wire id. The §3 determinism boundary holds: `model_meta.lua` stays curated-keyed (refresh_model_meta untouched), so an on-chain/genvm host lacking a discovered offer still fails closed. Pinned by test_openrouter_model_meta_still_keyed_by _curated_family and the dedup assertion in test_openrouter_discovery_derives_policy_families_from_raw_model_ids. Verification: nix-shell --run 'python -m pytest tests -q' -> 333 passed, 2 skipped, 0 failed, against the bumped core. No new dependency.
|
Warning Review limit reached
More reviews will be available in 54 minutes and 8 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ 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 |
retry_policies.balanced.context_overflow was the only non-stream kind that aborted the whole request. That predates provider-neutral families (#26): a family like gpt-5.4 now spans candidates with heterogeneous context windows (openai, openrouter, antseed), so an overflow on the first route says nothing about the rest — yet abort killed the request without trying them. retry_same would be futile (same model, same window); next_candidate is not. Now context_overflow falls through like bad_request/timeout. If every candidate overflows the request still ends cleanly in `exhausted: context_overflow`. stream_interrupted stays abort (content already delivered — can't retry). Behavioural test (fails against HEAD): family:gpt-5.4 whose every route returns context_overflow now calls >1 candidate before exhausting, where HEAD aborted on the first — the exact shape of the prod failure (family:gpt-5.4 tried only openrouter, then aborted).
Reconstructed from @MuncleUscles's #24, carrying only the family half. The provider-adapter half is #25; this PR makes discovered OpenRouter marketplace families provider-neutral.
What it does
sources/openrouter.py: a discovered marketplace model's policy-facing family is the provider-neutral name (openai/gpt-5-mini→gpt-5-mini), whilewire_model_idkeeps the exact OpenRouter slug for the wire.service_aliases(config) handle the canonicalization exceptions where stripping the vendor isn't the right family (dated/suffixed slugs). Curated families served by the staticopenrouterprovider are deduped out, so a marketplace row never shadows a curated family.provider_eq(feat(metering): capture prompt-cache reads + accurate cross-provider cost #18): family is the model, provider is a separate axis the algebra filters. Lets one provider-agnostic policy span curated + marketplace routes for the same model — the point of the router ("stop hardcoding models").Core bump (depends on
unhardcoded-engine#22, merged)core→97d0333, which makesserved_model_idthe offer's wire id (offer.wire_model_id or model_family). With a neutral family + a distinct wire slug, the engine wires the slug on both the curated and discovered paths without every adapter special-casingwire_model_id, and the replayable trace records the real wire id.Invariants (§3)
The determinism boundary holds:
model_meta.luastays curated-keyed (refresh_model_metauntouched), so an on-chain/genvm host lacking a discovered offer still fails closed. Pinned bytest_openrouter_model_meta_still_keyed_by_curated_family+ the dedup assertion intest_openrouter_discovery_derives_policy_families_from_raw_model_ids.Verification
nix-shell --run 'python -m pytest tests -q'→ 333 passed, 2 skipped, 0 failed, against the bumped core. No new dependency. No CI — re-run before merge.Split / order
Superseding #24:
unhardcoded-engine#22(merged) → this PR (families, bumps core) + #25 (native adapters). Merge #25 and this in either order; #24 to be closed once both land.