From 5b2f5eebb52f12aeb0fab2de9482abbc6ab4424c Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Fri, 9 May 2025 09:26:42 +0800 Subject: [PATCH] Add JsonIgnoreProperties to DeepSeek Model Response objects Continue of commit 53019c69d16f6e4b048765a39bb62d92b6f33c7a See GH-3026 Signed-off-by: Yanming Zhou --- .../ai/deepseek/api/DeepSeekApi.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java b/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java index 711a3359c..69b117db2 100644 --- a/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java +++ b/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java @@ -16,11 +16,22 @@ package org.springframework.ai.deepseek.api; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Predicate; + import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.ChatModelDescription; import org.springframework.ai.model.ModelOptionsUtils; @@ -35,17 +46,10 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import static org.springframework.ai.deepseek.api.common.DeepSeekConstants.*; +import static org.springframework.ai.deepseek.api.common.DeepSeekConstants.DEFAULT_BASE_URL; +import static org.springframework.ai.deepseek.api.common.DeepSeekConstants.DEFAULT_BETA_PATH; +import static org.springframework.ai.deepseek.api.common.DeepSeekConstants.DEFAULT_COMPLETIONS_PATH; /** * Single class implementation of the DeepSeek Chat Completion API: @@ -484,7 +488,7 @@ public class DeepSeekApi { * @param toolChoice Controls which (if any) function is called by the model. none * means the model will not call a function and instead generates a message. auto * means the model can pick between generating a message or calling a function. - * Specifying a particular function via {"type: "function", "function": {"name": + * Specifying a particular function via {"type": "function", "function": {"name": * "my_function"}} forces the model to call that function. none is the default when no * functions are present. auto is the default if functions are present. Use the * {@link ToolChoiceBuilder} to create the tool choice value. @@ -587,6 +591,7 @@ public class DeepSeekApi { * Applicable only for {@link Role#ASSISTANT} role and null otherwise. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ChatCompletionMessage(// @formatter:off @JsonProperty("content") Object rawContent, @JsonProperty("role") Role role, @@ -675,6 +680,7 @@ public class DeepSeekApi { * @param function The function definition. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ToolCall(// @formatter:off @JsonProperty("index") Integer index, @JsonProperty("id") String id, @@ -695,6 +701,7 @@ public class DeepSeekApi { * function. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ChatCompletionFunction(// @formatter:off @JsonProperty("name") String name, @JsonProperty("arguments") String arguments) { // @formatter:on @@ -718,6 +725,7 @@ public class DeepSeekApi { * @param usage Usage statistics for the completion request. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ChatCompletion(// @formatter:off @JsonProperty("id") String id, @JsonProperty("choices") List choices, @@ -737,6 +745,7 @@ public class DeepSeekApi { * @param logprobs Log probability information for the choice. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record Choice(// @formatter:off @JsonProperty("finish_reason") ChatCompletionFinishReason finishReason, @JsonProperty("index") Integer index, @@ -753,6 +762,7 @@ public class DeepSeekApi { * @param refusal A list of message refusal tokens with log probability information. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record LogProbs(@JsonProperty("content") List content, @JsonProperty("refusal") List refusal) { @@ -771,6 +781,7 @@ public class DeepSeekApi { * requested top_logprobs returned. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record Content(// @formatter:off @JsonProperty("token") String token, @JsonProperty("logprob") Float logprob, @@ -789,6 +800,7 @@ public class DeepSeekApi { * is no bytes representation for the token. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record TopLogProbs(// @formatter:off @JsonProperty("token") String token, @JsonProperty("logprob") Float logprob, @@ -812,6 +824,7 @@ public class DeepSeekApi { * @param promptTokensDetails Breakdown of tokens used in the prompt. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record Usage(// @formatter:off @JsonProperty("completion_tokens") Integer completionTokens, @JsonProperty("prompt_tokens") Integer promptTokens, @@ -828,6 +841,7 @@ public class DeepSeekApi { * @param cachedTokens Cached tokens present in the prompt. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record PromptTokensDetails(// @formatter:off @JsonProperty("cached_tokens") Integer cachedTokens) { // @formatter:on } @@ -853,6 +867,7 @@ public class DeepSeekApi { * only if the StreamOptions.includeUsage is set to true. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ChatCompletionChunk(// @formatter:off @JsonProperty("id") String id, @JsonProperty("choices") List choices, @@ -872,6 +887,7 @@ public class DeepSeekApi { * @param logprobs Log probability information for the choice. */ @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) public record ChunkChoice(// @formatter:off @JsonProperty("finish_reason") ChatCompletionFinishReason finishReason, @JsonProperty("index") Integer index,