Skip to content

Check what a model supports

Models within one vendor disagree. claude-sonnet-4-5 accepts temperature and refuses effort; claude-opus-5 does the reverse. Support for sampling on OpenAI goes away at gpt-5, returns for gpt-5.1 through gpt-5.4, goes away at gpt-5.5 (but not gpt-5.5-pro) and is absent across all three gpt-5.6 variants.

There is no rule there to infer from a version number, so the module measures each model instead and lets you ask.

Ask about a provider and model

info := chat.CapabilitiesFor(chat.ProviderOpenAI, "gpt-5.4")

switch info.Capabilities.Support(chat.CapSampling) {
case chat.SupportYes:
    // safe to set Config.Temperature
case chat.SupportNo:
    // it would be dropped at construction; use Config.Effort instead
case chat.SupportUnknown:
    // too new to have been measured; try it and handle the request error
}

Pass an empty model to ask about the provider's default.

Ask about a client you already have

info := chat.CapabilitiesOf(client)

This reports on the model the client will actually use (the configured one, or the default it fell back to) which is the question you usually mean.

Three values, not two

Support is deliberately three-valued, and there is no Supports() bool.

Value Meaning
SupportYes the model accepts it
SupportNo it will be dropped at construction
SupportUnknown nobody could say

Unknown is the common case, not an edge case: two of the five providers expose no capability data at all, and any model newer than the last generated table reports it. Collapsing it into a bool has to pick a reading, and either choice is wrong about half the time. Read as unsupported, claude-local looks featureless; read as supported, you promise things that will fail.

Unknown means proceed, not stop

The module treats Unknown as "carry on and let the provider answer". A stale table therefore costs you nothing: only a confident SupportNo changes behaviour.

The specifics, where a provider gives them

"Caching is supported" is not actionable. "Implicit caching engages above 1,024 tokens" tells you whether restructuring a prompt is worth it. The pointer fields carry that detail, and are nil when the provider said nothing:

if c := info.Capabilities.Caching; c != nil {
    fmt.Println("implicit caching from", c.ImplicitMinTokens, "tokens")
    fmt.Println("retention options:", c.TTLs)
}

if s := info.Capabilities.Sampling; s != nil {
    fmt.Printf("temperature range %.1f–%.1f\n", s.MinTemperature, s.MaxTemperature)
}

if info.Limits != nil {
    fmt.Println("max input tokens:", info.Limits.MaxInputTokens)
}

Nil is distinct from a provider that answered with zeroes, so always check before dereferencing.

Where the answers come from

Each provider module ships a generated table, and the three vendors disagree completely about what they will tell you:

Module Source What the vendor reports
chat-anthropic API and probe effort, structured outputs, image/PDF (but nothing about temperature)
chat-openai probe only no capability data at any API version
chat-gemini API limits, maxTemperature, topP, thinking, cache

Where a vendor is silent, the generator establishes the answer by sending a real request, because that is the same path a real call takes. A weekly job watches for models the tables do not yet reflect and raises an issue against the provider module rather than changing anything itself.