add optional ObjectMapper to BeanObjectMapper and allow for subclassing

This commit is contained in:
Mark Pollack
2023-08-23 12:47:56 -07:00
parent c9905fdaec
commit bc30051548
3 changed files with 46 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
package org.springframework.ai.parser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.victools.jsonschema.generator.OptionPreset;
@@ -19,9 +20,20 @@ public class BeanOutputParser<T> implements OutputParser<T> {
private Class clazz;
private ObjectMapper objectMapper;
public BeanOutputParser(Class<T> clazz) {
Objects.requireNonNull(clazz, "Java Class can not be null;");
this.clazz = clazz;
this.objectMapper = getObjectMapper();
generateSchema();
}
public BeanOutputParser(Class<T> clazz, ObjectMapper objectMapper) {
Objects.requireNonNull(clazz, "Java Class can not be null;");
Objects.requireNonNull(objectMapper, "ObjectMapper can not be null;");
this.clazz = clazz;
this.objectMapper = objectMapper;
generateSchema();
}
@@ -36,15 +48,20 @@ public class BeanOutputParser<T> implements OutputParser<T> {
@Override
public T parse(String text) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(text, this.clazz);
return (T) this.objectMapper.readValue(text, this.clazz);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
protected ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
@Override
public String getFormat() {

View File

@@ -0,0 +1,24 @@
package org.springframework.ai.autoconfigure;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;
import java.util.Set;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
public class NativeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.proxies().registerJdkProxy(TypeReference.of("com.theokanning.openai.OpenAiApi"));
for (var className : Set.of("com.theokanning.openai.Usage",
"com.theokanning.openai.completion.chat.ChatCompletionChoice",
"com.theokanning.openai.completion.chat.ChatCompletionRequest",
"com.theokanning.openai.completion.chat.ChatCompletionResult",
"com.theokanning.openai.completion.chat.ChatMessage"))
hints.reflection().registerType(TypeReference.of(className), MemberCategory.values());
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.ai.autoconfigure.openai;
import com.theokanning.openai.service.OpenAiService;
import org.springframework.ai.autoconfigure.NativeHints;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.openai.embedding.OpenAiEmbeddingClient;
import org.springframework.ai.openai.client.OpenAiClient;
@@ -25,6 +26,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.util.StringUtils;
import static org.springframework.ai.autoconfigure.openai.OpenAiProperties.CONFIG_PREFIX;
@@ -32,6 +34,7 @@ import static org.springframework.ai.autoconfigure.openai.OpenAiProperties.CONFI
@AutoConfiguration
@ConditionalOnClass(OpenAiService.class)
@EnableConfigurationProperties(OpenAiProperties.class)
@ImportRuntimeHints(NativeHints.class)
public class OpenAiAutoConfiguration {
private final OpenAiProperties openAiProperties;