diff --git a/README.md b/README.md index 46228b0ca8b..b70d46c1b3f 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,12 @@ To check javadocs using the [javadoc:javadoc](https://maven.apache.org/plugins/m ./mvnw javadoc:javadoc -Pjavadoc ``` +To build with checkstyles enabled. +Checkstyles are currently disabled, but you can enable them by doing the following: +```shell +./mvnw clean package -DskipTests -Ddisable.checks=false +``` + ## Project Links * [Documentation](https://docs.spring.io/spring-ai/reference/) diff --git a/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/MarkdownDocumentReader.java b/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/MarkdownDocumentReader.java index 19ebed9cad6..33c3709eb02 100644 --- a/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/MarkdownDocumentReader.java +++ b/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/MarkdownDocumentReader.java @@ -111,7 +111,7 @@ static class DocumentVisitor extends AbstractVisitor { private Document.Builder currentDocumentBuilder; - public DocumentVisitor(MarkdownDocumentReaderConfig config) { + DocumentVisitor(MarkdownDocumentReaderConfig config) { this.config = config; } diff --git a/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/config/MarkdownDocumentReaderConfig.java b/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/config/MarkdownDocumentReaderConfig.java index c22c573f0e8..a622f2531ba 100644 --- a/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/config/MarkdownDocumentReaderConfig.java +++ b/document-readers/markdown-reader/src/main/java/org/springframework/ai/reader/markdown/config/MarkdownDocumentReaderConfig.java @@ -56,7 +56,7 @@ public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private boolean horizontalRuleCreateDocument = false; diff --git a/document-readers/pdf-reader/pom.xml b/document-readers/pdf-reader/pom.xml index 1a44d4ef382..94d106a7517 100644 --- a/document-readers/pdf-reader/pom.xml +++ b/document-readers/pdf-reader/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-anthropic/pom.xml b/models/spring-ai-anthropic/pom.xml index 74663049a06..7cb9a41d8e3 100644 --- a/models/spring-ai-anthropic/pom.xml +++ b/models/spring-ai-anthropic/pom.xml @@ -38,7 +38,6 @@ - false diff --git a/models/spring-ai-azure-openai/pom.xml b/models/spring-ai-azure-openai/pom.xml index 35f8511d226..6e312cfca8a 100644 --- a/models/spring-ai-azure-openai/pom.xml +++ b/models/spring-ai-azure-openai/pom.xml @@ -36,7 +36,6 @@ - false diff --git a/models/spring-ai-bedrock-converse/pom.xml b/models/spring-ai-bedrock-converse/pom.xml index e684d6bf133..79c9364b203 100644 --- a/models/spring-ai-bedrock-converse/pom.xml +++ b/models/spring-ai-bedrock-converse/pom.xml @@ -1,4 +1,20 @@ + + @@ -81,4 +97,4 @@ - \ No newline at end of file + diff --git a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java index 013cba9be4b..4687504e075 100644 --- a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java +++ b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java @@ -1,11 +1,11 @@ /* - * Copyright 2024 - 2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.bedrock.converse; import java.io.IOException; @@ -26,44 +27,11 @@ import java.util.Map; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.ai.bedrock.converse.api.ConverseApiUtils; -import org.springframework.ai.bedrock.converse.api.URLValidator; -import org.springframework.ai.chat.messages.AssistantMessage; -import org.springframework.ai.chat.messages.MessageType; -import org.springframework.ai.chat.messages.ToolResponseMessage; -import org.springframework.ai.chat.messages.UserMessage; -import org.springframework.ai.chat.metadata.ChatGenerationMetadata; -import org.springframework.ai.chat.metadata.ChatResponseMetadata; -import org.springframework.ai.chat.metadata.DefaultUsage; -import org.springframework.ai.chat.model.AbstractToolCallSupport; -import org.springframework.ai.chat.model.ChatModel; -import org.springframework.ai.chat.model.ChatResponse; -import org.springframework.ai.chat.model.Generation; -import org.springframework.ai.chat.model.MessageAggregator; -import org.springframework.ai.chat.observation.ChatModelObservationContext; -import org.springframework.ai.chat.observation.ChatModelObservationConvention; -import org.springframework.ai.chat.observation.ChatModelObservationDocumentation; -import org.springframework.ai.chat.observation.DefaultChatModelObservationConvention; -import org.springframework.ai.chat.prompt.ChatOptions; -import org.springframework.ai.chat.prompt.ChatOptionsBuilder; -import org.springframework.ai.chat.prompt.Prompt; -import org.springframework.ai.model.ModelOptionsUtils; -import org.springframework.ai.model.function.FunctionCallback; -import org.springframework.ai.model.function.FunctionCallbackContext; -import org.springframework.ai.model.function.FunctionCallingOptions; -import org.springframework.ai.model.function.FunctionCallingOptionsBuilder; -import org.springframework.ai.model.function.FunctionCallingOptionsBuilder.PortableFunctionCallingOptions; -import org.springframework.ai.observation.conventions.AiProvider; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StreamUtils; -import org.springframework.util.StringUtils; - import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; @@ -97,6 +65,39 @@ import software.amazon.awssdk.services.bedrockruntime.model.ToolSpecification; import software.amazon.awssdk.services.bedrockruntime.model.ToolUseBlock; +import org.springframework.ai.bedrock.converse.api.ConverseApiUtils; +import org.springframework.ai.bedrock.converse.api.URLValidator; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.MessageType; +import org.springframework.ai.chat.messages.ToolResponseMessage; +import org.springframework.ai.chat.messages.UserMessage; +import org.springframework.ai.chat.metadata.ChatGenerationMetadata; +import org.springframework.ai.chat.metadata.ChatResponseMetadata; +import org.springframework.ai.chat.metadata.DefaultUsage; +import org.springframework.ai.chat.model.AbstractToolCallSupport; +import org.springframework.ai.chat.model.ChatModel; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.model.Generation; +import org.springframework.ai.chat.model.MessageAggregator; +import org.springframework.ai.chat.observation.ChatModelObservationContext; +import org.springframework.ai.chat.observation.ChatModelObservationConvention; +import org.springframework.ai.chat.observation.ChatModelObservationDocumentation; +import org.springframework.ai.chat.observation.DefaultChatModelObservationConvention; +import org.springframework.ai.chat.prompt.ChatOptions; +import org.springframework.ai.chat.prompt.ChatOptionsBuilder; +import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.ModelOptionsUtils; +import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.ai.model.function.FunctionCallbackContext; +import org.springframework.ai.model.function.FunctionCallingOptions; +import org.springframework.ai.model.function.FunctionCallingOptionsBuilder; +import org.springframework.ai.model.function.FunctionCallingOptionsBuilder.PortableFunctionCallingOptions; +import org.springframework.ai.observation.conventions.AiProvider; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StreamUtils; +import org.springframework.util.StringUtils; + /** * A {@link ChatModel} implementation that uses the Amazon Bedrock Converse API to * interact with the generations = message.content() .stream() .filter(content -> content.type() != ContentBlock.Type.TOOL_USE) - .map(content -> { - return new Generation(new AssistantMessage(content.text(), Map.of()), - ChatGenerationMetadata.from(response.stopReasonAsString(), null)); - }) + .map(content -> new Generation(new AssistantMessage(content.text(), Map.of()), + ChatGenerationMetadata.from(response.stopReasonAsString(), null))) .toList(); List allGenerations = new ArrayList<>(generations); @@ -508,7 +507,7 @@ public Flux stream(Prompt prompt) { // @formatter:off Flux chatResponses = ConverseApiUtils.toChatResponse(response); - Flux chatResponseFlux = chatResponses.switchMap(chatResponse -> { + Flux chatResponseFlux = chatResponses.switchMap(chatResponse -> { if (!this.isProxyToolCalls(prompt, this.defaultOptions) && chatResponse != null && this.isToolCall(chatResponse, Set.of("tool_use"))) { var toolCallConversation = this.handleToolCalls(prompt, chatResponse); @@ -540,14 +539,14 @@ public Flux converseStream(ConverseStreamRequest converseS Sinks.Many eventSink = Sinks.many().multicast().onBackpressureBuffer(); ConverseStreamResponseHandler.Visitor visitor = ConverseStreamResponseHandler.Visitor.builder() - .onDefault((output) -> { + .onDefault(output -> { logger.debug("Received converse stream output:{}", output); eventSink.tryEmitNext(output); }) .build(); ConverseStreamResponseHandler responseHandler = ConverseStreamResponseHandler.builder() - .onEventStream(stream -> stream.subscribe((e) -> e.accept(visitor))) + .onEventStream(stream -> stream.subscribe(e -> e.accept(visitor))) .onComplete(() -> { EmitResult emitResult = eventSink.tryEmitComplete(); @@ -559,7 +558,7 @@ public Flux converseStream(ConverseStreamRequest converseS eventSink.emitComplete(EmitFailureHandler.busyLooping(Duration.ofSeconds(3))); logger.info("Completed streaming response."); }) - .onError((error) -> { + .onError(error -> { logger.error("Error handling Bedrock converse stream response", error); eventSink.tryEmitError(error); }) @@ -571,11 +570,20 @@ public Flux converseStream(ConverseStreamRequest converseS } + /** + * Use the provided convention for reporting observation data + * @param observationConvention The provided convention + */ + public void setObservationConvention(ChatModelObservationConvention observationConvention) { + Assert.notNull(observationConvention, "observationConvention cannot be null"); + this.observationConvention = observationConvention; + } + public static Builder builder() { return new Builder(); } - public static class Builder { + public static final class Builder { private AwsCredentialsProvider credentialsProvider; @@ -696,13 +704,4 @@ public BedrockProxyChatModel build() { } - /** - * Use the provided convention for reporting observation data - * @param observationConvention The provided convention - */ - public void setObservationConvention(ChatModelObservationConvention observationConvention) { - Assert.notNull(observationConvention, "observationConvention cannot be null"); - this.observationConvention = observationConvention; - } - } diff --git a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/BedrockUsage.java b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/BedrockUsage.java index 96186b9b782..ac58a7ca502 100644 --- a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/BedrockUsage.java +++ b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/BedrockUsage.java @@ -1,11 +1,11 @@ /* - * Copyright 2024 - 2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.bedrock.converse.api; +import software.amazon.awssdk.services.bedrockruntime.model.TokenUsage; + import org.springframework.ai.chat.metadata.Usage; import org.springframework.util.Assert; -import software.amazon.awssdk.services.bedrockruntime.model.TokenUsage; - /** * {@link Usage} implementation for Bedrock Converse API. * @@ -46,17 +47,17 @@ protected BedrockUsage(Long inputTokens, Long outputTokens) { @Override public Long getPromptTokens() { - return inputTokens; + return this.inputTokens; } @Override public Long getGenerationTokens() { - return outputTokens; + return this.outputTokens; } @Override public String toString() { - return "BedrockUsage [inputTokens=" + inputTokens + ", outputTokens=" + outputTokens + "]"; + return "BedrockUsage [inputTokens=" + this.inputTokens + ", outputTokens=" + this.outputTokens + "]"; } -} \ No newline at end of file +} diff --git a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/ConverseApiUtils.java b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/ConverseApiUtils.java index a5203c39d95..29038d972f4 100644 --- a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/ConverseApiUtils.java +++ b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/ConverseApiUtils.java @@ -1,11 +1,11 @@ /* - * Copyright 2024 - 2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.ai.bedrock.converse.api; import java.math.BigDecimal; @@ -24,18 +25,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import org.springframework.ai.chat.messages.AssistantMessage; -import org.springframework.ai.chat.metadata.ChatGenerationMetadata; -import org.springframework.ai.chat.metadata.ChatResponseMetadata; -import org.springframework.ai.chat.metadata.DefaultUsage; -import org.springframework.ai.chat.model.ChatResponse; -import org.springframework.ai.chat.model.Generation; -import org.springframework.ai.chat.prompt.ChatOptions; -import org.springframework.ai.model.ModelOptions; -import org.springframework.ai.model.ModelOptionsUtils; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import software.amazon.awssdk.core.SdkField; @@ -56,6 +45,18 @@ import software.amazon.awssdk.services.bedrockruntime.model.TokenUsage; import software.amazon.awssdk.services.bedrockruntime.model.ToolUseBlockStart; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.metadata.ChatGenerationMetadata; +import org.springframework.ai.chat.metadata.ChatResponseMetadata; +import org.springframework.ai.chat.metadata.DefaultUsage; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.model.Generation; +import org.springframework.ai.chat.prompt.ChatOptions; +import org.springframework.ai.model.ModelOptions; +import org.springframework.ai.model.ModelOptionsUtils; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + /** * Amazon Bedrock Converse API utils. * @@ -63,7 +64,16 @@ * @author Christian Tzolov * @since 1.0.0 */ -public class ConverseApiUtils { +public final class ConverseApiUtils { + + public static final ChatResponse EMPTY_CHAT_RESPONSE = ChatResponse.builder() + .withGenerations(List.of()) + .withMetadata("empty", true) + .build(); + + private ConverseApiUtils() { + + } public static boolean isToolUseStart(ConverseStreamOutput event) { if (event == null || event.sdkEventType() == null || event.sdkEventType() != EventType.CONTENT_BLOCK_START) { @@ -80,139 +90,6 @@ public static boolean isToolUseFinish(ConverseStreamOutput event) { return true; } - public record Aggregation(MetadataAggregation metadataAggregation, ChatResponse chatResponse) { - public Aggregation() { - this(MetadataAggregation.builder().build(), EMPTY_CHAT_RESPONSE); - } - } - - /** - * Special event used to aggregate multiple tool use events into a single event with - * list of aggregated ContentBlockToolUse. - */ - public static class ToolUseAggregationEvent implements ConverseStreamOutput { - - public record ToolUseEntry(Integer index, String id, String name, String input) { - } - - private Integer index; - - private String id; - - private String name; - - private String partialJson = ""; - - private List toolUseEntries = new ArrayList<>(); - - private DefaultUsage usage; - - public List toolUseEntries() { - return this.toolUseEntries; - } - - public boolean isEmpty() { - return (this.index == null || this.id == null || this.name == null - || !StringUtils.hasText(this.partialJson)); - } - - ToolUseAggregationEvent withIndex(Integer index) { - this.index = index; - return this; - } - - ToolUseAggregationEvent withId(String id) { - this.id = id; - return this; - } - - ToolUseAggregationEvent withName(String name) { - this.name = name; - return this; - } - - ToolUseAggregationEvent withUsage(DefaultUsage usage) { - this.usage = usage; - return this; - } - - ToolUseAggregationEvent appendPartialJson(String partialJson) { - this.partialJson = this.partialJson + partialJson; - return this; - } - - void squashIntoContentBlock() { - this.toolUseEntries.add(new ToolUseEntry(this.index, this.id, this.name, this.partialJson)); - this.index = null; - this.id = null; - this.name = null; - this.partialJson = ""; - this.usage = null; - } - - @Override - public String toString() { - return "EventToolUseBuilder [index=" + this.index + ", id=" + this.id + ", name=" + this.name - + ", partialJson=" + this.partialJson + ", toolUseMap=" + "]"; - } - - @Override - public List> sdkFields() { - return List.of(); - } - - @Override - public void accept(Visitor visitor) { - throw new UnsupportedOperationException(); - } - - } - - public static ConverseStreamOutput mergeToolUseEvents(ConverseStreamOutput previousEvent, - ConverseStreamOutput event) { - - ToolUseAggregationEvent toolUseEventAggregator = (ToolUseAggregationEvent) previousEvent; - - if (event.sdkEventType() == EventType.CONTENT_BLOCK_START) { - - ContentBlockStartEvent contentBlockStart = (ContentBlockStartEvent) event; - - if (ContentBlockStart.Type.TOOL_USE.equals(contentBlockStart.start().type())) { - ToolUseBlockStart cbToolUse = contentBlockStart.start().toolUse(); - - return toolUseEventAggregator.withIndex(contentBlockStart.contentBlockIndex()) - .withId(cbToolUse.toolUseId()) - .withName(cbToolUse.name()) - .appendPartialJson(""); // CB START always has empty JSON. - } - } - else if (event.sdkEventType() == EventType.CONTENT_BLOCK_DELTA) { - ContentBlockDeltaEvent contentBlockDelta = (ContentBlockDeltaEvent) event; - if (ContentBlockDelta.Type.TOOL_USE == contentBlockDelta.delta().type()) { - return toolUseEventAggregator.appendPartialJson(contentBlockDelta.delta().toolUse().input()); - } - } - else if (event.sdkEventType() == EventType.CONTENT_BLOCK_STOP) { - return toolUseEventAggregator; - } - else if (event.sdkEventType() == EventType.MESSAGE_STOP) { - return toolUseEventAggregator; - } - else if (event.sdkEventType() == EventType.METADATA) { - ConverseStreamMetadataEvent metadataEvent = (ConverseStreamMetadataEvent) event; - DefaultUsage usage = new DefaultUsage(metadataEvent.usage().inputTokens().longValue(), - metadataEvent.usage().outputTokens().longValue(), metadataEvent.usage().totalTokens().longValue()); - toolUseEventAggregator.withUsage(usage); - // TODO - if (!toolUseEventAggregator.isEmpty()) { - toolUseEventAggregator.squashIntoContentBlock(); - return toolUseEventAggregator; - } - } - - return event; - } - public static Flux toChatResponse(Flux responses) { AtomicBoolean isInsideTool = new AtomicBoolean(false); @@ -228,7 +105,7 @@ public static Flux toChatResponse(Flux respo return true; } return !isInsideTool.get(); - }).concatMapIterable(window -> {// Merging the window chunks into a single chunk. + }).concatMapIterable(window -> { // Merging the window chunks into a single chunk. Mono monoChunk = window.reduce(new ToolUseAggregationEvent(), ConverseApiUtils::mergeToolUseEvents); return List.of(monoChunk); @@ -333,81 +210,49 @@ else if (nextEvent instanceof ConverseStreamMetadataEvent metadataEvent) { .filter(chatResponse -> chatResponse != ConverseApiUtils.EMPTY_CHAT_RESPONSE); } - public static final ChatResponse EMPTY_CHAT_RESPONSE = ChatResponse.builder() - .withGenerations(List.of()) - .withMetadata("empty", true) - .build(); - - public record MetadataAggregation(String role, String stopReason, Document additionalModelResponseFields, - TokenUsage tokenUsage, ConverseStreamMetrics metrics, ConverseStreamTrace trace) { - - public static Builder builder() { - return new Builder(); - } - - public final static class Builder { - - private String role; - - private String stopReason; - - private Document additionalModelResponseFields; - - private TokenUsage tokenUsage; - - private ConverseStreamMetrics metrics; - - private ConverseStreamTrace trace; - - private Builder() { - } - - public Builder copy(MetadataAggregation metadataAggregation) { - this.role = metadataAggregation.role; - this.stopReason = metadataAggregation.stopReason; - this.additionalModelResponseFields = metadataAggregation.additionalModelResponseFields; - this.tokenUsage = metadataAggregation.tokenUsage; - this.metrics = metadataAggregation.metrics; - this.trace = metadataAggregation.trace; - return this; - } + public static ConverseStreamOutput mergeToolUseEvents(ConverseStreamOutput previousEvent, + ConverseStreamOutput event) { - public Builder withRole(String role) { - this.role = role; - return this; - } + ToolUseAggregationEvent toolUseEventAggregator = (ToolUseAggregationEvent) previousEvent; - public Builder withStopReason(String stopReason) { - this.stopReason = stopReason; - return this; - } + if (event.sdkEventType() == EventType.CONTENT_BLOCK_START) { - public Builder withAdditionalModelResponseFields(Document additionalModelResponseFields) { - this.additionalModelResponseFields = additionalModelResponseFields; - return this; - } + ContentBlockStartEvent contentBlockStart = (ContentBlockStartEvent) event; - public Builder withTokenUsage(TokenUsage tokenUsage) { - this.tokenUsage = tokenUsage; - return this; - } + if (ContentBlockStart.Type.TOOL_USE.equals(contentBlockStart.start().type())) { + ToolUseBlockStart cbToolUse = contentBlockStart.start().toolUse(); - public Builder withMetrics(ConverseStreamMetrics metrics) { - this.metrics = metrics; - return this; + return toolUseEventAggregator.withIndex(contentBlockStart.contentBlockIndex()) + .withId(cbToolUse.toolUseId()) + .withName(cbToolUse.name()) + .appendPartialJson(""); // CB START always has empty JSON. } - - public Builder withTrace(ConverseStreamTrace trace) { - this.trace = trace; - return this; + } + else if (event.sdkEventType() == EventType.CONTENT_BLOCK_DELTA) { + ContentBlockDeltaEvent contentBlockDelta = (ContentBlockDeltaEvent) event; + if (ContentBlockDelta.Type.TOOL_USE == contentBlockDelta.delta().type()) { + return toolUseEventAggregator.appendPartialJson(contentBlockDelta.delta().toolUse().input()); } - - public MetadataAggregation build() { - return new MetadataAggregation(role, stopReason, additionalModelResponseFields, tokenUsage, metrics, - trace); + } + else if (event.sdkEventType() == EventType.CONTENT_BLOCK_STOP) { + return toolUseEventAggregator; + } + else if (event.sdkEventType() == EventType.MESSAGE_STOP) { + return toolUseEventAggregator; + } + else if (event.sdkEventType() == EventType.METADATA) { + ConverseStreamMetadataEvent metadataEvent = (ConverseStreamMetadataEvent) event; + DefaultUsage usage = new DefaultUsage(metadataEvent.usage().inputTokens().longValue(), + metadataEvent.usage().outputTokens().longValue(), metadataEvent.usage().totalTokens().longValue()); + toolUseEventAggregator.withUsage(usage); + // TODO + if (!toolUseEventAggregator.isEmpty()) { + toolUseEventAggregator.squashIntoContentBlock(); + return toolUseEventAggregator; } - } + + return event; } @SuppressWarnings("unchecked") @@ -496,4 +341,164 @@ private static Document convertMapToDocument(Map value) { return Document.fromMap(attr); } + public record Aggregation(MetadataAggregation metadataAggregation, ChatResponse chatResponse) { + public Aggregation() { + this(MetadataAggregation.builder().build(), EMPTY_CHAT_RESPONSE); + } + } + + /** + * Special event used to aggregate multiple tool use events into a single event with + * list of aggregated ContentBlockToolUse. + */ + public static class ToolUseAggregationEvent implements ConverseStreamOutput { + + private Integer index; + + private String id; + + private String name; + + private String partialJson = ""; + + private List toolUseEntries = new ArrayList<>(); + + private DefaultUsage usage; + + public List toolUseEntries() { + return this.toolUseEntries; + } + + public boolean isEmpty() { + return (this.index == null || this.id == null || this.name == null + || !StringUtils.hasText(this.partialJson)); + } + + ToolUseAggregationEvent withIndex(Integer index) { + this.index = index; + return this; + } + + ToolUseAggregationEvent withId(String id) { + this.id = id; + return this; + } + + ToolUseAggregationEvent withName(String name) { + this.name = name; + return this; + } + + ToolUseAggregationEvent withUsage(DefaultUsage usage) { + this.usage = usage; + return this; + } + + ToolUseAggregationEvent appendPartialJson(String partialJson) { + this.partialJson = this.partialJson + partialJson; + return this; + } + + void squashIntoContentBlock() { + this.toolUseEntries.add(new ToolUseEntry(this.index, this.id, this.name, this.partialJson)); + this.index = null; + this.id = null; + this.name = null; + this.partialJson = ""; + this.usage = null; + } + + @Override + public String toString() { + return "EventToolUseBuilder [index=" + this.index + ", id=" + this.id + ", name=" + this.name + + ", partialJson=" + this.partialJson + ", toolUseMap=" + "]"; + } + + @Override + public List> sdkFields() { + return List.of(); + } + + @Override + public void accept(Visitor visitor) { + throw new UnsupportedOperationException(); + } + + public record ToolUseEntry(Integer index, String id, String name, String input) { + } + + } + + public record MetadataAggregation(String role, String stopReason, Document additionalModelResponseFields, + TokenUsage tokenUsage, ConverseStreamMetrics metrics, ConverseStreamTrace trace) { + + public static Builder builder() { + return new Builder(); + } + + public final static class Builder { + + private String role; + + private String stopReason; + + private Document additionalModelResponseFields; + + private TokenUsage tokenUsage; + + private ConverseStreamMetrics metrics; + + private ConverseStreamTrace trace; + + private Builder() { + } + + public Builder copy(MetadataAggregation metadataAggregation) { + this.role = metadataAggregation.role; + this.stopReason = metadataAggregation.stopReason; + this.additionalModelResponseFields = metadataAggregation.additionalModelResponseFields; + this.tokenUsage = metadataAggregation.tokenUsage; + this.metrics = metadataAggregation.metrics; + this.trace = metadataAggregation.trace; + return this; + } + + public Builder withRole(String role) { + this.role = role; + return this; + } + + public Builder withStopReason(String stopReason) { + this.stopReason = stopReason; + return this; + } + + public Builder withAdditionalModelResponseFields(Document additionalModelResponseFields) { + this.additionalModelResponseFields = additionalModelResponseFields; + return this; + } + + public Builder withTokenUsage(TokenUsage tokenUsage) { + this.tokenUsage = tokenUsage; + return this; + } + + public Builder withMetrics(ConverseStreamMetrics metrics) { + this.metrics = metrics; + return this; + } + + public Builder withTrace(ConverseStreamTrace trace) { + this.trace = trace; + return this; + } + + public MetadataAggregation build() { + return new MetadataAggregation(this.role, this.stopReason, this.additionalModelResponseFields, + this.tokenUsage, this.metrics, this.trace); + } + + } + } + } diff --git a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/URLValidator.java b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/URLValidator.java index 342ce5ba545..121fe74877b 100644 --- a/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/URLValidator.java +++ b/models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/URLValidator.java @@ -1,18 +1,19 @@ /* -* Copyright 2024 - 2024 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* 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. -*/ + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.bedrock.converse.api; import java.net.MalformedURLException; @@ -27,7 +28,7 @@ * @author Christian Tzolov * @since 1.0.0 */ -public class URLValidator { +public final class URLValidator { // Basic URL regex pattern // Protocol (http:// or https://) @@ -41,6 +42,10 @@ public class URLValidator { "(#[\\w-]*)?" + // Optional fragment "$"); + private URLValidator() { + + } + /** * Quick validation using regex pattern Good for basic checks but may not catch all * edge cases @@ -121,4 +126,4 @@ public static String normalizeURL(String urlString) { return normalized; } -} \ No newline at end of file +} diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseChatClientIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseChatClientIT.java index 3486abd9d50..2719569dcce 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseChatClientIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseChatClientIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.ai.bedrock.converse; -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.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.model.ChatModel; @@ -47,7 +47,7 @@ import org.springframework.core.io.Resource; import org.springframework.util.MimeTypeUtils; -import reactor.core.publisher.Flux; +import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = BedrockConverseTestConfiguration.class) @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") @@ -88,7 +88,7 @@ void listOutputConverterString() { .user(u -> u.text("List five {subject}") .param("subject", "ice cream flavors")) .call() - .entity(new ParameterizedTypeReference>() {}); + .entity(new ParameterizedTypeReference>() { }); // @formatter:on logger.info(collection.toString()); @@ -211,7 +211,7 @@ void functionCallTest() { // @formatter:off String response = ChatClient.create(this.chatModel) - .prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.") + .prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.") .function("getCurrentWeather", "Get the weather in location", new MockWeatherService()) .call() .content(); diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseTestConfiguration.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseTestConfiguration.java index 4275e9fc75b..eaf220fb284 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseTestConfiguration.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseTestConfiguration.java @@ -18,13 +18,13 @@ import java.time.Duration; +import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; +import software.amazon.awssdk.regions.Region; + import org.springframework.ai.model.function.FunctionCallingOptions; import org.springframework.boot.SpringBootConfiguration; import org.springframework.context.annotation.Bean; -import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; -import software.amazon.awssdk.regions.Region; - @SpringBootConfiguration public class BedrockConverseTestConfiguration { diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java index e02965f6768..f2f5c19f29a 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelIT.java @@ -16,8 +16,6 @@ package org.springframework.ai.bedrock.converse; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -32,6 +30,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.chat.client.ChatClient; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; @@ -57,7 +57,7 @@ import org.springframework.core.io.Resource; import org.springframework.util.MimeTypeUtils; -import reactor.core.publisher.Flux; +import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = BedrockConverseTestConfiguration.class, properties = "spring.ai.retry.on-http-codes=429") @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java index 70c130bb2e6..1b2be8a2724 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModelObservationIT.java @@ -16,8 +16,6 @@ package org.springframework.ai.bedrock.converse; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.List; import java.util.stream.Collectors; @@ -45,6 +43,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; +import static org.assertj.core.api.Assertions.assertThat; + /** * Integration tests for observation instrumentation in {@link BedrockProxyChatModel}. * diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/MockWeatherService.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/MockWeatherService.java index af62aaf85a0..8579aa44329 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/MockWeatherService.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/MockWeatherService.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ public enum Unit { */ public final String unitName; - private Unit(String text) { + Unit(String text) { this.unitName = text; } diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/RequiresAwsCredentials.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/RequiresAwsCredentials.java index cc2db3b4914..bf750e1cfd6 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/RequiresAwsCredentials.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/RequiresAwsCredentials.java @@ -1,11 +1,11 @@ /* - * Copyright 2024 - 2024 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ai.bedrock.converse; -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +package org.springframework.ai.bedrock.converse; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; + @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*") diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain.java index 51493cf73a9..f7978fa1bb9 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain.java @@ -1,27 +1,28 @@ /* -* Copyright 2024 - 2024 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* 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. -*/ + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.bedrock.converse.experiements; +import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; +import software.amazon.awssdk.regions.Region; + import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; import org.springframework.ai.chat.prompt.ChatOptionsBuilder; import org.springframework.ai.chat.prompt.Prompt; -import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; -import software.amazon.awssdk.regions.Region; - /** * Used for reverse engineering the protocol. * @@ -29,7 +30,11 @@ * @since 1.0.0 */ -public class BedrockConverseChatModelMain { +public final class BedrockConverseChatModelMain { + + private BedrockConverseChatModelMain() { + + } public static void main(String[] args) { diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain2.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain2.java index 569bf021332..e42b60d9a8e 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain2.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/experiements/BedrockConverseChatModelMain2.java @@ -1,37 +1,42 @@ /* -* Copyright 2024 - 2024 the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* 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. -*/ + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.bedrock.converse.experiements; import java.util.List; +import reactor.core.publisher.Flux; +import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.model.ConverseStreamOutput; + import org.springframework.ai.bedrock.converse.BedrockProxyChatModel; import org.springframework.ai.bedrock.converse.MockWeatherService; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallbackWrapper; import org.springframework.ai.model.function.FunctionCallingOptionsBuilder.PortableFunctionCallingOptions; -import reactor.core.publisher.Flux; -import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.bedrockruntime.model.ConverseStreamOutput; - /** * Used for reverse engineering the protocol */ -public class BedrockConverseChatModelMain2 { +public final class BedrockConverseChatModelMain2 { + + private BedrockConverseChatModelMain2() { + + } public static void main(String[] args) { diff --git a/models/spring-ai-bedrock/pom.xml b/models/spring-ai-bedrock/pom.xml index a77188f9dae..25a54b28f05 100644 --- a/models/spring-ai-bedrock/pom.xml +++ b/models/spring-ai-bedrock/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-huggingface/pom.xml b/models/spring-ai-huggingface/pom.xml index d0fe5583636..9a1d487dbb4 100644 --- a/models/spring-ai-huggingface/pom.xml +++ b/models/spring-ai-huggingface/pom.xml @@ -36,7 +36,6 @@ - false diff --git a/models/spring-ai-minimax/pom.xml b/models/spring-ai-minimax/pom.xml index 198f47112e5..8a592901a91 100644 --- a/models/spring-ai-minimax/pom.xml +++ b/models/spring-ai-minimax/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-mistral-ai/pom.xml b/models/spring-ai-mistral-ai/pom.xml index b95c4a23feb..07e45c48d80 100644 --- a/models/spring-ai-mistral-ai/pom.xml +++ b/models/spring-ai-mistral-ai/pom.xml @@ -38,7 +38,6 @@ - false diff --git a/models/spring-ai-moonshot/pom.xml b/models/spring-ai-moonshot/pom.xml index 5d72d858348..40527b8a171 100644 --- a/models/spring-ai-moonshot/pom.xml +++ b/models/spring-ai-moonshot/pom.xml @@ -38,7 +38,6 @@ - false diff --git a/models/spring-ai-oci-genai/pom.xml b/models/spring-ai-oci-genai/pom.xml index 82c34d0442d..1355d4230cc 100644 --- a/models/spring-ai-oci-genai/pom.xml +++ b/models/spring-ai-oci-genai/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-ollama/pom.xml b/models/spring-ai-ollama/pom.xml index 0e9fb5b942a..9f8e340dd81 100644 --- a/models/spring-ai-ollama/pom.xml +++ b/models/spring-ai-ollama/pom.xml @@ -34,7 +34,6 @@ 17 17 UTF-8 - false diff --git a/models/spring-ai-openai/pom.xml b/models/spring-ai-openai/pom.xml index aa52d0521fc..a69a0224c08 100644 --- a/models/spring-ai-openai/pom.xml +++ b/models/spring-ai-openai/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-postgresml/pom.xml b/models/spring-ai-postgresml/pom.xml index d205720f1fa..ff1d1eed41b 100644 --- a/models/spring-ai-postgresml/pom.xml +++ b/models/spring-ai-postgresml/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-qianfan/pom.xml b/models/spring-ai-qianfan/pom.xml index 750fe69fc56..a2483861c68 100644 --- a/models/spring-ai-qianfan/pom.xml +++ b/models/spring-ai-qianfan/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-stability-ai/pom.xml b/models/spring-ai-stability-ai/pom.xml index b1a14b4c93f..0307df28df5 100644 --- a/models/spring-ai-stability-ai/pom.xml +++ b/models/spring-ai-stability-ai/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-transformers/pom.xml b/models/spring-ai-transformers/pom.xml index 3351485ed25..2b99d6a9981 100644 --- a/models/spring-ai-transformers/pom.xml +++ b/models/spring-ai-transformers/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-vertex-ai-embedding/pom.xml b/models/spring-ai-vertex-ai-embedding/pom.xml index dc61e8dfb7e..5327e48b45e 100644 --- a/models/spring-ai-vertex-ai-embedding/pom.xml +++ b/models/spring-ai-vertex-ai-embedding/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-vertex-ai-gemini/pom.xml b/models/spring-ai-vertex-ai-gemini/pom.xml index 0f503e4e781..cc184d54b22 100644 --- a/models/spring-ai-vertex-ai-gemini/pom.xml +++ b/models/spring-ai-vertex-ai-gemini/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/models/spring-ai-watsonx-ai/pom.xml b/models/spring-ai-watsonx-ai/pom.xml index ca14a148d5c..3b8d281d033 100644 --- a/models/spring-ai-watsonx-ai/pom.xml +++ b/models/spring-ai-watsonx-ai/pom.xml @@ -34,7 +34,6 @@ 17 17 UTF-8 - false diff --git a/models/spring-ai-zhipuai/pom.xml b/models/spring-ai-zhipuai/pom.xml index 10bb5cbfcf9..f0f6a920fc9 100644 --- a/models/spring-ai-zhipuai/pom.xml +++ b/models/spring-ai-zhipuai/pom.xml @@ -36,7 +36,6 @@ git@github.com:spring-projects/spring-ai.git - false diff --git a/spring-ai-core/pom.xml b/spring-ai-core/pom.xml index 1a58c4cf869..e278f72cc35 100644 --- a/spring-ai-core/pom.xml +++ b/spring-ai-core/pom.xml @@ -38,7 +38,6 @@ 4.13.1 - false diff --git a/spring-ai-retry/pom.xml b/spring-ai-retry/pom.xml index e479fa22059..596aef76a9e 100644 --- a/spring-ai-retry/pom.xml +++ b/spring-ai-retry/pom.xml @@ -36,7 +36,6 @@ - false diff --git a/spring-ai-spring-boot-autoconfigure/pom.xml b/spring-ai-spring-boot-autoconfigure/pom.xml index 2f6179bee67..425674e77f8 100644 --- a/spring-ai-spring-boot-autoconfigure/pom.xml +++ b/spring-ai-spring-boot-autoconfigure/pom.xml @@ -21,7 +21,6 @@ - false diff --git a/spring-ai-spring-boot-docker-compose/pom.xml b/spring-ai-spring-boot-docker-compose/pom.xml index 70115f2a57b..62d0d0de820 100644 --- a/spring-ai-spring-boot-docker-compose/pom.xml +++ b/spring-ai-spring-boot-docker-compose/pom.xml @@ -36,7 +36,6 @@ - false diff --git a/spring-ai-spring-boot-testcontainers/pom.xml b/spring-ai-spring-boot-testcontainers/pom.xml index 13acbba6858..f60e6b34da7 100644 --- a/spring-ai-spring-boot-testcontainers/pom.xml +++ b/spring-ai-spring-boot-testcontainers/pom.xml @@ -37,7 +37,6 @@ - false diff --git a/spring-ai-spring-cloud-bindings/pom.xml b/spring-ai-spring-cloud-bindings/pom.xml index 60de4a9514e..576e4bb337c 100644 --- a/spring-ai-spring-cloud-bindings/pom.xml +++ b/spring-ai-spring-cloud-bindings/pom.xml @@ -36,7 +36,6 @@ - false diff --git a/spring-ai-test/pom.xml b/spring-ai-test/pom.xml index 81a928a263a..3397a92ae7b 100644 --- a/spring-ai-test/pom.xml +++ b/spring-ai-test/pom.xml @@ -37,7 +37,6 @@ 17 17 - false diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index b19befaaab4..c95fea1a117 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -100,7 +100,7 @@ + value="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.embedding.observation.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-azure-cosmos-db-store/pom.xml b/vector-stores/spring-ai-azure-cosmos-db-store/pom.xml index 4dc1ca30dce..ca93a9ece8b 100644 --- a/vector-stores/spring-ai-azure-cosmos-db-store/pom.xml +++ b/vector-stores/spring-ai-azure-cosmos-db-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-azure-store/pom.xml b/vector-stores/spring-ai-azure-store/pom.xml index 015199de527..25bf7e5f11e 100644 --- a/vector-stores/spring-ai-azure-store/pom.xml +++ b/vector-stores/spring-ai-azure-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-cassandra-store/pom.xml b/vector-stores/spring-ai-cassandra-store/pom.xml index ea9892b3810..1032f363547 100644 --- a/vector-stores/spring-ai-cassandra-store/pom.xml +++ b/vector-stores/spring-ai-cassandra-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-elasticsearch-store/pom.xml b/vector-stores/spring-ai-elasticsearch-store/pom.xml index 824842bd002..440dc99b7a6 100644 --- a/vector-stores/spring-ai-elasticsearch-store/pom.xml +++ b/vector-stores/spring-ai-elasticsearch-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false 4.0.3 diff --git a/vector-stores/spring-ai-gemfire-store/pom.xml b/vector-stores/spring-ai-gemfire-store/pom.xml index 2d1f84a66c1..37d859f701a 100644 --- a/vector-stores/spring-ai-gemfire-store/pom.xml +++ b/vector-stores/spring-ai-gemfire-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-hanadb-store/pom.xml b/vector-stores/spring-ai-hanadb-store/pom.xml index 0e72805977f..430297bb718 100644 --- a/vector-stores/spring-ai-hanadb-store/pom.xml +++ b/vector-stores/spring-ai-hanadb-store/pom.xml @@ -40,7 +40,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-milvus-store/pom.xml b/vector-stores/spring-ai-milvus-store/pom.xml index c671083d436..fddad05b654 100644 --- a/vector-stores/spring-ai-milvus-store/pom.xml +++ b/vector-stores/spring-ai-milvus-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-mongodb-atlas-store/pom.xml b/vector-stores/spring-ai-mongodb-atlas-store/pom.xml index 753b5f9c8e5..b1b80300531 100644 --- a/vector-stores/spring-ai-mongodb-atlas-store/pom.xml +++ b/vector-stores/spring-ai-mongodb-atlas-store/pom.xml @@ -38,7 +38,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-neo4j-store/pom.xml b/vector-stores/spring-ai-neo4j-store/pom.xml index 29697aaeb3b..a8acbfc8f2c 100644 --- a/vector-stores/spring-ai-neo4j-store/pom.xml +++ b/vector-stores/spring-ai-neo4j-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-opensearch-store/pom.xml b/vector-stores/spring-ai-opensearch-store/pom.xml index e8c5972f268..aa3ddfbbd09 100644 --- a/vector-stores/spring-ai-opensearch-store/pom.xml +++ b/vector-stores/spring-ai-opensearch-store/pom.xml @@ -39,7 +39,6 @@ 4.0.3 - false diff --git a/vector-stores/spring-ai-oracle-store/pom.xml b/vector-stores/spring-ai-oracle-store/pom.xml index 3e56973eb57..0f795fa89e7 100644 --- a/vector-stores/spring-ai-oracle-store/pom.xml +++ b/vector-stores/spring-ai-oracle-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-pgvector-store/pom.xml b/vector-stores/spring-ai-pgvector-store/pom.xml index c36221d7e49..5b4a7b0df1f 100644 --- a/vector-stores/spring-ai-pgvector-store/pom.xml +++ b/vector-stores/spring-ai-pgvector-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-pinecone-store/pom.xml b/vector-stores/spring-ai-pinecone-store/pom.xml index 8603595fb88..87b2722c561 100644 --- a/vector-stores/spring-ai-pinecone-store/pom.xml +++ b/vector-stores/spring-ai-pinecone-store/pom.xml @@ -38,7 +38,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-qdrant-store/pom.xml b/vector-stores/spring-ai-qdrant-store/pom.xml index d2938dcb53d..2d9c598e529 100644 --- a/vector-stores/spring-ai-qdrant-store/pom.xml +++ b/vector-stores/spring-ai-qdrant-store/pom.xml @@ -39,7 +39,6 @@ 17 17 - false diff --git a/vector-stores/spring-ai-redis-store/pom.xml b/vector-stores/spring-ai-redis-store/pom.xml index 394f00aac60..80c7c687476 100644 --- a/vector-stores/spring-ai-redis-store/pom.xml +++ b/vector-stores/spring-ai-redis-store/pom.xml @@ -41,7 +41,6 @@ 5.1.0 17 17 - false diff --git a/vector-stores/spring-ai-typesense-store/pom.xml b/vector-stores/spring-ai-typesense-store/pom.xml index 860758ec40a..db03d79179b 100644 --- a/vector-stores/spring-ai-typesense-store/pom.xml +++ b/vector-stores/spring-ai-typesense-store/pom.xml @@ -39,7 +39,6 @@ - false diff --git a/vector-stores/spring-ai-weaviate-store/pom.xml b/vector-stores/spring-ai-weaviate-store/pom.xml index 7a1b19ef585..c1ea5ff95be 100644 --- a/vector-stores/spring-ai-weaviate-store/pom.xml +++ b/vector-stores/spring-ai-weaviate-store/pom.xml @@ -38,7 +38,6 @@ 17 17 - false