Add activation/deactivation auto-config property to all Model clients
Property is of format `*.enabled=` and is true by default. Note: the Bedrock clients are disabled by default. - Add deactivation support for Vertex AI PaLM2 clients - Add deactivation support for Azure OpenAI clients - Add deactivation support for huggingface chat client - Add deactivation support for Ollama clients - Add deactivation support for OpenAI clients - Add deactivation support for Stability Image and PostgresML clients - Add deactivation support for ONNX Transformers Embedding client Resolves #363
This commit is contained in:
@@ -94,6 +94,7 @@ The prefix `spring.ai.azure.openai.chat` is the property prefix that configures
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.azure.openai.chat.enabled | Enable Azure OpenAI chat client. | true
|
||||
| spring.ai.azure.openai.chat.options.model | * In use with Azure, this actually refers to the "Deployment Name" of your model, which you can find at https://oai.azure.com/portal. It's important to note that within an Azure OpenAI deployment, the "Deployment Name" is distinct from the model itself. The confusion around these terms stems from the intention to make the Azure OpenAI client library compatible with the original OpenAI endpoint. The deployment structures offered by Azure OpenAI and Sam Altman's OpenAI differ significantly. To clarify this distinction, we plan to rename this attribute to `deployment-name` in future updates.
|
||||
Deployments model name to provide as part of this completions request.
|
||||
| gpt-35-turbo
|
||||
|
||||
@@ -55,8 +55,9 @@ The prefix `spring.ai.openai.image` is the property prefix that lets you configu
|
||||
[cols="3,5,1"]
|
||||
|====
|
||||
| Property | Description | Default
|
||||
| spring.ai.openai.chat.base-url | Optional overrides the spring.ai.openai.base-url to provide chat specific url | -
|
||||
| spring.ai.openai.chat.api-key | Optional overrides the spring.ai.openai.api-key to provide chat specific api-key | -
|
||||
| spring.ai.openai.image.enabled | Enable OpenAI image client. | true
|
||||
| spring.ai.openai.image.base-url | Optional overrides the spring.ai.openai.base-url to provide chat specific url | -
|
||||
| spring.ai.openai.image.api-key | Optional overrides the spring.ai.openai.api-key to provide chat specific api-key | -
|
||||
| spring.ai.openai.image.options.n | The number of images to generate. Must be between 1 and 10. For dall-e-3, only n=1 is supported. | -
|
||||
| spring.ai.openai.image.options.model | The model to use for image generation. | OpenAiImageApi.DEFAULT_IMAGE_MODEL
|
||||
| spring.ai.openai.image.options.quality | The quality of the image that will be generated. HD creates images with finer details and greater consistency across the image. This parameter is only supported for dall-e-3. | -
|
||||
|
||||
@@ -57,19 +57,20 @@ The prefix `spring.ai.stabilityai.image` is the property prefix that lets you co
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| `spring.ai.stabilityai.image.base-url` | Optional overrides the spring.ai.openai.base-url to provide a specific url | `https://api.stability.ai/v1`
|
||||
| `spring.ai.stabilityai.image.api-key` | Optional overrides the spring.ai.openai.api-key to provide a specific api-key | -
|
||||
| `spring.ai.stabilityai.image.option.n` | The number of images to be generated. Must be between 1 and 10. | 1
|
||||
| `spring.ai.stabilityai.image.option.model` | The engine/model to use in Stability AI. The model is passed in the URL as a path parameter. | `stable-diffusion-v1-6`
|
||||
| `spring.ai.stabilityai.image.option.width` | Width of the image to generate, in pixels, in an increment divisible by 64. Engine-specific dimension validation applies. | 512
|
||||
| `spring.ai.stabilityai.image.option.height` | Height of the image to generate, in pixels, in an increment divisible by 64. Engine-specific dimension validation applies.| 512
|
||||
| `spring.ai.stabilityai.image.option.responseFormat` | The format in which the generated images are returned. Must be "application/json" or "image/png". | -
|
||||
| `spring.ai.stabilityai.image.option.cfg_scale` | The strictness level of the diffusion process adherence to the prompt text. Range: 0 to 35. | 7
|
||||
| `spring.ai.stabilityai.image.option.clip_guidance_preset` | Pass in a style preset to guide the image model towards a particular style. This list of style presets is subject to change. | `NONE`
|
||||
| `spring.ai.stabilityai.image.option.sampler` | Which sampler to use for the diffusion process. If this value is omitted, an appropriate sampler will be automatically selected. | -
|
||||
| `spring.ai.stabilityai.image.option.seed` | Random noise seed (omit this option or use 0 for a random seed). Valid range: 0 to 4294967295. | 0
|
||||
| `spring.ai.stabilityai.image.option.steps` | Number of diffusion steps to run. Valid range: 10 to 50. | 30
|
||||
| `spring.ai.stabilityai.image.option.style_preset` | Pass in a style preset to guide the image model towards a particular style. This list of style presets is subject to change. | -
|
||||
| spring.ai.stabilityai.image.enabled | Enable Stability AI image client. | true
|
||||
| spring.ai.stabilityai.image.base-url | Optional overrides the spring.ai.openai.base-url to provide a specific url | `https://api.stability.ai/v1`
|
||||
| spring.ai.stabilityai.image.api-key | Optional overrides the spring.ai.openai.api-key to provide a specific api-key | -
|
||||
| spring.ai.stabilityai.image.option.n | The number of images to be generated. Must be between 1 and 10. | 1
|
||||
| spring.ai.stabilityai.image.option.model | The engine/model to use in Stability AI. The model is passed in the URL as a path parameter. | `stable-diffusion-v1-6`
|
||||
| spring.ai.stabilityai.image.option.width | Width of the image to generate, in pixels, in an increment divisible by 64. Engine-specific dimension validation applies. | 512
|
||||
| spring.ai.stabilityai.image.option.height | Height of the image to generate, in pixels, in an increment divisible by 64. Engine-specific dimension validation applies.| 512
|
||||
| spring.ai.stabilityai.image.option.responseFormat | The format in which the generated images are returned. Must be "application/json" or "image/png". | -
|
||||
| spring.ai.stabilityai.image.option.cfg_scale | The strictness level of the diffusion process adherence to the prompt text. Range: 0 to 35. | 7
|
||||
| spring.ai.stabilityai.image.option.clip_guidance_preset | Pass in a style preset to guide the image model towards a particular style. This list of style presets is subject to change. | `NONE`
|
||||
| spring.ai.stabilityai.image.option.sampler | Which sampler to use for the diffusion process. If this value is omitted, an appropriate sampler will be automatically selected. | -
|
||||
| spring.ai.stabilityai.image.option.seed | Random noise seed (omit this option or use 0 for a random seed). Valid range: 0 to 4294967295. | 0
|
||||
| spring.ai.stabilityai.image.option.steps | Number of diffusion steps to run. Valid range: 10 to 50. | 30
|
||||
| spring.ai.stabilityai.image.option.style_preset | Pass in a style preset to guide the image model towards a particular style. This list of style presets is subject to change. | -
|
||||
|====
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ NOTE: The `options` properties are based on the link:https://github.com/jmorganc
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.ollama.chat.enabled | Enable Ollama chat client. | true
|
||||
| spring.ai.ollama.chat.model (DEPRECATED) | The name of the model to use. Deprecated use the `spring.ai.ollama.chat.options.model` instead | mistral
|
||||
| spring.ai.ollama.chat.options.model | The name of the https://github.com/ollama/ollama?tab=readme-ov-file#model-library[supported models] to use. | mistral
|
||||
| spring.ai.ollama.chat.options.numa | Whether to use NUMA. | false
|
||||
|
||||
@@ -65,6 +65,7 @@ The prefix `spring.ai.openai.chat` is the property prefix that lets you configur
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.openai.chat.enabled | Enable OpenAI chat client. | true
|
||||
| spring.ai.openai.chat.base-url | Optional overrides the spring.ai.openai.base-url to provide chat specific url | -
|
||||
| spring.ai.openai.chat.api-key | Optional overrides the spring.ai.openai.api-key to provide chat specific api-key | -
|
||||
| spring.ai.openai.chat.options.model | This is the OpenAI Chat model to use | `gpt-3.5-turbo` (the `gpt-3.5-turbo`, `gpt-4`, and `gpt-4-32k` point to the latest model versions)
|
||||
|
||||
@@ -67,6 +67,7 @@ The prefix `spring.ai.vertex.ai.chat` is the property prefix that lets you confi
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.vertex.ai.chat.enabled | Enable Vertex AI PaLM API Chat client. | true
|
||||
| spring.ai.vertex.ai.chat.model | This is the https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text-chat[Vertex Chat model] to use | chat-bison-001
|
||||
| spring.ai.vertex.ai.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 generative. This value specifies default to be used by the backend while making the call to the generative. | 0.7
|
||||
| spring.ai.vertex.ai.chat.options.topK | The maximum number of tokens to consider when sampling. The generative uses combined Top-k and nucleus sampling. Top-k sampling considers the set of topK most probable tokens. | 20
|
||||
|
||||
@@ -72,6 +72,7 @@ The prefix `spring.ai.azure.openai.embeddings` is the property prefix that confi
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.azure.openai.embedding.enabled | Enable Azure OpenAI embedding client. | true
|
||||
| spring.ai.azure.openai.embedding.metadata-mode | Document content extraction mode | EMBED
|
||||
| spring.ai.azure.openai.embedding.options.model | This is the value of the 'Deployment Name' as presented in the Azure AI Portal | text-embedding-ada-002
|
||||
| spring.ai.azure.openai.embedding.options.user | An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. | -
|
||||
|
||||
@@ -66,6 +66,7 @@ The prefix `spring.ai.ollama.embedding.options` is the property prefix that conf
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.ollama.embedding.enabled | Enable Ollama embedding client. | true
|
||||
| spring.ai.ollama.embedding.model (DEPRECATED) | The name of the model to use. Deprecated use the `spring.ai.ollama.embedding.options.model` instead | mistral
|
||||
| spring.ai.ollama.embedding.options.model | The name of the https://github.com/ollama/ollama?tab=readme-ov-file#model-library[supported models] to use. | mistral
|
||||
| spring.ai.ollama.embedding.options.numa | Whether to use NUMA. | false
|
||||
|
||||
@@ -127,6 +127,8 @@ The complete list of supported properties are:
|
||||
[cols="3*"]
|
||||
|===
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.embedding.transformer.enabled | Enable the Transformer Embedding client. | true
|
||||
| spring.ai.embedding.transformer.tokenizer.uri | URI of a pre-trained HuggingFaceTokenizer created by the ONNX engine (e.g. tokenizer.json). | onnx/all-MiniLM-L6-v2/tokenizer.json
|
||||
| spring.ai.embedding.transformer.tokenizer.options | HuggingFaceTokenizer options such as '`addSpecialTokens`', '`modelMaxLength`', '`truncation`', '`padding`', '`maxLength`', '`stride`', '`padToMultipleOf`'. Leave empty to fallback to the defaults. | empty
|
||||
| spring.ai.embedding.transformer.cache.enabled | Enable remote Resource caching. | true
|
||||
|
||||
@@ -65,6 +65,8 @@ The prefix `spring.ai.openai.embedding` is property prefix that configures the `
|
||||
[cols="3,5,1"]
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.openai.embedding.enabled | Enable OpenAI embedding client. | true
|
||||
| spring.ai.openai.embedding.base-url | Optional overrides the spring.ai.openai.base-url to provide embedding specific url | -
|
||||
| spring.ai.openai.embedding.api-key | Optional overrides the spring.ai.openai.api-key to provide embedding specific api-key | -
|
||||
| spring.ai.openai.embedding.metadata-mode | Document content extraction mode. | EMBED
|
||||
|
||||
@@ -49,6 +49,7 @@ The prefix `spring.ai.postgresml.embedding` is property prefix that configures t
|
||||
[cols="3,5,1"]
|
||||
|====
|
||||
| Property | Description | Default
|
||||
| spring.ai.postgresml.embedding.enabled | Enable PostgresML embedding client. | true
|
||||
| spring.ai.postgresml.embedding.options.transformer | The Huggingface transformer model to use for the embedding. | distilbert-base-uncased
|
||||
| spring.ai.postgresml.embedding.options.kwargs | Additional transformer specific options. | empty map
|
||||
| spring.ai.postgresml.embedding.options.vectorType | PostgresML vector type to use for the embedding. Two options are supported: `PG_ARRAY` and `PG_VECTOR`. | PG_ARRAY
|
||||
|
||||
@@ -49,7 +49,7 @@ dependencies {
|
||||
|
||||
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
|
||||
|
||||
=== Chat Properties
|
||||
=== Embedding Properties
|
||||
|
||||
The prefix `spring.ai.vertex.ai` is used as the property prefix that lets you connect to VertexAI.
|
||||
|
||||
@@ -61,13 +61,14 @@ The prefix `spring.ai.vertex.ai` is used as the property prefix that lets you co
|
||||
| spring.ai.vertex.ai.api-key | The API Key | -
|
||||
|====
|
||||
|
||||
The prefix `spring.ai.vertex.ai.chat` is the property prefix that lets you configure the chat client implementation for VertexAI Chat.
|
||||
The prefix `spring.ai.vertex.ai.embedding` is the property prefix that lets you configure the embedding client implementation for VertexAI Chat.
|
||||
|
||||
[cols="3,5,1"]
|
||||
|====
|
||||
| Property | Description | Default
|
||||
|
||||
| spring.ai.vertex.ai.chat.model | This is the https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text-embeddings[Vertex Embedding model] to use | chat-bison-001
|
||||
| spring.ai.vertex.ai.embedding.enabled | Enable Vertex AI PaLM API Embedding client. | true
|
||||
| spring.ai.vertex.ai.embedding.model | This is the https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text-embeddings[Vertex Embedding model] to use | embedding-gecko-001
|
||||
|====
|
||||
|
||||
|
||||
@@ -80,13 +81,13 @@ Add a `application.properties` file, under the `src/main/resources` directory, t
|
||||
[source,application.properties]
|
||||
----
|
||||
spring.ai.vertex.ai.api-key=YOUR_API_KEY
|
||||
spring.ai.vertex.ai.embedding.model=chat-bison-001
|
||||
spring.ai.vertex.ai.embedding.model=embedding-gecko-001
|
||||
----
|
||||
|
||||
TIP: replace the `api-key` with your VertexAI credentials.
|
||||
|
||||
This will create a `VertexAiEmbeddingClient` 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.
|
||||
Here is an example of a simple `@Controller` class that uses the embedding client for text generations.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -149,7 +150,7 @@ EmbeddingResponse embeddingResponse = embeddingClient
|
||||
|
||||
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai/src/main/java/org/springframework/ai/vertex/api/VertexAiApi.java[VertexAiApi] provides is lightweight Java client for VertexAiApi Chat API.
|
||||
|
||||
Following class diagram illustrates the `VertexAiApi` chat interfaces and building blocks:
|
||||
Following class diagram illustrates the `VertexAiApi` embedding interfaces and building blocks:
|
||||
|
||||
image::vertex-ai-chat-low-level-api.jpg[w=800,align="center"]
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -50,6 +51,8 @@ public class AzureOpenAiAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = AzureOpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public AzureOpenAiChatClient azureOpenAiChatClient(OpenAIClient openAIClient,
|
||||
AzureOpenAiChatProperties chatProperties) {
|
||||
|
||||
@@ -60,6 +63,8 @@ public class AzureOpenAiAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = AzureOpenAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public AzureOpenAiEmbeddingClient azureOpenAiEmbeddingClient(OpenAIClient openAIClient,
|
||||
AzureOpenAiEmbeddingProperties embeddingProperties) {
|
||||
return new AzureOpenAiEmbeddingClient(openAIClient, embeddingProperties.getMetadataMode(),
|
||||
|
||||
@@ -29,6 +29,11 @@ public class AzureOpenAiChatProperties {
|
||||
|
||||
private static final Double DEFAULT_TEMPERATURE = 0.7;
|
||||
|
||||
/**
|
||||
* Enable Azure OpenAI chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
|
||||
.withModel(DEFAULT_CHAT_MODEL)
|
||||
@@ -43,4 +48,12 @@ public class AzureOpenAiChatProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ public class AzureOpenAiEmbeddingProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.azure.openai.embedding";
|
||||
|
||||
/**
|
||||
* Enable Azure OpenAI embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
private AzureOpenAiEmbeddingOptions options = AzureOpenAiEmbeddingOptions.builder()
|
||||
.withModel("text-embedding-ada-002")
|
||||
.build();
|
||||
@@ -50,4 +55,12 @@ public class AzureOpenAiEmbeddingProperties {
|
||||
this.metadataMode = metadataMode;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
* Copyright 2023-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,8 @@ package org.springframework.ai.autoconfigure.huggingface;
|
||||
import org.springframework.ai.huggingface.HuggingfaceChatClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -27,13 +29,10 @@ import org.springframework.context.annotation.Bean;
|
||||
@EnableConfigurationProperties(HuggingfaceChatProperties.class)
|
||||
public class HuggingfaceChatAutoConfiguration {
|
||||
|
||||
private final HuggingfaceChatProperties huggingfaceChatProperties;
|
||||
|
||||
public HuggingfaceChatAutoConfiguration(HuggingfaceChatProperties huggingfaceChatProperties) {
|
||||
this.huggingfaceChatProperties = huggingfaceChatProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = HuggingfaceChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public HuggingfaceChatClient huggingfaceChatClient(HuggingfaceChatProperties huggingfaceChatProperties) {
|
||||
return new HuggingfaceChatClient(huggingfaceChatProperties.getApiKey(), huggingfaceChatProperties.getUrl());
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@ public class HuggingfaceChatProperties {
|
||||
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* Enable Huggingface chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
@@ -27,4 +32,12 @@ public class HuggingfaceChatProperties {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.ai.ollama.api.OllamaApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -45,6 +46,9 @@ public class OllamaAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OllamaChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OllamaChatClient ollamaChatClient(OllamaApi ollamaApi, OllamaChatProperties properties) {
|
||||
|
||||
return new OllamaChatClient(ollamaApi).withModel(properties.getModel())
|
||||
@@ -53,6 +57,8 @@ public class OllamaAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OllamaEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OllamaEmbeddingClient ollamaEmbeddingClient(OllamaApi ollamaApi, OllamaEmbeddingProperties properties) {
|
||||
|
||||
return new OllamaEmbeddingClient(ollamaApi).withModel(properties.getModel())
|
||||
|
||||
@@ -31,6 +31,11 @@ public class OllamaChatProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.ollama.chat";
|
||||
|
||||
/**
|
||||
* Enable Ollama chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Client lever Ollama options. Use this property to configure generative temperature,
|
||||
* topK and topP and alike parameters. The null values are ignored defaulting to the
|
||||
@@ -51,4 +56,12 @@ public class OllamaChatProperties {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ public class OllamaEmbeddingProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.ollama.embedding";
|
||||
|
||||
/**
|
||||
* Enable Ollama embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Client lever Ollama options. Use this property to configure generative temperature,
|
||||
* topK and topP and alike parameters. The null values are ignored defaulting to the
|
||||
@@ -48,7 +53,15 @@ public class OllamaEmbeddingProperties {
|
||||
}
|
||||
|
||||
public OllamaOptions getOptions() {
|
||||
return options;
|
||||
return this.options;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ai.openai.api.OpenAiImageApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -53,6 +54,8 @@ public class OpenAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OpenAiChatClient openAiChatClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext) {
|
||||
@@ -77,6 +80,8 @@ public class OpenAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OpenAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public EmbeddingClient openAiEmbeddingClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder) {
|
||||
|
||||
@@ -96,6 +101,8 @@ public class OpenAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OpenAiImageProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OpenAiImageClient openAiImageClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiImageProperties imageProperties, RestClient.Builder restClientBuilder) {
|
||||
String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey()
|
||||
|
||||
@@ -29,6 +29,11 @@ public class OpenAiChatProperties extends OpenAiParentProperties {
|
||||
|
||||
private static final Double DEFAULT_TEMPERATURE = 0.7;
|
||||
|
||||
/**
|
||||
* Enable OpenAI chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private OpenAiChatOptions options = OpenAiChatOptions.builder()
|
||||
.withModel(DEFAULT_CHAT_MODEL)
|
||||
@@ -43,4 +48,12 @@ public class OpenAiChatProperties extends OpenAiParentProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
* Copyright 2023-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,6 +28,11 @@ public class OpenAiEmbeddingProperties extends OpenAiParentProperties {
|
||||
|
||||
public static final String DEFAULT_EMBEDDING_MODEL = "text-embedding-ada-002";
|
||||
|
||||
/**
|
||||
* Enable OpenAI embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
private MetadataMode metadataMode = MetadataMode.EMBED;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
@@ -36,7 +41,7 @@ public class OpenAiEmbeddingProperties extends OpenAiParentProperties {
|
||||
.build();
|
||||
|
||||
public OpenAiEmbeddingOptions getOptions() {
|
||||
return options;
|
||||
return this.options;
|
||||
}
|
||||
|
||||
public void setOptions(OpenAiEmbeddingOptions options) {
|
||||
@@ -44,11 +49,19 @@ public class OpenAiEmbeddingProperties extends OpenAiParentProperties {
|
||||
}
|
||||
|
||||
public MetadataMode getMetadataMode() {
|
||||
return metadataMode;
|
||||
return this.metadataMode;
|
||||
}
|
||||
|
||||
public void setMetadataMode(MetadataMode metadataMode) {
|
||||
this.metadataMode = metadataMode;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ public class OpenAiImageProperties extends OpenAiParentProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.openai.image";
|
||||
|
||||
/**
|
||||
* Enable OpenAI Image client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Options for OpenAI Image API.
|
||||
*/
|
||||
@@ -45,4 +50,12 @@ public class OpenAiImageProperties extends OpenAiParentProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2024 - 2024 the original author or authors.
|
||||
* Copyright 2024-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import org.springframework.ai.postgresml.PostgresMlEmbeddingClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -38,6 +39,8 @@ public class PostgresMlAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = PostgresMlEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public EmbeddingClient postgresMlEmbeddingClient(JdbcTemplate jdbcTemplate,
|
||||
PostgresMlEmbeddingProperties embeddingProperties) {
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ public class PostgresMlEmbeddingProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.postgresml.embedding";
|
||||
|
||||
/**
|
||||
* Enable Postgres ML embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private PostgresMlEmbeddingOptions options = PostgresMlEmbeddingOptions.builder()
|
||||
.withTransformer(PostgresMlEmbeddingClient.DEFAULT_TRANSFORMER_MODEL)
|
||||
@@ -57,4 +62,12 @@ public class PostgresMlEmbeddingProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.ai.stabilityai.api.StabilityAiApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -28,9 +29,9 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Pollack
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
|
||||
@AutoConfiguration(after = { RestClientAutoConfiguration.class })
|
||||
@ConditionalOnClass(StabilityAiApi.class)
|
||||
@EnableConfigurationProperties({ StabilityAiConnectionProperties.class, StabilityAiImageProperties.class })
|
||||
@@ -55,6 +56,8 @@ public class StabilityAiImageAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = StabilityAiImageProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public StabilityAiImageClient stabilityAiImageClient(StabilityAiApi stabilityAiApi,
|
||||
StabilityAiImageProperties stabilityAiImageProperties) {
|
||||
return new StabilityAiImageClient(stabilityAiApi, stabilityAiImageProperties.getOptions());
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
|
||||
/**
|
||||
* @author Mark Pollack
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
@ConfigurationProperties(StabilityAiImageProperties.CONFIG_PREFIX)
|
||||
@@ -28,6 +29,11 @@ public class StabilityAiImageProperties extends StabilityAiParentProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.stabilityai.image";
|
||||
|
||||
/**
|
||||
* Enable Stability Image client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private StabilityAiImageOptions options = StabilityAiImageOptions.builder().build(); // stable-diffusion-v1-6
|
||||
// is
|
||||
@@ -42,4 +48,12 @@ public class StabilityAiImageProperties extends StabilityAiParentProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.ai.transformers.TransformersEmbeddingClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -37,6 +38,8 @@ public class TransformersEmbeddingClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = TransformersEmbeddingClientProperties.CONFIG_PREFIX, name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public EmbeddingClient embeddingClient(TransformersEmbeddingClientProperties properties) {
|
||||
|
||||
TransformersEmbeddingClient embeddingClient = new TransformersEmbeddingClient(properties.getMetadataMode());
|
||||
|
||||
@@ -43,6 +43,19 @@ public class TransformersEmbeddingClientProperties {
|
||||
"spring-ai-onnx-generative")
|
||||
.getAbsolutePath();
|
||||
|
||||
/**
|
||||
* Enable the Transformer Embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configurations for the {@link HuggingFaceTokenizer} used to convert sentences into
|
||||
* tokens.
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.ai.vertex.api.VertexAiApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -45,12 +46,16 @@ public class VertexAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = VertexAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public VertexAiChatClient vertexAiChatClient(VertexAiApi vertexAiApi, VertexAiChatProperties chatProperties) {
|
||||
return new VertexAiChatClient(vertexAiApi, chatProperties.getOptions());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = VertexAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public VertexAiEmbeddingClient vertexAiEmbeddingClient(VertexAiApi vertexAiApi) {
|
||||
return new VertexAiEmbeddingClient(vertexAiApi);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ public class VertexAiChatProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.vertex.ai.chat";
|
||||
|
||||
/**
|
||||
* Enable Vertex AI PaLM API chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Vertex AI PaLM API generative name. Defaults to chat-bison-001
|
||||
*/
|
||||
@@ -56,4 +61,12 @@ public class VertexAiChatProperties {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ public class VertexAiEmbeddingProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.vertex.ai.embedding";
|
||||
|
||||
/**
|
||||
* Enable Vertex AI PaLM API embedding client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Vertex AI PaLM API embedding generative name. Defaults to embedding-gecko-001.
|
||||
*/
|
||||
@@ -37,4 +42,12 @@ public class VertexAiEmbeddingProperties {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -123,4 +123,42 @@ public class AzureOpenAiAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatActivation() {
|
||||
|
||||
// Disable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.chat.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiChatClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
// The chat auto-configuration is enabled by default.
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.chat.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddingActivation() {
|
||||
|
||||
// Disable the embedding auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.embedding.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
// The embedding auto-configuration is enabled by default.
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the embedding auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.embedding.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
@Disabled("For manual smoke testing only.")
|
||||
@Testcontainers
|
||||
public class OllamaAutoConfigurationIT {
|
||||
public class OllamaChatAutoConfigurationIT {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(OllamaAutoConfigurationIT.class);
|
||||
private static final Log logger = LogFactory.getLog(OllamaChatAutoConfigurationIT.class);
|
||||
|
||||
private static String MODEL_NAME = "mistral";
|
||||
|
||||
@@ -120,4 +120,22 @@ public class OllamaAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void chatActivation() {
|
||||
contextRunner.withPropertyValues("spring.ai.ollama.chat.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaChatClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaChatClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
contextRunner.withPropertyValues("spring.ai.ollama.chat.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaChatClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class OllamaAutoConfigurationTests {
|
||||
public class OllamaChatAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void propertiesTest() {
|
||||
@@ -16,22 +16,23 @@
|
||||
|
||||
package org.springframework.ai.autoconfigure.ollama;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.ai.embedding.EmbeddingResponse;
|
||||
import org.springframework.ai.ollama.OllamaEmbeddingClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -78,4 +79,23 @@ public class OllamaEmbeddingAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddingActivation() {
|
||||
contextRunner.withPropertyValues("spring.ai.ollama.embedding.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
contextRunner.withPropertyValues("spring.ai.ollama.embedding.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OllamaEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ai.openai.OpenAiChatClient;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.OpenAiImageClient;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ResponseFormat;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ToolChoice;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.FunctionTool.Type;
|
||||
@@ -348,4 +351,94 @@ public class OpenAiPropertiesTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddingActivation() {
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.embedding.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.embedding.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void chatActivation() {
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.chat.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.chat.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void imageActivation() {
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.image.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
|
||||
"spring.ai.openai.image.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,4 +84,31 @@ public class PostgresMlAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddingActivation() {
|
||||
new ApplicationContextRunner().withBean(JdbcTemplate.class, () -> jdbcTemplate)
|
||||
.withConfiguration(AutoConfigurations.of(PostgresMlAutoConfiguration.class))
|
||||
.withPropertyValues("spring.ai.postgresml.embedding.enabled=false")
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner().withBean(JdbcTemplate.class, () -> jdbcTemplate)
|
||||
.withConfiguration(AutoConfigurations.of(PostgresMlAutoConfiguration.class))
|
||||
.withPropertyValues("spring.ai.postgresml.embedding.enabled=true")
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
new ApplicationContextRunner().withBean(JdbcTemplate.class, () -> jdbcTemplate)
|
||||
.withConfiguration(AutoConfigurations.of(PostgresMlAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(PostgresMlEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
package org.springframework.ai.autoconfigure.stabilityai;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration;
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties;
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiConnectionProperties;
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiEmbeddingProperties;
|
||||
|
||||
import org.springframework.ai.stabilityai.StabilityAiImageClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
@@ -37,9 +35,9 @@ public class StabilityAiImagePropertiesTests {
|
||||
|
||||
new ApplicationContextRunner().withPropertyValues(
|
||||
// @formatter:off
|
||||
"spring.ai.stabilityai.image.api-key=API_KEY",
|
||||
"spring.ai.stabilityai.image.api-key=API_KEY",
|
||||
"spring.ai.stabilityai.image.base-url=ENDPOINT",
|
||||
"spring.ai.stabilityai.image.options.n=10",
|
||||
"spring.ai.stabilityai.image.options.n=10",
|
||||
"spring.ai.stabilityai.image.options.model=MODEL_XYZ",
|
||||
"spring.ai.stabilityai.image.options.width=512",
|
||||
"spring.ai.stabilityai.image.options.height=256",
|
||||
@@ -74,4 +72,39 @@ public class StabilityAiImagePropertiesTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void stabilityImageActivation() {
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.stabilityai.image.api-key=API_KEY",
|
||||
"spring.ai.stabilityai.image.base-url=ENDPOINT", "spring.ai.stabilityai.image.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(StabilityAiImageAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(StabilityAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(StabilityAiImageClient.class)).isEmpty();
|
||||
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.stabilityai.image.api-key=API_KEY",
|
||||
"spring.ai.stabilityai.image.base-url=ENDPOINT")
|
||||
.withConfiguration(AutoConfigurations.of(StabilityAiImageAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(StabilityAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(StabilityAiImageClient.class)).isNotEmpty();
|
||||
|
||||
});
|
||||
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.ai.stabilityai.image.api-key=API_KEY",
|
||||
"spring.ai.stabilityai.image.base-url=ENDPOINT", "spring.ai.stabilityai.image.enabled=true")
|
||||
.withConfiguration(AutoConfigurations.of(StabilityAiImageAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(StabilityAiImageProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(StabilityAiImageClient.class)).isNotEmpty();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,4 +89,23 @@ public class TransformersEmbeddingClientAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void embeddingActivation() {
|
||||
contextRunner.withPropertyValues("spring.ai.embedding.transformer.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClientProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
contextRunner.withPropertyValues("spring.ai.embedding.transformer.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClientProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClientProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(TransformersEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
|
||||
import org.springframework.ai.embedding.EmbeddingResponse;
|
||||
import org.springframework.ai.vertex.VertexAiEmbeddingClient;
|
||||
import org.springframework.ai.vertex.VertexAiChatClient;
|
||||
import org.springframework.ai.vertex.VertexAiEmbeddingClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
@@ -73,4 +73,48 @@ public class VertexAiAutoConfigurationIT {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddingActivation() {
|
||||
|
||||
// Disable the embedding auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.vertex.ai.embedding.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
// The embedding auto-configuration is enabled by default.
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the embedding auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.vertex.ai.embedding.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiEmbeddingClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatActivation() {
|
||||
|
||||
// Disable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.vertex.ai.chat.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiChatClient.class)).isEmpty();
|
||||
});
|
||||
|
||||
// The chat auto-configuration is enabled by default.
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.vertex.ai.chat.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(VertexAiChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(VertexAiChatClient.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user