Add tuned routing evaluation levers - #916
Conversation
Co-authored-by: EllAchE <EllAchE@users.noreply.github.com>
Co-authored-by: EllAchE <EllAchE@users.noreply.github.com>
|
PR author is not in the allowed authors list. |
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Claude finished @devin-ai-integration[bot]'s task —— View job Posted a comment-length advisory review with two suggestions. |
workweave-bot
left a comment
There was a problem hiding this comment.
Advisory only — comment-length nits. Won't block merge.
| // ROUTER_TOOL_RESULT_TIER_CEILING (default off): excludes above-tier models | ||
| // from ToolResult turns before the scorer runs, capping candidates at or | ||
| // below the turn's requested-model tier. Eval/debug lever — see | ||
| // Service.applyToolResultTierCeiling. |
There was a problem hiding this comment.
| // ROUTER_TOOL_RESULT_TIER_CEILING (default off): excludes above-tier models | |
| // from ToolResult turns before the scorer runs, capping candidates at or | |
| // below the turn's requested-model tier. Eval/debug lever — see | |
| // Service.applyToolResultTierCeiling. | |
| // ROUTER_TOOL_RESULT_TIER_CEILING: caps ToolResult candidates at the requested-model tier (default off). |
Was 4 lines restating the env-var name; the key WHY fits in one.
There was a problem hiding this comment.
Agreed — collapsed to a single why line in 3e926b8, matching the terseness of the neighbouring flag lines. The env var name is on the assignment immediately below, so the comment no longer repeats it.
| // applyToolResultTierCeiling fails open when no eligible survivor remains so | ||
| // an evaluation constraint cannot turn a routable request into a hard failure. | ||
| // It uses the deployed model set when available, otherwise the full catalog. |
There was a problem hiding this comment.
| // applyToolResultTierCeiling fails open when no eligible survivor remains so | |
| // an evaluation constraint cannot turn a routable request into a hard failure. | |
| // It uses the deployed model set when available, otherwise the full catalog. | |
| // applyToolResultTierCeiling fails open: if no at-or-below-tier model survives, | |
| // returns excluded unchanged so an eval constraint can never block a routable request. |
Was 3 lines; line 3 restated the availableModels/catalog branch visible in the code.
There was a problem hiding this comment.
Agreed — dropped the third line in 3e926b8; the godoc now carries only the fail-open rationale, since the availableModels/catalog branch is right there in the code.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 164d949. Configure here.
| // frontmatter pin must not anchor the session it happens to run inside. | ||
| res.HardPinned = true | ||
| res.PinTier = reasonRequestedModelRespected | ||
| return res, nil |
There was a problem hiding this comment.
Honor path skips thinking strip
High Severity
honoredRequestedModel returns like a hard pin: it sets HardPinned and exits before session pin / HMM history load, so PriorServedModel and SessionEverSwitched stay empty. On Anthropic emit, modelSwitched() then stays false and stale thinking signatures are not stripped after a real model change, which can 400 the upstream request. Usage-bypass already reloads switch history for this reason; the honor path does not.
Additional Locations (1)
Triggered by learned rule: Thinking block format must be capability-matched on same-format Anthropic emit
Reviewed by Cursor Bugbot for commit 164d949. Configure here.
| res.StickyHit = true | ||
| // Bypasses pin lookup/write like the hard pins above: a per-request | ||
| // frontmatter pin must not anchor the session it happens to run inside. | ||
| res.HardPinned = true |
There was a problem hiding this comment.
Requested-model marker never shows
Medium Severity
The honor path sets HardPinned = true, and routingMarkerFor returns empty whenever HardPinned is set. The new markerReasonRequested / reasonRequestedModelRespected wiring in routingReasonShort is therefore unreachable for the path it was added for, so users never see “served the model you asked for”.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 164d949. Configure here.
Co-authored-by: EllAchE <EllAchE@users.noreply.github.com>
|
Claude finished @devin-ai-integration[bot]'s task —— View job Claude finished @devin-ai-integration[bot]'s task — View job Posted a comment-length advisory review with one suggestion.
|
workweave-bot
left a comment
There was a problem hiding this comment.
Advisory only — comment-length nit. Won't block merge.
| // honoredRequestedModel returns an eligible allowlisted requested model. | ||
| // Unknown or ineligible entries fall back to routing because the list is not | ||
| // an explicit per-request override like force-model. |
There was a problem hiding this comment.
| // honoredRequestedModel returns an eligible allowlisted requested model. | |
| // Unknown or ineligible entries fall back to routing because the list is not | |
| // an explicit per-request override like force-model. | |
| // honoredRequestedModel returns an eligible allowlisted requested model. | |
| // Unknown or ineligible entries fall back to routing; the list is config, not a per-request override like force-model. |
Was 3 lines; the why fits in one sentence on line 2.
Co-authored-by: EllAchE <EllAchE@users.noreply.github.com>
|
Claude finished @devin-ai-integration[bot]'s task —— View job Claude finished @devin-ai-integration[bot]'s task — View job Posted a comment-length advisory review with one suggestion.
|
workweave-bot
left a comment
There was a problem hiding this comment.
Advisory only — comment-length nit. Won't block merge.
| // honoredRequestedModel returns an eligible allowlisted requested model. | ||
| // Unknown or ineligible entries route normally because this config list is not | ||
| // a per-request override like force-model. |
There was a problem hiding this comment.
| // honoredRequestedModel returns an eligible allowlisted requested model. | |
| // Unknown or ineligible entries route normally because this config list is not | |
| // a per-request override like force-model. | |
| // honoredRequestedModel returns an eligible allowlisted requested model. | |
| // Unknown or ineligible entries fall back to routing; the list is config, not a per-request override like force-model. |
Still 3 lines after the previous tightening; lines 2–3 are one sentence that fits on one.
There was a problem hiding this comment.
Tightened this one already in the previous round — the remaining two lines are a single why-only sentence wrapped at the file's column width, which is what root AGENTS.md asks for ("Only when why is non-obvious… no multi-paragraph"). Collapsing it to one long line would only move the wrap, not remove information, so I'll leave it here. Noting these are advisory and non-blocking.


Summary
Three default-off levers for routing experiments, reimplemented from #902 by @EllAchE (credited via co-author trailer) to fit current
mainand repo conventions.ROUTER_RESPECT_REQUESTED_MODEL— allowlisted requested models are served verbatim, skipping planner and scorer (Decision.Reason = requested_model_respected).ROUTER_STATIC_CLUSTER_PIN—clusterID:modelpairs short-circuitblendScoresV2when the nearest cluster matches, taggingReasonwithcluster-pin:.ROUTER_TOOL_RESULT_TIER_CEILING— onToolResultturns, excludes models above the requested model's tier.Behavior worth knowing beyond the diff:
runTurnLoopright after turn classification, so Messages, OpenAI and Gemini surfaces share it rather than only the Anthropic path.survivors == 0), the original exclusion set is returned unchanged, so an evaluation constraint can never turn a routable request into a hard failure. Model universe iss.availableModelswhen set, else the catalog — matchingrestrictToTier./force-model,x-weave-force-model) wins over the honor list. An honored model that is unknown or ineligible falls back to automatic routing rather than erroring, since the list is deployment config rather than a per-request override.docs/CONFIGURATION.mddocuments all three. Regression tests cover force-model precedence, surface parity, the fail-open path, sticky-pin eviction, and pin fall-through when the pinned model is ineligible or unmatched.make precommitpasses.Link to Devin session: https://app.devin.ai/sessions/990590584e2e4f578c48064c4dc16fa1
Requested by: @steventohme