mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
fix: f32→f64 precision artifact in temperature causes provider 400 errors (#1450)
* fix: f32→f64 precision artifact in temperature causes provider 400 errors Direct f32-as-f64 preserves the binary representation, producing values like 0.699999988079071 instead of 0.7. Some OpenAI-compatible providers (e.g. Zhipu GLM-5) reject these with a 400 error. Add round_f32_to_f64() that formats to 6 decimal places before parsing back to f64. * fix: address clippy redundant_closure lint (takeover #1418) [skip-regression-check] Co-Authored-By: Boomboomdunce <[email protected]> Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: use numeric rounding, update doc comment, remove duplicate assertion [skip-regression-check] Address review feedback on #1450: - Replace format!+parse with numeric rounding to avoid allocation - Update doc comment to only mention temperature (not top_p) - Remove duplicate assert_eq in test Co-Authored-By: Boomboomdunce <[email protected]> Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --------- Co-authored-by: Boomboomdunce <[email protected]> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Boomboomdunce
Claude Opus 4.6
parent
455f543ba5
commit
3a523347b0
+22
-1
@@ -112,6 +112,16 @@ impl<M: CompletionModel> RigAdapter<M> {
|
||||
|
||||
// -- Type conversion helpers --
|
||||
|
||||
/// Round an f32 to f64 without precision artifacts.
|
||||
///
|
||||
/// Direct `f32 as f64` preserves the binary representation, producing values
|
||||
/// like `0.699999988079071` instead of `0.7`. Some providers (e.g. Zhipu/GLM)
|
||||
/// reject these values with a 400 error. Rounding to 6 decimal places removes
|
||||
/// the artifact while preserving all meaningful precision for temperature.
|
||||
fn round_f32_to_f64(val: f32) -> f64 {
|
||||
((val as f64) * 1_000_000.0).round() / 1_000_000.0
|
||||
}
|
||||
|
||||
/// Normalize a JSON Schema for OpenAI strict mode compliance.
|
||||
///
|
||||
/// OpenAI strict function calling requires:
|
||||
@@ -542,7 +552,7 @@ fn build_rig_request(
|
||||
chat_history,
|
||||
documents: Vec::new(),
|
||||
tools,
|
||||
temperature: temperature.map(|t| t as f64),
|
||||
temperature: temperature.map(round_f32_to_f64),
|
||||
max_tokens: max_tokens.map(|t| t as u64),
|
||||
tool_choice,
|
||||
additional_params,
|
||||
@@ -767,6 +777,17 @@ fn normalize_tool_name(name: &str, known_tools: &HashSet<String>) -> String {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_round_f32_to_f64_no_precision_artifacts() {
|
||||
// Direct f32->f64 cast produces 0.699999988079071 instead of 0.7
|
||||
assert_eq!(round_f32_to_f64(0.7_f32), 0.7_f64);
|
||||
assert_eq!(round_f32_to_f64(0.5_f32), 0.5_f64);
|
||||
assert_eq!(round_f32_to_f64(1.0_f32), 1.0_f64);
|
||||
assert_eq!(round_f32_to_f64(0.0_f32), 0.0_f64);
|
||||
// Original cast produces artifacts — our fix should not
|
||||
assert_ne!(0.7_f32 as f64, 0.7_f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_messages_system_to_preamble() {
|
||||
let messages = vec![
|
||||
|
||||
Reference in New Issue
Block a user