Skip to content

Add temperature: Option<f32> to api::MessageRequest - #24

Merged
nuniesmith merged 1 commit into
mainfrom
claude/api-temperature-field-2026-05-20
May 21, 2026
Merged

Add temperature: Option<f32> to api::MessageRequest#24
nuniesmith merged 1 commit into
mainfrom
claude/api-temperature-field-2026-05-20

Conversation

@nuniesmith

@nuniesmith nuniesmith commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

Adds pub temperature: Option<f32> to api::MessageRequest, fixing the determinism regression introduced in PR #23 when model_router.rs migrated to api::OpenAiCompatClient. The old Ollama-native payload pinned temperature: 0.0; the migrated path lost that because MessageRequest didn't expose a temperature knob. model_router.rs::llm_classify now pins temperature: Some(0.0) again.

Changes

  • api::MessageRequest gains pub temperature: Option<f32> with #[serde(default, skip_serializing_if = "Option::is_none")] — backward-compatible on the wire (None ⇒ field omitted).
  • api::MessageRequest::with_temperature(f32) builder method.
  • openai_compat::build_chat_completion_request copies temperature into the outgoing JSON payload when set. AnthropicClient's request body already goes through serde_json::to_value, so the field flows through automatically without further changes.
  • src/model_router.rs::llm_classify now pins temperature: Some(0.0) again, with the module comment updated to reflect that determinism is restored.
  • All 28 MessageRequest struct literals across src/, crates/, and tests/ now include temperature: None.
  • New unit tests:
    • types::temperature_serializes_when_set_and_is_omitted_when_none
    • openai_compat::temperature_is_included_in_payload_when_set

Test plan

  • cargo test -p api --lib types:: → 3 passed
  • cargo test -p api --lib openai_compat::tests:: → 9 passed (including new temperature test)
  • cargo test -p api --test openai_compat_integration → 5 passed
  • cargo test -p rusty-claude-cli --test api_integration → 3 passed
  • cargo check --workspace --tests --exclude rustcode → clean
  • cargo check -p rustcode (blocked locally by the ort-sys CDN sandbox restriction; CI verifies)

Pre-existing failures NOT addressed in this PR

Both verified to fail on main as well — out of scope:

  • api::client::tests::resolves_existing_and_grok_aliases (opus alias now resolves to claude-opus-4-7, test still asserts -4-6)
  • 3 prompt_cache disk-cleanup tests that race on CLAUDE_CONFIG_HOME

https://claude.ai/code/session_014DMg4gxA8VZv1MucmM7PV9


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added temperature control support to API requests, enabling fine-tuning of model response randomness.
  • Improvements

    • Model classifier now explicitly uses deterministic settings for consistent classification behavior.

Review Change Stack

Restores the determinism regression introduced in PR #23 when model_router.rs
migrated to api::OpenAiCompatClient. The old Ollama-native payload pinned
temperature: 0.0; the migrated path lost that because MessageRequest didn't
expose a temperature knob.

Changes
- api::MessageRequest gains `pub temperature: Option<f32>` with
  `#[serde(default, skip_serializing_if = "Option::is_none")]` — backward
  compatible on the wire (None ⇒ field omitted).
- api::MessageRequest::with_temperature(f32) builder method.
- openai_compat::build_chat_completion_request copies `temperature` into the
  outgoing JSON payload when set; AnthropicClient's request body already goes
  through `serde_json::to_value` so the field flows through automatically.
- src/model_router.rs::llm_classify now pins `temperature: Some(0.0)` again.
- All 28 MessageRequest struct literals across src/, crates/, and tests/ now
  include `temperature: None` (default behaviour matches pre-PR semantics).
- New unit tests:
  - types::temperature_serializes_when_set_and_is_omitted_when_none
  - openai_compat::temperature_is_included_in_payload_when_set

Test plan
- `cargo test -p api --lib types::` → 3 passed
- `cargo test -p api --lib openai_compat::tests::` → 9 passed (including new
  temperature test)
- `cargo test -p api --test openai_compat_integration` → 5 passed
- `cargo test -p rusty-claude-cli --test api_integration` → 3 passed
- `cargo check --workspace --tests --exclude rustcode` → clean
- `cargo check -p rustcode` blocked locally by ort-sys CDN sandbox; CI verifies.

Pre-existing failures NOT addressed:
- api::client::tests::resolves_existing_and_grok_aliases (opus alias
  now resolves to claude-opus-4-7, test still asserts -4-6)
- 3 prompt_cache disk-cleanup tests
Both verified to fail on main as well — out of scope for this PR.

