more ser-deser fixes for openai and anthropic

This commit is contained in:
Mark Pollack
2024-06-06 16:06:25 -04:00
parent cf0946b891
commit 2c4554eb3f
5 changed files with 108 additions and 3 deletions

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.ai.anthropic.metadata;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.ai.anthropic.api.AnthropicApi;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
import org.springframework.ai.chat.metadata.EmptyRateLimit;
@@ -89,4 +90,13 @@ public class AnthropicChatResponseMetadata extends HashMap<String, Object> imple
return AI_METADATA_STRING.formatted(getClass().getName(), getId(), getUsage(), getRateLimit());
}
public static class Module extends SimpleModule {
public Module() {
super("AnthropicChatResponseMetadata Module");
this.registerSubtypes(AnthropicChatResponseMetadata.class);
}
}
}

View File

@@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
import org.springframework.ai.chat.metadata.EmptyRateLimit;
import org.springframework.ai.chat.metadata.EmptyUsage;
@@ -124,4 +125,13 @@ public class OpenAiChatResponseMetadata implements ChatResponseMetadata {
return Objects.hash(id, rateLimit, usage, promptMetadata);
}
public static class Module extends SimpleModule {
public Module() {
super("OpenAiChatResponseMetadata Module");
this.registerSubtypes(OpenAiChatResponseMetadata.class);
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2024 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.openai.api;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.openai.metadata.OpenAiChatResponseMetadata;
public class ChatResponseJsonTests {
@Test
void serDeserChatResponse() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new OpenAiChatResponseMetadata.Module());
String json = """
{
"results" : [ {
"assistantMessage" : {
"messageType" : "ASSISTANT",
"content" : "Why couldn't the bicycle find its way home? Because it lost its bearings!",
"metadata" : {
"finishReason" : "STOP",
"role" : "ASSISTANT",
"id" : "chatcmpl-9XBoXJwhroi7d6vD8ncbNUl2vIOyk",
"messageType" : "ASSISTANT"
},
"messageType" : "ASSISTANT",
"media" : [ ]
},
"chatGenerationMetadata" : {
"type" : "default",
"finishReason" : "STOP",
"contentFilterMetadata" : null
}
} ],
"advisorContext" : { },
"metadata" : {
"type" : "openai",
"id" : "chatcmpl-9XBoXJwhroi7d6vD8ncbNUl2vIOyk",
"usage" : {
"promptTokens" : 11,
"generationTokens" : 16,
"totalTokens" : 27
},
"rateLimit" : {
"requestsLimit" : 5000,
"requestsRemaining" : 4999,
"requestsReset" : 0.012000000,
"tokensLimit" : 160000,
"tokensRemaining" : 159979,
"tokensReset" : 0.007000000
}
}
}
""";
ChatResponse deserializedChatResponse = objectMapper.readValue(json, ChatResponse.class);
System.out.println(deserializedChatResponse);
// assertThat(advisedRequest).usingRecursiveComparison().isEqualTo(deserialized);
}
}

View File

@@ -64,7 +64,7 @@ public class ChatResponse implements ModelResponse<Generation> {
*/
@JsonCreator
public ChatResponse(@JsonProperty("results") List<Generation> generations,
@JsonProperty("chatResponseMetadata") ChatResponseMetadata chatResponseMetadata,
@JsonProperty("metadata") ChatResponseMetadata chatResponseMetadata,
@JsonProperty("advisorContext") Map<String, Object> advisorContext) {
this.generations = generations;
this.chatResponseMetadata = chatResponseMetadata;

View File

@@ -50,7 +50,7 @@ public class BedrockAnthropicChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
public AnthropicChatBedrockApi anthropicApi(AwsCredentialsProvider credentialsProvider,
public AnthropicChatBedrockApi anthropicChatBedrockApi(AwsCredentialsProvider credentialsProvider,
AwsRegionProvider regionProvider, BedrockAnthropicChatProperties properties,
BedrockAwsConnectionProperties awsProperties) {
return new AnthropicChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(),
@@ -59,7 +59,7 @@ public class BedrockAnthropicChatAutoConfiguration {
@Bean
@ConditionalOnBean(AnthropicChatBedrockApi.class)
public BedrockAnthropicChatModel anthropicChatModel(AnthropicChatBedrockApi anthropicApi,
public BedrockAnthropicChatModel bedrockAnthropicChatModel(AnthropicChatBedrockApi anthropicApi,
BedrockAnthropicChatProperties properties) {
return new BedrockAnthropicChatModel(anthropicApi, properties.getOptions());
}