From 9e865f0b0f9aa03360d59f2974d0e1620d9fba77 Mon Sep 17 00:00:00 2001 From: wmz7year Date: Wed, 24 Apr 2024 07:36:41 +0800 Subject: [PATCH] Add Bedrock Meta LLama3 AI model support. - re-enable llama structured output tests --- README.md | 2 +- models/spring-ai-bedrock/README.md | 2 +- .../ai/bedrock/aot/BedrockRuntimeHints.java | 8 +- .../BedrockLlamaChatClient.java} | 45 +++++----- .../BedrockLlamaChatOptions.java} | 8 +- .../api/LlamaChatBedrockApi.java} | 84 ++++++++++-------- .../BedrockAnthropic3ChatClientIT.java | 2 +- .../bedrock/aot/BedrockRuntimeHintsTests.java | 4 +- .../BedrockLlamaChatClientIT.java} | 41 ++++----- .../BedrockLlamaCreateRequestTests.java} | 21 +++-- .../api/LlamaChatBedrockApiIT.java} | 34 +++---- ...hat-api.jpg => bedrock-llama-chat-api.jpg} | Bin .../src/main/antora/modules/ROOT/nav.adoc | 2 +- .../modules/ROOT/pages/api/bedrock.adoc | 6 +- ...bedrock-llama2.adoc => bedrock-llama.adoc} | 84 +++++++++--------- .../modules/ROOT/pages/api/chatclient.adoc | 2 +- .../modules/ROOT/pages/getting-started.adoc | 2 +- .../BedrockLlamaChatAutoConfiguration.java} | 29 +++--- .../BedrockLlamaChatProperties.java} | 26 +++--- ...ot.autoconfigure.AutoConfiguration.imports | 2 +- .../BedrockLlamaChatAutoConfigurationIT.java} | 70 +++++++-------- 21 files changed, 244 insertions(+), 230 deletions(-) rename models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/{llama2/BedrockLlama2ChatClient.java => llama/BedrockLlamaChatClient.java} (67%) rename models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/{llama2/BedrockLlama2ChatOptions.java => llama/BedrockLlamaChatOptions.java} (91%) rename models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/{llama2/api/Llama2ChatBedrockApi.java => llama/api/LlamaChatBedrockApi.java} (66%) rename models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/{llama2/BedrockLlama2ChatClientIT.java => llama/BedrockLlamaChatClientIT.java} (88%) rename models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/{llama2/BedrockLlama2CreateRequestTests.java => llama/BedrockLlamaCreateRequestTests.java} (67%) rename models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/{llama2/api/Llama2ChatBedrockApiIT.java => llama/api/LlamaChatBedrockApiIT.java} (61%) rename spring-ai-docs/src/main/antora/modules/ROOT/images/bedrock/{bedrock-llama2-chat-api.jpg => bedrock-llama-chat-api.jpg} (100%) rename spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/{bedrock-llama2.adoc => bedrock-llama.adoc} (55%) rename spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/{llama2/BedrockLlama2ChatAutoConfiguration.java => llama/BedrockLlamaChatAutoConfiguration.java} (64%) rename spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/{llama2/BedrockLlama2ChatProperties.java => llama/BedrockLlamaChatProperties.java} (63%) rename spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/{llama2/BedrockLlama2ChatAutoConfigurationIT.java => llama/BedrockLlamaChatAutoConfigurationIT.java} (61%) diff --git a/README.md b/README.md index 50e4facc713..1c53af2bdc9 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ You can find more details in the [Reference Documentation](https://docs.spring.i Spring AI supports many AI models. For an overview see here. Specific models currently supported are * OpenAI * Azure OpenAI -* Amazon Bedrock (Anthropic, Llama2, Cohere, Titan, Jurassic2) +* Amazon Bedrock (Anthropic, Llama, Cohere, Titan, Jurassic2) * HuggingFace * Google VertexAI (PaLM2, Gemini) * Mistral AI diff --git a/models/spring-ai-bedrock/README.md b/models/spring-ai-bedrock/README.md index 94311055fba..19e48518a60 100644 --- a/models/spring-ai-bedrock/README.md +++ b/models/spring-ai-bedrock/README.md @@ -4,7 +4,7 @@ - [Anthropic2 Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-anthropic.html) - [Cohere Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-cohere.html) - [Cohere Embedding Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/embeddings/bedrock-cohere-embedding.html) -- [Llama2 Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-llama2.html) +- [Llama Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-llama.html) - [Titan Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-titan.html) - [Titan Embedding Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/embeddings/bedrock-titan-embedding.html) - [Jurassic2 Chat Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/bedrock/bedrock-jurassic2.html) diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java index 8ed33139b7d..edb3c4b1337 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java @@ -25,8 +25,8 @@ 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.BedrockLlama2ChatOptions; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; +import org.springframework.ai.bedrock.llama.BedrockLlamaChatOptions; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi; import org.springframework.ai.bedrock.titan.BedrockTitanChatOptions; import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi; import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi; @@ -63,9 +63,9 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) { for (var tr : findJsonAnnotatedClassesInPackage(BedrockCohereEmbeddingOptions.class)) hints.reflection().registerType(tr, mcs); - for (var tr : findJsonAnnotatedClassesInPackage(Llama2ChatBedrockApi.class)) + for (var tr : findJsonAnnotatedClassesInPackage(LlamaChatBedrockApi.class)) hints.reflection().registerType(tr, mcs); - for (var tr : findJsonAnnotatedClassesInPackage(BedrockLlama2ChatOptions.class)) + for (var tr : findJsonAnnotatedClassesInPackage(BedrockLlamaChatOptions.class)) hints.reflection().registerType(tr, mcs); for (var tr : findJsonAnnotatedClassesInPackage(TitanChatBedrockApi.class)) diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClient.java similarity index 67% rename from models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java rename to models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClient.java index a12fe0b6eb9..c1be58e5a1d 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClient.java @@ -13,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2; +package org.springframework.ai.bedrock.llama; import java.util.List; import reactor.core.publisher.Flux; import org.springframework.ai.bedrock.MessageToPromptConverter; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatResponse; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatRequest; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatResponse; import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.ChatResponse; @@ -35,26 +35,27 @@ import org.springframework.util.Assert; /** - * Java {@link ChatClient} and {@link StreamingChatClient} for the Bedrock Llama2 chat + * Java {@link ChatClient} and {@link StreamingChatClient} for the Bedrock Llama chat * generative. * * @author Christian Tzolov + * @author Wei Jiang * @since 0.8.0 */ -public class BedrockLlama2ChatClient implements ChatClient, StreamingChatClient { +public class BedrockLlamaChatClient implements ChatClient, StreamingChatClient { - private final Llama2ChatBedrockApi chatApi; + private final LlamaChatBedrockApi chatApi; - private final BedrockLlama2ChatOptions defaultOptions; + private final BedrockLlamaChatOptions defaultOptions; - public BedrockLlama2ChatClient(Llama2ChatBedrockApi chatApi) { + public BedrockLlamaChatClient(LlamaChatBedrockApi chatApi) { this(chatApi, - BedrockLlama2ChatOptions.builder().withTemperature(0.8f).withTopP(0.9f).withMaxGenLen(100).build()); + BedrockLlamaChatOptions.builder().withTemperature(0.8f).withTopP(0.9f).withMaxGenLen(100).build()); } - public BedrockLlama2ChatClient(Llama2ChatBedrockApi chatApi, BedrockLlama2ChatOptions options) { - Assert.notNull(chatApi, "Llama2ChatBedrockApi must not be null"); - Assert.notNull(options, "BedrockLlama2ChatOptions must not be null"); + public BedrockLlamaChatClient(LlamaChatBedrockApi chatApi, BedrockLlamaChatOptions options) { + Assert.notNull(chatApi, "LlamaChatBedrockApi must not be null"); + Assert.notNull(options, "BedrockLlamaChatOptions must not be null"); this.chatApi = chatApi; this.defaultOptions = options; @@ -65,7 +66,7 @@ public ChatResponse call(Prompt prompt) { var request = createRequest(prompt); - Llama2ChatResponse response = this.chatApi.chatCompletion(request); + LlamaChatResponse response = this.chatApi.chatCompletion(request); return new ChatResponse(List.of(new Generation(response.generation()).withGenerationMetadata( ChatGenerationMetadata.from(response.stopReason().name(), extractUsage(response))))); @@ -76,7 +77,7 @@ public Flux stream(Prompt prompt) { var request = createRequest(prompt); - Flux fluxResponse = this.chatApi.chatCompletionStream(request); + Flux fluxResponse = this.chatApi.chatCompletionStream(request); return fluxResponse.map(response -> { String stopReason = response.stopReason() != null ? response.stopReason().name() : null; @@ -85,7 +86,7 @@ public Flux stream(Prompt prompt) { }); } - private Usage extractUsage(Llama2ChatResponse response) { + private Usage extractUsage(LlamaChatResponse response) { return new Usage() { @Override @@ -103,22 +104,22 @@ public Long getGenerationTokens() { /** * Accessible for testing. */ - Llama2ChatRequest createRequest(Prompt prompt) { + LlamaChatRequest createRequest(Prompt prompt) { final String promptValue = MessageToPromptConverter.create().toPrompt(prompt.getInstructions()); - Llama2ChatRequest request = Llama2ChatRequest.builder(promptValue).build(); + LlamaChatRequest request = LlamaChatRequest.builder(promptValue).build(); if (this.defaultOptions != null) { - request = ModelOptionsUtils.merge(request, this.defaultOptions, Llama2ChatRequest.class); + request = ModelOptionsUtils.merge(request, this.defaultOptions, LlamaChatRequest.class); } if (prompt.getOptions() != null) { if (prompt.getOptions() instanceof ChatOptions runtimeOptions) { - BedrockLlama2ChatOptions updatedRuntimeOptions = ModelOptionsUtils.copyToTarget(runtimeOptions, - ChatOptions.class, BedrockLlama2ChatOptions.class); + BedrockLlamaChatOptions updatedRuntimeOptions = ModelOptionsUtils.copyToTarget(runtimeOptions, + ChatOptions.class, BedrockLlamaChatOptions.class); - request = ModelOptionsUtils.merge(updatedRuntimeOptions, request, Llama2ChatRequest.class); + request = ModelOptionsUtils.merge(updatedRuntimeOptions, request, LlamaChatRequest.class); } else { throw new IllegalArgumentException("Prompt options are not of type ChatOptions: " diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatOptions.java similarity index 91% rename from models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java rename to models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatOptions.java index a944b09904a..3502fd4c441 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatOptions.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2; +package org.springframework.ai.bedrock.llama; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -26,7 +26,7 @@ * @author Christian Tzolov */ @JsonInclude(Include.NON_NULL) -public class BedrockLlama2ChatOptions implements ChatOptions { +public class BedrockLlamaChatOptions implements ChatOptions { /** * The temperature value controls the randomness of the generated text. Use a lower @@ -51,7 +51,7 @@ public static Builder builder() { public static class Builder { - private BedrockLlama2ChatOptions options = new BedrockLlama2ChatOptions(); + private BedrockLlamaChatOptions options = new BedrockLlamaChatOptions(); public Builder withTemperature(Float temperature) { this.options.setTemperature(temperature); @@ -68,7 +68,7 @@ public Builder withMaxGenLen(Integer maxGenLen) { return this; } - public BedrockLlama2ChatOptions build() { + public BedrockLlamaChatOptions build() { return this.options; } diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java similarity index 66% rename from models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java rename to models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java index 390ad28fffe..25d71aedeea 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2.api; +package org.springframework.ai.bedrock.llama.api; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -24,89 +24,89 @@ import software.amazon.awssdk.regions.Region; import org.springframework.ai.bedrock.api.AbstractBedrockApi; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatResponse; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatRequest; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatResponse; import java.time.Duration; // @formatter:off /** - * Java client for the Bedrock Llama2 chat model. + * Java client for the Bedrock Llama chat model. * https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-meta.html * * @author Christian Tzolov * @author Wei Jiang * @since 0.8.0 */ -public class Llama2ChatBedrockApi extends - AbstractBedrockApi { +public class LlamaChatBedrockApi extends + AbstractBedrockApi { /** - * Create a new Llama2ChatBedrockApi instance using the default credentials provider chain, the default object + * Create a new LlamaChatBedrockApi instance using the default credentials provider chain, the default object * mapper, default temperature and topP values. * - * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param modelId The model id to use. See the {@link LlamaChatModel} for the supported models. * @param region The AWS region to use. */ - public Llama2ChatBedrockApi(String modelId, String region) { + public LlamaChatBedrockApi(String modelId, String region) { super(modelId, region); } /** - * Create a new Llama2ChatBedrockApi instance using the provided credentials provider, region and object mapper. + * Create a new LlamaChatBedrockApi instance using the provided credentials provider, region and object mapper. * - * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param modelId The model id to use. See the {@link LlamaChatModel} for the supported models. * @param credentialsProvider The credentials provider to connect to AWS. * @param region The AWS region to use. * @param objectMapper The object mapper to use for JSON serialization and deserialization. */ - public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + public LlamaChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, ObjectMapper objectMapper) { super(modelId, credentialsProvider, region, objectMapper); } /** - * Create a new Llama2ChatBedrockApi instance using the default credentials provider chain, the default object + * Create a new LlamaChatBedrockApi instance using the default credentials provider chain, the default object * mapper, default temperature and topP values. * - * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param modelId The model id to use. See the {@link LlamaChatModel} for the supported models. * @param region The AWS region to use. * @param timeout The timeout to use. */ - public Llama2ChatBedrockApi(String modelId, String region, Duration timeout) { + public LlamaChatBedrockApi(String modelId, String region, Duration timeout) { super(modelId, region, timeout); } /** - * Create a new Llama2ChatBedrockApi instance using the provided credentials provider, region and object mapper. + * Create a new LlamaChatBedrockApi instance using the provided credentials provider, region and object mapper. * - * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param modelId The model id to use. See the {@link LlamaChatModel} for the supported models. * @param credentialsProvider The credentials provider to connect to AWS. * @param region The AWS region to use. * @param objectMapper The object mapper to use for JSON serialization and deserialization. * @param timeout The timeout to use. */ - public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, + public LlamaChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region, ObjectMapper objectMapper, Duration timeout) { super(modelId, credentialsProvider, region, objectMapper, timeout); } /** - * Create a new Llama2ChatBedrockApi instance using the provided credentials provider, region and object mapper. + * Create a new LlamaChatBedrockApi instance using the provided credentials provider, region and object mapper. * - * @param modelId The model id to use. See the {@link Llama2ChatModel} for the supported models. + * @param modelId The model id to use. See the {@link LlamaChatModel} for the supported models. * @param credentialsProvider The credentials provider to connect to AWS. * @param region The AWS region to use. * @param objectMapper The object mapper to use for JSON serialization and deserialization. * @param timeout The timeout to use. */ - public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, Region region, + public LlamaChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, Region region, ObjectMapper objectMapper, Duration timeout) { super(modelId, credentialsProvider, region, objectMapper, timeout); } /** - * Llama2ChatRequest encapsulates the request parameters for the Meta Llama2 chat model. + * LlamaChatRequest encapsulates the request parameters for the Meta Llama chat model. * * @param prompt The prompt to use for the chat. * @param temperature The temperature value controls the randomness of the generated text. Use a lower value to @@ -116,16 +116,16 @@ public Llama2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsPr * @param maxGenLen The maximum length of the generated text. */ @JsonInclude(Include.NON_NULL) - public record Llama2ChatRequest( + public record LlamaChatRequest( @JsonProperty("prompt") String prompt, @JsonProperty("temperature") Float temperature, @JsonProperty("top_p") Float topP, @JsonProperty("max_gen_len") Integer maxGenLen) { /** - * Create a new Llama2ChatRequest builder. + * Create a new LlamaChatRequest builder. * @param prompt compulsory prompt parameter. - * @return a new Llama2ChatRequest builder. + * @return a new LlamaChatRequest builder. */ public static Builder builder(String prompt) { return new Builder(prompt); @@ -156,8 +156,8 @@ public Builder withMaxGenLen(Integer maxGenLen) { return this; } - public Llama2ChatRequest build() { - return new Llama2ChatRequest( + public LlamaChatRequest build() { + return new LlamaChatRequest( prompt, temperature, topP, @@ -168,7 +168,7 @@ public Llama2ChatRequest build() { } /** - * Llama2ChatResponse encapsulates the response parameters for the Meta Llama2 chat model. + * LlamaChatResponse encapsulates the response parameters for the Meta Llama chat model. * * @param generation The generated text. * @param promptTokenCount The number of tokens in the prompt. @@ -179,7 +179,7 @@ public Llama2ChatRequest build() { * increasing the value of max_gen_len and trying again. */ @JsonInclude(Include.NON_NULL) - public record Llama2ChatResponse( + public record LlamaChatResponse( @JsonProperty("generation") String generation, @JsonProperty("prompt_token_count") Integer promptTokenCount, @JsonProperty("generation_token_count") Integer generationTokenCount, @@ -202,9 +202,9 @@ public enum StopReason { } /** - * Llama2 models version. + * Llama models version. */ - public enum Llama2ChatModel { + public enum LlamaChatModel { /** * meta.llama2-13b-chat-v1 @@ -214,7 +214,17 @@ public enum Llama2ChatModel { /** * meta.llama2-70b-chat-v1 */ - LLAMA2_70B_CHAT_V1("meta.llama2-70b-chat-v1"); + LLAMA2_70B_CHAT_V1("meta.llama2-70b-chat-v1"), + + /** + * meta.llama3-8b-instruct-v1:0 + */ + LLAMA3_8B_INSTRUCT_V1("meta.llama3-8b-instruct-v1:0"), + + /** + * meta.llama3-70b-instruct-v1:0 + */ + LLAMA3_70B_INSTRUCT_V1("meta.llama3-70b-instruct-v1:0"); private final String id; @@ -225,19 +235,19 @@ public String id() { return id; } - Llama2ChatModel(String value) { + LlamaChatModel(String value) { this.id = value; } } @Override - public Llama2ChatResponse chatCompletion(Llama2ChatRequest request) { - return this.internalInvocation(request, Llama2ChatResponse.class); + public LlamaChatResponse chatCompletion(LlamaChatRequest request) { + return this.internalInvocation(request, LlamaChatResponse.class); } @Override - public Flux chatCompletionStream(Llama2ChatRequest request) { - return this.internalInvocationStream(request, Llama2ChatResponse.class); + public Flux chatCompletionStream(LlamaChatRequest request) { + return this.internalInvocationStream(request, LlamaChatResponse.class); } } // @formatter:on \ No newline at end of file diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java index c2050f18ca0..4fa59402054 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic3/BedrockAnthropic3ChatClientIT.java @@ -161,9 +161,9 @@ void beanOutputParserRecords() { String format = outputParser.getFormat(); String template = """ Generate the filmography of 5 movies for Tom Hanks. - Remove non JSON tex blocks from the output. {format} Provide your answer in the JSON format with the feature names as the keys. + Remove Markdown code blocks from the output. """; PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format)); Prompt prompt = new Prompt(promptTemplate.createMessage()); diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java index a4b51a70750..92060ef5bf0 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java @@ -20,7 +20,7 @@ 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.llama.api.LlamaChatBedrockApi; import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi; import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi; import org.springframework.aot.hint.RuntimeHints; @@ -43,7 +43,7 @@ void registerHints() { bedrockRuntimeHints.registerHints(runtimeHints, null); List classList = Arrays.asList(Ai21Jurassic2ChatBedrockApi.class, CohereChatBedrockApi.class, - CohereEmbeddingBedrockApi.class, Llama2ChatBedrockApi.class, TitanChatBedrockApi.class, + CohereEmbeddingBedrockApi.class, LlamaChatBedrockApi.class, TitanChatBedrockApi.class, TitanEmbeddingBedrockApi.class, AnthropicChatBedrockApi.class); for (Class aClass : classList) { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClientIT.java similarity index 88% rename from models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java rename to models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClientIT.java index 7cbf3f23566..554afcf9fa0 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClientIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2; +package org.springframework.ai.bedrock.llama; import java.time.Duration; import java.util.Arrays; @@ -22,27 +22,25 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import reactor.core.publisher.Flux; - -import org.springframework.ai.chat.ChatResponse; -import org.springframework.ai.chat.messages.AssistantMessage; import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.regions.Region; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatModel; +import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.Generation; -import org.springframework.ai.parser.BeanOutputParser; -import org.springframework.ai.parser.ListOutputParser; -import org.springframework.ai.parser.MapOutputParser; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.ai.chat.prompt.SystemPromptTemplate; -import org.springframework.ai.chat.messages.Message; -import org.springframework.ai.chat.messages.UserMessage; +import org.springframework.ai.parser.BeanOutputParser; +import org.springframework.ai.parser.ListOutputParser; +import org.springframework.ai.parser.MapOutputParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringBootConfiguration; @@ -56,10 +54,10 @@ @SpringBootTest @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") @EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*") -class BedrockLlama2ChatClientIT { +class BedrockLlamaChatClientIT { @Autowired - private BedrockLlama2ChatClient client; + private BedrockLlamaChatClient client; @Value("classpath:/prompts/system-message.st") private Resource systemResource; @@ -67,8 +65,8 @@ class BedrockLlama2ChatClientIT { @Test void multipleStreamAttempts() { + Flux joke2Stream = client.stream(new Prompt(new UserMessage("Tell me a Toy joke?"))); Flux joke1Stream = client.stream(new Prompt(new UserMessage("Tell me a joke?"))); - Flux joke2Stream = client.stream(new Prompt(new UserMessage("Tell me a toy joke?"))); String joke1 = joke1Stream.collectList() .block() @@ -105,7 +103,6 @@ void roleTest() { assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard"); } - @Disabled("TODO: Fix the parser instructions to return the correct format") @Test void outputParser() { DefaultConversionService conversionService = new DefaultConversionService(); @@ -147,7 +144,6 @@ void mapOutputParser() { record ActorsFilmsRecord(String actor, List movies) { } - @Disabled("TODO: Fix the parser instructions to return the correct format") @Test void beanOutputParserRecords() { @@ -169,7 +165,6 @@ void beanOutputParserRecords() { assertThat(actorsFilms.movies()).hasSize(5); } - @Disabled("TODO: Fix the parser instructions to return the correct format") @Test void beanStreamOutputParserRecords() { @@ -204,16 +199,16 @@ void beanStreamOutputParserRecords() { public static class TestConfiguration { @Bean - public Llama2ChatBedrockApi llama2Api() { - return new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), + public LlamaChatBedrockApi llamaApi() { + return new LlamaChatBedrockApi(LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(), EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), Duration.ofMinutes(2)); } @Bean - public BedrockLlama2ChatClient llama2ChatClient(Llama2ChatBedrockApi llama2Api) { - return new BedrockLlama2ChatClient(llama2Api, - BedrockLlama2ChatOptions.builder().withTemperature(0.5f).withMaxGenLen(100).withTopP(0.9f).build()); + public BedrockLlamaChatClient llamaChatClient(LlamaChatBedrockApi llamaApi) { + return new BedrockLlamaChatClient(llamaApi, + BedrockLlamaChatOptions.builder().withTemperature(0.5f).withMaxGenLen(100).withTopP(0.9f).build()); } } diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaCreateRequestTests.java similarity index 67% rename from models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java rename to models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaCreateRequestTests.java index 1a3329016f3..77018af9e6e 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/BedrockLlamaCreateRequestTests.java @@ -13,15 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2; +package org.springframework.ai.bedrock.llama; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; + import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.regions.Region; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatModel; import org.springframework.ai.chat.prompt.Prompt; import java.time.Duration; @@ -30,18 +32,21 @@ /** * @author Christian Tzolov + * @author Wei Jiang */ -public class BedrockLlama2CreateRequestTests { +@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") +@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*") +public class BedrockLlamaCreateRequestTests { - private Llama2ChatBedrockApi api = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), + private LlamaChatBedrockApi api = new LlamaChatBedrockApi(LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(), EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), Duration.ofMinutes(2)); @Test public void createRequestWithChatOptions() { - var client = new BedrockLlama2ChatClient(api, - BedrockLlama2ChatOptions.builder().withTemperature(66.6f).withMaxGenLen(666).withTopP(0.66f).build()); + var client = new BedrockLlamaChatClient(api, + BedrockLlamaChatOptions.builder().withTemperature(66.6f).withMaxGenLen(666).withTopP(0.66f).build()); var request = client.createRequest(new Prompt("Test message content")); @@ -51,7 +56,7 @@ public void createRequestWithChatOptions() { assertThat(request.maxGenLen()).isEqualTo(666); request = client.createRequest(new Prompt("Test message content", - BedrockLlama2ChatOptions.builder().withTemperature(99.9f).withMaxGenLen(999).withTopP(0.99f).build())); + BedrockLlamaChatOptions.builder().withTemperature(99.9f).withMaxGenLen(999).withTopP(0.99f).build())); assertThat(request.prompt()).isNotEmpty(); assertThat(request.temperature()).isEqualTo(99.9f); diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApiIT.java similarity index 61% rename from models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java rename to models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApiIT.java index dc97d8e7b8f..5b4587358fb 100644 --- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApiIT.java @@ -13,47 +13,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.llama2.api; +package org.springframework.ai.bedrock.llama.api; import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatModel; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatRequest; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatResponse; + +import com.fasterxml.jackson.databind.ObjectMapper; + import reactor.core.publisher.Flux; +import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.regions.Region; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatResponse; - import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov + * @author Wei Jiang */ @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") @EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*") -public class Llama2ChatBedrockApiIT { +public class LlamaChatBedrockApiIT { - private Llama2ChatBedrockApi llama2ChatApi = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - Region.US_EAST_1.id(), Duration.ofMinutes(2)); + private LlamaChatBedrockApi llamaChatApi = new LlamaChatBedrockApi(LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(), + EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), + Duration.ofMinutes(2)); @Test public void chatCompletion() { - Llama2ChatRequest request = Llama2ChatRequest.builder("Hello, my name is") + LlamaChatRequest request = LlamaChatRequest.builder("Hello, my name is") .withTemperature(0.9f) .withTopP(0.9f) .withMaxGenLen(20) .build(); - Llama2ChatResponse response = llama2ChatApi.chatCompletion(request); + LlamaChatResponse response = llamaChatApi.chatCompletion(request); System.out.println(response.generation()); assertThat(response).isNotNull(); assertThat(response.generation()).isNotEmpty(); - assertThat(response.promptTokenCount()).isEqualTo(6); assertThat(response.generationTokenCount()).isGreaterThan(10); assertThat(response.generationTokenCount()).isLessThanOrEqualTo(20); assertThat(response.stopReason()).isNotNull(); @@ -63,15 +67,15 @@ public void chatCompletion() { @Test public void chatCompletionStream() { - Llama2ChatRequest request = new Llama2ChatRequest("Hello, my name is", 0.9f, 0.9f, 20); - Flux responseStream = llama2ChatApi.chatCompletionStream(request); - List responses = responseStream.collectList().block(); + LlamaChatRequest request = new LlamaChatRequest("Hello, my name is", 0.9f, 0.9f, 20); + Flux responseStream = llamaChatApi.chatCompletionStream(request); + List responses = responseStream.collectList().block(); assertThat(responses).isNotNull(); assertThat(responses).hasSizeGreaterThan(10); assertThat(responses.get(0).generation()).isNotEmpty(); - Llama2ChatResponse lastResponse = responses.get(responses.size() - 1); + LlamaChatResponse lastResponse = responses.get(responses.size() - 1); assertThat(lastResponse.stopReason()).isNotNull(); assertThat(lastResponse.amazonBedrockInvocationMetrics()).isNotNull(); } diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/bedrock/bedrock-llama2-chat-api.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/bedrock/bedrock-llama-chat-api.jpg similarity index 100% rename from spring-ai-docs/src/main/antora/modules/ROOT/images/bedrock/bedrock-llama2-chat-api.jpg rename to spring-ai-docs/src/main/antora/modules/ROOT/images/bedrock/bedrock-llama-chat-api.jpg diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc index 7d8e11bb98f..5c05e9d6277 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc @@ -11,7 +11,7 @@ *** xref:api/bedrock-chat.adoc[Amazon Bedrock] **** xref:api/chat/bedrock/bedrock-anthropic3.adoc[Anthropic3] **** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic2] -**** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2] +**** xref:api/chat/bedrock/bedrock-llama.adoc[Llama] **** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere] **** xref:api/chat/bedrock/bedrock-titan.adoc[Titan] **** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2] diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc index 89e3190b091..3bdb84e102f 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc @@ -85,7 +85,7 @@ Here are the supported `` and `` combinations: |==== | Model | Chat | Chat Streaming | Embedding -| llama2 | Yes | Yes | No +| llama | Yes | Yes | No | jurassic2 | Yes | No | No | cohere | Yes | Yes | Yes | anthropic 2 | Yes | Yes | No @@ -94,7 +94,7 @@ Here are the supported `` and `` combinations: | titan | Yes | Yes | Yes (however, no batch support) |==== -For example, to enable the Bedrock Llama2 Chat client, you need to set `spring.ai.bedrock.llama2.chat.enabled=true`. +For example, to enable the Bedrock Llama Chat client, you need to set `spring.ai.bedrock.llama.chat.enabled=true`. Next, you can use the `spring.ai.bedrock...*` properties to configure each model as provided. @@ -102,7 +102,7 @@ For more information, refer to the documentation below for each supported model. * xref:api/chat/bedrock/bedrock-anthropic.adoc[Spring AI Bedrock Anthropic 2 Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true` * xref:api/chat/bedrock/bedrock-anthropic3.adoc[Spring AI Bedrock Anthropic 3 Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true` -* xref:api/chat/bedrock/bedrock-llama2.adoc[Spring AI Bedrock Llama2 Chat]: `spring.ai.bedrock.llama2.chat.enabled=true` +* xref:api/chat/bedrock/bedrock-llama.adoc[Spring AI Bedrock Llama Chat]: `spring.ai.bedrock.llama.chat.enabled=true` * xref:api/chat/bedrock/bedrock-cohere.adoc[Spring AI Bedrock Cohere Chat]: `spring.ai.bedrock.cohere.chat.enabled=true` * xref:api/embeddings/bedrock-cohere-embedding.adoc[Spring AI Bedrock Cohere Embeddings]: `spring.ai.bedrock.cohere.embedding.enabled=true` * xref:api/chat/bedrock/bedrock-titan.adoc[Spring AI Bedrock Titan Chat]: `spring.ai.bedrock.titan.chat.enabled=true` diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama.adoc similarity index 55% rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama.adoc index 7f891e39432..1d04b2b8ffb 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama.adoc @@ -1,13 +1,13 @@ -= Llama2 Chat += Llama Chat -https://ai.meta.com/llama/[Meta's Llama 2 Chat] is part of the Llama 2 collection of large language models. +https://ai.meta.com/llama/[Meta's Llama Chat] is part of the Llama collection of large language models. It excels in dialogue-based applications with a parameter scale ranging from 7 billion to 70 billion. Leveraging public datasets and over 1 million human annotations, Llama Chat offers context-aware dialogues. -Trained on 2 trillion tokens from public data sources, Llama-2-Chat provides extensive knowledge for insightful conversations. +Trained on 2 trillion tokens from public data sources, Llama-Chat provides extensive knowledge for insightful conversations. Rigorous testing, including over 1,000 hours of red-teaming and annotation, ensures both performance and safety, making it a reliable choice for AI-driven dialogues. -The https://aws.amazon.com/bedrock/llama-2/[AWS Llama 2 Model Page] and https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html[Amazon Bedrock User Guide] contains detailed information on how to use the AWS hosted model. +The https://aws.amazon.com/bedrock/llama/[AWS Llama Model Page] and https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html[Amazon Bedrock User Guide] contains detailed information on how to use the AWS hosted model. == Prerequisites @@ -43,15 +43,15 @@ dependencies { TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file. -=== Enable Llama2 Chat Support +=== Enable Llama Chat Support -By default the Bedrock Llama2 model is disabled. -To enable it set the `spring.ai.bedrock.llama2.chat.enabled` property to `true`. +By default the Bedrock Llama model is disabled. +To enable it set the `spring.ai.bedrock.llama.chat.enabled` property to `true`. Exporting environment variable is one way to set this configuration property: [source,shell] ---- -export SPRING_AI_BEDROCK_LLAMA2_CHAT_ENABLED=true +export SPRING_AI_BEDROCK_LLAMA_CHAT_ENABLED=true ---- === Chat Properties @@ -69,29 +69,29 @@ The prefix `spring.ai.bedrock.aws` is the property prefix to configure the conne |==== -The prefix `spring.ai.bedrock.llama2.chat` is the property prefix that configures the chat client implementation for Llama2. +The prefix `spring.ai.bedrock.llama.chat` is the property prefix that configures the chat client implementation for Llama. [cols="2,5,1"] |==== | Property | Description | Default -| spring.ai.bedrock.llama2.chat.enabled | Enable or disable support for Llama2 | false -| spring.ai.bedrock.llama2.chat.model | The model id to use (See Below) | meta.llama2-70b-chat-v1 -| spring.ai.bedrock.llama2.chat.options.temperature | Controls the randomness of the output. Values can range over [0.0,1.0], inclusive. A value closer to 1.0 will produce responses that are more varied, while a value closer to 0.0 will typically result in less surprising responses from the model. This value specifies default to be used by the backend while making the call to the model. | 0.7 -| spring.ai.bedrock.llama2.chat.options.top-p | The maximum cumulative probability of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least topP. | AWS Bedrock default -| spring.ai.bedrock.llama2.chat.options.max-gen-len | Specify the maximum number of tokens to use in the generated response. The model truncates the response once the generated text exceeds maxGenLen. | 300 +| spring.ai.bedrock.llama.chat.enabled | Enable or disable support for Llama | false +| spring.ai.bedrock.llama.chat.model | The model id to use (See Below) | meta.llama3-70b-instruct-v1:0 +| spring.ai.bedrock.llama.chat.options.temperature | Controls the randomness of the output. Values can range over [0.0,1.0], inclusive. A value closer to 1.0 will produce responses that are more varied, while a value closer to 0.0 will typically result in less surprising responses from the model. This value specifies default to be used by the backend while making the call to the model. | 0.7 +| spring.ai.bedrock.llama.chat.options.top-p | The maximum cumulative probability of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least topP. | AWS Bedrock default +| spring.ai.bedrock.llama.chat.options.max-gen-len | Specify the maximum number of tokens to use in the generated response. The model truncates the response once the generated text exceeds maxGenLen. | 300 |==== -Look at https://github.com/spring-projects/spring-ai/blob/4ba9a3cd689b9fd3a3805f540debe398a079c6ef/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java#L164[Llama2ChatBedrockApi#Llama2ChatModel] for other model IDs. The other value supported is `meta.llama2-13b-chat-v1`. +Look at https://github.com/spring-projects/spring-ai/blob/4ba9a3cd689b9fd3a3805f540debe398a079c6ef/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java#L164[LlamaChatBedrockApi#LlamaChatModel] for other model IDs. The other value supported is `meta.llama2-13b-chat-v1`. Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html[AWS Bedrock documentation for base model IDs]. -TIP: All properties prefixed with `spring.ai.bedrock.llama2.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call. +TIP: All properties prefixed with `spring.ai.bedrock.llama.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call. == Runtime Options [[chat-options]] -The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java[BedrockLlama2ChatOptions.java] provides model configurations, such as temperature, topK, topP, etc. +The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatOptions.java[BedrockLlChatOptions.java] provides model configurations, such as temperature, topK, topP, etc. -On start-up, the default options can be configured with the `BedrockLlama2ChatClient(api, options)` constructor or the `spring.ai.bedrock.llama2.chat.options.*` properties. +On start-up, the default options can be configured with the `BedrockLlamaChatClient(api, options)` constructor or the `spring.ai.bedrock.llama.chat.options.*` properties. At run-time you can override the default options by adding new, request specific, options to the `Prompt` call. For example to override the default temperature for a specific request: @@ -101,13 +101,13 @@ For example to override the default temperature for a specific request: ChatResponse response = chatClient.call( new Prompt( "Generate the names of 5 famous pirates.", - BedrockLlama2ChatOptions.builder() + BedrockLlamaChatOptions.builder() .withTemperature(0.4) .build() )); ---- -TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java[BedrockLlama2ChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()]. +TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatOptions.java[BedrockLlamaChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()]. == Sample Controller @@ -122,13 +122,13 @@ spring.ai.bedrock.aws.timeout=1000ms spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID} spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY} -spring.ai.bedrock.llama2.chat.enabled=true -spring.ai.bedrock.llama2.chat.options.temperature=0.8 +spring.ai.bedrock.llama.chat.enabled=true +spring.ai.bedrock.llama.chat.options.temperature=0.8 ---- TIP: replace the `regions`, `access-key` and `secret-key` with your AWS credentials. -This will create a `BedrockLlama2ChatClient` implementation that you can inject into your class. +This will create a `BedrockLlamaChatClient` implementation that you can inject into your class. Here is an example of a simple `@Controller` class that uses the chat client for text generations. [source,java] @@ -136,10 +136,10 @@ Here is an example of a simple `@Controller` class that uses the chat client for @RestController public class ChatController { - private final BedrockLlama2ChatClient chatClient; + private final BedrockLlamaChatClient chatClient; @Autowired - public ChatController(BedrockLlama2ChatClient chatClient) { + public ChatController(BedrockLlamaChatClient chatClient) { this.chatClient = chatClient; } @@ -158,7 +158,7 @@ public class ChatController { == Manual Configuration -The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java[BedrockLlama2ChatClient] implements the `ChatClient` and `StreamingChatClient` and uses the <> to connect to the Bedrock Anthropic service. +The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClient.java[BedrockLlamaChatClient] implements the `ChatClient` and `StreamingChatClient` and uses the <> to connect to the Bedrock Anthropic service. Add the `spring-ai-bedrock` dependency to your project's Maven `pom.xml` file: @@ -181,18 +181,18 @@ dependencies { TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file. -Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java[BedrockLlama2ChatClient] and use it for text generations: +Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/BedrockLlamaChatClient.java[BedrockLlamaChatClient] and use it for text generations: [source,java] ---- -Llama2ChatBedrockApi api = new Llama2ChatBedrockApi(Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), +LlamaChatBedrockApi api = new LlamaChatBedrockApi(LlamaChatModel.LLAMA2_70B_CHAT_V1.id(), EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper(), Duration.ofMillis(1000L)); -BedrockLlama2ChatClient chatClient = new BedrockLlama2ChatClient(api, - BedrockLlama2ChatOptions.builder() +BedrockLlamaChatClient chatClient = new BedrockLlamaChatClient(api, + BedrockLlamaChatOptions.builder() .withTemperature(0.5f) .withMaxGenLen(100) .withTopP(0.9f).build()); @@ -205,38 +205,38 @@ Flux response = chatClient.stream( new Prompt("Generate the names of 5 famous pirates.")); ---- -== Low-level Llama2ChatBedrockApi Client [[low-level-api]] +== Low-level LlamaChatBedrockApi Client [[low-level-api]] -https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java[Llama2ChatBedrockApi] provides is lightweight Java client on top of AWS Bedrock https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-meta.html[Meta Llama 2 and Llama 2 Chat models]. +https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java[LlamaChatBedrockApi] provides is lightweight Java client on top of AWS Bedrock https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-meta.html[Meta Llama 2 and Llama 2 Chat models]. -Following class diagram illustrates the Llama2ChatBedrockApi interface and building blocks: +Following class diagram illustrates the LlamaChatBedrockApi interface and building blocks: -image::bedrock/bedrock-llama2-chat-api.jpg[Llama2ChatBedrockApi Class Diagram] +image::bedrock/bedrock-llama-chat-api.jpg[LlamaChatBedrockApi Class Diagram] -The Llama2ChatBedrockApi supports the `meta.llama2-13b-chat-v1` and `meta.llama2-70b-chat-v1` models for both synchronous (e.g. `chatCompletion()`) and streaming (e.g. `chatCompletionStream()`) responses. +The LlamaChatBedrockApi supports the `meta.llama3-8b-instruct-v1:0`,`meta.llama3-70b-instruct-v1:0`,`meta.llama2-13b-chat-v1` and `meta.llama2-70b-chat-v1` models for both synchronous (e.g. `chatCompletion()`) and streaming (e.g. `chatCompletionStream()`) responses. Here is a simple snippet how to use the api programmatically: [source,java] ---- -Llama2ChatBedrockApi llama2ChatApi = new Llama2ChatBedrockApi( - Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), +LlamaChatBedrockApi llamaChatApi = new LlamaChatBedrockApi( + LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(), Region.US_EAST_1.id(), Duration.ofMillis(1000L)); -Llama2ChatRequest request = Llama2ChatRequest.builder("Hello, my name is") +LlamaChatRequest request = LlamaChatRequest.builder("Hello, my name is") .withTemperature(0.9f) .withTopP(0.9f) .withMaxGenLen(20) .build(); -Llama2ChatResponse response = llama2ChatApi.chatCompletion(request); +LlamaChatResponse response = llamaChatApi.chatCompletion(request); // Streaming response -Flux responseStream = llama2ChatApi.chatCompletionStream(request); -List responses = responseStream.collectList().block(); +Flux responseStream = llamaChatApi.chatCompletionStream(request); +List responses = responseStream.collectList().block(); ---- -Follow the https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java[Llama2ChatBedrockApi.java]'s JavaDoc for further information. +Follow the https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama/api/LlamaChatBedrockApi.java[LlamaChatBedrockApi.java]'s JavaDoc for further information. diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc index 7bd008b400f..902d0d59b78 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc @@ -183,7 +183,7 @@ image::spring-ai-chat-completions-clients.jpg[align="center", width="800px"] * xref:api/chat/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support) * xref:api/bedrock.adoc[Amazon Bedrock] ** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere Chat Completion] -** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion] +** xref:api/chat/bedrock/bedrock-llama.adoc[Llama Chat Completion] ** xref:api/chat/bedrock/bedrock-titan.adoc[Titan Chat Completion] ** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion] ** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2 Chat Completion] diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc index 486e6e1e4ec..e2f04a0796f 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc @@ -147,7 +147,7 @@ Each of the following sections in the documentation shows which dependencies you ** xref:api/chat/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support) ** xref:api/bedrock.adoc[Amazon Bedrock] *** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere Chat Completion] -*** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion] +*** xref:api/chat/bedrock/bedrock-llama.adoc[Llama Chat Completion] *** xref:api/chat/bedrock/bedrock-titan.adoc[Titan Chat Completion] *** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion] *** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2 Chat Completion] diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfiguration.java similarity index 64% rename from spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java rename to spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfiguration.java index ef3d53e4faa..9293acc84f2 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfiguration.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.autoconfigure.bedrock.llama2; +package org.springframework.ai.autoconfigure.bedrock.llama; import com.fasterxml.jackson.databind.ObjectMapper; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; @@ -21,8 +21,8 @@ import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration; import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties; -import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatClient; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi; +import org.springframework.ai.bedrock.llama.BedrockLlamaChatClient; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -33,7 +33,7 @@ import org.springframework.context.annotation.Import; /** - * {@link AutoConfiguration Auto-configuration} for Bedrock Llama2 Chat Client. + * {@link AutoConfiguration Auto-configuration} for Bedrock Llama Chat Client. * * Leverages the Spring Cloud AWS to resolve the {@link AwsCredentialsProvider}. * @@ -42,27 +42,26 @@ * @since 0.8.0 */ @AutoConfiguration -@ConditionalOnClass(Llama2ChatBedrockApi.class) -@EnableConfigurationProperties({ BedrockLlama2ChatProperties.class, BedrockAwsConnectionProperties.class }) -@ConditionalOnProperty(prefix = BedrockLlama2ChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true") +@ConditionalOnClass(LlamaChatBedrockApi.class) +@EnableConfigurationProperties({ BedrockLlamaChatProperties.class, BedrockAwsConnectionProperties.class }) +@ConditionalOnProperty(prefix = BedrockLlamaChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true") @Import(BedrockAwsConnectionConfiguration.class) -public class BedrockLlama2ChatAutoConfiguration { +public class BedrockLlamaChatAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class }) - public Llama2ChatBedrockApi llama2Api(AwsCredentialsProvider credentialsProvider, AwsRegionProvider regionProvider, - BedrockLlama2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) { - return new Llama2ChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(), + public LlamaChatBedrockApi llamaApi(AwsCredentialsProvider credentialsProvider, AwsRegionProvider regionProvider, + BedrockLlamaChatProperties properties, BedrockAwsConnectionProperties awsProperties) { + return new LlamaChatBedrockApi(properties.getModel(), credentialsProvider, regionProvider.getRegion(), new ObjectMapper(), awsProperties.getTimeout()); } @Bean - @ConditionalOnBean(Llama2ChatBedrockApi.class) - public BedrockLlama2ChatClient llama2ChatClient(Llama2ChatBedrockApi llama2Api, - BedrockLlama2ChatProperties properties) { + @ConditionalOnBean(LlamaChatBedrockApi.class) + public BedrockLlamaChatClient llamaChatClient(LlamaChatBedrockApi llamaApi, BedrockLlamaChatProperties properties) { - return new BedrockLlama2ChatClient(llama2Api, properties.getOptions()); + return new BedrockLlamaChatClient(llamaApi, properties.getOptions()); } } diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatProperties.java similarity index 63% rename from spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java rename to spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatProperties.java index a81f3a4af0c..f93b65aca32 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatProperties.java @@ -13,36 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.autoconfigure.bedrock.llama2; +package org.springframework.ai.autoconfigure.bedrock.llama; -import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatOptions; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; +import org.springframework.ai.bedrock.llama.BedrockLlamaChatOptions; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatModel; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; /** - * Configuration properties for Bedrock Llama2. + * Configuration properties for Bedrock Llama. * * @author Christian Tzolov * @since 0.8.0 */ -@ConfigurationProperties(BedrockLlama2ChatProperties.CONFIG_PREFIX) -public class BedrockLlama2ChatProperties { +@ConfigurationProperties(BedrockLlamaChatProperties.CONFIG_PREFIX) +public class BedrockLlamaChatProperties { - public static final String CONFIG_PREFIX = "spring.ai.bedrock.llama2.chat"; + public static final String CONFIG_PREFIX = "spring.ai.bedrock.llama.chat"; /** - * Enable Bedrock Llama2 chat client. Disabled by default. + * Enable Bedrock Llama chat client. Disabled by default. */ private boolean enabled = false; /** - * The generative id to use. See the {@link Llama2ChatModel} for the supported models. + * The generative id to use. See the {@link LlamaChatModel} for the supported models. */ - private String model = Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(); + private String model = LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(); @NestedConfigurationProperty - private BedrockLlama2ChatOptions options = BedrockLlama2ChatOptions.builder() + private BedrockLlamaChatOptions options = BedrockLlamaChatOptions.builder() .withTemperature(0.7f) .withMaxGenLen(300) .build(); @@ -63,11 +63,11 @@ public void setModel(String model) { this.model = model; } - public BedrockLlama2ChatOptions getOptions() { + public BedrockLlamaChatOptions getOptions() { return this.options; } - public void setOptions(BedrockLlama2ChatOptions options) { + public void setOptions(BedrockLlamaChatOptions options) { this.options = options; } diff --git a/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 59f104b6825..c2816002bcd 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -6,7 +6,7 @@ org.springframework.ai.autoconfigure.huggingface.HuggingfaceChatAutoConfiguratio org.springframework.ai.autoconfigure.vertexai.palm2.VertexAiPalm2AutoConfiguration org.springframework.ai.autoconfigure.vertexai.gemini.VertexAiGeminiAutoConfiguration org.springframework.ai.autoconfigure.bedrock.jurrasic2.BedrockAi21Jurassic2ChatAutoConfiguration -org.springframework.ai.autoconfigure.bedrock.llama2.BedrockLlama2ChatAutoConfiguration +org.springframework.ai.autoconfigure.bedrock.llama.BedrockLlamaChatAutoConfiguration org.springframework.ai.autoconfigure.bedrock.cohere.BedrockCohereChatAutoConfiguration org.springframework.ai.autoconfigure.bedrock.cohere.BedrockCohereEmbeddingAutoConfiguration org.springframework.ai.autoconfigure.bedrock.anthropic.BedrockAnthropicChatAutoConfiguration diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfigurationIT.java similarity index 61% rename from spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java rename to spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfigurationIT.java index 3c55877bcaf..6ca69b65599 100644 --- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java +++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama/BedrockLlamaChatAutoConfigurationIT.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.autoconfigure.bedrock.llama2; +package org.springframework.ai.autoconfigure.bedrock.llama; import java.util.List; import java.util.Map; @@ -27,8 +27,8 @@ import software.amazon.awssdk.regions.Region; import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties; -import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatClient; -import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatModel; +import org.springframework.ai.bedrock.llama.BedrockLlamaChatClient; +import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatModel; import org.springframework.ai.chat.Generation; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.SystemPromptTemplate; @@ -41,21 +41,22 @@ /** * @author Christian Tzolov + * @author Wei Jiang * @since 0.8.0 */ @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") @EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*") -public class BedrockLlama2ChatAutoConfigurationIT { +public class BedrockLlamaChatAutoConfigurationIT { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.ai.bedrock.llama2.chat.enabled=true", + .withPropertyValues("spring.ai.bedrock.llama.chat.enabled=true", "spring.ai.bedrock.aws.access-key=" + System.getenv("AWS_ACCESS_KEY_ID"), "spring.ai.bedrock.aws.secret-key=" + System.getenv("AWS_SECRET_ACCESS_KEY"), "spring.ai.bedrock.aws.region=" + Region.US_EAST_1.id(), - "spring.ai.bedrock.llama2.chat.model=" + Llama2ChatModel.LLAMA2_70B_CHAT_V1.id(), - "spring.ai.bedrock.llama2.chat.options.temperature=0.5", - "spring.ai.bedrock.llama2.chat.options.maxGenLen=500") - .withConfiguration(AutoConfigurations.of(BedrockLlama2ChatAutoConfiguration.class)); + "spring.ai.bedrock.llama.chat.model=" + LlamaChatModel.LLAMA3_70B_INSTRUCT_V1.id(), + "spring.ai.bedrock.llama.chat.options.temperature=0.5", + "spring.ai.bedrock.llama.chat.options.maxGenLen=500") + .withConfiguration(AutoConfigurations.of(BedrockLlamaChatAutoConfiguration.class)); private final Message systemMessage = new SystemPromptTemplate(""" You are a helpful AI assistant. Your name is {name}. @@ -70,8 +71,8 @@ public class BedrockLlama2ChatAutoConfigurationIT { @Test public void chatCompletion() { contextRunner.run(context -> { - BedrockLlama2ChatClient llama2ChatClient = context.getBean(BedrockLlama2ChatClient.class); - ChatResponse response = llama2ChatClient.call(new Prompt(List.of(userMessage, systemMessage))); + BedrockLlamaChatClient llamaChatClient = context.getBean(BedrockLlamaChatClient.class); + ChatResponse response = llamaChatClient.call(new Prompt(List.of(userMessage, systemMessage))); assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard"); }); } @@ -80,9 +81,9 @@ public void chatCompletion() { public void chatCompletionStreaming() { contextRunner.run(context -> { - BedrockLlama2ChatClient llama2ChatClient = context.getBean(BedrockLlama2ChatClient.class); + BedrockLlamaChatClient llamaChatClient = context.getBean(BedrockLlamaChatClient.class); - Flux response = llama2ChatClient.stream(new Prompt(List.of(userMessage, systemMessage))); + Flux response = llamaChatClient.stream(new Prompt(List.of(userMessage, systemMessage))); List responses = response.collectList().block(); assertThat(responses.size()).isGreaterThan(2); @@ -102,23 +103,23 @@ public void chatCompletionStreaming() { public void propertiesTest() { new ApplicationContextRunner() - .withPropertyValues("spring.ai.bedrock.llama2.chat.enabled=true", + .withPropertyValues("spring.ai.bedrock.llama.chat.enabled=true", "spring.ai.bedrock.aws.access-key=ACCESS_KEY", "spring.ai.bedrock.aws.secret-key=SECRET_KEY", - "spring.ai.bedrock.llama2.chat.model=MODEL_XYZ", + "spring.ai.bedrock.llama.chat.model=MODEL_XYZ", "spring.ai.bedrock.aws.region=" + Region.EU_CENTRAL_1.id(), - "spring.ai.bedrock.llama2.chat.options.temperature=0.55", - "spring.ai.bedrock.llama2.chat.options.maxGenLen=123") - .withConfiguration(AutoConfigurations.of(BedrockLlama2ChatAutoConfiguration.class)) + "spring.ai.bedrock.llama.chat.options.temperature=0.55", + "spring.ai.bedrock.llama.chat.options.maxGenLen=123") + .withConfiguration(AutoConfigurations.of(BedrockLlamaChatAutoConfiguration.class)) .run(context -> { - var llama2ChatProperties = context.getBean(BedrockLlama2ChatProperties.class); + var llamaChatProperties = context.getBean(BedrockLlamaChatProperties.class); var awsProperties = context.getBean(BedrockAwsConnectionProperties.class); - assertThat(llama2ChatProperties.isEnabled()).isTrue(); + assertThat(llamaChatProperties.isEnabled()).isTrue(); assertThat(awsProperties.getRegion()).isEqualTo(Region.EU_CENTRAL_1.id()); - assertThat(llama2ChatProperties.getOptions().getTemperature()).isEqualTo(0.55f); - assertThat(llama2ChatProperties.getOptions().getMaxGenLen()).isEqualTo(123); - assertThat(llama2ChatProperties.getModel()).isEqualTo("MODEL_XYZ"); + assertThat(llamaChatProperties.getOptions().getTemperature()).isEqualTo(0.55f); + assertThat(llamaChatProperties.getOptions().getMaxGenLen()).isEqualTo(123); + assertThat(llamaChatProperties.getModel()).isEqualTo("MODEL_XYZ"); assertThat(awsProperties.getAccessKey()).isEqualTo("ACCESS_KEY"); assertThat(awsProperties.getSecretKey()).isEqualTo("SECRET_KEY"); @@ -129,27 +130,26 @@ public void propertiesTest() { public void chatCompletionDisabled() { // It is disabled by default - new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(BedrockLlama2ChatAutoConfiguration.class)) + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(BedrockLlamaChatAutoConfiguration.class)) .run(context -> { - assertThat(context.getBeansOfType(BedrockLlama2ChatProperties.class)).isEmpty(); - assertThat(context.getBeansOfType(BedrockLlama2ChatClient.class)).isEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatProperties.class)).isEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatClient.class)).isEmpty(); }); // Explicitly enable the chat auto-configuration. - new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.llama2.chat.enabled=true") - .withConfiguration(AutoConfigurations.of(BedrockLlama2ChatAutoConfiguration.class)) + new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.llama.chat.enabled=true") + .withConfiguration(AutoConfigurations.of(BedrockLlamaChatAutoConfiguration.class)) .run(context -> { - assertThat(context.getBeansOfType(BedrockLlama2ChatProperties.class)).isNotEmpty(); - assertThat(context.getBeansOfType(BedrockLlama2ChatClient.class)).isNotEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatProperties.class)).isNotEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatClient.class)).isNotEmpty(); }); // Explicitly disable the chat auto-configuration. - new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.llama2.chat.enabled=false") - .withConfiguration(AutoConfigurations.of(BedrockLlama2ChatAutoConfiguration.class)) + new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.llama.chat.enabled=false") + .withConfiguration(AutoConfigurations.of(BedrockLlamaChatAutoConfiguration.class)) .run(context -> { - assertThat(context.getBeansOfType(BedrockLlama2ChatProperties.class)).isEmpty(); - assertThat(context.getBeansOfType(BedrockLlama2ChatClient.class)).isEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatProperties.class)).isEmpty(); + assertThat(context.getBeansOfType(BedrockLlamaChatClient.class)).isEmpty(); }); }