https://claude.ai/code/session_014DMg4gxA8VZv1MucmM7PV9
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a77261fa-1f6c-4423-8f98-125654b3be54

📥 Commits

Reviewing files that changed from the base of the PR and between 6b42bb9 and 5987831.

📒 Files selected for processing (18)
  • TODO.md
  • crates/api/src/prompt_cache.rs
  • crates/api/src/providers/anthropic.rs
  • crates/api/src/providers/openai_compat.rs
  • crates/api/src/types.rs
  • crates/api/tests/client_integration.rs
  • crates/api/tests/openai_compat_integration.rs
  • crates/rusty-claude-cli/src/app.rs
  • crates/rusty-claude-cli/src/main.rs
  • crates/rusty-claude-cli/tests/api_integration.rs
  • crates/tools/src/lib.rs
  • src/agent/pipeline.rs
  • src/api/proxy.rs
  • src/grok_client.rs
  • src/llm/grok.rs
  • src/model_router.rs
  • src/simple_client.rs
  • tests/test_grok_integration.rs

📝 Walkthrough

Walkthrough

This PR introduces an optional temperature field to MessageRequest, allowing callers to control temperature on LLM requests. The OpenAI-compatible provider conditionally includes temperature in its JSON payload. All request construction sites explicitly set temperature: None or Some(0.0) to establish consistent request shape, with the model classifier pinning temperature: Some(0.0) for determinism.

Changes

Temperature Field Addition and Provider Integration

Layer / File(s) Summary
MessageRequest type definition and builder
crates/api/src/types.rs, crates/api/src/types.rs (tests)
MessageRequest gains temperature: Option<f32> field with serde skip-if-none serialization. Builder method with_temperature() is added. Test module imports are adjusted and serialization behavior (field absent when None, present when set) is validated.
OpenAI-compatible provider temperature handling
crates/api/src/providers/openai_compat.rs
build_chat_completion_request conditionally includes temperature in JSON payload when request.temperature is Some(...). Tests updated to set temperature: None. New test temperature_is_included_in_payload_when_set validates both presence and absence of the field.
API test helpers and anthropic provider tests
crates/api/src/prompt_cache.rs, crates/api/src/providers/anthropic.rs, crates/api/tests/client_integration.rs, crates/api/tests/openai_compat_integration.rs
Test helper functions and anthropic provider test explicitly set temperature: None on MessageRequest to match updated struct shape.

Callers Explicitly Setting Temperature

Layer / File(s) Summary
CLI application requests
crates/rusty-claude-cli/src/app.rs, crates/rusty-claude-cli/src/main.rs, crates/rusty-claude-cli/tests/api_integration.rs
CliApp and AnthropicRuntimeClient request construction sites explicitly set temperature: None. Integration test helpers also set temperature: None.
Agent pipeline phase requests
src/agent/pipeline.rs
Planner, executor (text-only and tool-use), reviewer, and session consolidation phases all explicitly set temperature: None on request construction.
Proxy dispatch and Grok integrations
src/api/proxy.rs, src/grok_client.rs, src/llm/grok.rs, src/simple_client.rs
API proxy Claude streaming and non-streaming dispatch paths set temperature: None. Grok client implementations set temperature: None on OpenAI-compatible requests.
Tool runtime and smoke test
crates/tools/src/lib.rs, tests/test_grok_integration.rs
ProviderRuntimeClient streaming and non-streaming request paths set temperature: None. Live integration test explicitly sets temperature: None.

Model Classifier Determinism

Layer / File(s) Summary
Model router classifier temperature pinning
src/model_router.rs
llm_classify now pins temperature: Some(0.0) in the OpenAI-compatible request for deterministic classification. File-level documentation updated to reflect restoration of determinism and that the temperature field is now supported in the type.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes


Possibly related PRs

  • nuniesmith/rustcode#1: Updates to Claude dispatch paths in src/api/proxy.rs are directly related to the Claude/Anthropic routing introduced in this PR.
  • nuniesmith/rustcode#22: Updates to integration tests in crates/rusty-claude-cli/tests/api_integration.rs adjust test fixtures introduced in this PR.

Poem

🐰 A temperature field hops in with grace,
Now every request knows its rightful place—
None by default, or zero when precision's key,
The classifier stays cool, deterministically free! 🌡️

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/api-temperature-field-2026-05-20

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nuniesmith
nuniesmith marked this pull request as ready for review May 21, 2026 01:14
@nuniesmith
nuniesmith merged commit 826abcb into main May 21, 2026
1 of 2 checks 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.

2 participants