Unreconized field "completion_tokens_details" coming in response from openai api. the error is occuring at class org.springframework.ai.openai.api.OpenAiApi.ChatCompletion#usage
and in Usage
we have no Usage#completion_tokens_details
Bug description there's not @JsonIgnoreProperties(ignoreUnkown=true)
Environment macOS spring framework ai version 1.0.0-M2
Steps to reproduce Call OpenAiChatModel#call
Expected behavior it should not throw an error if there's an unmapped field
Minimal Complete Reproducible example
PromptTemplate template = new PromptTemplate(promptString);
template.add("desc", product.getMetaDescription());
template.add("name", product.getProductName());
String desc = this.aiChatModel.call(template.create()).getResult().getOutput().getContent();
a.setDesc(desc);
encountered a similar bug a while back which was resolved here https://github.com/spring-projects/spring-ai/issues/1178
stack trace
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "completion_tokens_details" (class org.springframework.ai.openai.api.OpenAiApi$Usage), not marked as ignorable (3 known properties: "completion_tokens", "prompt_tokens", "total_tokens"])
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION
disabled); line: 22, column: 35] (through reference chain: org.springframework.ai.openai.api.OpenAiApi$ChatCompletion["usage"]->org.springframework.ai.openai.api.OpenAiApi$Usage["completion_tokens_details"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1153)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2241)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1793)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1771)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:279)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:470)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:545)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:576)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:446)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2125)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1501)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:395)
... 18 common frames omitted
Comment From: kashyappvb
Even we are facing exact same issue tried using 1.0.0-M2, 1.0.0-SNAPSHOT version for below
org.springframework.ai:spring-ai-bom
org.springframework.ai:spring-ai-openai-spring-boot-starter
Code : ChatResponse chatResponse = chatClient.prompt().user(payload).call().chatResponse();
Temporary solution worked for us:
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper; }
Comment From: dafriz
An alternative to the above work around - If you are using Spring Boot and want to keep using the existing auto configured ObjectMapper, but change this one property you can use:
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder.failOnUnknownProperties(false);
}
completion_tokens_details - it's a new field added by OpenAI with the release of the o1 models with a nested reasoning_tokens field.
Comment From: markpollack
We recently updated how object mapper is configured in Spring AI to better support Kotlin. Will revist for M4. Thanks for reporting.
Comment From: markpollack
The object mapper config doesn't impact this, we don't include the fail on unknown props by default.
thanks for the snippit @dafriz on how to configure the jackson behavior.
This commit has added @JsonIgnoreProperties
to the CompletionTokenDetails
in OpenAiApi
so there shouldn't be any parse errors if the field is there or not.
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record CompletionTokenDetails(// @formatter:off
@JsonProperty("reasoning_tokens") Integer reasoningTokens,
@JsonProperty("accepted_prediction_tokens") Integer acceptedPredictionTokens,
@JsonProperty("audio_tokens") Integer audioTokens,
@JsonProperty("rejected_prediction_tokens") Integer rejectedPredictionTokens) { // @formatter:on
}
let us know how it works for you now. There is related discussion in https://github.com/spring-projects/spring-ai/issues/1178 not sure if we want to enable this by default.
Comment From: markpollack
Closing, us know if there are any issues and reopen if necessary.
Comment From: YuriMB
This is not enough. It's in the this class:
@JsonInclude(Include.NON_NULL)
public record PromptTokensDetails(// @formatter:off
@JsonProperty("cached_tokens") Integer cachedTokens) { // @formatter:on
}
Comment From: tzolov
Thank you @YuriMB. Indeed the audio_tokens
is missing from there.
I will have a look and will also try to improve the OpenAiUsage implementation. There is not need of flattering the fields there
Comment From: ilayaperumalg
Might be related to https://github.com/spring-projects/spring-ai/issues/1720
Comment From: YuriMB
@ilayaperumalg it is, that's actually my issue ;)