Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.springframework.ai.reader.pdf.aot;

import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.IOException;
import java.util.Set;

/**
* The PdfReaderRuntimeHints class is responsible for registering runtime hints for PDFBox
* resources.
*
* @author Josh Long
* @author Christian Tzolov
* @author Mark Pollack
*/
public class PdfReaderRuntimeHints implements RuntimeHintsRegistrar {

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
try {

var resolver = new PathMatchingResourcePatternResolver();

var patterns = Set.of("/org/apache/pdfbox/resources/glyphlist/zapfdingbats.txt",
"/org/apache/pdfbox/resources/glyphlist/glyphlist.txt", "/org/apache/fontbox/cmap/**",
"/org/apache/pdfbox/resources/afm/**", "/org/apache/pdfbox/resources/glyphlist/**",
"/org/apache/pdfbox/resources/icc/**", "/org/apache/pdfbox/resources/text/**",
"/org/apache/pdfbox/resources/ttf/**", "/org/apache/pdfbox/resources/version.properties");

for (var pattern : patterns)
for (var resourceMatch : resolver.getResources(pattern))
hints.resources().registerResource(resourceMatch);

}
catch (IOException e) {
throw new RuntimeException(e);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.reader.pdf.aot.PdfReaderRuntimeHints
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.springframework.ai.reader.pdf.aot;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;

import java.util.Set;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource;

class PdfReaderRuntimeHintsTests {

@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
PdfReaderRuntimeHints pdfReaderRuntimeHints = new PdfReaderRuntimeHints();
pdfReaderRuntimeHints.registerHints(runtimeHints, null);

Assertions.assertThat(runtimeHints)
.matches(resource().forResource("/org/apache/pdfbox/resources/glyphlist/zapfdingbats.txt"));
Assertions.assertThat(runtimeHints)
.matches(resource().forResource("/org/apache/pdfbox/resources/glyphlist/glyphlist.txt"));
// Assertions.assertThat(runtimeHints).matches(resource().forResource("/org/apache/pdfbox/resources/afm/**"));
// Assertions.assertThat(runtimeHints).matches(resource().forResource("/org/apache/pdfbox/resources/glyphlist/**"));
// Assertions.assertThat(runtimeHints).matches(resource().forResource("/org/apache/pdfbox/resources/icc/**"));
// Assertions.assertThat(runtimeHints).matches(resource().forResource("/org/apache/pdfbox/resources/text/**"));
// Assertions.assertThat(runtimeHints).matches(resource().forResource("/org/apache/pdfbox/resources/ttf/**"));
Assertions.assertThat(runtimeHints)
.matches(resource().forResource("/org/apache/pdfbox/resources/version.properties"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.springframework.ai.bedrock.aot;

import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;

/**
* The BedrockRuntimeHints class is responsible for registering runtime hints for Bedrock
* AI API classes.
*
* @author Josh Long
* @author Christian Tzolov
* @author Mark Pollack
*/
public class BedrockRuntimeHints implements RuntimeHintsRegistrar {

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
var mcs = MemberCategory.values();
for (var tr : findJsonAnnotatedClasses(Ai21Jurassic2ChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(CohereChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(CohereEmbeddingBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(Llama2ChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(TitanChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(TitanEmbeddingBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(AnthropicChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.bedrock.aot.BedrockRuntimeHints
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.springframework.ai.bedrock.aot;

import org.junit.jupiter.api.Test;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;

import java.util.List;
import java.util.Set;
import java.util.Arrays;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;

class BedrockRuntimeHintsTests {

@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
BedrockRuntimeHints bedrockRuntimeHints = new BedrockRuntimeHints();
bedrockRuntimeHints.registerHints(runtimeHints, null);

List<Class> classList = Arrays.asList(Ai21Jurassic2ChatBedrockApi.class, CohereChatBedrockApi.class,
CohereEmbeddingBedrockApi.class, Llama2ChatBedrockApi.class, TitanChatBedrockApi.class,
TitanEmbeddingBedrockApi.class, AnthropicChatBedrockApi.class);

for (Class aClass : classList) {
Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClasses(aClass);
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
}
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.springframework.ai.ollama.aot;

import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;

/**
* The OllamaRuntimeHints class is responsible for registering runtime hints for Ollama AI
* API classes.
*
* @author Josh Long
* @author Christian Tzolov
* @author Mark Pollack
*/
public class OllamaRuntimeHints implements RuntimeHintsRegistrar {

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
var mcs = MemberCategory.values();
for (var tr : findJsonAnnotatedClasses(OllamaApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClasses(OllamaOptions.class))
hints.reflection().registerType(tr, mcs);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.vertex.aot.OllamaRuntimeHints
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.springframework.ai.ollama.aot;

import org.junit.jupiter.api.Test;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;

import java.util.Set;

import static org.assertj.core.api.AssertionsForClassTypes.*;
import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.*;

class OllamaRuntimeHintsTests {

@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
OllamaRuntimeHints ollamaRuntimeHints = new OllamaRuntimeHints();
ollamaRuntimeHints.registerHints(runtimeHints, null);

Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClasses(OllamaApi.class);
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
}

jsonAnnotatedClasses = findJsonAnnotatedClasses(OllamaOptions.class);
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.springframework.ai.openai.aot;

import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;

/**
* The OpenAiRuntimeHints class is responsible for registering runtime hints for OpenAI
* API classes.
*
* @author Josh Long
* @author Christian Tzolov
* @author Mark Pollack
*/
public class OpenAiRuntimeHints implements RuntimeHintsRegistrar {

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
var mcs = MemberCategory.values();
for (var tr : findJsonAnnotatedClasses(OpenAiApi.class))
hints.reflection().registerType(tr, mcs);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.openai.aot.OpenAiRuntimeHints
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.springframework.ai.openai.aot;

import org.junit.jupiter.api.Test;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;

import java.util.Set;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;

class OpenAiRuntimeHintsTests {

@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
OpenAiRuntimeHints openAiRuntimeHints = new OpenAiRuntimeHints();
openAiRuntimeHints.registerHints(runtimeHints, null);

Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClasses(OpenAiApi.class);
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.springframework.ai.vertex.aot;

import org.springframework.ai.vertex.api.VertexAiApi;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;

/**
* The VertexRuntimeHints class is responsible for registering runtime hints for Vertex AI
* API classes.
*
* @author Josh Long
* @author Christian Tzolov
* @author Mark Pollack
*/
public class VertexRuntimeHints implements RuntimeHintsRegistrar {

@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
var mcs = MemberCategory.values();
for (var tr : findJsonAnnotatedClasses(VertexAiApi.class))
hints.reflection().registerType(tr, mcs);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.vertex.aot.VertexRuntimeHints
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.springframework.ai.vertex.aot;

import org.junit.jupiter.api.Test;
import org.springframework.ai.vertex.api.VertexAiApi;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;

import java.util.Set;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClasses;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;

class VertexRuntimeHintsTests {

@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
VertexRuntimeHints vertexRuntimeHints = new VertexRuntimeHints();
vertexRuntimeHints.registerHints(runtimeHints, null);
Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClasses(VertexAiApi.class);
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
}
}

}
8 changes: 8 additions & 0 deletions spring-ai-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
<artifactId>reactor-core</artifactId>
</dependency>


<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
Expand Down
Loading