diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java index 55f41cf9457..92b16f85e49 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java @@ -1160,7 +1160,7 @@ public record ChatCompletionRequest(// @formatter:off @JsonProperty("verbosity") String verbosity, @JsonProperty("prompt_cache_key") String promptCacheKey, @JsonProperty("safety_identifier") String safetyIdentifier, - Map extraBody) { + @JsonProperty("extra_body") Map extraBody) { /** * Compact constructor that ensures extraBody is initialized as a mutable HashMap diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/ExtraBodySerializationTest.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/ExtraBodySerializationTest.java index 28e9113e27d..9282bebe7fc 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/ExtraBodySerializationTest.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/ExtraBodySerializationTest.java @@ -22,6 +22,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import org.springframework.ai.model.ModelOptionsUtils; +import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest; import static org.assertj.core.api.Assertions.assertThat; @@ -208,4 +210,25 @@ void testDeserializationWithComplexExtraFields() throws Exception { assertThat(request.extraBody().get("stop_token_ids")).isInstanceOf(List.class); } + @Test + void testMergeWithExtraBody() throws Exception { + // Arrange: Create OpenAiChatOptions with extraBody + OpenAiChatOptions requestOptions = OpenAiChatOptions.builder() + .model("test-model") + .extraBody(Map.of("enable_thinking", true, "max_depth", 10)) + .build(); + + // Create empty ChatCompletionRequest + ChatCompletionRequest request = new ChatCompletionRequest(null, null); + + // Act: Merge options into request + request = ModelOptionsUtils.merge(requestOptions, request, ChatCompletionRequest.class); + + // Assert: Verify extraBody was successfully merged + assertThat(request.extraBody()).isNotNull(); + assertThat(request.extraBody()).containsEntry("enable_thinking", true); + assertThat(request.extraBody()).containsEntry("max_depth", 10); + assertThat(request.model()).isEqualTo("test-model"); + } + }