Skip to content

fix(config): honor default_temperature config while running "zeroclaw agent" without temperature parameter#3067

Merged
theonlyhennygod merged 13 commits intozeroclaw-labs:masterfrom
kunalk16:fix-honor-default-temperature-agent-command
Mar 11, 2026
Merged

fix(config): honor default_temperature config while running "zeroclaw agent" without temperature parameter#3067
theonlyhennygod merged 13 commits intozeroclaw-labs:masterfrom
kunalk16:fix-honor-default-temperature-agent-command

Conversation

@kunalk16
Copy link
Copy Markdown
Contributor

@kunalk16 kunalk16 commented Mar 9, 2026

Summary

Describe this PR in 2-5 bullets:

  • Base branch target (master for all contributions): master
  • Problem: 'default_temperature config from config.toml is not honored when we execute the zeroclaw agent command without the --temperature
  • Why it matters: Some models like gpt-5.2-chat so not support temperature other than 1 so every time we execute zeroclaw agent, we have to pass --temperature parameter otherwise it defaults to the hardcoded 0.7 and the LLM chat completion call fails
  • What changed: Just the way the temperature value is extracted when we execute the zeroclaw agent command
  • What did not change (scope boundary): The behaviour of the zeroclaw agent command

Label Snapshot (required)

  • Risk label (risk: low|medium|high): low
  • Size label (size: XS|S|M|L|XL, auto-managed/read-only): XS
  • Scope labels (core|agent|channel|config|cron|daemon|doctor|gateway|health|heartbeat|integration|memory|observability|onboard|provider|runtime|security|service|skillforge|skills|tool|tunnel|docs|dependencies|ci|tests|scripts|dev, comma-separated): config
  • Module labels (<module>: <component>, for example channel: telegram, provider: kimi, tool: shell): config:default_temperature
  • Contributor tier label (trusted contributor|experienced contributor|principal contributor|distinguished contributor, auto-managed/read-only; author merged PRs >=5/10/20/50): auto-managed/read-only
  • If any auto-label is incorrect, note requested correction:

Change Metadata

  • Change type (bug|feature|refactor|docs|security|chore): bug
  • Primary scope (runtime|provider|channel|memory|security|ci|docs|multi): runtime

Linked Issue

