diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java index e925b305226..4555aa78d46 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatModelIT.java @@ -410,7 +410,7 @@ private String getApiKey() { @Bean public AnthropicChatModel openAiChatModel(AnthropicApi api) { - return new AnthropicChatModel(api); + return AnthropicChatModel.builder().anthropicApi(api).build(); } } diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicTestConfiguration.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicTestConfiguration.java index e90a94f8764..62e5663cf53 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicTestConfiguration.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicTestConfiguration.java @@ -40,8 +40,7 @@ private String getApiKey() { @Bean public AnthropicChatModel anthropicChatModel(AnthropicApi api) { - AnthropicChatModel anthropicChatModel = new AnthropicChatModel(api); - return anthropicChatModel; + return AnthropicChatModel.builder().anthropicApi(api).build(); } } diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java index 7222d6b9fec..facbaf39411 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatModel.java @@ -161,47 +161,6 @@ public class AzureOpenAiChatModel extends AbstractToolCallSupport implements Cha */ private final ToolCallingManager toolCallingManager; - @Deprecated - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder) { - this(openAIClientBuilder, - AzureOpenAiChatOptions.builder() - .deploymentName(DEFAULT_DEPLOYMENT_NAME) - .temperature(DEFAULT_TEMPERATURE) - .build()); - } - - @Deprecated - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder, AzureOpenAiChatOptions options) { - this(openAIClientBuilder, options, null); - } - - @Deprecated - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder, AzureOpenAiChatOptions options, - FunctionCallbackResolver functionCallbackResolver) { - this(openAIClientBuilder, options, functionCallbackResolver, List.of()); - } - - @Deprecated - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder, AzureOpenAiChatOptions options, - @Nullable FunctionCallbackResolver functionCallbackResolver, - @Nullable List toolFunctionCallbacks) { - this(openAIClientBuilder, options, functionCallbackResolver, toolFunctionCallbacks, ObservationRegistry.NOOP); - } - - @Deprecated - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder, AzureOpenAiChatOptions options, - @Nullable FunctionCallbackResolver functionCallbackResolver, - @Nullable List toolFunctionCallbacks, ObservationRegistry observationRegistry) { - this(openAIClientBuilder, options, - LegacyToolCallingManager.builder() - .functionCallbackResolver(functionCallbackResolver) - .functionCallbacks(toolFunctionCallbacks) - .build(), - observationRegistry); - logger.warn("This constructor is deprecated and will be removed in the next milestone. " - + "Please use the AzureOpenAiChatModel.Builder or the new constructor accepting ToolCallingManager instead."); - } - public AzureOpenAiChatModel(OpenAIClientBuilder openAIClientBuilder, AzureOpenAiChatOptions defaultOptions, ToolCallingManager toolCallingManager, ObservationRegistry observationRegistry) { // We do not pass the 'defaultOptions' to the AbstractToolSupport, diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseUsageAggregationTests.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseUsageAggregationTests.java index 25a44b63afe..8066439cf96 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseUsageAggregationTests.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseUsageAggregationTests.java @@ -61,8 +61,10 @@ public class BedrockConverseUsageAggregationTests { @BeforeEach public void beforeEach() { - this.chatModel = new BedrockProxyChatModel(this.bedrockRuntimeClient, this.bedrockRuntimeAsyncClient, - FunctionCallingOptions.builder().build(), null, List.of(), ObservationRegistry.NOOP); + this.chatModel = BedrockProxyChatModel.builder() + .bedrockRuntimeClient(this.bedrockRuntimeClient) + .bedrockRuntimeAsyncClient(this.bedrockRuntimeAsyncClient) + .build(); } @Test diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java index aefcf6a728b..ceb94457e2e 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java @@ -35,6 +35,7 @@ import org.springframework.ai.chat.observation.DefaultChatModelObservationConvention; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.ai.observation.conventions.AiOperationType; import org.springframework.ai.observation.conventions.AiProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -170,10 +171,10 @@ public BedrockProxyChatModel bedrockConverseChatModel(ObservationRegistry observ String modelId = "anthropic.claude-3-5-sonnet-20240620-v1:0"; return BedrockProxyChatModel.builder() - .withCredentialsProvider(EnvironmentVariableCredentialsProvider.create()) - .withRegion(Region.US_EAST_1) - .withObservationRegistry(observationRegistry) - .withDefaultOptions(FunctionCallingOptions.builder().model(modelId).build()) + .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) + .region(Region.US_EAST_1) + .observationRegistry(observationRegistry) + .defaultOptions(ToolCallingChatOptions.builder().model(modelId).build()) .build(); } diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain.java index e9008c0ced5..7253627b463 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain.java @@ -43,8 +43,8 @@ public static void main(String[] args) { var prompt = new Prompt("Tell me a joke?", ChatOptions.builder().model(modelId).build()); var chatModel = BedrockProxyChatModel.builder() - .withCredentialsProvider(EnvironmentVariableCredentialsProvider.create()) - .withRegion(Region.US_EAST_1) + .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) + .region(Region.US_EAST_1) .build(); var chatResponse = chatModel.call(prompt); diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain3.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain3.java index daee808fbb6..d81393bad18 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain3.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiments/BedrockConverseChatModelMain3.java @@ -58,8 +58,8 @@ public static void main(String[] args) { .build()); BedrockProxyChatModel chatModel = BedrockProxyChatModel.builder() - .withCredentialsProvider(EnvironmentVariableCredentialsProvider.create()) - .withRegion(Region.US_EAST_1) + .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) + .region(Region.US_EAST_1) .build(); var response = chatModel.call(prompt); diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java index c14f8ae0f31..0c1e8e2af72 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java @@ -120,48 +120,6 @@ public class MistralAiChatModel extends AbstractToolCallSupport implements ChatM */ private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION; - /** - * @deprecated Use {@link MistralAiChatModel.Builder}. - */ - @Deprecated - public MistralAiChatModel(MistralAiApi mistralAiApi) { - this(mistralAiApi, - MistralAiChatOptions.builder() - .temperature(0.7) - .topP(1.0) - .safePrompt(false) - .model(MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) - .build()); - } - - /** - * @deprecated Use {@link MistralAiChatModel.Builder}. - */ - @Deprecated - public MistralAiChatModel(MistralAiApi mistralAiApi, MistralAiChatOptions options) { - this(mistralAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE); - } - - /** - * @deprecated Use {@link MistralAiChatModel.Builder}. - */ - @Deprecated - public MistralAiChatModel(MistralAiApi mistralAiApi, MistralAiChatOptions options, - @Nullable FunctionCallbackResolver functionCallbackResolver, @Nullable RetryTemplate retryTemplate) { - this(mistralAiApi, options, functionCallbackResolver, List.of(), retryTemplate); - } - - /** - * @deprecated Use {@link MistralAiChatModel.Builder}. - */ - @Deprecated - public MistralAiChatModel(MistralAiApi mistralAiApi, MistralAiChatOptions options, - @Nullable FunctionCallbackResolver functionCallbackResolver, - @Nullable List toolFunctionCallbacks, RetryTemplate retryTemplate) { - this(mistralAiApi, options, functionCallbackResolver, toolFunctionCallbacks, retryTemplate, - ObservationRegistry.NOOP); - } - /** * @deprecated Use {@link MistralAiChatModel.Builder}. */ @@ -589,7 +547,7 @@ public static class Builder { .temperature(0.7) .topP(1.0) .safePrompt(false) - .model(MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) + .model(MistralAiApi.ChatModel.SMALL.getValue()) .build(); private ToolCallingManager toolCallingManager; diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java index 0be9617d590..4ca18dab2b6 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java @@ -265,12 +265,6 @@ public enum ChatCompletionFinishReason { public enum ChatModel implements ChatModelDescription { // @formatter:off - @Deprecated(forRemoval = true, since = "1.0.0-M6") - OPEN_MISTRAL_7B("open-mistral-7b"), - @Deprecated(forRemoval = true, since = "1.0.0-M6") - OPEN_MIXTRAL_7B("open-mixtral-8x7b"), - @Deprecated(forRemoval = true, since = "1.0.0-M6") - OPEN_MIXTRAL_22B("open-mixtral-8x22b"), // Premier Models CODESTRAL("codestral-latest"), LARGE("mistral-large-latest"), diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelObservationIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelObservationIT.java index 702f84874e5..459e2720376 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelObservationIT.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatModelObservationIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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. @@ -70,7 +70,7 @@ void beforeEach() { @Test void observationForChatOperation() { var options = MistralAiChatOptions.builder() - .model(MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) + .model(MistralAiApi.ChatModel.SMALL.getValue()) .maxTokens(2048) .stop(List.of("this-is-the-end")) .temperature(0.7) @@ -91,7 +91,7 @@ void observationForChatOperation() { @Test void observationForStreamingChatOperation() { var options = MistralAiChatOptions.builder() - .model(MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) + .model(MistralAiApi.ChatModel.SMALL.getValue()) .maxTokens(2048) .stop(List.of("this-is-the-end")) .temperature(0.7) @@ -125,12 +125,12 @@ private void validate(ChatResponseMetadata responseMetadata) { .doesNotHaveAnyRemainingCurrentObservation() .hasObservationWithNameEqualTo(DefaultChatModelObservationConvention.DEFAULT_NAME) .that() - .hasContextualNameEqualTo("chat " + MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) + .hasContextualNameEqualTo("chat " + MistralAiApi.ChatModel.SMALL.getValue()) .hasLowCardinalityKeyValue(LowCardinalityKeyNames.AI_OPERATION_TYPE.asString(), AiOperationType.CHAT.value()) .hasLowCardinalityKeyValue(LowCardinalityKeyNames.AI_PROVIDER.asString(), AiProvider.MISTRAL_AI.value()) .hasLowCardinalityKeyValue(LowCardinalityKeyNames.REQUEST_MODEL.asString(), - MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) + MistralAiApi.ChatModel.SMALL.getValue()) .hasLowCardinalityKeyValue(LowCardinalityKeyNames.RESPONSE_MODEL.asString(), StringUtils.hasText(responseMetadata.getModel()) ? responseMetadata.getModel() : KeyValue.NONE_VALUE) @@ -181,9 +181,13 @@ public MistralAiApi mistralAiApi() { @Bean public MistralAiChatModel openAiChatModel(MistralAiApi mistralAiApi, TestObservationRegistry observationRegistry) { - return new MistralAiChatModel(mistralAiApi, MistralAiChatOptions.builder().build(), - new DefaultFunctionCallbackResolver(), List.of(), RetryTemplate.defaultInstance(), - observationRegistry); + return MistralAiChatModel.builder() + .mistralAiApi(mistralAiApi) + .defaultOptions(MistralAiChatOptions.builder().build()) + .functionCallbackResolver(new DefaultFunctionCallbackResolver()) + .retryTemplate(RetryTemplate.defaultInstance()) + .observationRegistry(observationRegistry) + .build(); } } diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java index 27495508c7f..13dd882e3af 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java @@ -77,14 +77,16 @@ public void beforeEach() { this.retryListener = new TestRetryListener(); this.retryTemplate.registerListener(this.retryListener); - this.chatModel = new MistralAiChatModel(this.mistralAiApi, - MistralAiChatOptions.builder() - .temperature(0.7) - .topP(1.0) - .safePrompt(false) - .model(MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue()) - .build(), - null, this.retryTemplate); + this.chatModel = MistralAiChatModel.builder() + .mistralAiApi(this.mistralAiApi) + .defaultOptions(MistralAiChatOptions.builder() + .temperature(0.7) + .topP(1.0) + .safePrompt(false) + .model(MistralAiApi.ChatModel.SMALL.getValue()) + .build()) + .retryTemplate(this.retryTemplate) + .build(); this.embeddingModel = new MistralAiEmbeddingModel(this.mistralAiApi, MetadataMode.EMBED, MistralAiEmbeddingOptions.builder().withModel(MistralAiApi.EmbeddingModel.EMBED.getValue()).build(), this.retryTemplate); diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java index 11c084ff613..e519df8c60e 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java @@ -43,8 +43,10 @@ public EmbeddingModel mistralAiEmbeddingModel(MistralAiApi api) { @Bean public MistralAiChatModel mistralAiChatModel(MistralAiApi mistralAiApi) { - return new MistralAiChatModel(mistralAiApi, - MistralAiChatOptions.builder().model(MistralAiApi.ChatModel.OPEN_MIXTRAL_7B.getValue()).build()); + return MistralAiChatModel.builder() + .mistralAiApi(mistralAiApi) + .defaultOptions(MistralAiChatOptions.builder().model(MistralAiApi.ChatModel.SMALL.getValue()).build()) + .build(); } } diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java index 48f57e8b9e7..fcdf12afeaf 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java @@ -47,7 +47,7 @@ public class MistralAiApiIT { void chatCompletionEntity() { ChatCompletionMessage chatCompletionMessage = new ChatCompletionMessage("Hello world", Role.USER); ResponseEntity response = this.mistralAiApi.chatCompletionEntity(new ChatCompletionRequest( - List.of(chatCompletionMessage), MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue(), 0.8, false)); + List.of(chatCompletionMessage), MistralAiApi.ChatModel.SMALL.getValue(), 0.8, false)); assertThat(response).isNotNull(); assertThat(response.getBody()).isNotNull(); @@ -64,7 +64,7 @@ void chatCompletionEntityWithSystemMessage() { """, Role.SYSTEM); ResponseEntity response = this.mistralAiApi.chatCompletionEntity(new ChatCompletionRequest( - List.of(systemMessage, userMessage), MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue(), 0.8, false)); + List.of(systemMessage, userMessage), MistralAiApi.ChatModel.SMALL.getValue(), 0.8, false)); assertThat(response).isNotNull(); assertThat(response.getBody()).isNotNull(); @@ -74,7 +74,7 @@ void chatCompletionEntityWithSystemMessage() { void chatCompletionStream() { ChatCompletionMessage chatCompletionMessage = new ChatCompletionMessage("Hello world", Role.USER); Flux response = this.mistralAiApi.chatCompletionStream(new ChatCompletionRequest( - List.of(chatCompletionMessage), MistralAiApi.ChatModel.OPEN_MISTRAL_7B.getValue(), 0.8, true)); + List.of(chatCompletionMessage), MistralAiApi.ChatModel.SMALL.getValue(), 0.8, true)); assertThat(response).isNotNull(); assertThat(response.collectList().block()).isNotNull(); diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java index ab8bfe27317..0e1ee3158cb 100644 --- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java +++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java @@ -28,13 +28,6 @@ import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ai.model.tool.LegacyToolCallingManager; -import org.springframework.ai.model.tool.ToolCallingChatOptions; -import org.springframework.ai.model.tool.ToolCallingManager; -import org.springframework.ai.model.tool.ToolExecutionResult; -import org.springframework.ai.tool.definition.ToolDefinition; -import org.springframework.ai.util.json.JsonParser; -import org.springframework.lang.Nullable; import reactor.core.publisher.Flux; import org.springframework.ai.chat.messages.AssistantMessage; @@ -59,6 +52,9 @@ import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.model.function.FunctionCallbackResolver; import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.tool.ToolCallingChatOptions; +import org.springframework.ai.model.tool.ToolCallingManager; +import org.springframework.ai.model.tool.ToolExecutionResult; import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaApi.ChatRequest; import org.springframework.ai.ollama.api.OllamaApi.Message.Role; @@ -69,6 +65,8 @@ import org.springframework.ai.ollama.management.ModelManagementOptions; import org.springframework.ai.ollama.management.OllamaModelManager; import org.springframework.ai.ollama.management.PullModelStrategy; +import org.springframework.ai.tool.definition.ToolDefinition; +import org.springframework.ai.util.json.JsonParser; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -124,18 +122,6 @@ public class OllamaChatModel extends AbstractToolCallSupport implements ChatMode private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION; - @Deprecated - public OllamaChatModel(OllamaApi ollamaApi, OllamaOptions defaultOptions, - @Nullable FunctionCallbackResolver functionCallbackResolver, - @Nullable List toolFunctionCallbacks, ObservationRegistry observationRegistry, - ModelManagementOptions modelManagementOptions) { - this(ollamaApi, defaultOptions, new LegacyToolCallingManager(functionCallbackResolver, toolFunctionCallbacks), - observationRegistry, modelManagementOptions); - - logger.warn("This constructor is deprecated and will be removed in the next milestone. " - + "Please use the OllamaChatModel.Builder or the new constructor accepting ToolCallingManager instead."); - } - public OllamaChatModel(OllamaApi ollamaApi, OllamaOptions defaultOptions, ToolCallingManager toolCallingManager, ObservationRegistry observationRegistry, ModelManagementOptions modelManagementOptions) { // We do not pass the 'defaultOptions' to the AbstractToolSupport, @@ -599,8 +585,14 @@ public OllamaChatModel build() { "toolCallingManager must not be set when functionCallbackResolver is set"); List toolCallbacks = this.toolFunctionCallbacks != null ? this.toolFunctionCallbacks : List.of(); - return new OllamaChatModel(this.ollamaApi, this.defaultOptions, this.functionCallbackResolver, - toolCallbacks, this.observationRegistry, this.modelManagementOptions); + return OllamaChatModel.builder() + .ollamaApi(this.ollamaApi) + .defaultOptions(this.defaultOptions) + .functionCallbackResolver(this.functionCallbackResolver) + .toolFunctionCallbacks(toolCallbacks) + .observationRegistry(this.observationRegistry) + .modelManagementOptions(this.modelManagementOptions) + .build(); } return new OllamaChatModel(this.ollamaApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER, diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java index dc5b9bfb725..a2cafcee6c7 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelTests.java @@ -55,9 +55,11 @@ class OllamaChatModelTests { @Test void buildOllamaChatModelWithDeprecatedConstructor() { - ChatModel chatModel = new OllamaChatModel(this.ollamaApi, - OllamaOptions.builder().model(OllamaModel.MISTRAL).build(), null, null, ObservationRegistry.NOOP, - ModelManagementOptions.builder().build()); + ChatModel chatModel = OllamaChatModel.builder() + .ollamaApi(this.ollamaApi) + .defaultOptions(OllamaOptions.builder().model(OllamaModel.MISTRAL).build()) + .observationRegistry(ObservationRegistry.NOOP) + .build(); assertThat(chatModel).isNotNull(); } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java index 8065f0b8b8d..9fbfecec468 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java @@ -145,30 +145,6 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode */ private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION; - /** - * Creates an instance of the OpenAiChatModel. - * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI - * Chat API. - * @throws IllegalArgumentException if openAiApi is null - * @deprecated Use OpenAiChatModel.Builder. - */ - @Deprecated - public OpenAiChatModel(OpenAiApi openAiApi) { - this(openAiApi, OpenAiChatOptions.builder().model(OpenAiApi.DEFAULT_CHAT_MODEL).temperature(0.7).build()); - } - - /** - * Initializes an instance of the OpenAiChatModel. - * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI - * Chat API. - * @param options The OpenAiChatOptions to configure the chat model. - * @deprecated Use OpenAiChatModel.Builder. - */ - @Deprecated - public OpenAiChatModel(OpenAiApi openAiApi, OpenAiChatOptions options) { - this(openAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE); - } - /** * Initializes a new instance of the OpenAiChatModel. * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java index 751a63aee24..b320c1acc65 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java @@ -85,97 +85,6 @@ public static Builder builder() { private OpenAiStreamFunctionCallingHelper chunkMerger = new OpenAiStreamFunctionCallingHelper(); - /** - * Create a new chat completion api with base URL set to https://api.openai.com - * @param apiKey OpenAI apiKey. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String apiKey) { - this(OpenAiApiConstants.DEFAULT_BASE_URL, apiKey); - } - - /** - * Create a new chat completion api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String baseUrl, String apiKey) { - this(baseUrl, apiKey, RestClient.builder(), WebClient.builder()); - } - - /** - * Create a new chat completion api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder) { - this(baseUrl, apiKey, restClientBuilder, webClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); - } - - /** - * Create a new chat completion api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) { - this(baseUrl, apiKey, "/v1/chat/completions", "/v1/embeddings", restClientBuilder, webClientBuilder, - responseErrorHandler); - } - - /** - * Create a new chat completion api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param completionsPath the path to the chat completions endpoint. - * @param embeddingsPath the path to the embeddings endpoint. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String baseUrl, String apiKey, String completionsPath, String embeddingsPath, - RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { - - this(baseUrl, apiKey, CollectionUtils.toMultiValueMap(Map.of()), completionsPath, embeddingsPath, - restClientBuilder, webClientBuilder, responseErrorHandler); - } - - /** - * Create a new chat completion api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param headers the http headers to use. - * @param completionsPath the path to the chat completions endpoint. - * @param embeddingsPath the path to the embeddings endpoint. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated since 1.0.0.M6 - use {@link #builder()} instead - */ - @Deprecated(since = "1.0.0.M6") - public OpenAiApi(String baseUrl, String apiKey, MultiValueMap headers, String completionsPath, - String embeddingsPath, RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { - this(baseUrl, new SimpleApiKey(apiKey), headers, completionsPath, embeddingsPath, restClientBuilder, - webClientBuilder, responseErrorHandler); - } - /** * Create a new chat completion api. * @param baseUrl api base URL. diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java index 33507bb9956..6bb2eaf88ec 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java @@ -57,79 +57,6 @@ public class OpenAiAudioApi { private final WebClient webClient; - /** - * Create a new audio api. - * @param openAiToken OpenAI apiKey. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiAudioApi(String openAiToken) { - this(OpenAiApiConstants.DEFAULT_BASE_URL, openAiToken, RestClient.builder(), WebClient.builder(), - RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); - } - - /** - * Create a new audio api. - * @param baseUrl api base URL. - * @param openAiToken OpenAI apiKey. - * @param restClientBuilder RestClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, - ResponseErrorHandler responseErrorHandler) { - Consumer authHeaders; - if (openAiToken != null && !openAiToken.isEmpty()) { - authHeaders = h -> h.setBearerAuth(openAiToken); - } - else { - authHeaders = h -> { - }; - } - - this.restClient = restClientBuilder.baseUrl(baseUrl) - .defaultHeaders(authHeaders) - .defaultStatusHandler(responseErrorHandler) - .build(); - - this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(authHeaders).build(); - } - - /** - * Create a new audio api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiAudioApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder, - WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) { - - this(baseUrl, apiKey, CollectionUtils.toMultiValueMap(Map.of()), restClientBuilder, webClientBuilder, - responseErrorHandler); - } - - /** - * Create a new audio api. - * @param baseUrl api base URL. - * @param apiKey OpenAI apiKey. - * @param headers the http headers to use. - * @param restClientBuilder RestClient builder. - * @param webClientBuilder WebClient builder. - * @param responseErrorHandler Response error handler. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiAudioApi(String baseUrl, String apiKey, MultiValueMap headers, - RestClient.Builder restClientBuilder, WebClient.Builder webClientBuilder, - ResponseErrorHandler responseErrorHandler) { - this(baseUrl, new SimpleApiKey(apiKey), headers, restClientBuilder, webClientBuilder, responseErrorHandler); - } - /** * Create a new audio api. * @param baseUrl api base URL. @@ -496,71 +423,26 @@ public static class Builder { private Float speed; - /** - * @deprecated use {@link #model(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withModel(String model) { - this.model = model; - return this; - } - public Builder model(String model) { this.model = model; return this; } - /** - * @deprecated use {@link #input(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withInput(String input) { - this.input = input; - return this; - } - public Builder input(String input) { this.input = input; return this; } - /** - * @deprecated use {@link #voice(Voice)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withVoice(Voice voice) { - this.voice = voice; - return this; - } - public Builder voice(Voice voice) { this.voice = voice; return this; } - /** - * @deprecated use {@link #responseFormat(AudioResponseFormat)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withResponseFormat(AudioResponseFormat responseFormat) { - this.responseFormat = responseFormat; - return this; - } - public Builder responseFormat(AudioResponseFormat responseFormat) { this.responseFormat = responseFormat; return this; } - /** - * @deprecated use {@link #speed(Float)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withSpeed(Float speed) { - this.speed = speed; - return this; - } - public Builder speed(Float speed) { this.speed = speed; return this; @@ -653,99 +535,36 @@ public static class Builder { private GranularityType granularityType; - /** - * @deprecated use {@link #file(byte[])} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withFile(byte[] file) { - this.file = file; - return this; - } - public Builder file(byte[] file) { this.file = file; return this; } - /** - * @deprecated use {@link #model(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withModel(String model) { - this.model = model; - return this; - } - public Builder model(String model) { this.model = model; return this; } - /** - * @deprecated use {@link #language(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withLanguage(String language) { - this.language = language; - return this; - } - public Builder language(String language) { this.language = language; return this; } - /** - * @deprecated use {@link #prompt(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withPrompt(String prompt) { - this.prompt = prompt; - return this; - } - public Builder prompt(String prompt) { this.prompt = prompt; return this; } - /** - * @deprecated use {@link #responseFormat(TranscriptResponseFormat)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withResponseFormat(TranscriptResponseFormat response_format) { - this.responseFormat = response_format; - return this; - } - public Builder responseFormat(TranscriptResponseFormat responseFormat) { this.responseFormat = responseFormat; return this; } - /** - * @deprecated use {@link #temperature(Float)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withTemperature(Float temperature) { - this.temperature = temperature; - return this; - } - public Builder temperature(Float temperature) { this.temperature = temperature; return this; } - /** - * @deprecated use {@link #granularityType(GranularityType)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withGranularityType(GranularityType granularityType) { - this.granularityType = granularityType; - return this; - } - public Builder granularityType(GranularityType granularityType) { this.granularityType = granularityType; return this; @@ -805,71 +624,26 @@ public static class Builder { private Float temperature; - /** - * @deprecated use {@link #file(byte[])} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withFile(byte[] file) { - this.file = file; - return this; - } - public Builder file(byte[] file) { this.file = file; return this; } - /** - * @deprecated use {@link #model(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withModel(String model) { - this.model = model; - return this; - } - public Builder model(String model) { this.model = model; return this; } - /** - * @deprecated use {@link #prompt(String)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withPrompt(String prompt) { - this.prompt = prompt; - return this; - } - public Builder prompt(String prompt) { this.prompt = prompt; return this; } - /** - * @deprecated use {@link #responseFormat(TranscriptResponseFormat)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withResponseFormat(TranscriptResponseFormat responseFormat) { - this.responseFormat = responseFormat; - return this; - } - public Builder responseFormat(TranscriptResponseFormat responseFormat) { this.responseFormat = responseFormat; return this; } - /** - * @deprecated use {@link #temperature(Float)} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public Builder withTemperature(Float temperature) { - this.temperature = temperature; - return this; - } - public Builder temperature(Float temperature) { this.temperature = temperature; return this; diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java index 56661f3e0b1..fdb3423d23e 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java @@ -17,7 +17,6 @@ package org.springframework.ai.openai.api; import java.util.List; -import java.util.Map; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -30,7 +29,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.ResponseErrorHandler; @@ -47,56 +45,6 @@ public class OpenAiImageApi { private final RestClient restClient; - /** - * Create a new OpenAI Image api with base URL set to {@code https://api.openai.com}. - * @param openAiToken OpenAI apiKey. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiImageApi(String openAiToken) { - this(OpenAiApiConstants.DEFAULT_BASE_URL, openAiToken, RestClient.builder()); - } - - /** - * Create a new OpenAI Image API with the provided base URL. - * @param baseUrl the base URL for the OpenAI API. - * @param openAiToken OpenAI apiKey. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiImageApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) { - this(baseUrl, openAiToken, restClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); - } - - /** - * Create a new OpenAI Image API with the provided base URL. - * @param baseUrl the base URL for the OpenAI API. - * @param apiKey OpenAI apiKey. - * @param restClientBuilder the rest client builder to use. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiImageApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder, - ResponseErrorHandler responseErrorHandler) { - this(baseUrl, apiKey, CollectionUtils.toMultiValueMap(Map.of()), restClientBuilder, responseErrorHandler); - } - - /** - * Create a new OpenAI Image API with the provided base URL. - * @param baseUrl the base URL for the OpenAI API. - * @param apiKey OpenAI apiKey. - * @param headers the http headers to use. - * @param restClientBuilder the rest client builder to use. - * @param responseErrorHandler the response error handler to use. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiImageApi(String baseUrl, String apiKey, MultiValueMap headers, - RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { - - this(baseUrl, new SimpleApiKey(apiKey), headers, restClientBuilder, responseErrorHandler); - } - /** * Create a new OpenAI Image API with the provided base URL. * @param baseUrl the base URL for the OpenAI API. diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java index 1a509fc6b31..ad0a3e9620f 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java @@ -52,33 +52,6 @@ public class OpenAiModerationApi { private final ObjectMapper objectMapper; - /** - * Create a new OpenAI Moderation api with base URL set to https://api.openai.com - * @param openAiToken OpenAI apiKey. - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiModerationApi(String openAiToken) { - this(DEFAULT_BASE_URL, openAiToken, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); - } - - /** - * @deprecated use {@link Builder} instead. - */ - @Deprecated(forRemoval = true, since = "1.0.0-M6") - public OpenAiModerationApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, - ResponseErrorHandler responseErrorHandler) { - - this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(h -> { - if (openAiToken != null && !openAiToken.isEmpty()) { - h.setBearerAuth(openAiToken); - } - h.setContentType(MediaType.APPLICATION_JSON); - }).defaultStatusHandler(responseErrorHandler).build(); - } - /** * Create a new OpenAI Moderation API with the provided base URL. * @param baseUrl the base URL for the OpenAI API. diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java index 561b0fe95ec..84dc1c56773 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java @@ -74,8 +74,10 @@ void whenToolRuntimeOptionsThenMergeWithDefaults() { @Test void createRequestWithChatOptions() { - var client = new OpenAiChatModel(new OpenAiApi("TEST"), - OpenAiChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build()); + var client = OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder().apiKey("TEST").build()) + .defaultOptions(OpenAiChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build()) + .build(); var prompt = client.buildRequestPrompt(new Prompt("Test message content")); @@ -101,8 +103,10 @@ void createRequestWithChatOptions() { void promptOptionsTools() { final String TOOL_FUNCTION_NAME = "CurrentWeather"; - var client = new OpenAiChatModel(new OpenAiApi("TEST"), - OpenAiChatOptions.builder().model("DEFAULT_MODEL").build()); + var client = OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder().apiKey("TEST").build()) + .defaultOptions(OpenAiChatOptions.builder().model("DEFAULT_MODEL").build()) + .build(); var prompt = client.buildRequestPrompt(new Prompt("Test message content", OpenAiChatOptions.builder() @@ -128,15 +132,17 @@ void promptOptionsTools() { void defaultOptionsTools() { final String TOOL_FUNCTION_NAME = "CurrentWeather"; - var client = new OpenAiChatModel(new OpenAiApi("TEST"), - OpenAiChatOptions.builder() - .model("DEFAULT_MODEL") - .functionCallbacks(List.of(FunctionCallback.builder() - .function(TOOL_FUNCTION_NAME, new MockWeatherService()) - .description("Get the weather in location") - .inputType(MockWeatherService.Request.class) - .build())) - .build()); + var client = OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder().apiKey("TEST").build()) + .defaultOptions(OpenAiChatOptions.builder() + .model("DEFAULT_MODEL") + .functionCallbacks(List.of(FunctionCallback.builder() + .function(TOOL_FUNCTION_NAME, new MockWeatherService()) + .description("Get the weather in location") + .inputType(MockWeatherService.Request.class) + .build())) + .build()) + .build(); var prompt = client.buildRequestPrompt(new Prompt("Test message content")); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java index d669d4ad2b6..e7401d9d81b 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java @@ -61,28 +61,25 @@ private ApiKey getApiKey() { @Bean public OpenAiChatModel openAiChatModel(OpenAiApi api) { - OpenAiChatModel openAiChatModel = new OpenAiChatModel(api, - OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI).build()); - return openAiChatModel; + return OpenAiChatModel.builder() + .openAiApi(api) + .defaultOptions(OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI).build()) + .build(); } @Bean public OpenAiAudioTranscriptionModel openAiTranscriptionModel(OpenAiAudioApi api) { - OpenAiAudioTranscriptionModel openAiTranscriptionModel = new OpenAiAudioTranscriptionModel(api); - return openAiTranscriptionModel; + return new OpenAiAudioTranscriptionModel(api); } @Bean public OpenAiAudioSpeechModel openAiAudioSpeechModel(OpenAiAudioApi api) { - OpenAiAudioSpeechModel openAiAudioSpeechModel = new OpenAiAudioSpeechModel(api); - return openAiAudioSpeechModel; + return new OpenAiAudioSpeechModel(api); } @Bean public OpenAiImageModel openAiImageModel(OpenAiImageApi imageApi) { - OpenAiImageModel openAiImageModel = new OpenAiImageModel(imageApi); - // openAiImageModel.setModel("foobar"); - return openAiImageModel; + return new OpenAiImageModel(imageApi); } @Bean @@ -92,8 +89,7 @@ public OpenAiEmbeddingModel openAiEmbeddingModel(OpenAiApi api) { @Bean public OpenAiModerationModel openAiModerationClient(OpenAiModerationApi openAiModerationApi) { - OpenAiModerationModel openAiModerationModel = new OpenAiModerationModel(openAiModerationApi); - return openAiModerationModel; + return new OpenAiModerationModel(openAiModerationApi); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java index 71a3e7497a2..f843c0c7338 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java @@ -46,7 +46,7 @@ @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") public class OpenAiApiIT { - OpenAiApi openAiApi = new OpenAiApi(System.getenv("OPENAI_API_KEY")); + OpenAiApi openAiApi = OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); @Test void chatCompletionEntity() { diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java index 33f50b1f4d7..482fc115792 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java @@ -52,7 +52,7 @@ public class OpenAiApiToolFunctionCallIT { MockWeatherService weatherService = new MockWeatherService(); - OpenAiApi completionApi = new OpenAiApi(System.getenv("OPENAI_API_KEY")); + OpenAiApi completionApi = OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); private static T fromJson(String json, Class targetClass) { try { diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java index 65cc583fdb8..4a48c977ff3 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/MessageTypeContentTests.java @@ -74,7 +74,7 @@ public class MessageTypeContentTests { @BeforeEach public void beforeEach() { - this.chatModel = new OpenAiChatModel(this.openAiApi); + this.chatModel = OpenAiChatModel.builder().openAiApi(this.openAiApi).build(); } @Test diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelAdditionalHttpHeadersIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelAdditionalHttpHeadersIT.java index 07af49fba89..b1acd969478 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelAdditionalHttpHeadersIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelAdditionalHttpHeadersIT.java @@ -73,7 +73,7 @@ public OpenAiApi chatCompletionApi() { @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi); + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelFunctionCallingIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelFunctionCallingIT.java index 799b76ea1a4..e62358b4c60 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelFunctionCallingIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelFunctionCallingIT.java @@ -219,12 +219,12 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi); + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelNoOpApiKeysIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelNoOpApiKeysIT.java index 9a73f110571..5caf74c1cf8 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelNoOpApiKeysIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelNoOpApiKeysIT.java @@ -62,7 +62,7 @@ public OpenAiApi chatCompletionApi() { @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi); + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelObservationIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelObservationIT.java index e6e58499e4a..f341a23cbc4 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelObservationIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelObservationIT.java @@ -169,7 +169,7 @@ public TestObservationRegistry observationRegistry() { @Bean public OpenAiApi openAiApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelProxyToolCallsIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelProxyToolCallsIT.java index db047a3cfbb..bf492ce2021 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelProxyToolCallsIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelProxyToolCallsIT.java @@ -355,7 +355,7 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelResponseFormatIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelResponseFormatIT.java index f2f2864969f..65a3e2389aa 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelResponseFormatIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelResponseFormatIT.java @@ -234,12 +234,12 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi); + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java index 76dd5a7ee0e..f606e16ad4d 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelWithChatResponseMetadataTests.java @@ -18,6 +18,7 @@ import java.time.Duration; +import org.hamcrest.core.StringContains; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -133,7 +134,7 @@ private void prepareMock() { httpHeaders.set(OpenAiApiResponseHeaders.TOKENS_REMAINING_HEADER.getName(), "112358"); httpHeaders.set(OpenAiApiResponseHeaders.TOKENS_RESET_HEADER.getName(), "27h55s451ms"); - this.server.expect(requestTo("/v1/chat/completions")) + this.server.expect(requestTo(StringContains.containsString("/v1/chat/completions"))) .andExpect(method(HttpMethod.POST)) .andExpect(header(HttpHeaders.AUTHORIZATION, "Bearer " + TEST_API_KEY)) .andRespond(withSuccess(getJson(), MediaType.APPLICATION_JSON).headers(httpHeaders)); @@ -169,12 +170,16 @@ static class Config { @Bean public OpenAiApi chatCompletionApi(RestClient.Builder builder, WebClient.Builder webClientBuilder) { - return new OpenAiApi("", TEST_API_KEY, builder, webClientBuilder); + return OpenAiApi.builder() + .apiKey(TEST_API_KEY) + .restClientBuilder(builder) + .webClientBuilder(webClientBuilder) + .build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi); + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiCompatibleChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiCompatibleChatModelIT.java index 56cd6fa215a..6ac14d1196d 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiCompatibleChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiCompatibleChatModelIT.java @@ -55,7 +55,10 @@ static OpenAiChatOptions forModelName(String modelName) { static Stream openAiCompatibleApis() { Stream.Builder builder = Stream.builder(); - builder.add(new OpenAiChatModel(new OpenAiApi(System.getenv("OPENAI_API_KEY")), forModelName("gpt-3.5-turbo"))); + builder.add(OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build()) + .defaultOptions(forModelName("gpt-3.5-turbo")) + .build()); // (26.01.2025) Disable because the Groq API is down. TODO: Re-enable when the API // is back up. @@ -66,9 +69,13 @@ static Stream openAiCompatibleApis() { // } if (System.getenv("OPEN_ROUTER_API_KEY") != null) { - builder.add(new OpenAiChatModel( - new OpenAiApi("https://openrouter.ai/api", System.getenv("OPEN_ROUTER_API_KEY")), - forModelName("meta-llama/llama-3-8b-instruct"))); + builder.add(OpenAiChatModel.builder() + .openAiApi(OpenAiApi.builder() + .baseUrl("https://openrouter.ai/api") + .apiKey(System.getenv("OPEN_ROUTER_API_KEY")) + .build()) + .defaultOptions(forModelName("meta-llama/llama-3-8b-instruct")) + .build()); } return builder.build(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiPaymentTransactionIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiPaymentTransactionIT.java index f2a92a1efe9..b7d2fbc703a 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiPaymentTransactionIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiPaymentTransactionIT.java @@ -217,14 +217,18 @@ public ChatClient chatClient(OpenAiChatModel chatModel) { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi, FunctionCallbackResolver functionCallbackResolver) { - return new OpenAiChatModel(openAiApi, - OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI.getName()).temperature(0.1).build(), - functionCallbackResolver, RetryUtils.DEFAULT_RETRY_TEMPLATE); + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions( + OpenAiChatOptions.builder().model(ChatModel.GPT_4_O_MINI.getName()).temperature(0.1).build()) + .functionCallbackResolver(functionCallbackResolver) + .retryTemplate(RetryUtils.DEFAULT_RETRY_TEMPLATE) + .build(); } /** diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java index 20ca78309c1..2ab1a9517e9 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java @@ -110,8 +110,11 @@ public void beforeEach() { this.retryListener = new TestRetryListener(); this.retryTemplate.registerListener(this.retryListener); - this.chatModel = new OpenAiChatModel(this.openAiApi, OpenAiChatOptions.builder().build(), null, - this.retryTemplate); + this.chatModel = OpenAiChatModel.builder() + .openAiApi(this.openAiApi) + .defaultOptions(OpenAiChatOptions.builder().build()) + .retryTemplate(this.retryTemplate) + .build(); this.embeddingModel = new OpenAiEmbeddingModel(this.openAiApi, MetadataMode.EMBED, OpenAiEmbeddingOptions.builder().build(), this.retryTemplate); this.audioTranscriptionModel = new OpenAiAudioTranscriptionModel(this.openAiAudioApi, diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/DeepSeekWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/DeepSeekWithOpenAiChatModelIT.java index 461b8cdafda..975a172d260 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/DeepSeekWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/DeepSeekWithOpenAiChatModelIT.java @@ -330,12 +330,15 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(DEEPSEEK_BASE_URL, System.getenv("DEEPSEEK_API_KEY")); + return OpenAiApi.builder().baseUrl(DEEPSEEK_BASE_URL).apiKey(System.getenv("DEEPSEEK_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_DEEPSEEK_MODEL).build()); + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions(OpenAiChatOptions.builder().model(DEFAULT_DEEPSEEK_MODEL).build()) + .build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java index 94b4c0f07f8..2e6208398e1 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/GroqWithOpenAiChatModelIT.java @@ -383,12 +383,15 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(GROQ_BASE_URL, System.getenv("GROQ_API_KEY")); + return OpenAiApi.builder().baseUrl(GROQ_BASE_URL).apiKey(System.getenv("GROQ_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_GROQ_MODEL).build()); + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions(OpenAiChatOptions.builder().model(DEFAULT_GROQ_MODEL).build()) + .build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/NvidiaWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/NvidiaWithOpenAiChatModelIT.java index 4983e96c7e9..88263c92382 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/NvidiaWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/NvidiaWithOpenAiChatModelIT.java @@ -318,13 +318,15 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(NVIDIA_BASE_URL, System.getenv("NVIDIA_API_KEY")); + return OpenAiApi.builder().baseUrl(NVIDIA_BASE_URL).apiKey(System.getenv("NVIDIA_API_KEY")).build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi, - OpenAiChatOptions.builder().maxTokens(2048).model(DEFAULT_NVIDIA_MODEL).build()); + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions(OpenAiChatOptions.builder().maxTokens(2048).model(DEFAULT_NVIDIA_MODEL).build()) + .build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/PerplexityWithOpenAiChatModelIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/PerplexityWithOpenAiChatModelIT.java index ceb6c944121..6b4e7fbd46e 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/PerplexityWithOpenAiChatModelIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/PerplexityWithOpenAiChatModelIT.java @@ -327,14 +327,20 @@ static class Config { @Bean public OpenAiApi chatCompletionApi() { - return new OpenAiApi(PERPLEXITY_BASE_URL, System.getenv("PERPLEXITY_API_KEY"), PERPLEXITY_COMPLETIONS_PATH, - "/v1/embeddings", RestClient.builder(), WebClient.builder(), - RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER); + return OpenAiApi.builder() + .baseUrl(PERPLEXITY_BASE_URL) + .apiKey(System.getenv("PERPLEXITY_API_KEY")) + .completionsPath(PERPLEXITY_COMPLETIONS_PATH) + .embeddingsPath("/v1/embeddings") + .build(); } @Bean public OpenAiChatModel openAiClient(OpenAiApi openAiApi) { - return new OpenAiChatModel(openAiApi, OpenAiChatOptions.builder().model(DEFAULT_PERPLEXITY_MODEL).build()); + return OpenAiChatModel.builder() + .openAiApi(openAiApi) + .defaultOptions(OpenAiChatOptions.builder().model(DEFAULT_PERPLEXITY_MODEL).build()) + .build(); } } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/OpenAiEmbeddingModelObservationIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/OpenAiEmbeddingModelObservationIT.java index 684d9a92fad..aa76a67f7a5 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/OpenAiEmbeddingModelObservationIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/OpenAiEmbeddingModelObservationIT.java @@ -104,7 +104,7 @@ public TestObservationRegistry observationRegistry() { @Bean public OpenAiApi openAiApi() { - return new OpenAiApi(System.getenv("OPENAI_API_KEY")); + return OpenAiApi.builder().apiKey(System.getenv("OPENAI_API_KEY")).build(); } @Bean diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java index 66a8d3d8eda..5df6f389b1a 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java @@ -163,13 +163,12 @@ public OpenAiApi openAiApi() throws IOException { throw new IllegalArgumentException( "You must provide an API key. Put it in an environment variable under the name OPENAI_API_KEY"); } - return new OpenAiApi(apiKey); + return OpenAiApi.builder().apiKey(apiKey).build(); } @Bean public OpenAiChatModel openAiChatModel(OpenAiApi openAiApi) { - OpenAiChatModel openAiChatModel = new OpenAiChatModel(openAiApi); - return openAiChatModel; + return OpenAiChatModel.builder().openAiApi(openAiApi).build(); } @Bean diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/tool/VertexAiGeminiPaymentTransactionDeprecatedIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/tool/VertexAiGeminiPaymentTransactionDeprecatedIT.java deleted file mode 100644 index 96ff923bc29..00000000000 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/tool/VertexAiGeminiPaymentTransactionDeprecatedIT.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.vertexai.gemini.tool; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import com.google.cloud.vertexai.Transport; -import com.google.cloud.vertexai.VertexAI; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; - -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.ai.chat.client.advisor.api.AdvisedRequest; -import org.springframework.ai.chat.client.advisor.api.AdvisedResponse; -import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisor; -import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisorChain; -import org.springframework.ai.model.function.DefaultFunctionCallbackResolver; -import org.springframework.ai.model.function.FunctionCallback.SchemaType; -import org.springframework.ai.model.function.FunctionCallbackResolver; -import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; -import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Description; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Christian Tzolov - */ -@SpringBootTest -@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_PROJECT_ID", matches = ".*") -@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_LOCATION", matches = ".*") -@Deprecated -public class VertexAiGeminiPaymentTransactionDeprecatedIT { - - private static final Logger logger = LoggerFactory.getLogger(VertexAiGeminiPaymentTransactionDeprecatedIT.class); - - private static final Map DATASET = Map.of(new Transaction("001"), new Status("pending"), - new Transaction("002"), new Status("approved"), new Transaction("003"), new Status("rejected")); - - @Autowired - ChatClient chatClient; - - @Test - public void paymentStatuses() { - // @formatter:off - String content = this.chatClient.prompt() - .advisors(new LoggingAdvisor()) - .tools("paymentStatus") - .user(""" - What is the status of my payment transactions 001, 002 and 003? - If requred invoke the function per transaction. - """).call().content(); - - logger.info("" + content); - - assertThat(content).contains("001", "002", "003"); - assertThat(content).contains("pending", "approved", "rejected"); - } - - @RepeatedTest(5) - public void streamingPaymentStatuses() { - - Flux streamContent = this.chatClient.prompt() - .advisors(new LoggingAdvisor()) - .tools("paymentStatus") - .user(""" - What is the status of my payment transactions 001, 002 and 003? - If requred invoke the function per transaction. - """) - .stream() - .content(); - - String content = streamContent.collectList().block().stream().collect(Collectors.joining()); - - logger.info(content); - - assertThat(content).contains("001", "002", "003"); - assertThat(content).contains("pending", "approved", "rejected"); - - // Quota rate - try { - Thread.sleep(1000); - } - catch (InterruptedException e) { - } - } - - record TransactionStatusResponse(String id, String status) { - - } - - private static class LoggingAdvisor implements CallAroundAdvisor { - - private final Logger logger = LoggerFactory.getLogger(LoggingAdvisor.class); - - @Override - public String getName() { - return this.getClass().getSimpleName(); - } - - @Override - public int getOrder() { - return 0; - } - - @Override - public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) { - var response = chain.nextAroundCall(before(advisedRequest)); - observeAfter(response); - return response; - } - - private AdvisedRequest before(AdvisedRequest request) { - logger.info("System text: \n" + request.systemText()); - logger.info("System params: " + request.systemParams()); - logger.info("User text: \n" + request.userText()); - logger.info("User params:" + request.userParams()); - logger.info("Function names: " + request.functionNames()); - - logger.info("Options: " + request.chatOptions().toString()); - - return request; - } - - private void observeAfter(AdvisedResponse advisedResponse) { - logger.info("Response: " + advisedResponse.response()); - } - - } - - record Transaction(String id) { - } - - record Status(String name) { - } - - record Transactions(List transactions) { - } - - record Statuses(List statuses) { - } - - @SpringBootConfiguration - public static class TestConfiguration { - - @Bean - @Description("Get the status of a single payment transaction") - public Function paymentStatus() { - return transaction -> { - logger.info("Single Transaction: " + transaction); - return DATASET.get(transaction); - }; - } - - @Bean - @Description("Get the list statuses of a list of payment transactions") - public Function paymentStatuses() { - return transactions -> { - logger.info("Transactions: " + transactions); - return new Statuses(transactions.transactions().stream().map(t -> DATASET.get(t)).toList()); - }; - } - - @Bean - public ChatClient chatClient(VertexAiGeminiChatModel chatModel) { - return ChatClient.builder(chatModel).build(); - } - - @Bean - public VertexAI vertexAiApi() { - - String projectId = System.getenv("VERTEX_AI_GEMINI_PROJECT_ID"); - String location = System.getenv("VERTEX_AI_GEMINI_LOCATION"); - - return new VertexAI.Builder().setLocation(location) - .setProjectId(projectId) - .setTransport(Transport.REST) - // .setTransport(Transport.GRPC) - .build(); - } - - @Bean - public VertexAiGeminiChatModel vertexAiChatModel(VertexAI vertexAi, ApplicationContext context) { - - FunctionCallbackResolver functionCallbackResolver = springAiFunctionManager(context); - - return new VertexAiGeminiChatModel(vertexAi, - VertexAiGeminiChatOptions.builder() - .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) - .temperature(0.1) - .build(), - functionCallbackResolver); - } - - /** - * Because of the OPEN_API_SCHEMA type, the FunctionCallbackResolver instance - * must - * different from the other JSON schema types. - */ - private FunctionCallbackResolver springAiFunctionManager(ApplicationContext context) { - DefaultFunctionCallbackResolver manager = new DefaultFunctionCallbackResolver(); - manager.setSchemaType(SchemaType.OPEN_API_SCHEMA); - manager.setApplicationContext(context); - return manager; - } - - } - -} diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java index bced70c6af2..2efbef699e9 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java @@ -66,51 +66,6 @@ public class VectorStoreChatMemoryAdvisor extends AbstractChatMemoryAdvisor