diff --git a/langchain4j-anthropic-spring-boot-starter/pom.xml b/langchain4j-anthropic-spring-boot-starter/pom.xml
new file mode 100644
index 00000000..9be3489a
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+
+ dev.langchain4j
+ langchain4j-spring
+ 0.29.0-SNAPSHOT
+ ../pom.xml
+
+
+ langchain4j-anthropic-spring-boot-starter
+ LangChain4j Spring Boot starter for Anthropic
+
+
+
+
+ dev.langchain4j
+ langchain4j-anthropic
+ ${project.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure-processor
+ true
+
+
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ Apache-2.0
+ https://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+ A business-friendly OSS license
+
+
+
+
\ No newline at end of file
diff --git a/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java
new file mode 100644
index 00000000..5348e335
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java
@@ -0,0 +1,56 @@
+package dev.langchain4j.anthropic.spring;
+
+import dev.langchain4j.model.anthropic.AnthropicChatModel;
+import dev.langchain4j.model.anthropic.AnthropicStreamingChatModel;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+import static dev.langchain4j.anthropic.spring.Properties.PREFIX;
+
+@AutoConfiguration
+@EnableConfigurationProperties(Properties.class)
+public class AutoConfig {
+
+ @Bean
+ @ConditionalOnProperty(PREFIX + ".chat-model.api-key")
+ AnthropicChatModel anthropicChatModel(Properties properties) {
+ ChatModelProperties chatModelProperties = properties.getChatModel();
+ return AnthropicChatModel.builder()
+ .baseUrl(chatModelProperties.getBaseUrl())
+ .apiKey(chatModelProperties.getApiKey())
+ .version(chatModelProperties.getVersion())
+ .modelName(chatModelProperties.getModelName())
+ .temperature(chatModelProperties.getTemperature())
+ .topP(chatModelProperties.getTopP())
+ .topK(chatModelProperties.getTopK())
+ .maxTokens(chatModelProperties.getMaxTokens())
+ .stopSequences(chatModelProperties.getStopSequences())
+ .timeout(chatModelProperties.getTimeout())
+ .maxRetries(chatModelProperties.getMaxRetries())
+ .logRequests(chatModelProperties.getLogRequests())
+ .logResponses(chatModelProperties.getLogResponses())
+ .build();
+ }
+
+ @Bean
+ @ConditionalOnProperty(PREFIX + ".streaming-chat-model.api-key")
+ AnthropicStreamingChatModel anthropicStreamingChatModel(Properties properties) {
+ ChatModelProperties chatModelProperties = properties.getStreamingChatModel();
+ return AnthropicStreamingChatModel.builder()
+ .baseUrl(chatModelProperties.getBaseUrl())
+ .apiKey(chatModelProperties.getApiKey())
+ .version(chatModelProperties.getVersion())
+ .modelName(chatModelProperties.getModelName())
+ .temperature(chatModelProperties.getTemperature())
+ .topP(chatModelProperties.getTopP())
+ .topK(chatModelProperties.getTopK())
+ .maxTokens(chatModelProperties.getMaxTokens())
+ .stopSequences(chatModelProperties.getStopSequences())
+ .timeout(chatModelProperties.getTimeout())
+ .logRequests(chatModelProperties.getLogRequests())
+ .logResponses(chatModelProperties.getLogResponses())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java
new file mode 100644
index 00000000..c3c53b87
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java
@@ -0,0 +1,26 @@
+package dev.langchain4j.anthropic.spring;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.Duration;
+import java.util.List;
+
+@Getter
+@Setter
+class ChatModelProperties {
+
+ String baseUrl;
+ String apiKey;
+ String version;
+ String modelName;
+ Double temperature;
+ Double topP;
+ Integer topK;
+ Integer maxTokens;
+ List stopSequences;
+ Duration timeout;
+ Integer maxRetries;
+ Boolean logRequests;
+ Boolean logResponses;
+}
\ No newline at end of file
diff --git a/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java
new file mode 100644
index 00000000..8457629d
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java
@@ -0,0 +1,20 @@
+package dev.langchain4j.anthropic.spring;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+@Getter
+@Setter
+@ConfigurationProperties(prefix = Properties.PREFIX)
+public class Properties {
+
+ static final String PREFIX = "langchain4j.anthropic";
+
+ @NestedConfigurationProperty
+ ChatModelProperties chatModel;
+
+ @NestedConfigurationProperty
+ ChatModelProperties streamingChatModel;
+}
diff --git a/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring.factories b/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..6588156b
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=dev.langchain4j.anthropic.spring.AutoConfig
\ No newline at end of file
diff --git a/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 00000000..6fbc1082
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+dev.langchain4j.anthropic.spring.AutoConfig
\ No newline at end of file
diff --git a/langchain4j-anthropic-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java b/langchain4j-anthropic-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java
new file mode 100644
index 00000000..d150f7ae
--- /dev/null
+++ b/langchain4j-anthropic-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java
@@ -0,0 +1,76 @@
+package dev.langchain4j.anthropic.spring;
+
+import dev.langchain4j.data.message.AiMessage;
+import dev.langchain4j.model.StreamingResponseHandler;
+import dev.langchain4j.model.anthropic.AnthropicChatModel;
+import dev.langchain4j.model.anthropic.AnthropicStreamingChatModel;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import dev.langchain4j.model.chat.StreamingChatLanguageModel;
+import dev.langchain4j.model.output.Response;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import java.util.concurrent.CompletableFuture;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+class AutoConfigIT {
+
+ private static final String API_KEY = System.getenv("ANTHROPIC_API_KEY");
+
+ ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(AutoConfig.class));
+
+ @Test
+ void should_provide_chat_model() {
+ contextRunner
+ .withPropertyValues(
+ "langchain4j.anthropic.chat-model.api-key=" + API_KEY,
+ "langchain4j.anthropic.chat-model.max-tokens=20"
+ )
+ .run(context -> {
+
+ ChatLanguageModel chatLanguageModel = context.getBean(ChatLanguageModel.class);
+ assertThat(chatLanguageModel).isInstanceOf(AnthropicChatModel.class);
+ assertThat(chatLanguageModel.generate("What is the capital of Germany?")).contains("Berlin");
+
+ assertThat(context.getBean(AnthropicChatModel.class)).isSameAs(chatLanguageModel);
+ });
+ }
+
+ @Test
+ void should_provide_streaming_chat_model() {
+ contextRunner
+ .withPropertyValues(
+ "langchain4j.anthropic.streaming-chat-model.api-key=" + API_KEY,
+ "langchain4j.anthropic.streaming-chat-model.max-tokens=20"
+ )
+ .run(context -> {
+
+ StreamingChatLanguageModel streamingChatLanguageModel = context.getBean(StreamingChatLanguageModel.class);
+ assertThat(streamingChatLanguageModel).isInstanceOf(AnthropicStreamingChatModel.class);
+ CompletableFuture> future = new CompletableFuture<>();
+ streamingChatLanguageModel.generate("What is the capital of Germany?", new StreamingResponseHandler() {
+
+ @Override
+ public void onNext(String token) {
+ }
+
+ @Override
+ public void onComplete(Response response) {
+ future.complete(response);
+ }
+
+ @Override
+ public void onError(Throwable error) {
+ }
+ });
+ Response response = future.get(60, SECONDS);
+ assertThat(response.content().text()).contains("Berlin");
+
+ assertThat(context.getBean(AnthropicStreamingChatModel.class)).isSameAs(streamingChatLanguageModel);
+ });
+ }
+}
\ No newline at end of file
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/AutoConfig.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java
similarity index 99%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/AutoConfig.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java
index 8e47ecba..725fc08a 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/AutoConfig.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/AutoConfig.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import dev.langchain4j.model.openai.*;
import org.springframework.boot.autoconfigure.AutoConfiguration;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ChatModelProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java
similarity index 94%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ChatModelProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java
index 75e98ea7..b5e29b51 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ChatModelProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ChatModelProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/EmbeddingModelProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/EmbeddingModelProperties.java
similarity index 92%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/EmbeddingModelProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/EmbeddingModelProperties.java
index 1a227994..e499ab1d 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/EmbeddingModelProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/EmbeddingModelProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ImageModelProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ImageModelProperties.java
similarity index 93%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ImageModelProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ImageModelProperties.java
index bd96c7e0..5a01d2b1 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ImageModelProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ImageModelProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/LanguageModelProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/LanguageModelProperties.java
similarity index 91%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/LanguageModelProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/LanguageModelProperties.java
index 0101313b..994c9bbf 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/LanguageModelProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/LanguageModelProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ModerationModelProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ModerationModelProperties.java
similarity index 91%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ModerationModelProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ModerationModelProperties.java
index 80420ff1..e26aa282 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ModerationModelProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ModerationModelProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/Properties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java
similarity index 95%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/Properties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java
index 8cd88766..3a36498c 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/Properties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/Properties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ProxyProperties.java b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ProxyProperties.java
similarity index 90%
rename from langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ProxyProperties.java
rename to langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ProxyProperties.java
index 141af329..aa58287f 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/openai/spring/ProxyProperties.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/main/java/dev/langchain4j/anthropic/spring/ProxyProperties.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import lombok.Getter;
import lombok.Setter;
diff --git a/langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/openai/spring/AutoConfigIT.java b/langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java
similarity index 99%
rename from langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/openai/spring/AutoConfigIT.java
rename to langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java
index 3f99a713..a48d44d7 100644
--- a/langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/openai/spring/AutoConfigIT.java
+++ b/langchain4j-open-ai-spring-boot-starter/src/test/java/dev/langchain4j/anthropic/spring/AutoConfigIT.java
@@ -1,4 +1,4 @@
-package dev.langchain4j.openai.spring;
+package dev.langchain4j.anthropic.spring;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.StreamingResponseHandler;
diff --git a/pom.xml b/pom.xml
index c0f38a58..8e85966d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,6 +14,7 @@
https://github.com/langchain4j/langchain4j-spring
+ langchain4j-anthropic-spring-boot-starter
langchain4j-ollama-spring-boot-starter
langchain4j-open-ai-spring-boot-starter