Skip to content

[FEATURE] Add ability to set default providers #686

@llenodo

Description

@llenodo

Scope check

  • This is core LLM communication (not application logic)
  • This benefits most users (not just my use case)
  • This can't be solved in application code with current RubyLLM
  • I read the Contributing Guide

Due diligence

  • I searched existing issues
  • I checked the documentation

What problem does this solve?

Using a non-default provider requires passing provider: on every call:

RubyLLM.chat(model: 'claude-sonnet-4-6', provider: :bedrock)
RubyLLM.chat(model: 'claude-haiku-4-5', provider: :bedrock)

There's no way to configure this globally, so anyone using bedrock/azure/vertexai as their primary provider ends up with a monkey patch or extra provider: keys everywhere.

This only covers chat — you'd need the same for embed, paint, transcribe, and moderate. It also bypasses the model resolution layer, so alias handling and bedrock region inference don't work correctly.

Proposed solution

default_providers: Route models to specific providers based on model ID prefix.

  • More specific keys take precedence over shorter ones.
  • Only applies when no explicit provider: argument is passed.
RubyLLM.configure do |config|
  config.default_providers = {
    'claude' => :bedrock,                # all claude models route to bedrock
    'claude-haiku' => :anthropic,        # except haiku, which goes direct to anthropic
    'gpt' => :azure,                     # all gpt models route to azure
    'gemini' => :vertexai,               # all gemini models route to vertex ai
    'claude-sonnet-4-5' => :openrouter,  # one specific model via openrouter
  }
end

Why this belongs in RubyLLM

Specifying provider every time is a waste and unnecessary.

Right now I do this with a Monkey Patch because we always use bedrock for claude, would love to get rid of it!

module RubyLLMBedrockDefaultPatch
  def chat(model:, provider: nil, **options)
    provider ||= :bedrock if model.to_s.match?(/^claude-/)
    super
  end
end

# Prepend to RubyLLM module to default Claude models to Bedrock
RubyLLM.singleton_class.prepend(RubyLLMBedrockDefaultPatch)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions