Skip to content

fix(llm): temperature is always sent and rejected by claude-opus-5-5 (breaks the #700 federation path) #701

Closed

Description

@ajianaz

Problem

cora always sends temperature in the chat-completions request (src/engine/llm/transport.rs:270, "temperature": config.temperature, default 0.0, an f32 that cannot be unset). Newer Anthropic models reject the parameter, so every review against them fails:

LLM API returned status 400: {"error":{"code":"invalid_request_error","message":"`temperature` is deprecated for this model.","type":"invalid_request_error","param":null}}

This makes the workload identity federation path from #700 unusable with its default model (claude-opus-5-5): the token exchange succeeds, then the review fails. The Cora Review check still turns green, but the verdict is "Review could not complete", which blocks a merge gate that requires a real verdict.

Reproduction

codecoradev/tole#449 ports #700 to tole (pull_request trigger, so the PR's own run uses the new workflow):

  • Run 40462794838 (head fedb691): step "Exchange the GitHub OIDC token…" logs Using a short-lived Anthropic access token (workload identity federation).
  • "Run Cora AI Code Review" with cora-base-url: https://api.anthropic.com/v1, cora-model: claude-opus-5-5 (cora 0.19.0): Attempt 1: exit=0, sarif_bytes=612 (fallback SARIF), retries, and the PR comment ends as the 400 above.

The only difference from the passing #700 smoke test (anthropic-wif-smoke.yml, HTTP 200 on /v1/chat/completions with the same token type and model) is the temperature key, which the smoke request does not send. Expected minimal reproduction (not run outside CI, since it needs a federated token):

curl -sS https://api.anthropic.com/v1/chat/completions \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"model":"claude-opus-5-5","max_tokens":16,"temperature":0,"messages":[{"role":"user","content":"ok"}]}'

Proposal

  • Make temperature optional: Option<f32> in LlmConfig/the engine config, sent only when set (in .cora.yaml llm.temperature or the global config), and keep it in the cache key as None vs Some.
  • Or, on a 400 that names temperature, retry once without it (and log that it was dropped).
  • Consider a model capability check so cora config validate can warn about a temperature the model will reject.

Acceptance

  • A review with base_url: https://api.anthropic.com/v1 and model: claude-opus-5-5 completes with a real verdict.
  • Providers that accept temperature keep deterministic 0.0 output when it is configured.
  • A regression test asserts the request body has no temperature key when it is unset.

Activity

  1. added 2 commits that reference this issue on Oct 27, 2026
    ca4e189
    36a8dba
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions