Skip to content

feat: Support multi-provider model resolution with budget-based selection #887

@Aureliolo

Description

@Aureliolo

Problem

The ModelResolver (src/synthorg/providers/routing/resolver.py:64-86) raises ModelResolutionError when two providers register the same model ID. This prevents users from adding duplicate providers for the same models (e.g., two Anthropic subscriptions both offering claude-sonnet-4-20250514).

Use Case

A user has two Claude subscriptions (personal + work) and wants to add both as providers. Agents should be able to use either, with selection based on budget/quota tracking.

Current Workaround

Users must use different model aliases per provider (e.g., sonnet-personal vs sonnet-work). This is ugly and leaks provider specifics into routing rules.

Proposed Solution

  1. Change ModelResolver index from dict[str, ResolvedModel] to dict[str, list[ResolvedModel]]
  2. Add a selection strategy (budget-aware, round-robin, or rule-based) when multiple providers serve the same model
  3. Integrate with the existing SubscriptionConfig quota tracking for budget-based selection
  4. The routing rules and fallback chain should consider provider quota state

Scope

  • src/synthorg/providers/routing/resolver.py -- multi-provider index
  • src/synthorg/providers/routing/router.py -- selection strategy
  • src/synthorg/budget/ -- quota-aware provider selection
  • Tests for all changes

Context

Discovered during #785 (Providers page rework). The litellm_provider field added in #785 enables multiple providers to share the same LiteLLM routing prefix, but the resolver collision prevents them from sharing model IDs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    prio:mediumShould do, but not blockingtype:featureNew feature implementationv0.6Minor version v0.6v0.6.1Patch release v0.6.1

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions