Skip to content

Stop defaulting temperature in Raix::Configuration#50

Merged
obie merged 1 commit into
mainfrom
fix/no-default-temperature
May 20, 2026
Merged

Stop defaulting temperature in Raix::Configuration#50
obie merged 1 commit into
mainfrom
fix/no-default-temperature

Conversation

@obie
Copy link
Copy Markdown
Contributor

@obie obie commented May 20, 2026

Summary

  • Raix::Configuration#initialize no longer sets temperature = 0.0. Callers who want a specific temperature now have to set one explicitly (or rely on the provider's server-side default).
  • Adds spec/raix/default_temperature_spec.rb covering both directions: the parameter is now omitted when unset, and an explicit value (including class-level configure) still flows through to RubyLLM::Chat#with_temperature.
  • CHANGELOG entry under `[Unreleased]`.

Why

Production hit RubyLLM::Error: No endpoints found that can handle the requested parameters from a routine chat_completion(json: true) call against `anthropic/claude-opus-4-7`. Sentry: INGENIUM-6.

Tracing through Raix + RubyLLM + OpenRouter:

  1. `Configuration#initialize` ran `self.temperature = DEFAULT_TEMPERATURE` (`0.0`).
  2. `chat_completion` line: `params[:temperature] ||= temperature.presence || configuration.temperature` → `params[:temperature] = 0.0`.
  3. `ruby_llm_request` line: `chat.with_temperature(params[:temperature]) if params[:temperature]` — `0.0` is truthy in Ruby, so it fires.
  4. RubyLLM's OpenRouter provider serializes `temperature: 0.0` into the payload.
  5. `json: true` also sets `provider.require_parameters: true` (only-route-to-providers-that-natively-support-every-param).
  6. OpenRouter's catalog for `anthropic/claude-opus-4.7` lists `supported_parameters` as: `include_reasoning, max_tokens, reasoning, response_format, stop, structured_outputs, tool_choice, tools, verbosity` — no `temperature`.
  7. With `require_parameters: true` and no eligible providers → 404 "No endpoints found...".

Verified locally with the exact production payload via `curl`: removing the `temperature: 0.0` field is the difference between success and the 404. Repro'd in Raix and confirmed the fix unblocks it.

Temperature is the only knob the Configuration was forcing on. Every other parameter (`top_p`, `frequency_penalty`, `presence_penalty`, etc.) is nil by default and is only serialized when the caller sets it. This change makes temperature consistent with the rest.

Breaking change note

Requests that previously ran at temperature 0.0 will now run at the provider's default (typically ~1.0). Pin explicitly if you relied on the old behavior:

```ruby
Raix.configure { |c| c.temperature = 0.0 } # global

or

class MyAgent
include Raix::ChatCompletion
self.temperature = 0.0 # per-class
end
```

Test plan

  • `bundle exec rspec spec/raix/default_temperature_spec.rb` — 6 examples, 0 failures
  • `bundle exec rspec` (full suite) — 104 examples, 0 failures, 1 pending (pre-existing)
  • End-to-end repro via `bin/rails runner` against `anthropic/claude-opus-4-7` with stock Raix → 404; with this patch → returns the JSON object cleanly

The Configuration#initialize line `self.temperature = DEFAULT_TEMPERATURE`
forced `temperature: 0.0` into every chat_completion request whose caller
hadn't set a temperature explicitly. With `provider.require_parameters: true`
— which Raix sets automatically whenever `json: true` is passed — OpenRouter
rejects the request 404 "No endpoints found that can handle the requested
parameters" for any provider whose `supported_parameters` list omits
`temperature`. Anthropic's Claude 4.7 models (opus-4.7, opus-4.7-fast) are
exactly that case, so `chat_completion(json: true)` against
`anthropic/claude-opus-4-7` failed in production.

Drop the default. When temperature is unset, the request omits it and the
provider applies its own server-side default. Callers wanting deterministic
output set it explicitly (`self.temperature = 0.0` per-class, or
`Raix.configure { |c| c.temperature = 0.0 }` globally).

Adds spec/raix/default_temperature_spec.rb covering:
  - no with_temperature call when nothing is set
  - explicit `temperature = 0.0` still forwards
  - class-level configured temperature still forwards
  - fresh Configuration#temperature is nil; other defaults unchanged

Note for upgraders: requests that previously ran at temperature 0.0 will now
run at the provider's default (typically 1.0). Pin temperature explicitly if
you relied on the old behavior.
@obie obie merged commit c53f8fb into main May 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant