Serialize numeric custom reasoning effort as JSON numbers (#47590)

## What changed

Serialize custom reasoning effort values that parse as `u64` as JSON numbers in API requests. For example, `model_reasoning_effort = "64"` now sends `reasoning.effort` as `64`. Keep named values and custom values that cannot parse as `u64` as strings.

## Testing

Expand the request integration test to cover configured named effort, zero, a positive integer, an unknown name, a negative value, and an integer exceeding `u64`.

GitOrigin-RevId: 18ad03a1cd97dfa3f1a3cc49a43b3f7ca7d9b657
This commit is contained in:
Dylan Hurd
2026-09-23 17:02:51 +00:00
committed by copyberry
parent e0a64cf2bc
commit ae132dc50a
2 changed files with 56 additions and 35 deletions
+19 -1
View File
@@ -155,7 +155,10 @@ pub enum ReasoningContext {
#[derive(Debug, Serialize, Clone, PartialEq)]
pub struct Reasoning {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "serialize_reasoning_effort"
)]
pub effort: Option<ReasoningEffortConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<ReasoningSummaryConfig>,
@@ -163,6 +166,21 @@ pub struct Reasoning {
pub context: Option<ReasoningContext>,
}
fn serialize_reasoning_effort<S>(
effort: &Option<ReasoningEffortConfig>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if let Some(ReasoningEffortConfig::Custom(value)) = effort
&& let Ok(value) = value.parse::<u64>()
{
return serializer.serialize_u64(value);
}
effort.serialize(serializer)
}
#[derive(Debug, Serialize, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningSummaryDelivery {