feat(llm): support profile slots so the chat path tracks reviewed selections - #1501
Conversation
…ections Two changes so Manager-Database follows the fleet's reviewed model selections instead of frozen model pins. 1. llm/client.py: an explicitly configured slot file may now name a `profile` (resolved through llm_registry.select_model_for_profile) in addition to an explicit `model` or legacy `quality_tier`/`tier`. Workflows now ships config/llm_slots.json in profile form with no model pins; before this change such a file resolved to ZERO slots here and the chat path served no model at all. An unresolvable profile fails closed rather than falling back. 2. config/llm_slots.json: migrate to the profile form. The pinned form did not track the registry: the shared resolver deliberately RETAINS an unprofiled pin while the pinned model is still lifecycle=current, so slot1 stayed on gpt-5.4 and slot3 on codex-mini-latest even after the reviewed selection advanced. Only slot2 followed the selection, and only because its pinned claude-sonnet-4-6 is absent from the registry. This file is sync_mode: create_only in the Workflows manifest, so it can only change here. Also make the two tests that read the AMBIENT config assert the reviewed selection rather than hardcoded ids, so a synced registry refresh is not a CI failure. Hermetic tests that write their own fixtures keep explicit ids. Verified: 13 tests pass; deliberate break (neutralizing the profile read) makes test_profile_slot_resolves_reviewed_selection fail, and reverting restores it; freshness gate reports 0 blocking with the profile-form slots; ruff clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 7 minutes Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?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 reviews. How do review 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 refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
Comment |
Why
Manager-Database was pinned to frozen model ids and would not pick up an advanced reviewed selection. Two independent causes, both verified against
main:config/llm_slots.jsonpins don't track the registry. The shared resolver deliberately retains an unprofiled pin while the pinned model is stilllifecycle: current(tools/llm_registry.py, theexplicit_entry ... lifecycle == "current"branch). Probed with a registry whose selections had advanced:gpt-5.4gpt-5.4current→ retainedclaude-sonnet-4-6claude-sonnet-5codex-mini-latestcodex-mini-latestcurrent→ retainedSo only slot2 followed the selection, and only by accident of its pin being invalid.
llm/client.pyhad noprofilesupport. Workflows now shipsconfig/llm_slots.jsonin profile form (no model pins). Verified: with that file set viaLANGCHAIN_SLOT_CONFIG,_load_slot_config()returned[]andbuild_chat_client()returnedNone— the chat path would serve no model at all.config/llm_slots.jsonissync_mode: create_onlyin the Workflows manifest ("repos may customize provider preferences"), so it can only be changed here.What changed
llm/client.py— an explicitly configured slot entry may now name aprofile, resolved viallm_registry.select_model_for_profile, alongside the existing explicitmodeland legacyquality_tier/tier. An unresolvable profile is skipped (fails closed), never silently replaced by a default. This mirrorstools/llm_registry.load_slot_configsemantics. Thelifecycle/blocked eligibility checks from fix: enforce current registry models for chat #1490 are untouched.config/llm_slots.json— migrated to the profile form, so all three slots resolve from the reviewedverifier-balancedselections.tests/test_llm_client.py— the two tests that read the ambient config now assert the reviewed selection instead of hardcodinggpt-5.4/claude-opus-4-6. A synced registry refresh was otherwise a guaranteed CI failure with no underlying defect. Hermetic tests that write their own registry/slot fixtures deliberately keep explicit ids.Test gate
test_profile_slot_resolves_reviewed_selection— a profile-only slot resolves to the reviewed selection for that profile/provider.test_profile_slot_with_unresolvable_profile_fails_closed— a profile with no matching selection serves nothing; the fakecreate_llmraises if reached.profile = "") makestest_profile_slot_resolves_reviewed_selectionFAIL; restoring it returns all 13 to green.Verification
Pairs with stranske/Workflows#2852, which advances the reviewed selections. Order-independent: this PR is correct against the current registry too (it resolves today's selections), and starts tracking the new ones as soon as the registry syncs.
🤖 Generated with Claude Code