diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java index 5bed3ea2b96..7fb4271dace 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingModel.java @@ -42,6 +42,8 @@ import org.springframework.ai.openai.api.OpenAiApi.EmbeddingList; import org.springframework.ai.openai.api.common.OpenAiApiConstants; import org.springframework.ai.retry.RetryUtils; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.retry.support.RetryTemplate; import org.springframework.util.Assert; @@ -50,6 +52,8 @@ * * @author Christian Tzolov * @author Thomas Vitale + * @author Josh Long + * */ public class OpenAiEmbeddingModel extends AbstractEmbeddingModel { diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java index 36f3bc39e05..a65e241b236 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/aot/OpenAiRuntimeHints.java @@ -16,15 +16,10 @@ package org.springframework.ai.openai.aot; -import java.util.Set; - -import org.springframework.ai.openai.api.OpenAiApi; -import org.springframework.ai.openai.api.OpenAiAudioApi; -import org.springframework.ai.openai.api.OpenAiImageApi; +import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -40,23 +35,13 @@ */ public class OpenAiRuntimeHints implements RuntimeHintsRegistrar { - private static Set eval(Set referenceSet) { - referenceSet.forEach(tr -> System.out.println(tr.toString())); - return referenceSet; - } - @Override public void registerHints(@NonNull RuntimeHints hints, @Nullable ClassLoader classLoader) { var mcs = MemberCategory.values(); - for (var tr : eval(findJsonAnnotatedClassesInPackage(OpenAiApi.class))) { - hints.reflection().registerType(tr, mcs); - } - for (var tr : eval(findJsonAnnotatedClassesInPackage(OpenAiAudioApi.class))) { - hints.reflection().registerType(tr, mcs); - } - for (var tr : eval(findJsonAnnotatedClassesInPackage(OpenAiImageApi.class))) { + for (var tr : (findJsonAnnotatedClassesInPackage(OpenAiChatOptions.class))) { hints.reflection().registerType(tr, mcs); } + } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java b/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java index 17b7c5100d2..3706e4ecf32 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingModel.java @@ -16,28 +16,41 @@ package org.springframework.ai.embedding; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.util.Assert; + import java.io.IOException; import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import org.springframework.core.io.DefaultResourceLoader; - /** * Abstract implementation of the {@link EmbeddingModel} interface that provides * dimensions calculation caching. * * @author Christian Tzolov + * @author Josh Long */ +@ImportRuntimeHints(AbstractEmbeddingModel.Hints.class) public abstract class AbstractEmbeddingModel implements EmbeddingModel { + private static final Resource EMBEDDING_MODEL_DIMENSIONS_PROPERTIES = new ClassPathResource( + "/embedding/embedding-model-dimensions.properties"); + private static final Map KNOWN_EMBEDDING_DIMENSIONS = loadKnownModelDimensions(); - /** - * Default constructor. - */ - public AbstractEmbeddingModel() { + static class Hints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerResource(EMBEDDING_MODEL_DIMENSIONS_PROPERTIES); + } + } /** @@ -69,10 +82,13 @@ public static int dimensions(EmbeddingModel embeddingModel, String modelName, St private static Map loadKnownModelDimensions() { try { - Properties properties = new Properties(); - properties.load(new DefaultResourceLoader() - .getResource("classpath:/embedding/embedding-model-dimensions.properties") - .getInputStream()); + var resource = EMBEDDING_MODEL_DIMENSIONS_PROPERTIES; + Assert.notNull(resource, "the embedding dimensions must be non-null"); + Assert.state(resource.exists(), "the embedding dimensions properties file must exist"); + var properties = new Properties(); + try (var in = resource.getInputStream()) { + properties.load(in); + } return properties.entrySet() .stream() .collect(Collectors.toMap(e -> e.getKey().toString(), e -> Integer.parseInt(e.getValue().toString()))); diff --git a/spring-ai-model/src/main/resources/META-INF.spring/aot.factories b/spring-ai-model/src/main/resources/META-INF/spring/aot.factories similarity index 100% rename from spring-ai-model/src/main/resources/META-INF.spring/aot.factories rename to spring-ai-model/src/main/resources/META-INF/spring/aot.factories