Providers and Models
This guide explains how to route model IDs to providers and when to discover a provider's model catalog.
Default Provider
Use a default provider when one upstream should receive any model name:
configuration = Laiya::Configuration.build do |builder|
builder.provider :ollama, Laiya::Provider::Ollama.new
builder.default_provider :ollama
end
With no explicit model routes or discovery setting, Laiya forwards
GET /v1/models to the default provider and passes completion requests through
to it.
Discover Models from an Upstream
Providers such as Ollama expose an OpenAI-compatible GET /v1/models endpoint.
Use models: :discover to query it at runtime instead of copying model names
into configuration:
configuration = Laiya::Configuration.build do |builder|
builder.provider :ollama, Laiya::Provider::Ollama.new, models: :discover
builder.default_provider :ollama
end
Laiya::Models::Discover fetches and caches the provider's catalog for 60
seconds. Laiya uses the discovered IDs for GET /v1/models and routes requests
for those IDs to the provider. The builder itself does not make network calls.
For multiple providers, enable discovery on each provider. Distinct model IDs
are routed automatically. If two providers advertise the same ID, the default
provider wins; an explicit builder.model route overrides discovery:
configuration = Laiya::Configuration.build do |builder|
builder.provider :openai, Laiya::Provider::OpenAI.new(
api_key: ENV.fetch("OPENAI_API_KEY")
), models: :discover
builder.provider :ollama, Laiya::Provider::Ollama.new, models: :discover
builder.model "llama3.2", provider: :ollama
builder.default_provider :openai
end
Expose Model Limits
OpenAI's standard model-list format has no context-window fields. Laiya lets
you attach a display name and limits to an explicit model route; it publishes
them under its laiya extension field:
configuration = Laiya::Configuration.build do |builder|
builder.provider :ollama, Laiya::Provider::Ollama.new, models: :discover
builder.model "llama3.2",
provider: :ollama,
display_name: "Llama 3.2",
limits: {context: 32_768, input: 28_672, output: 4_096}
builder.default_provider :ollama
end
The limits keys are context, input, and output, and values are positive
token counts. OpenCode does not currently infer these custom fields from
GET /v1/models; configure its model limit.context, limit.input, and
limit.output values on each client as well. The context limit should match
the effective upstream model configuration (for Ollama, including num_ctx).
Expose Ollama Thinking Controls
When Ollama model discovery is enabled, Laiya also queries /api/show for each
model and publishes available thinking controls under laiya.reasoning. Named
levels appear as supported_efforts with a default_effort; boolean-only
controls appear as thinking_values with a default_thinking. If a model has
no thinking metadata, advertises only [false], or /api/show is unavailable,
Laiya still lists it without reasoning metadata.
The OpenAI-compatible proxy already forwards reasoning_effort requests to
Ollama. OpenCode custom providers do not automatically turn Laiya's extension
metadata into variants, so configure variants from the discovered values in
each OpenCode model entry:
{
"providers": {
"laiya": {
"models": {
"qwen3-coder": {
"modelID": "qwen3-coder:latest",
"variants": [
{"id": "low", "body": {"reasoning_effort": "low"}},
{"id": "medium", "body": {"reasoning_effort": "medium"}},
{"id": "high", "body": {"reasoning_effort": "high"}},
],
},
},
},
},
}
Only configure variants advertised by the selected model. Thinking metadata and supported levels are model-specific.
Customize Discovery
Subclass Laiya::Models::Discover to filter models or attach provider-specific
metadata. Override include_model? to filter entries and normalize_model to
add or adjust model fields:
class LocalModels < Laiya::Models::Discover
protected
def include_model?(model)
super && model["id"].start_with?("llama")
end
def normalize_model(model)
super.merge("laiya" => {"limits" => {"context" => 32_768, "output" => 4_096}})
end
end
ollama = Laiya::Provider::Ollama.new
configuration = Laiya::Configuration.build do |builder|
builder.provider :ollama, ollama, models: LocalModels.new(ollama)
builder.default_provider :ollama
end
The model list includes configured IDs and discovered metadata. Custom discovery metadata is provider-specific and is likewise exposed under Laiya's extension field; standard clients may ignore it.