Supersede Attribution (required when Supersedes # is used)

  • Superseded PRs + authors (#<pr> by @<author>, one per line):
  • Integrated scope by source PR (what was materially carried forward):
  • Co-authored-by trailers added for materially incorporated contributors? (Yes/No)
  • If No, explain why (for example: inspiration-only, no direct code/design carry-over):
  • Trailer format check (separate lines, no escaped \n): (Pass/Fail)

Validation Evidence (required)

Commands and result summary:

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test

cargo fmt --all -- --check -> Fixed all issues
cargo clippy --all-targets -- -D warnings -> Fixed all issues
cargo test -> All unit tests are passing

  • Evidence provided (test/log/trace/screenshot/perf): screenshot
  • If any command is intentionally skipped, explain why: no command skipped

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • New external network calls? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • File system access scope changed? (Yes/No) No
  • If any Yes, describe risk and mitigation:

Privacy and Data Hygiene (required)

  • Data-hygiene status (pass|needs-follow-up): pass
  • Redaction/anonymization notes:
  • Neutral wording confirmation (use ZeroClaw/project-native labels if identity-like wording is needed):

Compatibility / Migration

  • Backward compatible? (Yes/No) Not applicable
  • Config/env changes? (Yes/No) Not applicable
  • Migration needed? (Yes/No) Not applicable
  • If yes, exact upgrade steps:

i18n Follow-Through (required when docs or user-facing wording changes)

  • i18n follow-through triggered? (Yes/No) Not applicable
  • If Yes, locale navigation parity updated in README*, docs/README*, and docs/SUMMARY.md for supported locales (en, zh-CN, ja, ru, fr, vi)? (Yes/No)
  • If Yes, localized runtime-contract docs updated where equivalents exist (minimum for fr/vi: commands-reference, config-reference, troubleshooting)? (Yes/No/N.A.)
  • If Yes, Vietnamese canonical docs under docs/i18n/vi/** synced and compatibility shims under docs/*.vi.md validated? (Yes/No/N.A.)
  • If any No/N.A., link follow-up issue/PR and explain scope decision:

Human Verification (required)

What was personally validated beyond CI: Manual testing done

  • Verified scenarios: Config contains temperature and validated if the correct value is passed on, if temperature parameter is passed on, verified if things are working as expected
  • Edge cases checked: yes
  • What was not verified: ?

Validation screenshots:
Previously before the fix:
temperature-not-honored-config
temperature-not-honored

After the fix:
default_temperature set to 0.7
temperature-config-honored-0 7
temperature-config-honored-chat-0 7

value from temperature parameter is honored
temperature-chat-honored-with-parameter

default_temperature set to 1
temperature-config-honored
temperature-chat-honored

default_temperature config missing defaults to 0.7
temperature-honored-without-default_temperature

default_temperature out of range
image

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: zeroclaw agent command
  • Potential unintended effects: ?
  • Guardrails/monitoring for early detection: ?

Agent Collaboration Notes (recommended)

  • Agent tools used (if any): Github Copilot
  • Workflow/plan summary (if any):
  • Verification focus:
  • Confirmation: naming + architecture boundaries followed (AGENTS.md + CONTRIBUTING.md):

Rollback Plan (required)

  • Fast rollback command/path: PR Revert & Release
  • Feature flags or config toggles (if any):
  • Observable failure symptoms:

Risks and Mitigations

List real risks in this PR (or write None).
None

  • Risk:
    • Mitigation:

Summary by CodeRabbit

  • New Features

    • Agent command temperature is now optional; CLI help indicates default fallback.
    • Centralized temperature validation and enforced allowed range (0.0–2.0); invalid environment values are ignored with a warning.
  • Behavior Change

    • Missing temperature falls back to the configured default (or the built-in default) at runtime.
  • Tests

    • Expanded tests for parsing with/without temperature, fallback logic, and rejection of out-of-range defaults.

@kunalk16 kunalk16 requested a review from JordanTheJet as a code owner March 9, 2026 11:11
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'tools', 'path_filters', 'review_instructions'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

Agent CLI temperature is now optional (Option); runtime falls back to config.default_temperature when omitted. Config schema adds TEMPERATURE_RANGE, serde deserializer, and default helper with validation. Tests updated to cover deserialization range checks and CLI fallback behavior.

Changes

Cohort / File(s) Summary
CLI / Runtime
src/main.rs
Agent variant temperature: f64temperature: Option<f64>; removed local range check and now calls config::schema::validate_temperature; compute final_temperature = temperature.unwrap_or(config.default_temperature) and pass to agent::run; updated CLI help and tests for Some/None.
Configuration Schema
src/config/schema.rs
Added pub const TEMPERATURE_RANGE: RangeInclusive<f64> = 0.0..=2.0, DEFAULT_TEMPERATURE helper, deserialize_temperature (serde), and pub fn validate_temperature(f64) -> Result<f64,String>; Config.default_temperature annotated with #[serde(default = "default_temperature", deserialize_with = "deserialize_temperature")]; env var ZEROCLAW_TEMPERATURE now validated with warnings on invalid/ out-of-range values and ignored when invalid.
Tests
tests/config_schema.rs
Refactored config_empty_toml test to assert default (0.7); added config_out_of_range_temperature_fails and config_negative_temperature_fails to validate deserialization rejects invalid values; added tests for CLI Agent temperature parsing and fallback to config/default.
Manifest
Cargo.toml, manifest_file
Updated manifest metadata/files (lines changed noted).

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (user)
    participant Runtime as Runtime (main)
    participant Config as Config Loader
    participant Agent as Agent Runner

    CLI->>Runtime: invoke `agent` (temperature: Some or None)
    Runtime->>Config: load configuration (includes default_temperature)
    Config-->>Runtime: return validated Config
    Runtime->>Runtime: parsed_temp = CLI.temperature
    alt parsed_temp is Some
        Runtime->>Agent: run(final_temperature = parsed_temp)
    else parsed_temp is None
        Runtime->>Runtime: final_temperature = config.default_temperature
        Runtime->>Agent: run(final_temperature = config.default_temperature)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and clearly describes the main fix: honoring the default_temperature config when running the agent command without explicit temperature parameter.
Linked Issues check ✅ Passed The code changes directly address issue #3033 by implementing temperature fallback logic that uses config.default_temperature when --temperature is not provided, and adding centralized validation that enforces the valid range (0.0..=2.0).
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objective: making Agent command temperature optional, implementing fallback logic to honor config.default_temperature, and centralizing temperature validation in config schema with tests.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description is comprehensive and follows most of the required template with detailed validation evidence, edge case testing, and screenshots demonstrating the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/main.rs (2)

190-192: Document the config fallback in zeroclaw agent --help.

Now that omitting --temperature means “use config.default_temperature”, the flag help should say that explicitly so the CLI contract is visible to users.

✏️ Suggested wording
-        /// Temperature (0.0 - 2.0)
+        /// Temperature override (0.0 - 2.0). Defaults to config.default_temperature when omitted.
         #[arg(short, long, value_parser = parse_temperature)]
         temperature: Option<f64>,

Based on learnings, Treat config keys and CLI commands as public API contract; document defaults, compatibility impact, and migration/rollback path for changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 190 - 192, Update the CLI help for the temperature
flag so it documents the new config fallback: modify the #[arg(...)] on the
temperature field (the temperature: Option<f64> argument parsed with
parse_temperature) to include a help string that states the valid range
(0.0–2.0) and explicitly that omitting --temperature will use
config.default_temperature; keep the existing short/long and value_parser
settings and ensure the messaging mentions the config key name
"config.default_temperature" so users see the CLI ↔ config contract.

779-795: Make the effective-temperature rule directly testable.

The fix is correct here, but the new tests only prove Clap returns Some/None. If this line ever regresses to a hardcoded value again, those tests still pass. A tiny helper for resolving the effective temperature would keep the fallback localized and let you unit-test the actual behavior.

♻️ Minimal extraction
+fn resolve_agent_temperature(cli_temperature: Option<f64>, config: &Config) -> f64 {
+    cli_temperature.unwrap_or(config.default_temperature)
+}
+
 ...
-            // Implement temperature fallback logic:
-            // 1. Use --temperature if provided
-            // 2. Use config.default_temperature if --temperature not provided
-            // 3. Use hardcoded 0.7 if config.default_temperature not set (though config always has default)
-            let final_temperature = temperature.unwrap_or(config.default_temperature);
+            let final_temperature = resolve_agent_temperature(temperature, &config);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 779 - 795, Extract the temperature fallback logic
into a small pure helper function (e.g., resolve_effective_temperature or
effective_temperature) that takes Option<f64> temperature and &Config (or f64
default_temperature) and returns the resolved f64; replace the inline unwrap_or
call that sets final_temperature with a call to that helper (referencing
temperature, config.default_temperature, and final_temperature) so the rule is
localized and then write unit tests for the helper covering Some, None with
config default, and None with a fallback default to ensure behavior is directly
testable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main.rs`:
- Around line 190-192: Update the CLI help for the temperature flag so it
documents the new config fallback: modify the #[arg(...)] on the temperature
field (the temperature: Option<f64> argument parsed with parse_temperature) to
include a help string that states the valid range (0.0–2.0) and explicitly that
omitting --temperature will use config.default_temperature; keep the existing
short/long and value_parser settings and ensure the messaging mentions the
config key name "config.default_temperature" so users see the CLI ↔ config
contract.
- Around line 779-795: Extract the temperature fallback logic into a small pure
helper function (e.g., resolve_effective_temperature or effective_temperature)
that takes Option<f64> temperature and &Config (or f64 default_temperature) and
returns the resolved f64; replace the inline unwrap_or call that sets
final_temperature with a call to that helper (referencing temperature,
config.default_temperature, and final_temperature) so the rule is localized and
then write unit tests for the helper covering Some, None with config default,
and None with a fallback default to ensure behavior is directly testable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2efe8de2-75d4-4878-a37c-8e517471f425

📥 Commits

Reviewing files that changed from the base of the PR and between f7fefd4 and a6cf7d4.

📒 Files selected for processing (1)
  • src/main.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/config/schema.rs (1)

272-274: Reuse this helper in Config::default() as well.

Line 3603 still hardcodes 0.7, so the default now lives in two places. Calling this helper there would keep the config contract from drifting later.

♻️ Small follow-up
-            default_temperature: 0.7,
+            default_temperature: default_temperature(),
Based on learnings, treat config keys as public contract: document defaults, compatibility impact, and migration/rollback path.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config/schema.rs` around lines 272 - 274, The default temperature helper
default_temperature() is defined but not used in Config::default(), which still
hardcodes 0.7; update Config::default() to call default_temperature() (instead
of the literal 0.7) so the default value is defined in one place (refer to the
Config::default() implementation and the default_temperature() function),
ensuring the config default remains consistent and documented as the public
contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main.rs`:
- Around line 779-790: The config's default_temperature can be out-of-range
because TOML deserialization and apply_env_overrides() don't validate it, so add
a shared validator that enforces 0.0..=2.0: implement a custom serde
deserializer (e.g., deserialize_temperature) and annotate
Config::default_temperature with it so TOML loads fail on invalid values; reuse
the same validation in parse_temperature for CLI parity and call it from
apply_env_overrides() to return an error (instead of silently ignoring) when
ZEROCLAW_TEMPERATURE is out of range; finally, ensure any post-deserialize paths
(config loader before agent::run) check/propagate this validation error so
final_temperature used in main.rs is guaranteed valid.

---

Nitpick comments:
In `@src/config/schema.rs`:
- Around line 272-274: The default temperature helper default_temperature() is
defined but not used in Config::default(), which still hardcodes 0.7; update
Config::default() to call default_temperature() (instead of the literal 0.7) so
the default value is defined in one place (refer to the Config::default()
implementation and the default_temperature() function), ensuring the config
default remains consistent and documented as the public contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9fa71b11-b86f-4a64-ac64-53da7dd5a960

📥 Commits

Reviewing files that changed from the base of the PR and between a6cf7d4 and e70ca52.

📒 Files selected for processing (3)
  • src/config/schema.rs
  • src/main.rs
  • tests/config_schema.rs

Comment thread src/main.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/config/schema.rs`:
- Around line 275-305: Config currently only enforces temperature bounds for
default_temperature via deserialize_temperature, leaving
DelegateAgentConfig.temperature unchecked; update Config::validate() to iterate
all agents and, for each DelegateAgentConfig.temperature (the Option<f64>), call
validate_temperature(value) and bail/return an error if out of range (use
anyhow::bail! or propagate a clear Err with a message like "agent <name>
temperature X out of range"), so invalid config like `[agents.foo] temperature =
6` fails at load time; you can alternatively add a custom deserializer for
Option<f64> that reuses deserialize_temperature, but the simplest fix is adding
the explicit per-agent checks in Config::validate() referencing
DelegateAgentConfig.temperature and validate_temperature.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9fe5954b-8076-4fcf-bc3e-0c4b61e2ca05

📥 Commits

Reviewing files that changed from the base of the PR and between 465b2ea and 225edec.

📒 Files selected for processing (1)
  • src/config/schema.rs

Comment thread src/config/schema.rs
@kunalk16
Copy link
Copy Markdown
Contributor Author

kunalk16 commented Mar 9, 2026

@JordanTheJet my PR is ready for review. Requesting a review please. :)

@kunalk16 kunalk16 changed the title bug(config): honor default_temperature config while running "zeroclaw agent" without temperature parameter fix(config): honor default_temperature config while running "zeroclaw agent" without temperature parameter Mar 9, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main.rs (1)

779-790: Extract the resolver and test that shared code path.

The new fallback tests replay user_temperature.unwrap_or(config.default_temperature) instead of exercising the production branch at Line 779, so they would still pass if this dispatch regressed. A tiny helper also makes it easy to cover the missing CLI-over-config precedence and invalid-input cases.

♻️ Suggested refactor
+fn resolve_agent_temperature(cli_temperature: Option<f64>, config: &Config) -> f64 {
+    cli_temperature.unwrap_or(config.default_temperature)
+}
+
 ...
-            let final_temperature = temperature.unwrap_or(config.default_temperature);
+            let final_temperature = resolve_agent_temperature(temperature, &config);
-        let user_temperature: Option<f64> = None;
-        let final_temperature = user_temperature.unwrap_or(config.default_temperature);
+        let final_temperature = resolve_agent_temperature(None, &config);

         assert!((final_temperature - 1.5).abs() < f64::EPSILON);
     }

     #[test]
     fn agent_fallback_uses_hardcoded_when_config_uses_default() {
         let config = Config::default();

-        let user_temperature: Option<f64> = None;
-        let final_temperature = user_temperature.unwrap_or(config.default_temperature);
+        let final_temperature = resolve_agent_temperature(None, &config);

         assert!((final_temperature - 0.7).abs() < f64::EPSILON);
     }
+
+    #[test]
+    fn agent_fallback_prefers_cli_temperature_over_config_default() {
+        let mut config = Config::default();
+        config.default_temperature = 1.5;
+
+        let final_temperature = resolve_agent_temperature(Some(0.5), &config);
+
+        assert!((final_temperature - 0.5).abs() < f64::EPSILON);
+    }
+
+    #[test]
+    fn agent_command_rejects_out_of_range_temperature() {
+        let err = Cli::try_parse_from(["zeroclaw", "agent", "--temperature", "6"])
+            .expect_err("out-of-range temperature should fail");
+
+        assert!(err.to_string().contains("out of range"));
+    }

Also applies to: 2008-2031

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 779 - 790, Extract the temperature resolution into
a small helper (e.g., resolve_temperature) that encapsulates the precedence
logic currently expressed by temperature.unwrap_or(config.default_temperature)
and any validation for invalid inputs; replace the inline computation of
final_temperature in main.rs with a call to this helper before invoking
agent::run so the same code path is exercised in production, and add unit tests
that call resolve_temperature directly to cover CLI-over-config precedence, the
config fallback (config.default_temperature), and invalid-input cases; reference
the symbols temperature, final_temperature, config.default_temperature,
agent::run, and the new resolve_temperature helper when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main.rs`:
- Around line 779-790: Extract the temperature resolution into a small helper
(e.g., resolve_temperature) that encapsulates the precedence logic currently
expressed by temperature.unwrap_or(config.default_temperature) and any
validation for invalid inputs; replace the inline computation of
final_temperature in main.rs with a call to this helper before invoking
agent::run so the same code path is exercised in production, and add unit tests
that call resolve_temperature directly to cover CLI-over-config precedence, the
config fallback (config.default_temperature), and invalid-input cases; reference
the symbols temperature, final_temperature, config.default_temperature,
agent::run, and the new resolve_temperature helper when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4110bc0f-c923-4c18-8b30-ca6f521a57a6

📥 Commits

Reviewing files that changed from the base of the PR and between 225edec and 76d5419.

📒 Files selected for processing (3)
  • src/config/schema.rs
  • src/main.rs
  • tests/config_schema.rs

@kunalk16
Copy link
Copy Markdown
Contributor Author

@JordanTheJet Gentle reminder, my PR is ready for review. Requesting a review please.

@theonlyhennygod theonlyhennygod merged commit 46d68fc into zeroclaw-labs:master Mar 11, 2026
6 checks passed
@kunalk16 kunalk16 deleted the fix-honor-default-temperature-agent-command branch March 11, 2026 08:51
lantrinh1999 pushed a commit to lantrinh1999/zeroclaw-1 that referenced this pull request Mar 18, 2026
…-temperature-agent-command

fix(config): honor default_temperature config while running "zeroclaw agent" without temperature parameter
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.

[Bug]: default_temperature in the config is not honored for zeroclaw commands example zeroclaw agent

2 participants