(
candidates: list[str],
*,
mode: RoutingMode,
tier: Tier,
lane: CapabilityLane,
effective_output: int,
estimated_input_tokens: int,
pricing: dict[str, ModelPricing],
capabilities: dict[str, ModelCapabilities],
requirements: RequestRequirements,
weights: SelectionWeights,
target_quality: ServedQuality,
previous_served_quality: ServedQuality | None,
quality_by_model: dict[str, ServedQuality],
user_keyed_models: set[str] | None,
bandit_config: BanditConfig,
model_experience: object | None,
)
| 550 | |
| 551 | |
| 552 | def _score_candidates( |
| 553 | candidates: list[str], |
| 554 | *, |
| 555 | mode: RoutingMode, |
| 556 | tier: Tier, |
| 557 | lane: CapabilityLane, |
| 558 | effective_output: int, |
| 559 | estimated_input_tokens: int, |
| 560 | pricing: dict[str, ModelPricing], |
| 561 | capabilities: dict[str, ModelCapabilities], |
| 562 | requirements: RequestRequirements, |
| 563 | weights: SelectionWeights, |
| 564 | target_quality: ServedQuality, |
| 565 | previous_served_quality: ServedQuality | None, |
| 566 | quality_by_model: dict[str, ServedQuality], |
| 567 | user_keyed_models: set[str] | None, |
| 568 | bandit_config: BanditConfig, |
| 569 | model_experience: object | None, |
| 570 | ) -> list[CandidateScore]: |
| 571 | experience = { |
| 572 | model: _experience_snapshot(model_experience, model, mode, tier) |
| 573 | for model in candidates |
| 574 | } |
| 575 | costs = { |
| 576 | model: _calc_cost( |
| 577 | model, |
| 578 | estimated_input_tokens, |
| 579 | effective_output, |
| 580 | pricing, |
| 581 | input_cost_multiplier=experience[model].input_cost_multiplier, |
| 582 | ) |
| 583 | for model in candidates |
| 584 | } |
| 585 | cost_scores = _normalize_inverse(costs) |
| 586 | ranked: list[CandidateScore] = [] |
| 587 | candidate_count = len(candidates) |
| 588 | cheapest_cost = min(costs.values()) if costs else 0.0 |
| 589 | bucket_pulls = _bucket_pulls(model_experience, mode, tier) |
| 590 | bandit_active = bandit_config.enabled and tier in bandit_config.enabled_tiers |
| 591 | |
| 592 | for index, model in enumerate(candidates): |
| 593 | cap = capabilities.get(model, ModelCapabilities()) |
| 594 | exp = experience[model] |
| 595 | editorial = 1.0 / (index + 1) |
| 596 | reasoning_bias = 1.0 if requirements.prefers_reasoning and cap.reasoning else 0.0 |
| 597 | candidate_quality = quality_by_model.get(model, ServedQuality.ECONOMY) |
| 598 | quality_alignment = quality_alignment_score(candidate_quality, target_quality) |
| 599 | continuity_bias = continuity_alignment_score(candidate_quality, previous_served_quality) |
| 600 | byok = 1.0 if user_keyed_models and model in user_keyed_models else 0.0 |
| 601 | free_bias = 1.0 if cap.free else 0.0 |
| 602 | local_bias = 1.0 if cap.local else 0.0 |
| 603 | exploration_bonus = _bandit_bonus( |
| 604 | enabled=bandit_active, |
| 605 | bandit_config=bandit_config, |
| 606 | candidate_cost=costs[model], |
| 607 | cheapest_cost=cheapest_cost, |
| 608 | reliability=exp.reliability, |
| 609 | samples=exp.samples, |
no test coverage detected