diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsAutoConfigurationIT.java index 4c1fc68ec04..e01c1948b66 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsAutoConfigurationIT.java @@ -18,7 +18,6 @@ import java.util.Arrays; -import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; @@ -26,6 +25,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import static org.assertj.core.api.Assertions.assertThat; + /** * Integration tests for the {@link ElevenLabsAutoConfiguration}. * diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsPropertiesTests.java b/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsPropertiesTests.java index e8ab28a2dcc..29ba913db57 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsPropertiesTests.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs/src/test/java/org/springframework/ai/model/elevenlabs/autoconfigure/ElevenLabsPropertiesTests.java @@ -16,7 +16,6 @@ package org.springframework.ai.model.elevenlabs.autoconfigure; -import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.springframework.ai.elevenlabs.ElevenLabsTextToSpeechModel; @@ -24,6 +23,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests for the {@link ElevenLabsSpeechProperties} and * {@link ElevenLabsConnectionProperties}. diff --git a/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/main/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.java b/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/main/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.java index eeef83b940c..40e5336e473 100644 --- a/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/main/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.java +++ b/auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/main/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.java @@ -16,9 +16,10 @@ package org.springframework.ai.model.tool.autoconfigure; -import io.micrometer.observation.ObservationRegistry; import java.util.ArrayList; import java.util.List; + +import io.micrometer.observation.ObservationRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate/src/main/java/org/springframework/ai/vectorstore/weaviate/autoconfigure/WeaviateVectorStoreProperties.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate/src/main/java/org/springframework/ai/vectorstore/weaviate/autoconfigure/WeaviateVectorStoreProperties.java index 48eb859ab33..c534e1b7b4d 100644 --- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate/src/main/java/org/springframework/ai/vectorstore/weaviate/autoconfigure/WeaviateVectorStoreProperties.java +++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate/src/main/java/org/springframework/ai/vectorstore/weaviate/autoconfigure/WeaviateVectorStoreProperties.java @@ -91,7 +91,7 @@ public void setObjectClass(String indexName) { * @since 1.1.0 */ public String getContentFieldName() { - return contentFieldName; + return this.contentFieldName; } /** @@ -105,7 +105,7 @@ public void setContentFieldName(String contentFieldName) { * @since 1.1.0 */ public String getMetaFieldPrefix() { - return metaFieldPrefix; + return this.metaFieldPrefix; } /** diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java index d8be2179675..7e2701d3a17 100644 --- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java +++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReader.java @@ -18,7 +18,6 @@ import java.awt.Rectangle; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import org.apache.pdfbox.pdfparser.PDFParser; @@ -201,7 +200,8 @@ public String getTextBetweenParagraphs(Paragraph fromParagraph, Paragraph toPara int x = (int) page.getMediaBox().getLowerLeftX(); int w = (int) page.getMediaBox().getWidth(); - int y, h; + int y; + int h; if (pageNumber == startPage && pageNumber == endPage) { y = toPos; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallback.java b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallback.java index b0fffcf3327..3caec7cfc21 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallback.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallback.java @@ -16,10 +16,11 @@ package org.springframework.ai.mcp; +import java.util.Map; + import io.modelcontextprotocol.client.McpAsyncClient; import io.modelcontextprotocol.spec.McpSchema.CallToolRequest; import io.modelcontextprotocol.spec.McpSchema.Tool; -import java.util.Map; import org.springframework.ai.chat.model.ToolContext; import org.springframework.ai.model.ModelOptionsUtils; diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallback.java b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallback.java index fc61d801df1..740d156e868 100644 --- a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallback.java +++ b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallback.java @@ -16,11 +16,12 @@ package org.springframework.ai.mcp; +import java.util.Map; + import io.modelcontextprotocol.client.McpSyncClient; import io.modelcontextprotocol.spec.McpSchema.CallToolRequest; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; import io.modelcontextprotocol.spec.McpSchema.Tool; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mcp/common/src/test/java/org/springframework/ai/mcp/AsyncMcpToolCallbackTest.java b/mcp/common/src/test/java/org/springframework/ai/mcp/AsyncMcpToolCallbackTest.java index e4ceb618efd..d1486580302 100644 --- a/mcp/common/src/test/java/org/springframework/ai/mcp/AsyncMcpToolCallbackTest.java +++ b/mcp/common/src/test/java/org/springframework/ai/mcp/AsyncMcpToolCallbackTest.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-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. + * 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.mcp; import io.modelcontextprotocol.client.McpAsyncClient; @@ -9,6 +25,7 @@ import reactor.core.publisher.Mono; import org.springframework.ai.tool.execution.ToolExecutionException; + import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; diff --git a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java index 72b04394a49..3a47a1bfefc 100644 --- a/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java +++ b/mcp/common/src/test/java/org/springframework/ai/mcp/SyncMcpToolCallbackTests.java @@ -16,11 +16,11 @@ package org.springframework.ai.mcp; -import io.modelcontextprotocol.spec.McpSchema; import java.util.List; import java.util.Map; import io.modelcontextprotocol.client.McpSyncClient; +import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpSchema.CallToolRequest; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; import io.modelcontextprotocol.spec.McpSchema.Implementation; @@ -31,7 +31,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.ai.chat.model.ToolContext; -import org.springframework.ai.content.Content; import org.springframework.ai.tool.execution.ToolExecutionException; import static org.assertj.core.api.Assertions.assertThat; diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java index 526c0908c77..f936e6f5ec5 100644 --- a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java @@ -16,9 +16,10 @@ package org.springframework.ai.chat.memory.repository.jdbc; -import javax.sql.DataSource; import java.sql.Connection; +import javax.sql.DataSource; + /** * Abstraction for database-specific SQL for chat memory repository. */ diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java index 02407e52c41..937a81f6d46 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java @@ -279,11 +279,12 @@ public Flux internalStream(Prompt prompt, ChatResponse previousCha chatResponse); } }).subscribeOn(Schedulers.boundedElastic()); - } else { + } + else { return Mono.empty(); } - - } else { + } + else { // If internal tool execution is not required, just return the chat response. return Mono.just(chatResponse); } diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java index cf410690216..b573ff8a139 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java @@ -24,8 +24,17 @@ import java.util.function.Consumer; import java.util.function.Predicate; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.springframework.ai.anthropic.api.StreamHelper.ChatCompletionResponseBuilder; import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.ChatModelDescription; @@ -45,16 +54,6 @@ import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - /** * The Anthropic API client. * @@ -227,7 +226,6 @@ public Flux chatCompletionStream(ChatCompletionRequest c .filter(event -> event.type() != EventType.PING) // Detect if the chunk is part of a streaming function call. .map(event -> { - logger.debug("Received event: {}", event); if (this.streamHelper.isToolUseStart(event)) { @@ -1179,7 +1177,6 @@ public record ContentBlockThinking( @JsonProperty("thinking") String thinking, @JsonProperty("signature") String signature) implements ContentBlockBody { } - } // @formatter:on diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/StreamHelper.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/StreamHelper.java index 980c3342afe..63bee5d3bda 100644 --- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/StreamHelper.java +++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/StreamHelper.java @@ -25,13 +25,13 @@ import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlock.Type; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent.ContentBlockDeltaJson; +import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent.ContentBlockDeltaSignature; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent.ContentBlockDeltaText; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent.ContentBlockDeltaThinking; -import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockDeltaEvent.ContentBlockDeltaSignature; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockStartEvent; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockStartEvent.ContentBlockText; -import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockStartEvent.ContentBlockToolUse; import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockStartEvent.ContentBlockThinking; +import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlockStartEvent.ContentBlockToolUse; import org.springframework.ai.anthropic.api.AnthropicApi.EventType; import org.springframework.ai.anthropic.api.AnthropicApi.MessageDeltaEvent; import org.springframework.ai.anthropic.api.AnthropicApi.MessageStartEvent; diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/api/AnthropicApiBuilderTests.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/api/AnthropicApiBuilderTests.java index d2c0fce008f..8a89ea306c7 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/api/AnthropicApiBuilderTests.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/api/AnthropicApiBuilderTests.java @@ -16,20 +16,21 @@ package org.springframework.ai.anthropic.api; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.SimpleApiKey; import org.springframework.http.HttpHeaders; @@ -42,10 +43,9 @@ import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.opentest4j.AssertionFailedError; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; /** * @author Filip Hrisafov @@ -139,13 +139,13 @@ class MockRequests { @BeforeEach void setUp() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(); + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); } @AfterEach void tearDown() throws IOException { - mockWebServer.shutdown(); + this.mockWebServer.shutdown(); } @Test @@ -153,7 +153,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); AnthropicApi api = AnthropicApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -173,8 +173,8 @@ void dynamicApiKeyRestClient() throws InterruptedException { } } """); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); AnthropicApi.AnthropicMessage chatCompletionMessage = new AnthropicApi.AnthropicMessage( List.of(new AnthropicApi.ContentBlock("Hello world")), AnthropicApi.Role.USER); @@ -185,14 +185,14 @@ void dynamicApiKeyRestClient() throws InterruptedException { .build(); ResponseEntity response = api.chatCompletionEntity(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("key1"); response = api.chatCompletionEntity(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("key2"); } @@ -201,7 +201,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { void dynamicApiKeyRestClientWithAdditionalApiKeyHeader() throws InterruptedException { AnthropicApi api = AnthropicApi.builder().apiKey(() -> { throw new AssertionFailedError("Should not be called, API key is provided in headers"); - }).baseUrl(mockWebServer.url("/").toString()).build(); + }).baseUrl(this.mockWebServer.url("/").toString()).build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) @@ -220,7 +220,7 @@ void dynamicApiKeyRestClientWithAdditionalApiKeyHeader() throws InterruptedExcep } } """); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); AnthropicApi.AnthropicMessage chatCompletionMessage = new AnthropicApi.AnthropicMessage( List.of(new AnthropicApi.ContentBlock("Hello world")), AnthropicApi.Role.USER); @@ -234,7 +234,7 @@ void dynamicApiKeyRestClientWithAdditionalApiKeyHeader() throws InterruptedExcep ResponseEntity response = api.chatCompletionEntity(request, additionalHeaders); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("additional-key"); } @@ -244,7 +244,7 @@ void dynamicApiKeyWebClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); AnthropicApi api = AnthropicApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -267,8 +267,8 @@ void dynamicApiKeyWebClient() throws InterruptedException { } } """.replace("\n", "")); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); AnthropicApi.AnthropicMessage chatCompletionMessage = new AnthropicApi.AnthropicMessage( List.of(new AnthropicApi.ContentBlock("Hello world")), AnthropicApi.Role.USER); @@ -279,13 +279,13 @@ void dynamicApiKeyWebClient() throws InterruptedException { .stream(true) .build(); api.chatCompletionStream(request).collectList().block(); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("key1"); api.chatCompletionStream(request).collectList().block(); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("key2"); } @@ -295,7 +295,7 @@ void dynamicApiKeyWebClientWithAdditionalApiKey() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); AnthropicApi api = AnthropicApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -318,7 +318,7 @@ void dynamicApiKeyWebClientWithAdditionalApiKey() throws InterruptedException { } } """.replace("\n", "")); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); AnthropicApi.AnthropicMessage chatCompletionMessage = new AnthropicApi.AnthropicMessage( List.of(new AnthropicApi.ContentBlock("Hello world")), AnthropicApi.Role.USER); @@ -332,7 +332,7 @@ void dynamicApiKeyWebClientWithAdditionalApiKey() throws InterruptedException { additionalHeaders.add("x-api-key", "additional-key"); api.chatCompletionStream(request, additionalHeaders).collectList().block(); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull(); assertThat(recordedRequest.getHeader("x-api-key")).isEqualTo("additional-key"); } diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientIT.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientIT.java index 2baf73dd97e..6af5955e594 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientIT.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientIT.java @@ -16,8 +16,6 @@ package org.springframework.ai.anthropic.client; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.net.URL; import java.util.Arrays; @@ -31,6 +29,8 @@ import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; + import org.springframework.ai.anthropic.AnthropicChatOptions; import org.springframework.ai.anthropic.AnthropicTestConfiguration; import org.springframework.ai.anthropic.api.AnthropicApi; @@ -55,7 +55,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.util.MimeTypeUtils; -import reactor.core.publisher.Flux; +import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = AnthropicTestConfiguration.class, properties = "spring.ai.retry.on-http-codes=429") @EnabledIfEnvironmentVariable(named = "ANTHROPIC_API_KEY", matches = ".+") @@ -341,10 +341,6 @@ void streamingMultiModality() throws IOException { assertThat(content).containsAnyOf("bananas", "apple", "bowl", "basket", "fruit stand"); } - record ActorsFilms(String actor, List movies) { - - } - @ParameterizedTest(name = "{0} : {displayName} ") @ValueSource(strings = { "claude-3-7-sonnet-latest", "claude-sonnet-4-0" }) void streamToolCallingResponseShouldNotContainToolCallMessages(String modelName) { @@ -380,4 +376,8 @@ String getCurrentDateTime(String cityName) { } + record ActorsFilms(String actor, List movies) { + + } + } diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java index 56d245a846f..7bf2ee5e50e 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java @@ -28,6 +28,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; import org.springframework.ai.anthropic.AnthropicTestConfiguration; import org.springframework.ai.chat.client.ChatClient; @@ -44,8 +45,6 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.util.ReflectionUtils; -import reactor.core.publisher.Flux; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; @@ -60,6 +59,9 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT { public static Map arguments = new ConcurrentHashMap<>(); + @Autowired + ChatModel chatModel; + @BeforeEach void beforeEach() { arguments.clear(); @@ -302,9 +304,6 @@ String getCurrentDateTime() { } - @Autowired - ChatModel chatModel; - record MyRecord(String foo, String bar) { } diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionModelIT.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionModelIT.java index abad2ee928d..97f71a57bde 100644 --- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionModelIT.java +++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionModelIT.java @@ -1,4 +1,3 @@ - /* * Copyright 2023-2024 the original author or authors. * diff --git a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModel.java b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModel.java index fbb53bb3dc9..58f1b4ca363 100644 --- a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModel.java +++ b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModel.java @@ -73,8 +73,8 @@ public static Builder builder() { public TextToSpeechResponse call(TextToSpeechPrompt prompt) { RequestContext requestContext = prepareRequest(prompt); - byte[] audioData = retryTemplate.execute(context -> { - var response = elevenLabsApi.textToSpeech(requestContext.request, requestContext.voiceId, + byte[] audioData = this.retryTemplate.execute(context -> { + var response = this.elevenLabsApi.textToSpeech(requestContext.request, requestContext.voiceId, requestContext.queryParameters); if (response.getBody() == null) { logger.warn("No speech response returned for request: {}", requestContext.request); @@ -90,7 +90,7 @@ public TextToSpeechResponse call(TextToSpeechPrompt prompt) { public Flux stream(TextToSpeechPrompt prompt) { RequestContext requestContext = prepareRequest(prompt); - return retryTemplate.execute(context -> elevenLabsApi + return this.retryTemplate.execute(context -> this.elevenLabsApi .textToSpeechStream(requestContext.request, requestContext.voiceId, requestContext.queryParameters) .map(entity -> new TextToSpeechResponse(List.of(new Speech(entity.getBody()))))); } @@ -104,10 +104,6 @@ private RequestContext prepareRequest(TextToSpeechPrompt prompt) { return new RequestContext(request, voiceId, queryParameters); } - private record RequestContext(ElevenLabsApi.SpeechRequest request, String voiceId, - MultiValueMap queryParameters) { - } - private MultiValueMap buildQueryParameters(ElevenLabsTextToSpeechOptions options) { MultiValueMap queryParameters = new LinkedMultiValueMap<>(); if (options.getEnableLogging() != null) { @@ -209,11 +205,15 @@ public Builder defaultOptions(ElevenLabsTextToSpeechOptions defaultOptions) { } public ElevenLabsTextToSpeechModel build() { - Assert.notNull(elevenLabsApi, "ElevenLabsApi must not be null"); - Assert.notNull(defaultOptions, "ElevenLabsSpeechOptions must not be null"); - return new ElevenLabsTextToSpeechModel(elevenLabsApi, defaultOptions, retryTemplate); + Assert.notNull(this.elevenLabsApi, "ElevenLabsApi must not be null"); + Assert.notNull(this.defaultOptions, "ElevenLabsSpeechOptions must not be null"); + return new ElevenLabsTextToSpeechModel(this.elevenLabsApi, this.defaultOptions, this.retryTemplate); } } + private record RequestContext(ElevenLabsApi.SpeechRequest request, String voiceId, + MultiValueMap queryParameters) { + } + } diff --git a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java index d60584a115b..b2037672c55 100644 --- a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java +++ b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java @@ -264,38 +264,42 @@ public void setApplyLanguageTextNormalization(Boolean applyLanguageTextNormaliza @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof ElevenLabsTextToSpeechOptions that)) + } + if (!(o instanceof ElevenLabsTextToSpeechOptions that)) { return false; - return Objects.equals(modelId, that.modelId) && Objects.equals(voiceId, that.voiceId) - && Objects.equals(outputFormat, that.outputFormat) && Objects.equals(voiceSettings, that.voiceSettings) - && Objects.equals(languageCode, that.languageCode) - && Objects.equals(pronunciationDictionaryLocators, that.pronunciationDictionaryLocators) - && Objects.equals(seed, that.seed) && Objects.equals(previousText, that.previousText) - && Objects.equals(nextText, that.nextText) - && Objects.equals(previousRequestIds, that.previousRequestIds) - && Objects.equals(applyTextNormalization, that.applyTextNormalization) - && Objects.equals(nextRequestIds, that.nextRequestIds) - && Objects.equals(applyLanguageTextNormalization, that.applyLanguageTextNormalization); + } + return Objects.equals(this.modelId, that.modelId) && Objects.equals(this.voiceId, that.voiceId) + && Objects.equals(this.outputFormat, that.outputFormat) + && Objects.equals(this.voiceSettings, that.voiceSettings) + && Objects.equals(this.languageCode, that.languageCode) + && Objects.equals(this.pronunciationDictionaryLocators, that.pronunciationDictionaryLocators) + && Objects.equals(this.seed, that.seed) && Objects.equals(this.previousText, that.previousText) + && Objects.equals(this.nextText, that.nextText) + && Objects.equals(this.previousRequestIds, that.previousRequestIds) + && Objects.equals(this.applyTextNormalization, that.applyTextNormalization) + && Objects.equals(this.nextRequestIds, that.nextRequestIds) + && Objects.equals(this.applyLanguageTextNormalization, that.applyLanguageTextNormalization); } @Override public int hashCode() { - return Objects.hash(modelId, voiceId, outputFormat, voiceSettings, languageCode, - pronunciationDictionaryLocators, seed, previousText, nextText, previousRequestIds, nextRequestIds, - applyTextNormalization, applyLanguageTextNormalization); + return Objects.hash(this.modelId, this.voiceId, this.outputFormat, this.voiceSettings, this.languageCode, + this.pronunciationDictionaryLocators, this.seed, this.previousText, this.nextText, + this.previousRequestIds, this.nextRequestIds, this.applyTextNormalization, + this.applyLanguageTextNormalization); } @Override public String toString() { - return "ElevenLabsSpeechOptions{" + "modelId='" + modelId + '\'' + ", voiceId='" + voiceId + '\'' - + ", outputFormat='" + outputFormat + '\'' + ", voiceSettings=" + voiceSettings + ", languageCode='" - + languageCode + '\'' + ", pronunciationDictionaryLocators=" + pronunciationDictionaryLocators - + ", seed=" + seed + ", previousText='" + previousText + '\'' + ", nextText='" + nextText + '\'' - + ", previousRequestIds=" + previousRequestIds + ", nextRequestIds=" + nextRequestIds - + ", applyTextNormalization=" + applyTextNormalization + ", applyLanguageTextNormalization=" - + applyLanguageTextNormalization + '}'; + return "ElevenLabsSpeechOptions{" + "modelId='" + this.modelId + '\'' + ", voiceId='" + this.voiceId + '\'' + + ", outputFormat='" + this.outputFormat + '\'' + ", voiceSettings=" + this.voiceSettings + + ", languageCode='" + this.languageCode + '\'' + ", pronunciationDictionaryLocators=" + + this.pronunciationDictionaryLocators + ", seed=" + this.seed + ", previousText='" + this.previousText + + '\'' + ", nextText='" + this.nextText + '\'' + ", previousRequestIds=" + this.previousRequestIds + + ", nextRequestIds=" + this.nextRequestIds + ", applyTextNormalization=" + this.applyTextNormalization + + ", applyLanguageTextNormalization=" + this.applyLanguageTextNormalization + '}'; } @Override @@ -331,7 +335,7 @@ public static class Builder { * @return this builder. */ public Builder model(String model) { - options.setModel(model); + this.options.setModel(model); return this; } @@ -342,7 +346,7 @@ public Builder model(String model) { * @return this builder. */ public Builder modelId(String modelId) { - options.setModelId(modelId); + this.options.setModelId(modelId); return this; } @@ -353,7 +357,7 @@ public Builder modelId(String modelId) { * @return this builder. */ public Builder voice(String voice) { - options.setVoice(voice); + this.options.setVoice(voice); return this; } @@ -364,69 +368,69 @@ public Builder voice(String voice) { * @return this builder. */ public Builder voiceId(String voiceId) { - options.setVoiceId(voiceId); + this.options.setVoiceId(voiceId); return this; } public Builder format(String format) { - options.setFormat(format); + this.options.setFormat(format); return this; } public Builder outputFormat(String outputFormat) { - options.setOutputFormat(outputFormat); + this.options.setOutputFormat(outputFormat); return this; } public Builder voiceSettings(ElevenLabsApi.SpeechRequest.VoiceSettings voiceSettings) { - options.setVoiceSettings(voiceSettings); + this.options.setVoiceSettings(voiceSettings); return this; } public Builder languageCode(String languageCode) { - options.setLanguageCode(languageCode); + this.options.setLanguageCode(languageCode); return this; } public Builder pronunciationDictionaryLocators( List pronunciationDictionaryLocators) { - options.setPronunciationDictionaryLocators(pronunciationDictionaryLocators); + this.options.setPronunciationDictionaryLocators(pronunciationDictionaryLocators); return this; } public Builder seed(Integer seed) { - options.setSeed(seed); + this.options.setSeed(seed); return this; } public Builder previousText(String previousText) { - options.setPreviousText(previousText); + this.options.setPreviousText(previousText); return this; } public Builder nextText(String nextText) { - options.setNextText(nextText); + this.options.setNextText(nextText); return this; } public Builder previousRequestIds(List previousRequestIds) { - options.setPreviousRequestIds(previousRequestIds); + this.options.setPreviousRequestIds(previousRequestIds); return this; } public Builder nextRequestIds(List nextRequestIds) { - options.setNextRequestIds(nextRequestIds); + this.options.setNextRequestIds(nextRequestIds); return this; } public Builder applyTextNormalization( ElevenLabsApi.SpeechRequest.TextNormalizationMode applyTextNormalization) { - options.setApplyTextNormalization(applyTextNormalization); + this.options.setApplyTextNormalization(applyTextNormalization); return this; } public Builder applyLanguageTextNormalization(Boolean applyLanguageTextNormalization) { - options.setApplyLanguageTextNormalization(applyLanguageTextNormalization); + this.options.setApplyLanguageTextNormalization(applyLanguageTextNormalization); return this; } diff --git a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/api/ElevenLabsApi.java b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/api/ElevenLabsApi.java index 2b309f130d2..407cf3bd9a9 100644 --- a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/api/ElevenLabsApi.java +++ b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/api/ElevenLabsApi.java @@ -45,7 +45,7 @@ * * @author Alexandros Pappas */ -public class ElevenLabsApi { +public final class ElevenLabsApi { public static final String DEFAULT_BASE_URL = "https://api.elevenlabs.io"; @@ -311,10 +311,11 @@ public Builder applyLanguageTextNormalization(Boolean applyLanguageTextNormaliza } public SpeechRequest build() { - Assert.hasText(text, "text must not be empty"); - return new SpeechRequest(text, modelId, languageCode, voiceSettings, pronunciationDictionaryLocators, - seed, previousText, nextText, previousRequestIds, nextRequestIds, applyTextNormalization, - applyLanguageTextNormalization); + Assert.hasText(this.text, "text must not be empty"); + return new SpeechRequest(this.text, this.modelId, this.languageCode, this.voiceSettings, + this.pronunciationDictionaryLocators, this.seed, this.previousText, this.nextText, + this.previousRequestIds, this.nextRequestIds, this.applyTextNormalization, + this.applyLanguageTextNormalization); } } diff --git a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModelIT.java b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModelIT.java index 1a9ade0feef..0cc3d45d8bb 100644 --- a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModelIT.java +++ b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechModelIT.java @@ -26,10 +26,9 @@ import org.springframework.ai.audio.tts.TextToSpeechPrompt; import org.springframework.ai.audio.tts.TextToSpeechResponse; import org.springframework.ai.elevenlabs.api.ElevenLabsApi; +import org.springframework.ai.retry.NonTransientAiException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.ai.retry.NonTransientAiException; -import org.springframework.web.client.HttpClientErrorException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -56,7 +55,7 @@ public class ElevenLabsTextToSpeechModelIT { void textToSpeechWithVoiceTest() { ElevenLabsTextToSpeechOptions options = ElevenLabsTextToSpeechOptions.builder().voice(VOICE_ID).build(); TextToSpeechPrompt prompt = new TextToSpeechPrompt("Hello, world!", options); - TextToSpeechResponse response = textToSpeechModel.call(prompt); + TextToSpeechResponse response = this.textToSpeechModel.call(prompt); assertThat(response).isNotNull(); List results = response.getResults(); @@ -70,7 +69,7 @@ void textToSpeechStreamWithVoiceTest() { ElevenLabsTextToSpeechOptions options = ElevenLabsTextToSpeechOptions.builder().voice(VOICE_ID).build(); TextToSpeechPrompt prompt = new TextToSpeechPrompt( "Hello, world! This is a test of streaming speech synthesis.", options); - Flux responseFlux = textToSpeechModel.stream(prompt); + Flux responseFlux = this.textToSpeechModel.stream(prompt); List responses = responseFlux.collectList().block(); assertThat(responses).isNotNull().isNotEmpty(); @@ -92,18 +91,14 @@ void invalidVoiceId() { TextToSpeechPrompt speechPrompt = new TextToSpeechPrompt("Hello, this is a text-to-speech example.", options); - assertThatThrownBy(() -> { - textToSpeechModel.call(speechPrompt); - }).isInstanceOf(NonTransientAiException.class) + assertThatThrownBy(() -> this.textToSpeechModel.call(speechPrompt)).isInstanceOf(NonTransientAiException.class) .hasMessageContaining("An invalid ID has been received: 'invalid-voice-id'"); } @Test void emptyInputText() { TextToSpeechPrompt prompt = new TextToSpeechPrompt(""); - assertThatThrownBy(() -> { - textToSpeechModel.call(prompt); - }).isInstanceOf(IllegalArgumentException.class) + assertThatThrownBy(() -> this.textToSpeechModel.call(prompt)).isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("A voiceId must be specified in the ElevenLabsSpeechOptions."); } diff --git a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsApiIT.java b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsApiIT.java index 8b2c8f0669c..9c3215203d6 100644 --- a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsApiIT.java +++ b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsApiIT.java @@ -58,7 +58,7 @@ public void testTextToSpeech() throws IOException { .build(); String validVoiceId = "9BWtsMINqrJLrRacOk9x"; - ResponseEntity response = elevenLabsApi.textToSpeech(request, validVoiceId, null); + ResponseEntity response = this.elevenLabsApi.textToSpeech(request, validVoiceId, null); assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(response.getBody()).isNotNull().isNotEmpty(); @@ -73,7 +73,7 @@ public void testTextToSpeechWithVoiceSettings() { .build(); String validVoiceId = "9BWtsMINqrJLrRacOk9x"; - ResponseEntity response = elevenLabsApi.textToSpeech(request, validVoiceId, null); + ResponseEntity response = this.elevenLabsApi.textToSpeech(request, validVoiceId, null); assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(response.getBody()).isNotNull().isNotEmpty(); @@ -92,7 +92,7 @@ public void testTextToSpeechWithQueryParams() { queryParams.add("enable_logging", "true"); queryParams.add("output_format", ElevenLabsApi.OutputFormat.MP3_22050_32.getValue()); - ResponseEntity response = elevenLabsApi.textToSpeech(request, validVoiceId, queryParams); + ResponseEntity response = this.elevenLabsApi.textToSpeech(request, validVoiceId, queryParams); assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(response.getBody()).isNotNull().isNotEmpty(); @@ -106,7 +106,7 @@ public void testTextToSpeechVoiceIdNull() { .build(); Exception exception = assertThrows(IllegalArgumentException.class, - () -> elevenLabsApi.textToSpeech(request, null, null)); + () -> this.elevenLabsApi.textToSpeech(request, null, null)); assertThat(exception.getMessage()).isEqualTo("voiceId must be provided. It cannot be null."); } @@ -127,7 +127,7 @@ public void testTextToSpeechStream() { .build(); String validVoiceId = "9BWtsMINqrJLrRacOk9x"; - Flux> responseFlux = elevenLabsApi.textToSpeechStream(request, validVoiceId, null); + Flux> responseFlux = this.elevenLabsApi.textToSpeechStream(request, validVoiceId, null); // Track the number of chunks received AtomicInteger chunkCount = new AtomicInteger(0); @@ -154,7 +154,7 @@ public void testTextToSpeechStreamWithVoiceSettings() { .build(); String validVoiceId = "9BWtsMINqrJLrRacOk9x"; - Flux> responseFlux = elevenLabsApi.textToSpeechStream(request, validVoiceId, null); + Flux> responseFlux = this.elevenLabsApi.textToSpeechStream(request, validVoiceId, null); StepVerifier.create(responseFlux).thenConsumeWhile(response -> { assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); @@ -176,7 +176,7 @@ public void testTextToSpeechStreamWithQueryParams() { queryParams.add("enable_logging", "true"); queryParams.add("output_format", "mp3_44100_128"); - Flux> responseFlux = elevenLabsApi.textToSpeechStream(request, validVoiceId, + Flux> responseFlux = this.elevenLabsApi.textToSpeechStream(request, validVoiceId, queryParams); StepVerifier.create(responseFlux).thenConsumeWhile(response -> { @@ -194,7 +194,7 @@ public void testTextToSpeechStreamVoiceIdNull() { .build(); Exception exception = assertThrows(IllegalArgumentException.class, - () -> elevenLabsApi.textToSpeechStream(request, null, null)); + () -> this.elevenLabsApi.textToSpeechStream(request, null, null)); assertThat(exception.getMessage()).isEqualTo("voiceId must be provided for streaming. It cannot be null."); } @@ -203,7 +203,7 @@ public void testTextToSpeechStreamRequestBodyNull() { String validVoiceId = "9BWtsMINqrJLrRacOk9x"; Exception exception = assertThrows(IllegalArgumentException.class, - () -> elevenLabsApi.textToSpeechStream(null, validVoiceId, null)); + () -> this.elevenLabsApi.textToSpeechStream(null, validVoiceId, null)); assertThat(exception.getMessage()).isEqualTo("requestBody can not be null."); } @@ -216,7 +216,7 @@ public void testTextToSpeechStreamTextEmpty() { .build(); String validVoiceId = "9BWtsMINqrJLrRacOk9x"; - elevenLabsApi.textToSpeechStream(request, validVoiceId, null); + this.elevenLabsApi.textToSpeechStream(request, validVoiceId, null); }); assertThat(exception.getMessage()).isEqualTo("text must not be empty"); } diff --git a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsVoicesApiIT.java b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsVoicesApiIT.java index c10efa78353..44fbb43726e 100644 --- a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsVoicesApiIT.java +++ b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/api/ElevenLabsVoicesApiIT.java @@ -46,7 +46,7 @@ public class ElevenLabsVoicesApiIT { @Test void getVoices() { - ResponseEntity response = voicesApi.getVoices(); + ResponseEntity response = this.voicesApi.getVoices(); System.out.println("Response: " + response); assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); @@ -63,7 +63,7 @@ void getVoices() { @Test void getDefaultVoiceSettings() { - ResponseEntity response = voicesApi.getDefaultVoiceSettings(); + ResponseEntity response = this.voicesApi.getDefaultVoiceSettings(); assertThat(response.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(response.getBody()).isNotNull(); @@ -76,13 +76,13 @@ void getDefaultVoiceSettings() { @Test void getVoiceSettings() { - ResponseEntity voicesResponse = voicesApi.getVoices(); + ResponseEntity voicesResponse = this.voicesApi.getVoices(); assertThat(voicesResponse.getStatusCode().is2xxSuccessful()).isTrue(); List voices = voicesResponse.getBody().voices(); assertThat(voices).isNotEmpty(); String voiceId = voices.get(0).voiceId(); - ResponseEntity settingsResponse = voicesApi.getVoiceSettings(voiceId); + ResponseEntity settingsResponse = this.voicesApi.getVoiceSettings(voiceId); assertThat(settingsResponse.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(settingsResponse.getBody()).isNotNull(); @@ -95,13 +95,13 @@ void getVoiceSettings() { @Test void getVoice() { - ResponseEntity voicesResponse = voicesApi.getVoices(); + ResponseEntity voicesResponse = this.voicesApi.getVoices(); assertThat(voicesResponse.getStatusCode().is2xxSuccessful()).isTrue(); List voices = voicesResponse.getBody().voices(); assertThat(voices).isNotEmpty(); String voiceId = voices.get(0).voiceId(); - ResponseEntity voiceResponse = voicesApi.getVoice(voiceId); + ResponseEntity voiceResponse = this.voicesApi.getVoice(voiceId); assertThat(voiceResponse.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(voiceResponse.getBody()).isNotNull(); diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxChatOptions.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxChatOptions.java index a8f1e62e77e..3ef50450d9a 100644 --- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxChatOptions.java +++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxChatOptions.java @@ -364,28 +364,32 @@ public void setToolContext(Map toolContext) { @Override public int hashCode() { - return Objects.hash(model, frequencyPenalty, maxTokens, n, presencePenalty, responseFormat, seed, stop, - temperature, topP, maskSensitiveInfo, tools, toolChoice, toolCallbacks, toolNames, toolContext, - internalToolExecutionEnabled); + return Objects.hash(this.model, this.frequencyPenalty, this.maxTokens, this.n, this.presencePenalty, + this.responseFormat, this.seed, this.stop, this.temperature, this.topP, this.maskSensitiveInfo, + this.tools, this.toolChoice, this.toolCallbacks, this.toolNames, this.toolContext, + this.internalToolExecutionEnabled); } @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } MiniMaxChatOptions that = (MiniMaxChatOptions) o; - return Objects.equals(model, that.model) && Objects.equals(frequencyPenalty, that.frequencyPenalty) - && Objects.equals(maxTokens, that.maxTokens) && Objects.equals(n, that.n) - && Objects.equals(presencePenalty, that.presencePenalty) - && Objects.equals(responseFormat, that.responseFormat) && Objects.equals(seed, that.seed) - && Objects.equals(stop, that.stop) && Objects.equals(temperature, that.temperature) - && Objects.equals(topP, that.topP) && Objects.equals(maskSensitiveInfo, that.maskSensitiveInfo) - && Objects.equals(tools, that.tools) && Objects.equals(toolChoice, that.toolChoice) - && Objects.equals(toolCallbacks, that.toolCallbacks) && Objects.equals(toolNames, that.toolNames) - && Objects.equals(toolContext, that.toolContext) - && Objects.equals(internalToolExecutionEnabled, that.internalToolExecutionEnabled); + return Objects.equals(this.model, that.model) && Objects.equals(this.frequencyPenalty, that.frequencyPenalty) + && Objects.equals(this.maxTokens, that.maxTokens) && Objects.equals(this.n, that.n) + && Objects.equals(this.presencePenalty, that.presencePenalty) + && Objects.equals(this.responseFormat, that.responseFormat) && Objects.equals(this.seed, that.seed) + && Objects.equals(this.stop, that.stop) && Objects.equals(this.temperature, that.temperature) + && Objects.equals(this.topP, that.topP) + && Objects.equals(this.maskSensitiveInfo, that.maskSensitiveInfo) + && Objects.equals(this.tools, that.tools) && Objects.equals(this.toolChoice, that.toolChoice) + && Objects.equals(this.toolCallbacks, that.toolCallbacks) + && Objects.equals(this.toolNames, that.toolNames) && Objects.equals(this.toolContext, that.toolContext) + && Objects.equals(this.internalToolExecutionEnabled, that.internalToolExecutionEnabled); } @Override diff --git a/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java index cbcd25a87de..51fac854755 100644 --- a/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java +++ b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java @@ -16,13 +16,14 @@ package org.springframework.ai.minimax; -import org.junit.jupiter.api.Test; -import org.springframework.ai.minimax.api.MiniMaxApi; - import java.util.List; import java.util.Map; import java.util.Set; +import org.junit.jupiter.api.Test; + +import org.springframework.ai.minimax.api.MiniMaxApi; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java index 3177e85a442..ffc892b68a3 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java @@ -19,12 +19,12 @@ import java.util.List; import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; - import org.junit.jupiter.api.Test; -import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest.ResponseFormat; import org.springframework.ai.mistralai.api.MistralAiApi; +import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest.ResponseFormat; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link MistralAiChatOptions}. 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 44dc45347b6..d36c779ed26 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 @@ -65,13 +65,10 @@ 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.retry.RetryUtils; import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.ai.util.json.JsonParser; - -import org.springframework.ai.retry.RetryUtils; import org.springframework.retry.support.RetryTemplate; - import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelFunctionCallingIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelFunctionCallingIT.java index f8ec3091c3f..8400d3d8622 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelFunctionCallingIT.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelFunctionCallingIT.java @@ -35,8 +35,8 @@ import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaOptions; import org.springframework.ai.ollama.api.tool.MockWeatherService; -import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.ai.retry.RetryUtils; +import org.springframework.ai.tool.function.FunctionToolCallback; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.test.context.SpringBootTest; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelIT.java index ae79f67350e..c9f3a920b1d 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelIT.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelIT.java @@ -52,12 +52,9 @@ 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.retry.RetryUtils; import org.springframework.ai.support.ToolCallbacks; import org.springframework.ai.tool.annotation.Tool; - -import org.springframework.ai.retry.RetryUtils; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.test.context.SpringBootTest; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java index 3174c459afb..a2444116b33 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java @@ -28,7 +28,6 @@ import org.springframework.ai.content.Media; import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaOptions; -import org.springframework.ai.retry.RetryUtils; import org.springframework.ai.retry.TransientAiException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; 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 1cb17781b0e..aa4a5fedfe4 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 @@ -38,7 +38,9 @@ import org.springframework.ai.retry.RetryUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author Jihoon Kim diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java index dbc65e1fb25..d03de073b7e 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatRequestTests.java @@ -25,10 +25,10 @@ import org.springframework.ai.model.tool.ToolCallingChatOptions; import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaOptions; +import org.springframework.ai.retry.RetryUtils; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.definition.DefaultToolDefinition; import org.springframework.ai.tool.definition.ToolDefinition; -import org.springframework.ai.retry.RetryUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaRetryTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaRetryTests.java index bb1c1bb22ee..ec468df8db3 100644 --- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaRetryTests.java +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaRetryTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-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. + * 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.ollama; import java.time.Instant; 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 44e08cc114d..9177c365a8d 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 @@ -71,9 +71,7 @@ public OpenAiAudioApi(String baseUrl, ApiKey apiKey, MultiValueMap authHeaders = h -> { - h.addAll(headers); - }; + Consumer authHeaders = h -> h.addAll(headers); // @formatter:off this.restClient = restClientBuilder.clone() diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java index 70b7f1fad66..245624768e6 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java @@ -30,7 +30,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice.ALLOY; -import static org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.WebSearchOptions.SearchContextSize.MEDIUM; /** * Tests for {@link OpenAiChatOptions}. @@ -263,14 +262,16 @@ void testDefaultValues() { @Test void testFromOptions_webSearchOptions() { var chatOptions = OpenAiChatOptions.builder() - .webSearchOptions(new OpenAiApi.ChatCompletionRequest.WebSearchOptions(MEDIUM, + .webSearchOptions(new OpenAiApi.ChatCompletionRequest.WebSearchOptions( + org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.WebSearchOptions.SearchContextSize.MEDIUM, new OpenAiApi.ChatCompletionRequest.WebSearchOptions.UserLocation("type", new OpenAiApi.ChatCompletionRequest.WebSearchOptions.UserLocation.Approximate("beijing", "china", "region", "UTC+8")))) .build(); var target = OpenAiChatOptions.fromOptions(chatOptions); assertThat(target.getWebSearchOptions()).isNotNull(); - assertThat(target.getWebSearchOptions().searchContextSize()).isEqualTo(MEDIUM); + assertThat(target.getWebSearchOptions().searchContextSize()).isEqualTo( + org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.WebSearchOptions.SearchContextSize.MEDIUM); assertThat(target.getWebSearchOptions().userLocation()).isNotNull(); assertThat(target.getWebSearchOptions().userLocation().type()).isEqualTo("type"); assertThat(target.getWebSearchOptions().userLocation().approximate()).isNotNull(); diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java index b47a4a91bac..72329d3aa88 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiBuilderTests.java @@ -166,13 +166,13 @@ class MockRequests { @BeforeEach void setUp() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(); + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); } @AfterEach void tearDown() throws IOException { - mockWebServer.shutdown(); + this.mockWebServer.shutdown(); } @Test @@ -180,7 +180,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiApi api = OpenAiApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -208,8 +208,8 @@ void dynamicApiKeyRestClient() throws InterruptedException { } } """); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiApi.ChatCompletionMessage chatCompletionMessage = new OpenAiApi.ChatCompletionMessage("Hello world", OpenAiApi.ChatCompletionMessage.Role.USER); @@ -217,13 +217,13 @@ void dynamicApiKeyRestClient() throws InterruptedException { List.of(chatCompletionMessage), "gpt-3.5-turbo", 0.8, false); ResponseEntity response = api.chatCompletionEntity(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.chatCompletionEntity(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } @@ -231,7 +231,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { void dynamicApiKeyRestClientWithAdditionalAuthorizationHeader() throws InterruptedException { OpenAiApi api = OpenAiApi.builder().apiKey(() -> { throw new AssertionFailedError("Should not be called, API key is provided in headers"); - }).baseUrl(mockWebServer.url("/").toString()).build(); + }).baseUrl(this.mockWebServer.url("/").toString()).build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) @@ -258,7 +258,7 @@ void dynamicApiKeyRestClientWithAdditionalAuthorizationHeader() throws Interrupt } } """); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiApi.ChatCompletionMessage chatCompletionMessage = new OpenAiApi.ChatCompletionMessage("Hello world", OpenAiApi.ChatCompletionMessage.Role.USER); @@ -269,7 +269,7 @@ void dynamicApiKeyRestClientWithAdditionalAuthorizationHeader() throws Interrupt additionalHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer additional-key"); ResponseEntity response = api.chatCompletionEntity(request, additionalHeaders); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer additional-key"); } @@ -278,7 +278,7 @@ void dynamicApiKeyWebClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiApi api = OpenAiApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -306,8 +306,8 @@ void dynamicApiKeyWebClient() throws InterruptedException { } } """.replace("\n", "")); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiApi.ChatCompletionMessage chatCompletionMessage = new OpenAiApi.ChatCompletionMessage("Hello world", OpenAiApi.ChatCompletionMessage.Role.USER); @@ -315,13 +315,13 @@ void dynamicApiKeyWebClient() throws InterruptedException { List.of(chatCompletionMessage), "gpt-3.5-turbo", 0.8, true); List response = api.chatCompletionStream(request).collectList().block(); assertThat(response).hasSize(1); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.chatCompletionStream(request).collectList().block(); assertThat(response).hasSize(1); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } @@ -329,7 +329,7 @@ void dynamicApiKeyWebClient() throws InterruptedException { void dynamicApiKeyWebClientWithAdditionalAuthorizationHeader() throws InterruptedException { OpenAiApi api = OpenAiApi.builder().apiKey(() -> { throw new AssertionFailedError("Should not be called, API key is provided in headers"); - }).baseUrl(mockWebServer.url("/").toString()).build(); + }).baseUrl(this.mockWebServer.url("/").toString()).build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) @@ -356,7 +356,7 @@ void dynamicApiKeyWebClientWithAdditionalAuthorizationHeader() throws Interrupte } } """.replace("\n", "")); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiApi.ChatCompletionMessage chatCompletionMessage = new OpenAiApi.ChatCompletionMessage("Hello world", OpenAiApi.ChatCompletionMessage.Role.USER); @@ -368,7 +368,7 @@ void dynamicApiKeyWebClientWithAdditionalAuthorizationHeader() throws Interrupte .collectList() .block(); assertThat(response).hasSize(1); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer additional-key"); } @@ -377,7 +377,7 @@ void dynamicApiKeyRestClientEmbeddings() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiApi api = OpenAiApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -407,19 +407,19 @@ void dynamicApiKeyRestClientEmbeddings() throws InterruptedException { } } """); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiApi.EmbeddingRequest request = new OpenAiApi.EmbeddingRequest<>("Hello world"); ResponseEntity> response = api.embeddings(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.embeddings(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelperTest.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelperTest.java index 53d6c0e4063..98195aaa0ae 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelperTest.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelperTest.java @@ -20,10 +20,12 @@ import java.util.Collections; import java.util.List; import java.util.function.Consumer; -import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import static org.assertj.core.api.Assertions.assertThat; + /** * Unit tests for {@link OpenAiStreamFunctionCallingHelper} * @@ -42,27 +44,27 @@ public void merge_whenInputIsValid() { var current = new OpenAiApi.ChatCompletionChunk(expectedResult.id(), null, null, null, null, expectedResult.systemFingerprint(), expectedResult.object(), expectedResult.usage()); - var result = helper.merge(previous, current); + var result = this.helper.merge(previous, current); assertThat(result).isEqualTo(expectedResult); } @Test public void isStreamingToolFunctionCall_whenChatCompletionChunkIsNull() { - assertThat(helper.isStreamingToolFunctionCall(null)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCall(null)).isFalse(); } @Test public void isStreamingToolFunctionCall_whenChatCompletionChunkChoicesIsEmpty() { var chunk = new OpenAiApi.ChatCompletionChunk(null, Collections.emptyList(), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCall(chunk)).isFalse(); } @Test public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceIsNull() { var choice = (org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice) null; var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCall(chunk)).isFalse(); } @Test @@ -71,16 +73,16 @@ public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaI null); var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice, null), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCall(chunk)).isFalse(); } @Test public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaToolCallsIsNullOrEmpty() { - var assertion = (Consumer) (OpenAiApi.ChatCompletionMessage delta) -> { + var assertion = (Consumer) delta -> { var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null, delta, null); var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCall(chunk)).isFalse(); }; // Test for null. assertion.accept(new OpenAiApi.ChatCompletionMessage(null, null)); @@ -91,11 +93,11 @@ public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaT @Test public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaToolCallsIsNonEmpty() { - var assertion = (Consumer) (OpenAiApi.ChatCompletionMessage delta) -> { + var assertion = (Consumer) delta -> { var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null, delta, null); var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCall(chunk)).isTrue(); + assertThat(this.helper.isStreamingToolFunctionCall(chunk)).isTrue(); }; assertion.accept(new OpenAiApi.ChatCompletionMessage(null, null, null, null, List.of(Mockito.mock(org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.ToolCall.class)), @@ -104,21 +106,21 @@ public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaT @Test public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkIsNull() { - assertThat(helper.isStreamingToolFunctionCallFinish(null)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(null)).isFalse(); } @Test public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkChoicesIsEmpty() { var chunk = new OpenAiApi.ChatCompletionChunk(null, Collections.emptyList(), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); } @Test public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoiceIsNull() { var choice = (org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice) null; var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); } @Test @@ -127,7 +129,7 @@ public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoice null); var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice, null), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); } @Test @@ -135,7 +137,7 @@ public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoice var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null, new OpenAiApi.ChatCompletionMessage(null, null), null); var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(chunk)).isFalse(); } @Test @@ -144,7 +146,7 @@ public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoice OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS, null, new OpenAiApi.ChatCompletionMessage(null, null), null); var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null); - assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isTrue(); + assertThat(this.helper.isStreamingToolFunctionCallFinish(chunk)).isTrue(); } @Test @@ -157,9 +159,9 @@ public void chunkToChatCompletion_whenInputIsValid() { null); var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice1, choice2), null, null, null, null, null, null); - OpenAiApi.ChatCompletion result = helper.chunkToChatCompletion(chunk); + OpenAiApi.ChatCompletion result = this.helper.chunkToChatCompletion(chunk); assertThat(result.object()).isEqualTo("chat.completion"); assertThat(result.choices()).hasSize(2); } -} \ No newline at end of file +} diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiBuilderTests.java index 1b11fa6807a..ecd506277d3 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiBuilderTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiBuilderTests.java @@ -16,20 +16,20 @@ package org.springframework.ai.openai.audio.api; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; + import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.SimpleApiKey; import org.springframework.ai.openai.api.OpenAiAudioApi; @@ -43,9 +43,9 @@ import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; /** * @author Filip Hrisafov @@ -135,13 +135,13 @@ class MockRequests { @BeforeEach void setUp() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(); + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); } @AfterEach void tearDown() throws IOException { - mockWebServer.shutdown(); + this.mockWebServer.shutdown(); } @Test @@ -149,14 +149,14 @@ void dynamicApiKeyRestClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiAudioApi api = OpenAiAudioApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE) .setBody("Audio bytes as string"); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiAudioApi.SpeechRequest request = OpenAiAudioApi.SpeechRequest.builder() .model(OpenAiAudioApi.TtsModel.TTS_1.value) @@ -164,13 +164,13 @@ void dynamicApiKeyRestClient() throws InterruptedException { .build(); ResponseEntity response = api.createSpeech(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.createSpeech(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } @@ -179,14 +179,14 @@ void dynamicApiKeyWebClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiAudioApi api = OpenAiAudioApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE) .setBody("Audio bytes as string"); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiAudioApi.SpeechRequest request = OpenAiAudioApi.SpeechRequest.builder() .model(OpenAiAudioApi.TtsModel.TTS_1.value) @@ -194,13 +194,13 @@ void dynamicApiKeyWebClient() throws InterruptedException { .build(); List> response = api.stream(request).collectList().block(); assertThat(response).hasSize(1); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.stream(request).collectList().block(); assertThat(response).hasSize(1); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } 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 f1a91dc6060..ed35717a5ef 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 @@ -30,8 +30,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.util.MimeType; import reactor.core.publisher.Flux; import org.springframework.ai.chat.messages.SystemMessage; @@ -42,7 +40,9 @@ import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest; +import org.springframework.core.io.ByteArrayResource; import org.springframework.http.ResponseEntity; +import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; import org.springframework.util.MultiValueMap; diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/api/OpenAiImageApiBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/api/OpenAiImageApiBuilderTests.java index 5564a087a71..50bfd71fef3 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/api/OpenAiImageApiBuilderTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/api/OpenAiImageApiBuilderTests.java @@ -16,20 +16,20 @@ package org.springframework.ai.openai.image.api; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; + import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.SimpleApiKey; import org.springframework.ai.openai.api.OpenAiImageApi; @@ -42,9 +42,9 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; /** * @author Filip Hrisafov @@ -125,13 +125,13 @@ class MockRequests { @BeforeEach void setUp() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(); + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); } @AfterEach void tearDown() throws IOException { - mockWebServer.shutdown(); + this.mockWebServer.shutdown(); } @Test @@ -139,7 +139,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiImageApi api = OpenAiImageApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -154,20 +154,20 @@ void dynamicApiKeyRestClient() throws InterruptedException { ] } """); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiImageApi.OpenAiImageRequest request = new OpenAiImageApi.OpenAiImageRequest("Test", OpenAiImageApi.ImageModel.DALL_E_3.getValue()); ResponseEntity response = api.createImage(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.createImage(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/moderation/api/OpenAiModerationApiBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/moderation/api/OpenAiModerationApiBuilderTests.java index 1c757789b27..f2fe8cd167f 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/moderation/api/OpenAiModerationApiBuilderTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/moderation/api/OpenAiModerationApiBuilderTests.java @@ -16,20 +16,20 @@ package org.springframework.ai.openai.moderation.api; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Queue; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; + import org.springframework.ai.model.ApiKey; import org.springframework.ai.model.SimpleApiKey; import org.springframework.ai.openai.api.OpenAiModerationApi; @@ -42,9 +42,9 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; /** * @author Filip Hrisafov @@ -125,13 +125,13 @@ class MockRequests { @BeforeEach void setUp() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(); + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); } @AfterEach void tearDown() throws IOException { - mockWebServer.shutdown(); + this.mockWebServer.shutdown(); } @Test @@ -139,7 +139,7 @@ void dynamicApiKeyRestClient() throws InterruptedException { Queue apiKeys = new LinkedList<>(List.of(new SimpleApiKey("key1"), new SimpleApiKey("key2"))); OpenAiModerationApi api = OpenAiModerationApi.builder() .apiKey(() -> Objects.requireNonNull(apiKeys.poll()).getValue()) - .baseUrl(mockWebServer.url("/").toString()) + .baseUrl(this.mockWebServer.url("/").toString()) .build(); MockResponse mockResponse = new MockResponse().setResponseCode(200) @@ -154,20 +154,20 @@ void dynamicApiKeyRestClient() throws InterruptedException { ] } """); - mockWebServer.enqueue(mockResponse); - mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); + this.mockWebServer.enqueue(mockResponse); OpenAiModerationApi.OpenAiModerationRequest request = new OpenAiModerationApi.OpenAiModerationRequest( "Test"); ResponseEntity response = api.createModeration(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RecordedRequest recordedRequest = mockWebServer.takeRequest(); + RecordedRequest recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key1"); response = api.createModeration(request); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - recordedRequest = mockWebServer.takeRequest(); + recordedRequest = this.mockWebServer.takeRequest(); assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer key2"); } diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/MimeTypeDetectorTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/MimeTypeDetectorTests.java index 8883c9b598c..c653df65f35 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/MimeTypeDetectorTests.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/MimeTypeDetectorTests.java @@ -30,7 +30,6 @@ import org.springframework.util.MimeType; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.ai.vertexai.gemini.MimeTypeDetector.GEMINI_MIME_TYPES; /** * @author YunKui Lu @@ -38,7 +37,9 @@ class MimeTypeDetectorTests { private static Stream provideMimeTypes() { - return GEMINI_MIME_TYPES.entrySet().stream().map(entry -> Arguments.of(entry.getKey(), entry.getValue())); + return org.springframework.ai.vertexai.gemini.MimeTypeDetector.GEMINI_MIME_TYPES.entrySet() + .stream() + .map(entry -> Arguments.of(entry.getKey(), entry.getValue())); } @ParameterizedTest diff --git a/pom.xml b/pom.xml index a555ea45419..5ec523a2706 100644 --- a/pom.xml +++ b/pom.xml @@ -343,7 +343,7 @@ true 9.3 - true + false diff --git a/spring-ai-commons/src/main/java/org/springframework/ai/document/DocumentMetadata.java b/spring-ai-commons/src/main/java/org/springframework/ai/document/DocumentMetadata.java index d5a5435e116..5cef1f5f458 100644 --- a/spring-ai-commons/src/main/java/org/springframework/ai/document/DocumentMetadata.java +++ b/spring-ai-commons/src/main/java/org/springframework/ai/document/DocumentMetadata.java @@ -32,12 +32,12 @@ public enum DocumentMetadata { * The lower the distance, the more they are similar. * It's the opposite of the similarity score. */ - DISTANCE("distance"); + DISTANCE(); private final String value; - DocumentMetadata(String value) { - this.value = value; + DocumentMetadata() { + this.value = "distance"; } public String value() { return this.value; diff --git a/spring-ai-commons/src/main/java/org/springframework/ai/observation/conventions/AiObservationMetricAttributes.java b/spring-ai-commons/src/main/java/org/springframework/ai/observation/conventions/AiObservationMetricAttributes.java index 03f4aacd0de..a06e4e60f3b 100644 --- a/spring-ai-commons/src/main/java/org/springframework/ai/observation/conventions/AiObservationMetricAttributes.java +++ b/spring-ai-commons/src/main/java/org/springframework/ai/observation/conventions/AiObservationMetricAttributes.java @@ -33,12 +33,12 @@ public enum AiObservationMetricAttributes { /** * The type of token being counted (input, output, total). */ - TOKEN_TYPE("gen_ai.token.type"); + TOKEN_TYPE(); private final String value; - AiObservationMetricAttributes(String value) { - this.value = value; + AiObservationMetricAttributes() { + this.value = "gen_ai.token.type"; } /** diff --git a/spring-ai-commons/src/test/java/org/springframework/ai/document/TextBlockAssertion.java b/spring-ai-commons/src/test/java/org/springframework/ai/document/TextBlockAssertion.java index 0490cd7a6d0..0fec59f8c0f 100644 --- a/spring-ai-commons/src/test/java/org/springframework/ai/document/TextBlockAssertion.java +++ b/spring-ai-commons/src/test/java/org/springframework/ai/document/TextBlockAssertion.java @@ -33,13 +33,13 @@ public static TextBlockAssertion assertThat(String actual) { @Override public TextBlockAssertion isEqualTo(Object expected) { - Assertions.assertThat(normalizedEOL(actual)).isEqualTo(normalizedEOL((String) expected)); + Assertions.assertThat(normalizedEOL(this.actual)).isEqualTo(normalizedEOL((String) expected)); return this; } @Override public TextBlockAssertion contains(CharSequence... values) { - Assertions.assertThat(normalizedEOL(actual)).contains(normalizedEOL(values)); + Assertions.assertThat(normalizedEOL(this.actual)).contains(normalizedEOL(values)); return this; } diff --git a/spring-ai-commons/src/test/java/org/springframework/ai/writer/FileDocumentWriterTest.java b/spring-ai-commons/src/test/java/org/springframework/ai/writer/FileDocumentWriterTest.java index f7c8c6f146c..b1b6093a554 100644 --- a/spring-ai-commons/src/test/java/org/springframework/ai/writer/FileDocumentWriterTest.java +++ b/spring-ai-commons/src/test/java/org/springframework/ai/writer/FileDocumentWriterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 the original author or authors. + * Copyright 2025-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. @@ -16,18 +16,20 @@ package org.springframework.ai.writer; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; + import org.springframework.ai.document.Document; import org.springframework.ai.document.MetadataMode; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Jemin Huh @@ -43,8 +45,8 @@ public class FileDocumentWriterTest { @BeforeEach void setUp() { - testFileName = tempDir.resolve("file-document-test-output.txt").toString(); - testDocuments = List.of( + this.testFileName = this.tempDir.resolve("file-document-test-output.txt").toString(); + this.testDocuments = List.of( Document.builder() .text("Document one introduces the core functionality of Spring AI.") .metadata("page_number", "1") @@ -69,10 +71,10 @@ void setUp() { @Test void testBasicWrite() throws IOException { - var writer = new FileDocumentWriter(testFileName); - writer.accept(testDocuments); + var writer = new FileDocumentWriter(this.testFileName); + writer.accept(this.testDocuments); - List lines = Files.readAllLines(Path.of(testFileName)); + List lines = Files.readAllLines(Path.of(this.testFileName)); assertEquals("", lines.get(0)); assertEquals("", lines.get(1)); assertEquals("Document one introduces the core functionality of Spring AI.", lines.get(2)); @@ -85,10 +87,10 @@ void testBasicWrite() throws IOException { @Test void testWriteWithDocumentMarkers() throws IOException { - var writer = new FileDocumentWriter(testFileName, true, MetadataMode.NONE, false); - writer.accept(testDocuments); + var writer = new FileDocumentWriter(this.testFileName, true, MetadataMode.NONE, false); + writer.accept(this.testDocuments); - List lines = Files.readAllLines(Path.of(testFileName)); + List lines = Files.readAllLines(Path.of(this.testFileName)); assertEquals("", lines.get(0)); assertEquals("### Doc: 0, pages:[1,2]", lines.get(1)); assertEquals("", lines.get(2)); @@ -107,10 +109,10 @@ void testWriteWithDocumentMarkers() throws IOException { @Test void testMetadataModeAllWithDocumentMarkers() throws IOException { - var writer = new FileDocumentWriter(testFileName, true, MetadataMode.ALL, false); - writer.accept(testDocuments); + var writer = new FileDocumentWriter(this.testFileName, true, MetadataMode.ALL, false); + writer.accept(this.testDocuments); - List lines = Files.readAllLines(Path.of(testFileName)); + List lines = Files.readAllLines(Path.of(this.testFileName)); assertEquals("", lines.get(0)); assertEquals("### Doc: 0, pages:[1,2]", lines.get(1)); String subListToString = lines.subList(2, 7).toString(); @@ -142,12 +144,12 @@ void testMetadataModeAllWithDocumentMarkers() throws IOException { @Test void testAppendWrite() throws IOException { - Files.writeString(Path.of(testFileName), "Test String\n"); + Files.writeString(Path.of(this.testFileName), "Test String\n"); - var writer = new FileDocumentWriter(testFileName, false, MetadataMode.NONE, true); - writer.accept(testDocuments.subList(0, 2)); + var writer = new FileDocumentWriter(this.testFileName, false, MetadataMode.NONE, true); + writer.accept(this.testDocuments.subList(0, 2)); - List lines = Files.readAllLines(Path.of(testFileName)); + List lines = Files.readAllLines(Path.of(this.testFileName)); assertEquals("Test String", lines.get(0)); assertEquals("", lines.get(1)); assertEquals("", lines.get(2)); diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptions.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptions.java index 48a23433608..73b7cfb890a 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptions.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptions.java @@ -26,7 +26,7 @@ * @author Alexandros Pappas */ @JsonInclude(JsonInclude.Include.NON_NULL) -public class DefaultTextToSpeechOptions implements TextToSpeechOptions { +public final class DefaultTextToSpeechOptions implements TextToSpeechOptions { private final String model; @@ -69,23 +69,25 @@ public Double getSpeed() { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof DefaultTextToSpeechOptions that)) + } + if (!(o instanceof DefaultTextToSpeechOptions that)) { return false; - return Objects.equals(model, that.model) && Objects.equals(voice, that.voice) - && Objects.equals(format, that.format) && Objects.equals(speed, that.speed); + } + return Objects.equals(this.model, that.model) && Objects.equals(this.voice, that.voice) + && Objects.equals(this.format, that.format) && Objects.equals(this.speed, that.speed); } @Override public int hashCode() { - return Objects.hash(model, voice, format, speed); + return Objects.hash(this.model, this.voice, this.format, this.speed); } @Override public String toString() { - return "DefaultTextToSpeechOptions{" + "model='" + model + '\'' + ", voice='" + voice + '\'' + ", format='" - + format + '\'' + ", speed=" + speed + '}'; + return "DefaultTextToSpeechOptions{" + "model='" + this.model + '\'' + ", voice='" + this.voice + '\'' + + ", format='" + this.format + '\'' + ", speed=" + this.speed + '}'; } @Override diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/Speech.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/Speech.java index 794d2a2b390..8755e7fafbd 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/Speech.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/Speech.java @@ -42,21 +42,23 @@ public byte[] getOutput() { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof Speech speech1)) + } + if (!(o instanceof Speech speech1)) { return false; - return Arrays.equals(speech, speech1.speech); + } + return Arrays.equals(this.speech, speech1.speech); } @Override public int hashCode() { - return Objects.hash(Arrays.hashCode(speech)); + return Objects.hash(Arrays.hashCode(this.speech)); } @Override public String toString() { - return "Speech{" + "speech=" + Arrays.toString(speech) + '}'; + return "Speech{" + "speech=" + Arrays.toString(this.speech) + '}'; } @Override diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechMessage.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechMessage.java index d6d299a26bb..029704beb7e 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechMessage.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechMessage.java @@ -33,26 +33,28 @@ public TextToSpeechMessage(String text) { } public String getText() { - return text; + return this.text; } @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof TextToSpeechMessage that)) + } + if (!(o instanceof TextToSpeechMessage that)) { return false; - return Objects.equals(text, that.text); + } + return Objects.equals(this.text, that.text); } @Override public int hashCode() { - return Objects.hash(text); + return Objects.hash(this.text); } @Override public String toString() { - return "TextToSpeechMessage{" + "text='" + text + '\'' + '}'; + return "TextToSpeechMessage{" + "text='" + this.text + '\'' + '}'; } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechPrompt.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechPrompt.java index f679018df51..cc359356a46 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechPrompt.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechPrompt.java @@ -64,21 +64,23 @@ public void setOptions(TextToSpeechOptions options) { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof TextToSpeechPrompt that)) + } + if (!(o instanceof TextToSpeechPrompt that)) { return false; - return Objects.equals(message, that.message) && Objects.equals(options, that.options); + } + return Objects.equals(this.message, that.message) && Objects.equals(this.options, that.options); } @Override public int hashCode() { - return Objects.hash(message, options); + return Objects.hash(this.message, this.options); } @Override public String toString() { - return "TextToSpeechPrompt{" + "message=" + message + ", options=" + options + '}'; + return "TextToSpeechPrompt{" + "message=" + this.message + ", options=" + this.options + '}'; } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponse.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponse.java index 6e23ef43e49..5d20023c2ff 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponse.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponse.java @@ -57,21 +57,23 @@ public TextToSpeechResponseMetadata getMetadata() { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof TextToSpeechResponse that)) + } + if (!(o instanceof TextToSpeechResponse that)) { return false; - return Objects.equals(results, that.results); + } + return Objects.equals(this.results, that.results); } @Override public int hashCode() { - return Objects.hash(results); + return Objects.hash(this.results); } @Override public String toString() { - return "TextToSpeechResponse{" + "results=" + results + '}'; + return "TextToSpeechResponse{" + "results=" + this.results + '}'; } } diff --git a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponseMetadata.java b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponseMetadata.java index f581b167064..c0fc80390a1 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponseMetadata.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/audio/tts/TextToSpeechResponseMetadata.java @@ -1,3 +1,19 @@ +/* + * Copyright 2025-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. + * 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.audio.tts; import org.springframework.ai.model.MutableResponseMetadata; diff --git a/spring-ai-model/src/main/java/org/springframework/ai/chat/model/MessageAggregator.java b/spring-ai-model/src/main/java/org/springframework/ai/chat/model/MessageAggregator.java index 222d53d426f..b8de3bac4dd 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/chat/model/MessageAggregator.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/chat/model/MessageAggregator.java @@ -25,7 +25,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.util.CollectionUtils; import reactor.core.publisher.Flux; import org.springframework.ai.chat.messages.AssistantMessage; @@ -35,9 +34,10 @@ import org.springframework.ai.chat.metadata.PromptMetadata; import org.springframework.ai.chat.metadata.RateLimit; import org.springframework.ai.chat.metadata.Usage; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.springframework.ai.chat.messages.AssistantMessage.*; +import static org.springframework.ai.chat.messages.AssistantMessage.ToolCall; /** * Helper that for streaming chat responses, aggregate the chat response messages into a diff --git a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java index 6e2aa03ad4a..af8973fbc05 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessor.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,7 +101,7 @@ public Builder rethrowExceptions(List> excepti } public DefaultToolExecutionExceptionProcessor build() { - return new DefaultToolExecutionExceptionProcessor(this.alwaysThrow, exceptions); + return new DefaultToolExecutionExceptionProcessor(this.alwaysThrow, this.exceptions); } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java index 7affe701a02..58d19777aa8 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/aot/ToolBeanRegistrationAotProcessorTests.java @@ -16,6 +16,13 @@ package org.springframework.ai.aot; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + import org.junit.jupiter.api.Test; import org.springframework.ai.tool.annotation.Tool; @@ -30,8 +37,6 @@ import org.springframework.core.annotation.AliasFor; import org.springframework.lang.Nullable; -import java.lang.annotation.*; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/spring-ai-model/src/test/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptionsTests.java b/spring-ai-model/src/test/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptionsTests.java index 7194a42214e..3c7213e7651 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptionsTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/audio/tts/DefaultTextToSpeechOptionsTests.java @@ -16,9 +16,10 @@ package org.springframework.ai.audio.tts; +import org.junit.jupiter.api.Test; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.within; -import org.junit.jupiter.api.Test; /** * Unit tests for {@link DefaultTextToSpeechOptions}. diff --git a/spring-ai-model/src/test/java/org/springframework/ai/chat/model/ChatResponseTests.java b/spring-ai-model/src/test/java/org/springframework/ai/chat/model/ChatResponseTests.java index 08cdc993fba..56f73b6fc8d 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/chat/model/ChatResponseTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/chat/model/ChatResponseTests.java @@ -22,15 +22,15 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.metadata.ChatGenerationMetadata; import org.springframework.ai.chat.metadata.ChatResponseMetadata; -import reactor.core.publisher.Flux; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.springframework.ai.chat.messages.AssistantMessage.*; +import static org.springframework.ai.chat.messages.AssistantMessage.ToolCall; /** * Unit tests for {@link ChatResponse}. diff --git a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java index 955194dd2a3..8f4af1878ea 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/tool/execution/DefaultToolExecutionExceptionProcessorTests.java @@ -17,12 +17,13 @@ package org.springframework.ai.tool.execution; import java.util.List; + import org.junit.jupiter.api.Test; import org.springframework.ai.tool.definition.DefaultToolDefinition; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.InstanceOfAssertFactories.type; /** * Unit tests for {@link DefaultToolExecutionExceptionProcessor}. @@ -36,8 +37,8 @@ class DefaultToolExecutionExceptionProcessorTests { private final DefaultToolDefinition toolDefinition = new DefaultToolDefinition("toolName", "toolDescription", "inputSchema"); - private final ToolExecutionException toolExecutionException = new ToolExecutionException(toolDefinition, - toolException); + private final ToolExecutionException toolExecutionException = new ToolExecutionException(this.toolDefinition, + this.toolException); @Test void processReturnsMessage() { @@ -57,7 +58,7 @@ void processAlwaysThrows() { assertThatThrownBy(() -> processor.process(this.toolExecutionException)) .hasMessage(this.toolException.getMessage()) .hasCauseInstanceOf(this.toolException.getClass()) - .asInstanceOf(type(ToolExecutionException.class)) + .asInstanceOf(org.assertj.core.api.InstanceOfAssertFactories.type(ToolExecutionException.class)) .extracting(ToolExecutionException::getToolDefinition) .isEqualTo(this.toolDefinition); } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/tool/method/MethodToolCallbackProviderTests.java b/spring-ai-model/src/test/java/org/springframework/ai/tool/method/MethodToolCallbackProviderTests.java index a5659a9cc9d..6465aa7d478 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/tool/method/MethodToolCallbackProviderTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/tool/method/MethodToolCallbackProviderTests.java @@ -16,7 +16,12 @@ package org.springframework.ai.tool.method; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java index 39e46d7d6f7..1c8d91957af 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java @@ -86,8 +86,9 @@ public void add(List documents) { } private void validateNonTextDocuments(List documents) { - if (documents == null) + if (documents == null) { return; + } for (Document document : documents) { if (document != null && !document.isText()) { throw new IllegalArgumentException( diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 1083d78182d..33be2bf0fc2 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -30,6 +30,8 @@ + + diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index b03fd710392..43cdbb1d873 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -106,7 +106,7 @@ + value="org.springframework.ai.chat.messages.AssistantMessage.ToolCall, org.springframework.ai.chat.messages.AbstractMessage.*, org.springframework.ai.model.openai.autoconfigure.OpenAIAutoConfigurationUtil.*, org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.AudioParameters.Voice.*, org.springframework.ai.mistralai.api.MistralAiModerationApi.*, org.springframework.ai.util.LoggingMarkers.*, org.springframework.ai.embedding.observation.EmbeddingModelObservationDocumentation.*, org.springframework.ai.test.vectorstore.ObservationTestUtil.*, org.springframework.ai.autoconfigure.vectorstore.observation.ObservationTestUtil.*, org.awaitility.Awaitility.*, org.springframework.ai.aot.AiRuntimeHints.*, org.springframework.ai.openai.metadata.support.OpenAiApiResponseHeaders.*, org.springframework.ai.image.observation.ImageModelObservationDocumentation.*, org.springframework.ai.observation.embedding.EmbeddingModelObservationDocumentation.*, org.springframework.aot.hint.predicate.RuntimeHintsPredicates.*, org.springframework.ai.vectorstore.filter.Filter.ExpressionType.*, org.springframework.ai.chat.observation.ChatModelObservationDocumentation.*, org.assertj.core.groups.Tuple.*, org.assertj.core.api.AssertionsForClassTypes.*, org.junit.jupiter.api.Assertions.*, org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.Matchers.*, org.mockito.ArgumentMatchers.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*, org.springframework.web.reactive.function.server.RequestPredicates.*, org.springframework.web.reactive.function.server.RouterFunctions.*, org.springframework.test.web.servlet.setup.MockMvcBuilders.*"/> diff --git a/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaApiIT.java b/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaApiIT.java index 9c0db87551e..a421712defd 100644 --- a/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaApiIT.java +++ b/vector-stores/spring-ai-chroma-store/src/test/java/org/springframework/ai/chroma/vectorstore/ChromaApiIT.java @@ -43,8 +43,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatNoException; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; -import static net.javacrumbs.jsonunit.assertj.JsonAssertions.json; /** * @author Christian Tzolov @@ -290,7 +288,7 @@ public void testAddEmbeddingsRequestMetadataConversion() { assertThat(processed.get("doubleVal")).isInstanceOf(Number.class).isEqualTo(3.14); assertThat(processed.get("listVal")).isInstanceOf(String.class).isEqualTo("[1,2,3]"); assertThat(processed.get("mapVal")).isInstanceOf(String.class); - assertThatJson(processed.get("mapVal")).isEqualTo("{a:1,b:2}"); + net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson(processed.get("mapVal")).isEqualTo("{a:1,b:2}"); } @SpringBootConfiguration diff --git a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStoreIT.java b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStoreIT.java index 5d8ceb7b7b4..9c73f292c8d 100644 --- a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStoreIT.java +++ b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/Neo4jVectorStoreIT.java @@ -31,7 +31,6 @@ import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import org.springframework.context.annotation.Primary; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -51,6 +50,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; import static org.assertj.core.api.Assertions.assertThat; diff --git a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreOptions.java b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreOptions.java index 3bff73e05b0..50bd292de96 100644 --- a/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreOptions.java +++ b/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStoreOptions.java @@ -33,7 +33,7 @@ public class WeaviateVectorStoreOptions { private String metaFieldPrefix = "meta_"; public String getObjectClass() { - return objectClass; + return this.objectClass; } public void setObjectClass(String objectClass) { @@ -42,7 +42,7 @@ public void setObjectClass(String objectClass) { } public String getContentFieldName() { - return contentFieldName; + return this.contentFieldName; } public void setContentFieldName(String contentFieldName) { @@ -51,7 +51,7 @@ public void setContentFieldName(String contentFieldName) { } public String getMetaFieldPrefix() { - return metaFieldPrefix; + return this.metaFieldPrefix; } public void setMetaFieldPrefix(String metaFieldPrefix) {