diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 6f0053e66f3..32d1054f8f4 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -35,7 +35,7 @@ jobs:
- name: Generate Java docs
run: mvn javadoc:aggregate
- - name: Generate Reference docs
+ - name: Generate assembly
working-directory: spring-ai-docs
run: mvn assembly:single
@@ -60,5 +60,5 @@ jobs:
working-directory: spring-ai-docs/target
run: |
unzip spring-ai-$PROJECT_VERSION-docs.zip
- ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api
+ ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api"
scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api
diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload.yml
index e5efc5f9215..9ed08413499 100644
--- a/.github/workflows/documentation-upload.yml
+++ b/.github/workflows/documentation-upload.yml
@@ -28,9 +28,9 @@ jobs:
- name: Generate Java docs
run: mvn javadoc:aggregate
- - name: Generate Reference docs
+ - name: Generate assembly
working-directory: spring-ai-docs
- run: mvn site
+ run: mvn assembly:single
- name: Setup SSH key
env:
@@ -50,7 +50,6 @@ jobs:
working-directory: spring-ai-docs/target
run: |
unzip spring-ai-$RELEASE_VERSION-docs.zip
- ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir $RELEASE_VERSION
- scp -i $HOME/.ssh/key -r api reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION
- ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST rm current && ln -s $RELEASE_VERSION current
-
+ ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api"
+ scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION
+
diff --git a/.gitignore b/.gitignore
index 4f6717355c4..43e4193b0d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,6 @@ node_modules
package-lock.json
package.json
.vscode
-.antlr
\ No newline at end of file
+.antlr
+
+shell.log
\ No newline at end of file
diff --git a/README.md b/README.md
index 296d747cc05..b55533ae454 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ The Spring AI project provides a Spring-friendly API and abstractions for develo
Let's make your `@Beans` intelligent!
-For further information go to our [Spring AI refernce documentation](https://docs.spring.io/spring-ai/reference/).
+For further information go to our [Spring AI reference documentation](https://docs.spring.io/spring-ai/reference/).
## Project Links
@@ -17,7 +17,7 @@ For further information go to our [Spring AI refernce documentation](https://doc
## Educational Resources
-- Follow the [Workshop](#workshop)
+- Follow the [Workshop material for Azure OpenAI](https://github.com/Azure-Samples/spring-ai-azure-workshop)
- The workshop contains step-by-step examples from 'hello world' to 'retrieval augmented generation'
Some selected videos. Search YouTube! for more.
@@ -29,19 +29,6 @@ Some selected videos. Search YouTube! for more.
* Introducing Spring AI - Add Generative AI to your Spring Applications
[](https://www.youtube.com/watch?v=1g_wuincUdU)
-
-## Workshop
-
-* You can try out the features of Spring AI by following the [workshop material for Azure OpenAI](https://github.com/Azure-Samples/spring-ai-azure-workshop)
-* To use the workshop material with OpenAI (not Azure's offering) you will need to *replace* the Azure Open AI Boot Starter in the `pom.xml` with the Open AI Boot Starter.
-```xml
-
- org.springframework.ai
- spring-ai-openai-spring-boot-starter
- 0.7.1-SNAPSHOT
-
-```
-
## Getting Started
Please refer to the [Getting Started Guide](https://docs.spring.io/spring-ai/reference/getting-started.html) for instruction on adding your dependencies.
@@ -96,7 +83,7 @@ You can find more details in the [Reference Documentation](https://docs.spring.i
Spring AI supports many AI models. For an overview see here. Specific models currently supported are
* OpenAI
-*
+*
**Prompts:** Central to AI model interaction is the Prompt, which provides specific instructions for the AI to act upon.
@@ -202,3 +189,17 @@ To build the docs
The docs are then in the directory `spring-ai-docs/target/antora/site/index.html`
+To reformat using the [java-format plugin](https://github.com/spring-io/spring-javaformat)
+```shell
+./mvnw spring-javaformat:apply
+```
+
+To update the year on license headers using the [license-maven-plugin](https://oss.carbou.me/license-maven-plugin/#goals)
+```shell
+./mvnw license:update-file-header -Plicense
+```
+
+To check javadocs using the [javadoc:javadoc](https://maven.apache.org/plugins/maven-javadoc-plugin/)
+```shell
+./mvnw javadoc:javadoc -Pjavadoc
+```
\ No newline at end of file
diff --git a/document-readers/pdf-reader/pom.xml b/document-readers/pdf-reader/pom.xml
index 661081dc85e..c870c9176c2 100644
--- a/document-readers/pdf-reader/pom.xml
+++ b/document-readers/pdf-reader/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-pdf-document-reader
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java
index bf2daeda3e5..6b48ecdb790 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/PagePdfDocumentReader.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf;
import java.awt.Rectangle;
@@ -26,6 +25,8 @@
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
@@ -45,6 +46,8 @@
*/
public class PagePdfDocumentReader implements DocumentReader {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
private static final String PDF_PAGE_REGION = "pdfPageRegion";
public static final String METADATA_START_PAGE_NUMBER = "page_number";
@@ -100,7 +103,17 @@ public List get() {
List pageTextGroupList = new ArrayList<>();
+ int totalPages = this.document.getDocumentCatalog().getPages().getCount();
+ int logFrequency = totalPages > 10 ? totalPages / 10 : 1; // if less than 10
+ // pages, print
+ // each iteration
+ int counter = 0;
+
for (PDPage page : this.document.getDocumentCatalog().getPages()) {
+ if (counter % logFrequency == 0 && counter / logFrequency < 10) {
+ logger.info("Processing PDF page: {}", (counter + 1));
+ }
+ counter++;
pagesPerDocument++;
@@ -140,7 +153,7 @@ public List get() {
readDocuments.add(toDocument(pageTextGroupList.stream().collect(Collectors.joining()), startPageNumber,
pageNumber));
}
-
+ logger.info("Processing {} pages", totalPages);
return readDocuments;
}
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 27949ec8a04..3d5235bf10c 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
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf;
import java.awt.Rectangle;
@@ -24,6 +23,8 @@
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.pdf.config.ParagraphManager;
@@ -47,6 +48,8 @@
*/
public class ParagraphPdfDocumentReader implements DocumentReader {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
// Constants for metadata keys
private static final String METADATA_START_PAGE = "page_number";
@@ -129,6 +132,7 @@ public List get() {
List documents = new ArrayList<>(paragraphs.size());
if (!CollectionUtils.isEmpty(paragraphs)) {
+ logger.info("Start processing paragraphs from PDF");
Iterator itr = paragraphs.iterator();
var current = itr.next();
@@ -147,7 +151,7 @@ public List get() {
}
}
}
-
+ logger.info("End processing paragraphs from PDF");
return documents;
}
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHints.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHints.java
index 220160dd873..0e2c7fbe975 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHints.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader.pdf.aot;
import org.springframework.aot.hint.RuntimeHints;
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/ParagraphManager.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/ParagraphManager.java
index d92d58d755f..01188074347 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/ParagraphManager.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/ParagraphManager.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf.config;
import java.io.IOException;
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/PdfDocumentReaderConfig.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/PdfDocumentReaderConfig.java
index a5f87bd1f10..fe0ed437c0f 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/PdfDocumentReaderConfig.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/config/PdfDocumentReaderConfig.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader.pdf.config;
import org.springframework.ai.reader.ExtractedTextFormatter;
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/ForkPDFLayoutTextStripper.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/ForkPDFLayoutTextStripper.java
index 43119c61bb4..80e35acb399 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/ForkPDFLayoutTextStripper.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/ForkPDFLayoutTextStripper.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
/* 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
diff --git a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/PDFLayoutTextStripperByArea.java b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/PDFLayoutTextStripperByArea.java
index 54183b0e05e..44bcb511a79 100644
--- a/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/PDFLayoutTextStripperByArea.java
+++ b/document-readers/pdf-reader/src/main/java/org/springframework/ai/reader/pdf/layout/PDFLayoutTextStripperByArea.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf.layout;
import java.awt.geom.Rectangle2D;
diff --git a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/PagePdfDocumentReaderTests.java b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/PagePdfDocumentReaderTests.java
index 8c31d4a7331..f42d7ef3d2a 100644
--- a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/PagePdfDocumentReaderTests.java
+++ b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/PagePdfDocumentReaderTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf;
import java.util.List;
@@ -51,7 +50,7 @@ public void classpathRead() {
assertThat(docs).hasSize(4);
- String allText = docs.stream().map(d -> d.getContent()).collect(Collectors.joining("\n"));
+ String allText = docs.stream().map(d -> d.getContent()).collect(Collectors.joining(System.lineSeparator()));
assertThat(allText).doesNotContain(
List.of("Page 1 of 4", "Page 2 of 4", "Page 3 of 4", "Page 4 of 4", "PDF Bookmark Sample"));
diff --git a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReaderTests.java b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReaderTests.java
index 3d5ca379dc3..eec22054d41 100644
--- a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReaderTests.java
+++ b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/ParagraphPdfDocumentReaderTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.pdf;
import org.junit.jupiter.api.Test;
diff --git a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHintsTests.java b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHintsTests.java
index ee1236b2138..4667aeb43e8 100644
--- a/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHintsTests.java
+++ b/document-readers/pdf-reader/src/test/java/org/springframework/ai/reader/pdf/aot/PdfReaderRuntimeHintsTests.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader.pdf.aot;
import org.assertj.core.api.Assertions;
diff --git a/document-readers/tika-reader/pom.xml b/document-readers/tika-reader/pom.xml
index a471967458d..76f52a057a1 100644
--- a/document-readers/tika-reader/pom.xml
+++ b/document-readers/tika-reader/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-tika-document-reader
diff --git a/document-readers/tika-reader/src/main/java/org/springframework/ai/reader/tika/TikaDocumentReader.java b/document-readers/tika-reader/src/main/java/org/springframework/ai/reader/tika/TikaDocumentReader.java
index 46128d6ee9c..9301303aac9 100644
--- a/document-readers/tika-reader/src/main/java/org/springframework/ai/reader/tika/TikaDocumentReader.java
+++ b/document-readers/tika-reader/src/main/java/org/springframework/ai/reader/tika/TikaDocumentReader.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.tika;
import java.io.IOException;
diff --git a/document-readers/tika-reader/src/test/java/org/springframework/ai/reader/tika/TikaDocumentReaderTests.java b/document-readers/tika-reader/src/test/java/org/springframework/ai/reader/tika/TikaDocumentReaderTests.java
index 9b523029a83..ee85cf10d41 100644
--- a/document-readers/tika-reader/src/test/java/org/springframework/ai/reader/tika/TikaDocumentReaderTests.java
+++ b/document-readers/tika-reader/src/test/java/org/springframework/ai/reader/tika/TikaDocumentReaderTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader.tika;
import org.junit.jupiter.params.ParameterizedTest;
diff --git a/models/spring-ai-azure-openai/README.md b/models/spring-ai-azure-openai/README.md
index af87a28e288..e38143ee766 100644
--- a/models/spring-ai-azure-openai/README.md
+++ b/models/spring-ai-azure-openai/README.md
@@ -1,3 +1,3 @@
-[Azure OpenAI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/azure-openai-chat.html)
+[Azure OpenAI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/azure-openai-chat.html)
[Azure OpenAI Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/azure-openai-embeddings.html)
diff --git a/models/spring-ai-azure-openai/pom.xml b/models/spring-ai-azure-openai/pom.xml
index 33af86b0ee9..ab762222663 100644
--- a/models/spring-ai-azure-openai/pom.xml
+++ b/models/spring-ai-azure-openai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-azure-openai
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatClient.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatClient.java
index a64ca2b722b..1ddc732fc60 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatClient.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import java.util.Collections;
@@ -76,7 +75,7 @@ public class AzureOpenAiChatClient
extends AbstractFunctionCallSupport
implements ChatClient, StreamingChatClient {
- private static final String DEFAULT_MODEL = "gpt-35-turbo";
+ private static final String DEFAULT_DEPLOYMENT_NAME = "gpt-35-turbo";
private static final Float DEFAULT_TEMPERATURE = 0.7f;
@@ -94,7 +93,10 @@ public class AzureOpenAiChatClient
public AzureOpenAiChatClient(OpenAIClient microsoftOpenAiClient) {
this(microsoftOpenAiClient,
- AzureOpenAiChatOptions.builder().withModel(DEFAULT_MODEL).withTemperature(DEFAULT_TEMPERATURE).build());
+ AzureOpenAiChatOptions.builder()
+ .withDeploymentName(DEFAULT_DEPLOYMENT_NAME)
+ .withTemperature(DEFAULT_TEMPERATURE)
+ .build());
}
public AzureOpenAiChatClient(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options) {
@@ -132,12 +134,7 @@ public ChatResponse call(Prompt prompt) {
options.setStream(false);
logger.trace("Azure ChatCompletionsOptions: {}", options);
-
ChatCompletions chatCompletions = this.callWithFunctionSupport(options);
-
- // ChatCompletions chatCompletions =
- // this.openAIClient.getChatCompletions(options.getModel(), options);
-
logger.trace("Azure ChatCompletions: {}", chatCompletions);
List generations = chatCompletions.getChoices()
@@ -324,7 +321,7 @@ private ChatCompletionsOptions merge(ChatCompletionsOptions azureOptions, AzureO
mergedAzureOptions.setUser(azureOptions.getUser() != null ? azureOptions.getUser() : springAiOptions.getUser());
mergedAzureOptions
- .setModel(azureOptions.getModel() != null ? azureOptions.getModel() : springAiOptions.getModel());
+ .setModel(azureOptions.getModel() != null ? azureOptions.getModel() : springAiOptions.getDeploymentName());
return mergedAzureOptions;
}
@@ -377,8 +374,8 @@ private ChatCompletionsOptions merge(AzureOpenAiChatOptions springAiOptions, Cha
mergedAzureOptions.setUser(springAiOptions.getUser());
}
- if (springAiOptions.getModel() != null) {
- mergedAzureOptions.setModel(springAiOptions.getModel());
+ if (springAiOptions.getDeploymentName() != null) {
+ mergedAzureOptions.setModel(springAiOptions.getDeploymentName());
}
return mergedAzureOptions;
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java
index c10636f6ef3..fdc6a2354b3 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import java.util.ArrayList;
@@ -121,12 +120,11 @@ public class AzureOpenAiChatOptions implements FunctionCallingOptions, ChatOptio
private Double frequencyPenalty;
/**
- * The model name to provide as part of this completions request. Not applicable to
- * Azure OpenAI, where deployment information should be included in the Azure resource
- * URI that's connected to.
+ * The deployment name as defined in Azure Open AI Studio when creating a deployment
+ * backed by an Azure OpenAI base model.
*/
- @JsonProperty(value = "model")
- private String model;
+ @JsonProperty(value = "deployment_name")
+ private String deploymentName;
/**
* OpenAI Tool Function Callbacks to register with the ChatClient. For Prompt Options
@@ -170,8 +168,8 @@ public Builder(AzureOpenAiChatOptions options) {
this.options = options;
}
- public Builder withModel(String model) {
- this.options.model = model;
+ public Builder withDeploymentName(String deploymentName) {
+ this.options.deploymentName = deploymentName;
return this;
}
@@ -299,12 +297,12 @@ public void setFrequencyPenalty(Double frequencyPenalty) {
this.frequencyPenalty = frequencyPenalty;
}
- public String getModel() {
- return this.model;
+ public String getDeploymentName() {
+ return this.deploymentName;
}
- public void setModel(String model) {
- this.model = model;
+ public void setDeploymentName(String deploymentName) {
+ this.deploymentName = deploymentName;
}
@Override
@@ -312,7 +310,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -322,7 +319,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -333,7 +329,6 @@ public Integer getTopK() {
throw new UnsupportedOperationException("Unimplemented method 'getTopK'");
}
- @Override
@JsonIgnore
public void setTopK(Integer topK) {
throw new UnsupportedOperationException("Unimplemented method 'setTopK'");
@@ -344,7 +339,6 @@ public List getFunctionCallbacks() {
return this.functionCallbacks;
}
- @Override
public void setFunctionCallbacks(List functionCallbacks) {
this.functionCallbacks = functionCallbacks;
}
@@ -354,7 +348,6 @@ public Set getFunctions() {
return this.functions;
}
- @Override
public void setFunctions(Set functions) {
this.functions = functions;
}
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClient.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClient.java
index 8cbbded1f38..ab2c4c03487 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClient.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClient.java
@@ -1,3 +1,18 @@
+/*
+ * 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.azure.openai;
import java.util.ArrayList;
@@ -21,6 +36,7 @@
import org.springframework.ai.embedding.EmbeddingResponseMetadata;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
public class AzureOpenAiEmbeddingClient extends AbstractEmbeddingClient {
@@ -38,7 +54,7 @@ public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient) {
public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient, MetadataMode metadataMode) {
this(azureOpenAiClient, metadataMode,
- AzureOpenAiEmbeddingOptions.builder().withModel("text-embedding-ada-002").build());
+ AzureOpenAiEmbeddingOptions.builder().withDeploymentName("text-embedding-ada-002").build());
}
public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient, MetadataMode metadataMode,
@@ -78,7 +94,7 @@ public EmbeddingResponse call(EmbeddingRequest embeddingRequest) {
EmbeddingsOptions toEmbeddingOptions(EmbeddingRequest embeddingRequest) {
var azureOptions = new EmbeddingsOptions(embeddingRequest.getInstructions());
if (this.defaultOptions != null) {
- azureOptions.setModel(this.defaultOptions.getModel());
+ azureOptions.setModel(this.defaultOptions.getDeploymentName());
azureOptions.setUser(this.defaultOptions.getUser());
}
if (embeddingRequest.getOptions() != null && !EmbeddingOptions.EMPTY.equals(embeddingRequest.getOptions())) {
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java
index 3d89c40ae01..84445803d17 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -36,12 +35,13 @@ public class AzureOpenAiEmbeddingOptions implements EmbeddingOptions {
private String user;
/**
- * The model name to provide as part of this embeddings request. Not applicable to
- * Azure OpenAI, where deployment information should be included in the Azure resource
- * URI that's connected to.
+ * The deployment name as defined in Azure Open AI Studio when creating a deployment
+ * backed by an Azure OpenAI base model. If using Azure OpenAI library to communicate
+ * with OpenAI (not Azure OpenAI) then this value will be used as the name of the
+ * model. The json serialization of this field is 'model'.
*/
@JsonProperty(value = "model")
- private String model;
+ private String deploymentName;
public static Builder builder() {
return new Builder();
@@ -56,8 +56,8 @@ public Builder withUser(String user) {
return this;
}
- public Builder withModel(String model) {
- this.options.setModel(model);
+ public Builder withDeploymentName(String model) {
+ this.options.setDeploymentName(model);
return this;
}
@@ -75,12 +75,12 @@ public void setUser(String user) {
this.user = user;
}
- public String getModel() {
- return this.model;
+ public String getDeploymentName() {
+ return this.deploymentName;
}
- public void setModel(String model) {
- this.model = model;
+ public void setDeploymentName(String deploymentName) {
+ this.deploymentName = deploymentName;
}
}
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHints.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHints.java
index 461e082dc08..488870bcbc1 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHints.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHints.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.aot;
import com.azure.ai.openai.OpenAIAsyncClient;
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatResponseMetadata.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatResponseMetadata.java
index 4472a6df2c3..db9be145274 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatResponseMetadata.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatResponseMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.metadata;
import com.azure.ai.openai.models.ChatCompletions;
diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiUsage.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiUsage.java
index b5af6fe603b..a1bd5ddf1ce 100644
--- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiUsage.java
+++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiUsage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.metadata;
import com.azure.ai.openai.models.ChatCompletions;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureChatCompletionsOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureChatCompletionsOptionsTests.java
index 3f03d2111f3..70a0ac67e29 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureChatCompletionsOptionsTests.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureChatCompletionsOptionsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import com.azure.ai.openai.OpenAIClient;
@@ -34,7 +33,7 @@ public void createRequestWithChatOptions() {
OpenAIClient mockClient = Mockito.mock(OpenAIClient.class);
var client = new AzureOpenAiChatClient(mockClient,
- AzureOpenAiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6f).build());
+ AzureOpenAiChatOptions.builder().withDeploymentName("DEFAULT_MODEL").withTemperature(66.6f).build());
var requestOptions = client.toAzureChatCompletionsOptions(new Prompt("Test message content"));
@@ -44,7 +43,7 @@ public void createRequestWithChatOptions() {
assertThat(requestOptions.getTemperature()).isEqualTo(66.6f);
requestOptions = client.toAzureChatCompletionsOptions(new Prompt("Test message content",
- AzureOpenAiChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9f).build()));
+ AzureOpenAiChatOptions.builder().withDeploymentName("PROMPT_MODEL").withTemperature(99.9f).build()));
assertThat(requestOptions.getMessages()).hasSize(1);
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureEmbeddingsOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureEmbeddingsOptionsTests.java
index 818086df889..3a5e194d93f 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureEmbeddingsOptionsTests.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureEmbeddingsOptionsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import java.util.List;
@@ -38,7 +37,10 @@ public void createRequestWithChatOptions() {
OpenAIClient mockClient = Mockito.mock(OpenAIClient.class);
var client = new AzureOpenAiEmbeddingClient(mockClient, MetadataMode.EMBED,
- AzureOpenAiEmbeddingOptions.builder().withModel("DEFAULT_MODEL").withUser("USER_TEST").build());
+ AzureOpenAiEmbeddingOptions.builder()
+ .withDeploymentName("DEFAULT_MODEL")
+ .withUser("USER_TEST")
+ .build());
var requestOptions = client.toEmbeddingOptions(new EmbeddingRequest(List.of("Test message content"), null));
@@ -48,7 +50,10 @@ public void createRequestWithChatOptions() {
assertThat(requestOptions.getUser()).isEqualTo("USER_TEST");
requestOptions = client.toEmbeddingOptions(new EmbeddingRequest(List.of("Test message content"),
- AzureOpenAiEmbeddingOptions.builder().withModel("PROMPT_MODEL").withUser("PROMPT_USER").build()));
+ AzureOpenAiEmbeddingOptions.builder()
+ .withDeploymentName("PROMPT_MODEL")
+ .withUser("PROMPT_USER")
+ .build()));
assertThat(requestOptions.getInput()).hasSize(1);
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java
index a34c1ef15c3..a2fa5e24d31 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.azure.openai;
import java.util.Arrays;
@@ -181,7 +196,7 @@ public OpenAIClient openAIClient() {
@Bean
public AzureOpenAiChatClient azureOpenAiChatClient(OpenAIClient openAIClient) {
return new AzureOpenAiChatClient(openAIClient,
- AzureOpenAiChatOptions.builder().withModel("gpt-35-turbo").withMaxTokens(200).build());
+ AzureOpenAiChatOptions.builder().withDeploymentName("gpt-35-turbo").withMaxTokens(200).build());
}
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClientIT.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClientIT.java
index 00f301f72c6..b973aa19b53 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClientIT.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.azure.openai;
import java.util.List;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAiTestConfiguration.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAiTestConfiguration.java
index 6e3a402a035..124cd4485b5 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAiTestConfiguration.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAiTestConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAzureOpenAiTestConfiguration.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAzureOpenAiTestConfiguration.java
index 95241ab4a96..f5e7b438a25 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAzureOpenAiTestConfiguration.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/MockAzureOpenAiTestConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai;
import com.azure.ai.openai.OpenAIClient;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHintsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHintsTests.java
index 128dd904e5d..eaec2cbdddd 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHintsTests.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHintsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.aot;
import java.util.Set;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/AzureOpenAiChatClientFunctionCallIT.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/AzureOpenAiChatClientFunctionCallIT.java
index b32bf7c27c5..3e67dc3c694 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/AzureOpenAiChatClientFunctionCallIT.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/AzureOpenAiChatClientFunctionCallIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.azure.openai.function;
import java.util.ArrayList;
@@ -43,7 +58,7 @@ void functionCallTest() {
List messages = new ArrayList<>(List.of(userMessage));
var promptOptions = AzureOpenAiChatOptions.builder()
- .withModel("gpt-4-0125-preview")
+ .withDeploymentName("gpt-4-0125-preview")
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
.withName("getCurrentWeather")
.withDescription("Get the current weather in a given location")
@@ -73,8 +88,10 @@ public OpenAIClient openAIClient() {
@Bean
public AzureOpenAiChatClient azureOpenAiChatClient(OpenAIClient openAIClient) {
return new AzureOpenAiChatClient(openAIClient,
- AzureOpenAiChatOptions.builder().withModel("gpt-35-turbo-0613").withMaxTokens(500).build());
-
+ AzureOpenAiChatOptions.builder()
+ .withDeploymentName("gpt-4-0125-preview")
+ .withMaxTokens(500)
+ .build());
}
}
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/MockWeatherService.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/MockWeatherService.java
index e09c7e92a1a..898a1c61b6f 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/MockWeatherService.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.function;
import java.util.function.Function;
diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatClientMetadataTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatClientMetadataTests.java
index e4cc08d31d9..2338e72f42e 100644
--- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatClientMetadataTests.java
+++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/metadata/AzureOpenAiChatClientMetadataTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.azure.openai.metadata;
import java.nio.charset.StandardCharsets;
diff --git a/models/spring-ai-bedrock/README.md b/models/spring-ai-bedrock/README.md
index ec570633693..1dd28b2808d 100644
--- a/models/spring-ai-bedrock/README.md
+++ b/models/spring-ai-bedrock/README.md
@@ -1,10 +1,11 @@
[Amazon Bedrock Overview](https://docs.spring.io/spring-ai/reference/api/bedrock.html)
-- [Anthropic Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/bedrock/bedrock-anthropic.html)
-- [Cohere Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/bedrock/bedrock-cohere.html)
+- [Anthropic Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-anthropic.html)
+- [Cohere Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-cohere.html)
- [Cohere Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/bedrock-cohere-embedding.html)
-- [Llama2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/bedrock/bedrock-llama2.html)
-- [Titan Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/bedrock/bedrock-titan.html)
+- [Llama2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-llama2.html)
+- [Titan Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-titan.html)
- [Titan Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/bedrock-titan-embedding.html)
+- [Jurassic2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-jurassic2.html)
NOTE: There is not yet an implementation for Jurassic, but you can use the lower level client [Ai21Jurassic2ChatBedrockApi.java](https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java) in the meantime. See [Issue 343](https://github.com/spring-projects/spring-ai/issues/343)
\ No newline at end of file
diff --git a/models/spring-ai-bedrock/pom.xml b/models/spring-ai-bedrock/pom.xml
index 0762a147cf0..c7e7d340071 100644
--- a/models/spring-ai-bedrock/pom.xml
+++ b/models/spring-ai-bedrock/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-bedrock
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/BedrockUsage.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/BedrockUsage.java
index 9fa68242a01..6eb31aa28e7 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/BedrockUsage.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/BedrockUsage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock;
import org.springframework.ai.bedrock.api.AbstractBedrockApi.AmazonBedrockInvocationMetrics;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java
index d01ecffddc5..6f2f3301e3a 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/MessageToPromptConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock;
import java.util.List;
@@ -38,11 +37,18 @@ public class MessageToPromptConverter {
private String assistantPrompt = ASSISTANT_PROMPT;
- private MessageToPromptConverter() {
+ private final String lineSeparator;
+
+ private MessageToPromptConverter(String lineSeparator) {
+ this.lineSeparator = lineSeparator;
}
public static MessageToPromptConverter create() {
- return new MessageToPromptConverter();
+ return create(System.lineSeparator());
+ }
+
+ public static MessageToPromptConverter create(String lineSeparator) {
+ return new MessageToPromptConverter(lineSeparator);
}
public MessageToPromptConverter withHumanPrompt(String humanPrompt) {
@@ -60,15 +66,17 @@ public String toPrompt(List messages) {
final String systemMessages = messages.stream()
.filter(message -> message.getMessageType() == MessageType.SYSTEM)
.map(Message::getContent)
- .collect(Collectors.joining("\n"));
+ .collect(Collectors.joining(System.lineSeparator()));
final String userMessages = messages.stream()
.filter(message -> message.getMessageType() == MessageType.USER
|| message.getMessageType() == MessageType.ASSISTANT)
.map(this::messageToString)
- .collect(Collectors.joining("\n"));
+ .collect(Collectors.joining(System.lineSeparator()));
- final String prompt = String.format("%s%n%n%s%n%s", systemMessages, userMessages, ASSISTANT_PROMPT);
+ // Related to: https://github.com/spring-projects/spring-ai/issues/404
+ final String prompt = systemMessages + this.lineSeparator + this.lineSeparator + userMessages
+ + this.lineSeparator + ASSISTANT_PROMPT;
return prompt;
}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.java
index 75e209b6a64..2daceca219b 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.anthropic;
import java.util.List;
@@ -119,7 +118,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -137,7 +135,6 @@ public Integer getTopK() {
return this.topK;
}
- @Override
public void setTopK(Integer topK) {
this.topK = topK;
}
@@ -147,7 +144,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClient.java
index 79782d42961..26b88734471 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.anthropic;
import java.util.List;
@@ -94,7 +93,8 @@ public Flux stream(Prompt prompt) {
*/
AnthropicChatRequest createRequest(Prompt prompt) {
- final String promptValue = MessageToPromptConverter.create().toPrompt(prompt.getInstructions());
+ // Related to: https://github.com/spring-projects/spring-ai/issues/404
+ final String promptValue = MessageToPromptConverter.create("\n").toPrompt(prompt.getInstructions());
AnthropicChatRequest request = AnthropicChatRequest.builder(promptValue).build();
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java
index 676324969ec..38fdd503059 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.anthropic.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java
index 6aa2eecd2b2..3cca99876b3 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.aot;
import org.springframework.ai.bedrock.anthropic.AnthropicChatOptions;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java
index f656e93caea..91c813e167a 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/api/AbstractBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
// @formatter:off
package org.springframework.ai.bedrock.api;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClient.java
index 7a9a752bf5b..3ff2b2ceecb 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.java
index d1db43ac730..89f625432fd 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere;
import java.util.List;
@@ -144,7 +143,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -154,7 +152,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -164,7 +161,6 @@ public Integer getTopK() {
return this.topK;
}
- @Override
public void setTopK(Integer topK) {
this.topK = topK;
}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClient.java
index 514b6385f98..2c0145059f9 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java
index c79c73bc88f..420aff28d80 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -33,7 +32,7 @@ public class BedrockCohereEmbeddingOptions implements EmbeddingOptions {
// @formatter:off
/**
* Prepends special tokens to differentiate each type from one another. You should not mix
- * different types together, except when mixing types for for search and retrieval.
+ * different types together, except when mixing types for search and retrieval.
* In this case, embed your corpus with the search_document type and embedded queries with
* type search_query type.
*/
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java
index 6d2cd9fb80b..cc9cc67e618 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java
index 682bd450a0d..9bd928a4a64 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -69,7 +69,7 @@ public CohereEmbeddingBedrockApi(String modelId, AwsCredentialsProvider credenti
* @param texts An array of strings for the model to embed. For optimal performance, we recommend reducing the
* length of each text to less than 512 tokens. 1 token is about 4 characters.
* @param inputType Prepends special tokens to differentiate each type from one another. You should not mix
- * different types together, except when mixing types for for search and retrieval. In this case, embed your corpus
+ * different types together, except when mixing types for search and retrieval. In this case, embed your corpus
* with the search_document type and embedded queries with type search_query type.
* @param truncate Specifies how the API handles inputs longer than the maximum token length. If you specify LEFT or
* RIGHT, the model discards the input until the remaining input is exactly the maximum input token length for the
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatClient.java
new file mode 100644
index 00000000000..7a11a25246c
--- /dev/null
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatClient.java
@@ -0,0 +1,124 @@
+/*
+ * 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.jurassic2;
+
+import org.springframework.ai.bedrock.MessageToPromptConverter;
+import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
+import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatRequest;
+import org.springframework.ai.chat.ChatClient;
+import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.Generation;
+import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
+import org.springframework.ai.chat.prompt.ChatOptions;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.model.ModelOptionsUtils;
+import org.springframework.util.Assert;
+
+/**
+ * Java {@link ChatClient} for the Bedrock Jurassic2 chat generative model.
+ *
+ * @author Ahmed Yousri
+ * @since 1.0.0
+ */
+public class BedrockAi21Jurassic2ChatClient implements ChatClient {
+
+ private final Ai21Jurassic2ChatBedrockApi chatApi;
+
+ private final BedrockAi21Jurassic2ChatOptions defaultOptions;
+
+ public BedrockAi21Jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi chatApi,
+ BedrockAi21Jurassic2ChatOptions options) {
+ Assert.notNull(chatApi, "Ai21Jurassic2ChatBedrockApi must not be null");
+ Assert.notNull(options, "BedrockAi21Jurassic2ChatOptions must not be null");
+
+ this.chatApi = chatApi;
+ this.defaultOptions = options;
+ }
+
+ public BedrockAi21Jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi chatApi) {
+ this(chatApi,
+ BedrockAi21Jurassic2ChatOptions.builder()
+ .withTemperature(0.8f)
+ .withTopP(0.9f)
+ .withMaxTokens(100)
+ .build());
+ }
+
+ @Override
+ public ChatResponse call(Prompt prompt) {
+ var request = createRequest(prompt);
+ var response = this.chatApi.chatCompletion(request);
+
+ return new ChatResponse(response.completions()
+ .stream()
+ .map(completion -> new Generation(completion.data().text())
+ .withGenerationMetadata(ChatGenerationMetadata.from(completion.finishReason().reason(), null)))
+ .toList());
+ }
+
+ private Ai21Jurassic2ChatRequest createRequest(Prompt prompt) {
+
+ final String promptValue = MessageToPromptConverter.create().toPrompt(prompt.getInstructions());
+
+ Ai21Jurassic2ChatRequest request = Ai21Jurassic2ChatRequest.builder(promptValue).build();
+
+ if (prompt.getOptions() != null) {
+ if (prompt.getOptions() instanceof ChatOptions runtimeOptions) {
+ BedrockAi21Jurassic2ChatOptions updatedRuntimeOptions = ModelOptionsUtils.copyToTarget(runtimeOptions,
+ ChatOptions.class, BedrockAi21Jurassic2ChatOptions.class);
+ request = ModelOptionsUtils.merge(updatedRuntimeOptions, request, Ai21Jurassic2ChatRequest.class);
+ }
+ else {
+ throw new IllegalArgumentException("Prompt options are not of type ChatOptions: "
+ + prompt.getOptions().getClass().getSimpleName());
+ }
+ }
+
+ if (this.defaultOptions != null) {
+ request = ModelOptionsUtils.merge(request, this.defaultOptions, Ai21Jurassic2ChatRequest.class);
+ }
+
+ return request;
+ }
+
+ public static Builder builder(Ai21Jurassic2ChatBedrockApi chatApi) {
+ return new Builder(chatApi);
+ }
+
+ public static class Builder {
+
+ private final Ai21Jurassic2ChatBedrockApi chatApi;
+
+ private BedrockAi21Jurassic2ChatOptions options;
+
+ public Builder(Ai21Jurassic2ChatBedrockApi chatApi) {
+ this.chatApi = chatApi;
+ }
+
+ public Builder withOptions(BedrockAi21Jurassic2ChatOptions options) {
+ this.options = options;
+ return this;
+ }
+
+ public BedrockAi21Jurassic2ChatClient build() {
+ return new BedrockAi21Jurassic2ChatClient(chatApi,
+ options != null ? options : BedrockAi21Jurassic2ChatOptions.builder().build());
+ }
+
+ }
+
+}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatOptions.java
new file mode 100644
index 00000000000..4b62a58548d
--- /dev/null
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatOptions.java
@@ -0,0 +1,416 @@
+/*
+ * 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.jurassic2;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.springframework.ai.chat.prompt.ChatOptions;
+
+/**
+ * Request body for the /complete endpoint of the Jurassic-2 API.
+ *
+ * @author Ahmed Yousri
+ * @since 1.0.0
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BedrockAi21Jurassic2ChatOptions implements ChatOptions {
+
+ /**
+ * The text which the model is requested to continue.
+ */
+ @JsonProperty("prompt")
+ private String prompt;
+
+ /**
+ * Number of completions to sample and return.
+ */
+ @JsonProperty("numResults")
+ private Integer numResults;
+
+ /**
+ * The maximum number of tokens to generate per result.
+ */
+ @JsonProperty("maxTokens")
+ private Integer maxTokens;
+
+ /**
+ * The minimum number of tokens to generate per result.
+ */
+ @JsonProperty("minTokens")
+ private Integer minTokens;
+
+ /**
+ * Modifies the distribution from which tokens are sampled.
+ */
+ @JsonProperty("temperature")
+ private Float temperature;
+
+ /**
+ * Sample tokens from the corresponding top percentile of probability mass.
+ */
+ @JsonProperty("topP")
+ private Float topP;
+
+ /**
+ * Return the top-K (topKReturn) alternative tokens.
+ */
+ @JsonProperty("topKReturn")
+ private Integer topK;
+
+ /**
+ * Stops decoding if any of the strings is generated.
+ */
+ @JsonProperty("stopSequences")
+ private String[] stopSequences;
+
+ /**
+ * Penalty object for frequency.
+ */
+ @JsonProperty("frequencyPenalty")
+ private Penalty frequencyPenalty;
+
+ /**
+ * Penalty object for presence.
+ */
+ @JsonProperty("presencePenalty")
+ private Penalty presencePenalty;
+
+ /**
+ * Penalty object for count.
+ */
+ @JsonProperty("countPenalty")
+ private Penalty countPenalty;
+
+ // Getters and setters
+
+ /**
+ * Gets the prompt text for the model to continue.
+ * @return The prompt text.
+ */
+ public String getPrompt() {
+ return prompt;
+ }
+
+ /**
+ * Sets the prompt text for the model to continue.
+ * @param prompt The prompt text.
+ */
+ public void setPrompt(String prompt) {
+ this.prompt = prompt;
+ }
+
+ /**
+ * Gets the number of completions to sample and return.
+ * @return The number of results.
+ */
+ public Integer getNumResults() {
+ return numResults;
+ }
+
+ /**
+ * Sets the number of completions to sample and return.
+ * @param numResults The number of results.
+ */
+ public void setNumResults(Integer numResults) {
+ this.numResults = numResults;
+ }
+
+ /**
+ * Gets the maximum number of tokens to generate per result.
+ * @return The maximum number of tokens.
+ */
+ public Integer getMaxTokens() {
+ return maxTokens;
+ }
+
+ /**
+ * Sets the maximum number of tokens to generate per result.
+ * @param maxTokens The maximum number of tokens.
+ */
+ public void setMaxTokens(Integer maxTokens) {
+ this.maxTokens = maxTokens;
+ }
+
+ /**
+ * Gets the minimum number of tokens to generate per result.
+ * @return The minimum number of tokens.
+ */
+ public Integer getMinTokens() {
+ return minTokens;
+ }
+
+ /**
+ * Sets the minimum number of tokens to generate per result.
+ * @param minTokens The minimum number of tokens.
+ */
+ public void setMinTokens(Integer minTokens) {
+ this.minTokens = minTokens;
+ }
+
+ /**
+ * Gets the temperature for modifying the token sampling distribution.
+ * @return The temperature.
+ */
+ public Float getTemperature() {
+ return temperature;
+ }
+
+ /**
+ * Sets the temperature for modifying the token sampling distribution.
+ * @param temperature The temperature.
+ */
+ public void setTemperature(Float temperature) {
+ this.temperature = temperature;
+ }
+
+ /**
+ * Gets the topP parameter for sampling tokens from the top percentile of probability
+ * mass.
+ * @return The topP parameter.
+ */
+ public Float getTopP() {
+ return topP;
+ }
+
+ /**
+ * Sets the topP parameter for sampling tokens from the top percentile of probability
+ * mass.
+ * @param topP The topP parameter.
+ */
+ public void setTopP(Float topP) {
+ this.topP = topP;
+ }
+
+ /**
+ * Gets the top-K (topKReturn) alternative tokens to return.
+ * @return The top-K parameter. (topKReturn)
+ */
+ @Override
+ public Integer getTopK() {
+ return topK;
+ }
+
+ /**
+ * Sets the top-K (topKReturn) alternative tokens to return.
+ * @param topK The top-K parameter (topKReturn).
+ */
+ public void setTopK(Integer topK) {
+ this.topK = topK;
+ }
+
+ /**
+ * Gets the stop sequences for stopping decoding if any of the strings is generated.
+ * @return The stop sequences.
+ */
+ public String[] getStopSequences() {
+ return stopSequences;
+ }
+
+ /**
+ * Sets the stop sequences for stopping decoding if any of the strings is generated.
+ * @param stopSequences The stop sequences.
+ */
+ public void setStopSequences(String[] stopSequences) {
+ this.stopSequences = stopSequences;
+ }
+
+ /**
+ * Gets the frequency penalty object.
+ * @return The frequency penalty object.
+ */
+ public Penalty getFrequencyPenalty() {
+ return frequencyPenalty;
+ }
+
+ /**
+ * Sets the frequency penalty object.
+ * @param frequencyPenalty The frequency penalty object.
+ */
+ public void setFrequencyPenalty(Penalty frequencyPenalty) {
+ this.frequencyPenalty = frequencyPenalty;
+ }
+
+ /**
+ * Gets the presence penalty object.
+ * @return The presence penalty object.
+ */
+ public Penalty getPresencePenalty() {
+ return presencePenalty;
+ }
+
+ /**
+ * Sets the presence penalty object.
+ * @param presencePenalty The presence penalty object.
+ */
+ public void setPresencePenalty(Penalty presencePenalty) {
+ this.presencePenalty = presencePenalty;
+ }
+
+ /**
+ * Gets the count penalty object.
+ * @return The count penalty object.
+ */
+ public Penalty getCountPenalty() {
+ return countPenalty;
+ }
+
+ /**
+ * Sets the count penalty object.
+ * @param countPenalty The count penalty object.
+ */
+ public void setCountPenalty(Penalty countPenalty) {
+ this.countPenalty = countPenalty;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private final BedrockAi21Jurassic2ChatOptions request = new BedrockAi21Jurassic2ChatOptions();
+
+ public Builder withPrompt(String prompt) {
+ request.setPrompt(prompt);
+ return this;
+ }
+
+ public Builder withNumResults(Integer numResults) {
+ request.setNumResults(numResults);
+ return this;
+ }
+
+ public Builder withMaxTokens(Integer maxTokens) {
+ request.setMaxTokens(maxTokens);
+ return this;
+ }
+
+ public Builder withMinTokens(Integer minTokens) {
+ request.setMinTokens(minTokens);
+ return this;
+ }
+
+ public Builder withTemperature(Float temperature) {
+ request.setTemperature(temperature);
+ return this;
+ }
+
+ public Builder withTopP(Float topP) {
+ request.setTopP(topP);
+ return this;
+ }
+
+ public Builder withStopSequences(String[] stopSequences) {
+ request.setStopSequences(stopSequences);
+ return this;
+ }
+
+ public Builder withTopK(Integer topKReturn) {
+ request.setTopK(topKReturn);
+ return this;
+ }
+
+ public Builder withFrequencyPenalty(BedrockAi21Jurassic2ChatOptions.Penalty frequencyPenalty) {
+ request.setFrequencyPenalty(frequencyPenalty);
+ return this;
+ }
+
+ public Builder withPresencePenalty(BedrockAi21Jurassic2ChatOptions.Penalty presencePenalty) {
+ request.setPresencePenalty(presencePenalty);
+ return this;
+ }
+
+ public Builder withCountPenalty(BedrockAi21Jurassic2ChatOptions.Penalty countPenalty) {
+ request.setCountPenalty(countPenalty);
+ return this;
+ }
+
+ public BedrockAi21Jurassic2ChatOptions build() {
+ return request;
+ }
+
+ }
+
+ /**
+ * Penalty object for frequency, presence, and count penalties.
+ */
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public record Penalty(@JsonProperty("scale") Float scale, @JsonProperty("applyToNumbers") Boolean applyToNumbers,
+ @JsonProperty("applyToPunctuations") Boolean applyToPunctuations,
+ @JsonProperty("applyToStopwords") Boolean applyToStopwords,
+ @JsonProperty("applyToWhitespaces") Boolean applyToWhitespaces,
+ @JsonProperty("applyToEmojis") Boolean applyToEmojis) {
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private Float scale;
+
+ // can't keep it null due to modelOptionsUtils#mapToClass convert null to
+ // false
+ private Boolean applyToNumbers = true;
+
+ private Boolean applyToPunctuations = true;
+
+ private Boolean applyToStopwords = true;
+
+ private Boolean applyToWhitespaces = true;
+
+ private Boolean applyToEmojis = true;
+
+ public Builder scale(Float scale) {
+ this.scale = scale;
+ return this;
+ }
+
+ public Builder applyToNumbers(Boolean applyToNumbers) {
+ this.applyToNumbers = applyToNumbers;
+ return this;
+ }
+
+ public Builder applyToPunctuations(Boolean applyToPunctuations) {
+ this.applyToPunctuations = applyToPunctuations;
+ return this;
+ }
+
+ public Builder applyToStopwords(Boolean applyToStopwords) {
+ this.applyToStopwords = applyToStopwords;
+ return this;
+ }
+
+ public Builder applyToWhitespaces(Boolean applyToWhitespaces) {
+ this.applyToWhitespaces = applyToWhitespaces;
+ return this;
+ }
+
+ public Builder applyToEmojis(Boolean applyToEmojis) {
+ this.applyToEmojis = applyToEmojis;
+ return this;
+ }
+
+ public Penalty build() {
+ return new Penalty(scale, applyToNumbers, applyToPunctuations, applyToStopwords, applyToWhitespaces,
+ applyToEmojis);
+ }
+
+ }
+ }
+
+}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java
index 410fb21e1a5..451dd234653 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -22,10 +22,12 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatRequest;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatResponse;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
/**
* Java client for the Bedrock Jurassic2 chat model.
@@ -48,6 +50,21 @@ public Ai21Jurassic2ChatBedrockApi(String modelId, String region) {
super(modelId, region);
}
+
+ /**
+ * Create a new Ai21Jurassic2ChatBedrockApi instance.
+ *
+ * @param modelId The model id to use. See the {@link Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel} for the supported models.
+ * @param credentialsProvider The credentials provider to connect to AWS.
+ * @param region The AWS region to use.
+ * @param objectMapper The object mapper to use for JSON serialization and deserialization.
+ */
+ public Ai21Jurassic2ChatBedrockApi(String modelId, AwsCredentialsProvider credentialsProvider, String region,
+ ObjectMapper objectMapper) {
+ super(modelId, credentialsProvider, region, objectMapper);
+ }
+
+
/**
* AI21 Jurassic2 chat request parameters.
*
@@ -129,6 +146,74 @@ public record FloatScalePenalty(@JsonProperty("scale") Float scale,
@JsonProperty("applyToStopwords") boolean applyToStopwords,
@JsonProperty("applyToEmojis") boolean applyToEmojis) {
}
+
+
+
+ public static Builder builder(String prompt) {
+ return new Builder(prompt);
+ }
+ public static class Builder {
+ private String prompt;
+ private Float temperature;
+ private Float topP;
+ private Integer maxTokens;
+ private List stopSequences;
+ private IntegerScalePenalty countPenalty;
+ private FloatScalePenalty presencePenalty;
+ private IntegerScalePenalty frequencyPenalty;
+
+ public Builder(String prompt) {
+ this.prompt = prompt;
+ }
+
+ public Builder withTemperature(Float temperature) {
+ this.temperature = temperature;
+ return this;
+ }
+
+ public Builder withTopP(Float topP) {
+ this.topP = topP;
+ return this;
+ }
+
+ public Builder withMaxTokens(Integer maxTokens) {
+ this.maxTokens = maxTokens;
+ return this;
+ }
+
+ public Builder withStopSequences(List stopSequences) {
+ this.stopSequences = stopSequences;
+ return this;
+ }
+
+ public Builder withCountPenalty(IntegerScalePenalty countPenalty) {
+ this.countPenalty = countPenalty;
+ return this;
+ }
+
+ public Builder withPresencePenalty(FloatScalePenalty presencePenalty) {
+ this.presencePenalty = presencePenalty;
+ return this;
+ }
+
+ public Builder withFrequencyPenalty(IntegerScalePenalty frequencyPenalty) {
+ this.frequencyPenalty = frequencyPenalty;
+ return this;
+ }
+
+ public Ai21Jurassic2ChatRequest build() {
+ return new Ai21Jurassic2ChatRequest(
+ prompt,
+ temperature,
+ topP,
+ maxTokens,
+ stopSequences,
+ countPenalty,
+ presencePenalty,
+ frequencyPenalty
+ );
+ }
+ }
}
/**
@@ -273,5 +358,7 @@ public String id() {
public Ai21Jurassic2ChatResponse chatCompletion(Ai21Jurassic2ChatRequest request) {
return this.internalInvocation(request, Ai21Jurassic2ChatResponse.class);
}
+
+
}
// @formatter:on
\ No newline at end of file
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java
index b6aa407150b..a12fe0b6eb9 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.llama2;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java
index 5c2bed1efbd..a944b09904a 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.llama2;
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -105,7 +104,6 @@ public Integer getTopK() {
throw new UnsupportedOperationException("Unsupported option: 'TopK'");
}
- @Override
@JsonIgnore
public void setTopK(Integer topK) {
throw new UnsupportedOperationException("Unsupported option: 'TopK'");
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java
index c619042da23..3d631732ae1 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.llama2.api;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClient.java
index 091eaa5bb65..e77d8277cb2 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.java
index 86d93fd764e..61b16d16e95 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan;
import java.util.List;
@@ -122,12 +121,11 @@ public void setStopSequences(List stopSequences) {
@Override
public Integer getTopK() {
- throw new UnsupportedOperationException("Bedrock Titian Chat does not support the 'TopK' option.");
+ throw new UnsupportedOperationException("Bedrock Titan Chat does not support the 'TopK' option.");
}
- @Override
public void setTopK(Integer topK) {
- throw new UnsupportedOperationException("Bedrock Titian Chat does not support the 'TopK' option.'");
+ throw new UnsupportedOperationException("Bedrock Titan Chat does not support the 'TopK' option.'");
}
}
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClient.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClient.java
index 09bae908336..d48135f80ec 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClient.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan;
import java.util.ArrayList;
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java
index 244730a9bd8..b2e0fb6b7d0 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java
index 63adadf1bbf..5f2db007249 100644
--- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java
+++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java
index 241dfb7b4c4..23d853aea20 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.anthropic;
import java.util.Arrays;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java
index 2f3bb239567..b3763479275 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/BedrockAnthropicCreateRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.anthropic;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java
index fdf49ab5575..09c2d9ff3e4 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/anthropic/api/AnthropicChatBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.anthropic.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java
index 43382fd4321..a4b51a70750 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/aot/BedrockRuntimeHintsTests.java
@@ -1,3 +1,18 @@
+/*
+ * 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.aot;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java
index 73b88766bce..12512af50cf 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.cohere;
import java.util.Arrays;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java
index 15227244feb..4eafef9ef19 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatCreateRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java
index f00e2d7425c..9dda3870c22 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.cohere;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java
index a54ef148108..d56e7beb6cf 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereChatBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java
index a76b1d7474d..721c78783d1 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.cohere.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java
index 1bca68660c2..6b58cb77277 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.jurassic2.api;
import java.util.stream.Collectors;
@@ -55,7 +54,7 @@ public void chatCompletion() {
String responseContent = response.completions()
.stream()
.map(c -> c.data().text())
- .collect(Collectors.joining("\n"));
+ .collect(Collectors.joining(System.lineSeparator()));
assertThat(responseContent).contains("Blackbeard");
}
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java
new file mode 100644
index 00000000000..076eb3e68ee
--- /dev/null
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/jurassic2/api/BedrockAi21Jurassic2ChatClientIT.java
@@ -0,0 +1,165 @@
+/*
+ * 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.jurassic2.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatClient;
+import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatOptions;
+import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.Generation;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.chat.prompt.PromptTemplate;
+import org.springframework.ai.chat.prompt.SystemPromptTemplate;
+import org.springframework.ai.parser.MapOutputParser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.Resource;
+import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
+@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
+class BedrockAi21Jurassic2ChatClientIT {
+
+ @Autowired
+ private BedrockAi21Jurassic2ChatClient client;
+
+ @Value("classpath:/prompts/system-message.st")
+ private Resource systemResource;
+
+ @Test
+ void roleTest() {
+ UserMessage userMessage = new UserMessage(
+ "Tell me about 3 famous pirates from the Golden Age of Piracy and why they did.");
+ SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
+ Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
+
+ Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
+
+ ChatResponse response = client.call(prompt);
+
+ assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
+ }
+
+ @Test
+ void testEmojiPenaltyFalse() {
+ BedrockAi21Jurassic2ChatOptions.Penalty penalty = new BedrockAi21Jurassic2ChatOptions.Penalty.Builder()
+ .applyToEmojis(false)
+ .build();
+ BedrockAi21Jurassic2ChatOptions options = new BedrockAi21Jurassic2ChatOptions.Builder()
+ .withPresencePenalty(penalty)
+ .build();
+
+ UserMessage userMessage = new UserMessage("Can you express happiness using an emoji like 😄 ?");
+ Prompt prompt = new Prompt(List.of(userMessage), options);
+
+ ChatResponse response = client.call(prompt);
+
+ assertThat(response.getResult().getOutput().getContent()).matches(content -> content.contains("😄"));
+ }
+
+ @Test
+ @Disabled("This test is failing when run in combination with the other tests")
+ void emojiPenaltyWhenTrueByDefaultApplyPenaltyTest() {
+ // applyToEmojis is by default true
+ BedrockAi21Jurassic2ChatOptions.Penalty penalty = new BedrockAi21Jurassic2ChatOptions.Penalty.Builder().build();
+ BedrockAi21Jurassic2ChatOptions options = new BedrockAi21Jurassic2ChatOptions.Builder()
+ .withPresencePenalty(penalty)
+ .build();
+
+ UserMessage userMessage = new UserMessage("Can you express happiness using an emoji like 😄?");
+ SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
+ Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
+
+ Prompt prompt = new Prompt(List.of(userMessage, systemMessage), options);
+
+ ChatResponse response = client.call(prompt);
+
+ assertThat(response.getResult().getOutput().getContent()).doesNotContain("😄");
+ }
+
+ @Test
+ void mapOutputParser() {
+ MapOutputParser outputParser = new MapOutputParser();
+
+ String format = outputParser.getFormat();
+ String template = """
+ Provide me a List of {subject}
+ {format}
+ """;
+ PromptTemplate promptTemplate = new PromptTemplate(template,
+ Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
+ Prompt prompt = new Prompt(promptTemplate.createMessage());
+ Generation generation = client.call(prompt).getResult();
+
+ Map result = outputParser.parse(generation.getOutput().getContent());
+ assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
+
+ }
+
+ @Test
+ void simpleChatResponse() {
+ UserMessage userMessage = new UserMessage("Tell me a joke about AI.");
+ SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
+ Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
+
+ Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
+
+ ChatResponse response = client.call(prompt);
+
+ assertThat(response.getResult().getOutput().getContent()).contains("AI");
+ }
+
+ @SpringBootConfiguration
+ public static class TestConfiguration {
+
+ @Bean
+ public Ai21Jurassic2ChatBedrockApi jurassic2ChatBedrockApi() {
+ return new Ai21Jurassic2ChatBedrockApi(
+ Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(),
+ EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper());
+ }
+
+ @Bean
+ public BedrockAi21Jurassic2ChatClient bedrockAi21Jurassic2ChatClient(
+ Ai21Jurassic2ChatBedrockApi jurassic2ChatBedrockApi) {
+ return new BedrockAi21Jurassic2ChatClient(jurassic2ChatBedrockApi,
+ BedrockAi21Jurassic2ChatOptions.builder()
+ .withTemperature(0.5f)
+ .withMaxTokens(100)
+ .withTopP(0.9f)
+ .build());
+ }
+
+ }
+
+}
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java
index fae4991c589..c73a3e9264a 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.llama2;
import java.util.Arrays;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java
index 20e7ec1b0d2..876f3a303e0 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/BedrockLlama2CreateRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.llama2;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java
index 7d215a63a5e..19acc1d0f12 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/llama2/api/Llama2ChatBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.llama2.api;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java
index 9d98681a68c..51fae542c0e 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.titan;
import java.util.Arrays;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java
index b154f5b18a2..b7907c11b16 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanChatCreateRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan;
import java.util.List;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java
index ba2d53723bf..e6253e2db6f 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.titan;
import java.io.IOException;
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java
index dacb7fd6604..c60ce5dfc25 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan.api;
import java.util.List;
@@ -60,8 +59,9 @@ public void chatCompletionStream() {
Flux response = titanBedrockApi.chatCompletionStream(titanChatRequest);
List results = response.collectList().block();
- assertThat(results.stream().map(TitanChatResponseChunk::outputText).collect(Collectors.joining("\n")))
- .contains("Blackbeard");
+ assertThat(results.stream()
+ .map(TitanChatResponseChunk::outputText)
+ .collect(Collectors.joining(System.lineSeparator()))).contains("Blackbeard");
}
}
diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java
index 7e65156265b..4595e6edf2c 100644
--- a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java
+++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/api/TitanEmbeddingBedrockApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.bedrock.titan.api;
import java.io.IOException;
diff --git a/models/spring-ai-huggingface/README.md b/models/spring-ai-huggingface/README.md
index 720a250504e..cc64e74b626 100644
--- a/models/spring-ai-huggingface/README.md
+++ b/models/spring-ai-huggingface/README.md
@@ -1,2 +1,2 @@
-[Huggingface Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/huggingface.html)
+[Huggingface Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/huggingface.html)
diff --git a/models/spring-ai-huggingface/pom.xml b/models/spring-ai-huggingface/pom.xml
index 17d31f24caf..43f32d638b0 100644
--- a/models/spring-ai-huggingface/pom.xml
+++ b/models/spring-ai-huggingface/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-huggingface
diff --git a/models/spring-ai-huggingface/src/main/java/org/springframework/ai/huggingface/HuggingfaceChatClient.java b/models/spring-ai-huggingface/src/main/java/org/springframework/ai/huggingface/HuggingfaceChatClient.java
index a279f79372b..65b6ecdc993 100644
--- a/models/spring-ai-huggingface/src/main/java/org/springframework/ai/huggingface/HuggingfaceChatClient.java
+++ b/models/spring-ai-huggingface/src/main/java/org/springframework/ai/huggingface/HuggingfaceChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.huggingface;
import java.util.ArrayList;
diff --git a/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/HuggingfaceTestConfiguration.java b/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/HuggingfaceTestConfiguration.java
index 3246c20c3b8..e4adf3bb8d6 100644
--- a/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/HuggingfaceTestConfiguration.java
+++ b/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/HuggingfaceTestConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.huggingface;
import org.springframework.boot.SpringBootConfiguration;
diff --git a/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/client/ClientIT.java b/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/client/ClientIT.java
index 05f814a5fc8..2fa2e89bb68 100644
--- a/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/client/ClientIT.java
+++ b/models/spring-ai-huggingface/src/test/java/org/springframework/ai/huggingface/client/ClientIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.huggingface.client;
import org.junit.jupiter.api.Disabled;
diff --git a/models/spring-ai-mistral-ai/pom.xml b/models/spring-ai-mistral-ai/pom.xml
index a613e4f6a1c..316e22b2a8f 100644
--- a/models/spring-ai-mistral-ai/pom.xml
+++ b/models/spring-ai-mistral-ai/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-mistral-ai
@@ -29,24 +29,13 @@
${project.parent.version}
-
- org.springframework
- spring-web
- ${spring-framework.version}
-
-
-
- org.springframework.retry
- spring-retry
- 2.0.4
-
-
+
+ org.springframework.ai
+ spring-ai-retry
+ ${project.parent.version}
+
-
- org.springframework
- spring-webflux
- org.springframeworkspring-context-support
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatClient.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatClient.java
index f924b8ad978..91aad8f5490 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatClient.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatClient.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,
@@ -15,10 +15,11 @@
*/
package org.springframework.ai.mistralai;
-import java.time.Duration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -35,16 +36,16 @@
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.mistralai.api.MistralAiApi;
import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletion;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletion.Choice;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionChunk;
import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage;
import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.ToolCall;
import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.model.function.AbstractFunctionCallSupport;
import org.springframework.ai.model.function.FunctionCallbackContext;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.ResponseEntity;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -70,17 +71,7 @@ public class MistralAiChatClient extends
*/
private final MistralAiApi mistralAiApi;
- private final RetryTemplate retryTemplate = RetryTemplate.builder()
- .maxAttempts(10)
- .retryOn(MistralAiApi.MistralAiApiException.class)
- .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
- .withListener(new RetryListener() {
- public void onError(RetryContext context,
- RetryCallback callback, Throwable throwable) {
- log.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
- };
- })
- .build();
+ private final RetryTemplate retryTemplate;
public MistralAiChatClient(MistralAiApi mistralAiApi) {
this(mistralAiApi,
@@ -93,46 +84,63 @@ public MistralAiChatClient(MistralAiApi mistralAiApi) {
}
public MistralAiChatClient(MistralAiApi mistralAiApi, MistralAiChatOptions options) {
- this(mistralAiApi, options, null);
+ this(mistralAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
public MistralAiChatClient(MistralAiApi mistralAiApi, MistralAiChatOptions options,
- FunctionCallbackContext functionCallbackContext) {
+ FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
super(functionCallbackContext);
Assert.notNull(mistralAiApi, "MistralAiApi must not be null");
Assert.notNull(options, "Options must not be null");
+ Assert.notNull(retryTemplate, "RetryTemplate must not be null");
this.mistralAiApi = mistralAiApi;
this.defaultOptions = options;
+ this.retryTemplate = retryTemplate;
}
@Override
public ChatResponse call(Prompt prompt) {
- // return retryTemplate.execute(ctx -> {
var request = createRequest(prompt, false);
- // var completionEntity = this.mistralAiApi.chatCompletionEntity(request);
- ResponseEntity completionEntity = this.callWithFunctionSupport(request);
+ return retryTemplate.execute(ctx -> {
- var chatCompletion = completionEntity.getBody();
- if (chatCompletion == null) {
- log.warn("No chat completion returned for prompt: {}", prompt);
- return new ChatResponse(List.of());
- }
+ ResponseEntity completionEntity = this.callWithFunctionSupport(request);
- List generations = chatCompletion.choices()
- .stream()
- .map(choice -> new Generation(choice.message().content(), Map.of("role", choice.message().role().name()))
- .withGenerationMetadata(ChatGenerationMetadata.from(choice.finishReason().name(), null)))
- .toList();
+ var chatCompletion = completionEntity.getBody();
+ if (chatCompletion == null) {
+ log.warn("No chat completion returned for prompt: {}", prompt);
+ return new ChatResponse(List.of());
+ }
+
+ List generations = chatCompletion.choices()
+ .stream()
+ .map(choice -> new Generation(choice.message().content(), toMap(chatCompletion.id(), choice))
+ .withGenerationMetadata(ChatGenerationMetadata.from(choice.finishReason().name(), null)))
+ .toList();
- return new ChatResponse(generations);
- // });
+ return new ChatResponse(generations);
+ });
+ }
+
+ private Map toMap(String id, ChatCompletion.Choice choice) {
+ Map map = new HashMap<>();
+
+ var message = choice.message();
+ if (message.role() != null) {
+ map.put("role", message.role().name());
+ }
+ if (choice.finishReason() != null) {
+ map.put("finishReason", choice.finishReason().name());
+ }
+ map.put("id", id);
+ return map;
}
@Override
public Flux stream(Prompt prompt) {
+ var request = createRequest(prompt, true);
+
return retryTemplate.execute(ctx -> {
- var request = createRequest(prompt, true);
var completionChunks = this.mistralAiApi.chatCompletionStream(request);
@@ -140,13 +148,21 @@ public Flux stream(Prompt prompt) {
// The rest of the chunks with same ID share the same role.
ConcurrentHashMap roleMap = new ConcurrentHashMap<>();
- return completionChunks.map(chunk -> {
- String chunkId = chunk.id();
- List generations = chunk.choices().stream().map(choice -> {
- if (choice.delta().role() != null) {
- roleMap.putIfAbsent(chunkId, choice.delta().role().name());
+ return completionChunks.map(chunk -> toChatCompletion(chunk)).map(chatCompletion -> {
+
+ chatCompletion = handleFunctionCallOrReturn(request, ResponseEntity.of(Optional.of(chatCompletion)))
+ .getBody();
+
+ @SuppressWarnings("null")
+ String id = chatCompletion.id();
+
+ List generations = chatCompletion.choices().stream().map(choice -> {
+ if (choice.message().role() != null) {
+ roleMap.putIfAbsent(id, choice.message().role().name());
}
- var generation = new Generation(choice.delta().content(), Map.of("role", roleMap.get(chunkId)));
+ String finish = (choice.finishReason() != null ? choice.finishReason().name() : "");
+ var generation = new Generation(choice.message().content(),
+ Map.of("id", id, "role", roleMap.get(id), "finishReason", finish));
if (choice.finishReason() != null) {
generation = generation
.withGenerationMetadata(ChatGenerationMetadata.from(choice.finishReason().name(), null));
@@ -158,6 +174,15 @@ public Flux stream(Prompt prompt) {
});
}
+ private ChatCompletion toChatCompletion(ChatCompletionChunk chunk) {
+ List choices = chunk.choices()
+ .stream()
+ .map(cc -> new Choice(cc.index(), cc.delta(), cc.finishReason()))
+ .toList();
+
+ return new ChatCompletion(chunk.id(), "chat.completion", chunk.created(), chunk.model(), choices, null);
+ }
+
/**
* Accessible for testing.
*/
@@ -203,10 +228,6 @@ MistralAiApi.ChatCompletionRequest createRequest(Prompt prompt, boolean stream)
// Add the enabled functions definitions to the request's tools parameter.
if (!CollectionUtils.isEmpty(functionsForThisRequest)) {
- if (stream) {
- throw new IllegalArgumentException("Currently tool functions are not supported in streaming mode");
- }
-
request = ModelOptionsUtils.merge(
MistralAiChatOptions.builder().withTools(this.getFunctionTools(functionsForThisRequest)).build(),
request, ChatCompletionRequest.class);
@@ -250,7 +271,7 @@ protected ChatCompletionRequest doCreateToolResponseRequest(ChatCompletionReques
// Recursively call chatCompletionWithTools until the model doesn't call a
// functions anymore.
- ChatCompletionRequest newRequest = new ChatCompletionRequest(conversationHistory, previousRequest.stream());
+ ChatCompletionRequest newRequest = new ChatCompletionRequest(conversationHistory, false);
newRequest = ModelOptionsUtils.merge(newRequest, previousRequest, ChatCompletionRequest.class);
return newRequest;
@@ -261,6 +282,7 @@ protected List doGetUserMessages(ChatCompletionRequest re
return request.messages();
}
+ @SuppressWarnings("null")
@Override
protected ChatCompletionMessage doGetToolResponseMessage(ResponseEntity chatCompletion) {
return chatCompletion.getBody().choices().iterator().next().message();
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java
index c47d95946ad..86c0bda36bb 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
import java.util.ArrayList;
@@ -264,7 +263,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -274,7 +272,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -285,7 +282,6 @@ public Integer getTopK() {
throw new UnsupportedOperationException("Unsupported option: 'TopK'");
}
- @Override
@JsonIgnore
public void setTopK(Integer topK) {
throw new UnsupportedOperationException("Unsupported option: 'TopK'");
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingClient.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingClient.java
index 85012017e97..e42908c348d 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingClient.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingClient.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,26 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
+import java.util.List;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.springframework.ai.document.Document;
import org.springframework.ai.document.MetadataMode;
-import org.springframework.ai.embedding.*;
+import org.springframework.ai.embedding.AbstractEmbeddingClient;
+import org.springframework.ai.embedding.Embedding;
+import org.springframework.ai.embedding.EmbeddingOptions;
+import org.springframework.ai.embedding.EmbeddingRequest;
+import org.springframework.ai.embedding.EmbeddingResponse;
+import org.springframework.ai.embedding.EmbeddingResponseMetadata;
import org.springframework.ai.mistralai.api.MistralAiApi;
-import org.springframework.ai.mistralai.api.MistralAiApi.MistralAiApiException;
import org.springframework.ai.model.ModelOptionsUtils;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
-import java.time.Duration;
-import java.util.List;
-
/**
* @author Ricken Bazolo
* @since 0.8.1
@@ -47,17 +48,7 @@ public class MistralAiEmbeddingClient extends AbstractEmbeddingClient {
private final MistralAiApi mistralAiApi;
- private final RetryTemplate retryTemplate = RetryTemplate.builder()
- .maxAttempts(10)
- .retryOn(MistralAiApiException.class)
- .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
- .withListener(new RetryListener() {
- public void onError(RetryContext context,
- RetryCallback callback, Throwable throwable) {
- log.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
- };
- })
- .build();
+ private final RetryTemplate retryTemplate;
public MistralAiEmbeddingClient(MistralAiApi mistralAiApi) {
this(mistralAiApi, MetadataMode.EMBED);
@@ -65,22 +56,25 @@ public MistralAiEmbeddingClient(MistralAiApi mistralAiApi) {
public MistralAiEmbeddingClient(MistralAiApi mistralAiApi, MetadataMode metadataMode) {
this(mistralAiApi, metadataMode,
- MistralAiEmbeddingOptions.builder().withModel(MistralAiApi.EmbeddingModel.EMBED.getValue()).build());
+ MistralAiEmbeddingOptions.builder().withModel(MistralAiApi.EmbeddingModel.EMBED.getValue()).build(),
+ RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
public MistralAiEmbeddingClient(MistralAiApi mistralAiApi, MistralAiEmbeddingOptions options) {
- this(mistralAiApi, MetadataMode.EMBED, options);
+ this(mistralAiApi, MetadataMode.EMBED, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
public MistralAiEmbeddingClient(MistralAiApi mistralAiApi, MetadataMode metadataMode,
- MistralAiEmbeddingOptions options) {
+ MistralAiEmbeddingOptions options, RetryTemplate retryTemplate) {
Assert.notNull(mistralAiApi, "MistralAiApi must not be null");
Assert.notNull(metadataMode, "metadataMode must not be null");
Assert.notNull(options, "options must not be null");
+ Assert.notNull(retryTemplate, "retryTemplate must not be null");
this.mistralAiApi = mistralAiApi;
this.metadataMode = metadataMode;
this.defaultOptions = options;
+ this.retryTemplate = retryTemplate;
}
@Override
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java
index 2bf3a4b4820..1603ac18696 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHints.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHints.java
index 68681e88a92..cd6bcfa40f7 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHints.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHints.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,
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MIstralAiStreamFunctionCallingHelper.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MIstralAiStreamFunctionCallingHelper.java
new file mode 100644
index 00000000000..6165ce90065
--- /dev/null
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MIstralAiStreamFunctionCallingHelper.java
@@ -0,0 +1,198 @@
+/*
+ * 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.mistralai.api;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionChunk;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionChunk.ChunkChoice;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionFinishReason;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.ChatCompletionFunction;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.Role;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.ToolCall;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Helper class to support Streaming function calling.
+ *
+ * It can merge the streamed ChatCompletionChunk in case of function calling message.
+ *
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+public class MIstralAiStreamFunctionCallingHelper {
+
+ /**
+ * Merge the previous and current ChatCompletionChunk into a single one.
+ * @param previous the previous ChatCompletionChunk
+ * @param current the current ChatCompletionChunk
+ * @return the merged ChatCompletionChunk
+ */
+ public ChatCompletionChunk merge(ChatCompletionChunk previous, ChatCompletionChunk current) {
+
+ if (previous == null) {
+ return current;
+ }
+
+ String id = (current.id() != null ? current.id() : previous.id());
+ Long created = (current.created() != null ? current.created() : previous.created());
+ String model = (current.model() != null ? current.model() : previous.model());
+ String object = (current.object() != null ? current.object() : previous.object());
+
+ ChunkChoice previousChoice0 = (CollectionUtils.isEmpty(previous.choices()) ? null : previous.choices().get(0));
+ ChunkChoice currentChoice0 = (CollectionUtils.isEmpty(current.choices()) ? null : current.choices().get(0));
+
+ ChunkChoice choice = merge(previousChoice0, currentChoice0);
+
+ return new ChatCompletionChunk(id, object, created, model, List.of(choice));
+ }
+
+ private ChunkChoice merge(ChunkChoice previous, ChunkChoice current) {
+ if (previous == null) {
+ if (current.delta() != null && current.delta().toolCalls() != null) {
+ Optional id = current.delta()
+ .toolCalls()
+ .stream()
+ .filter(tool -> tool.id() != null)
+ .map(tool -> tool.id())
+ .findFirst();
+ if (!id.isPresent()) {
+ var newId = UUID.randomUUID().toString();
+
+ var toolCallsWithID = current.delta()
+ .toolCalls()
+ .stream()
+ .map(toolCall -> new ToolCall(newId, "function", toolCall.function()))
+ .toList();
+
+ var role = current.delta().role() != null ? current.delta().role() : Role.ASSISTANT;
+ current = new ChunkChoice(current.index(), new ChatCompletionMessage(current.delta().content(),
+ role, current.delta().name(), toolCallsWithID), current.finishReason());
+ }
+ }
+ return current;
+ }
+
+ ChatCompletionFinishReason finishReason = (current.finishReason() != null ? current.finishReason()
+ : previous.finishReason());
+ Integer index = (current.index() != null ? current.index() : previous.index());
+
+ ChatCompletionMessage message = merge(previous.delta(), current.delta());
+
+ return new ChunkChoice(index, message, finishReason);
+ }
+
+ private ChatCompletionMessage merge(ChatCompletionMessage previous, ChatCompletionMessage current) {
+ String content = (current.content() != null ? current.content()
+ : "" + ((previous.content() != null) ? previous.content() : ""));
+ Role role = (current.role() != null ? current.role() : previous.role());
+ role = (role != null ? role : Role.ASSISTANT); // default to ASSISTANT (if null
+ String name = (current.name() != null ? current.name() : previous.name());
+
+ List toolCalls = new ArrayList<>();
+ ToolCall lastPreviousTooCall = null;
+ if (previous.toolCalls() != null) {
+ lastPreviousTooCall = previous.toolCalls().get(previous.toolCalls().size() - 1);
+ if (previous.toolCalls().size() > 1) {
+ toolCalls.addAll(previous.toolCalls().subList(0, previous.toolCalls().size() - 1));
+ }
+ }
+ if (current.toolCalls() != null) {
+ if (current.toolCalls().size() > 1) {
+ throw new IllegalStateException("Currently only one tool call is supported per message!");
+ }
+ var currentToolCall = current.toolCalls().iterator().next();
+ if (currentToolCall.id() != null) {
+ if (lastPreviousTooCall != null) {
+ toolCalls.add(lastPreviousTooCall);
+ }
+ toolCalls.add(currentToolCall);
+ }
+ else {
+ toolCalls.add(merge(lastPreviousTooCall, currentToolCall));
+ }
+ }
+ else {
+ if (lastPreviousTooCall != null) {
+ toolCalls.add(lastPreviousTooCall);
+ }
+ }
+ return new ChatCompletionMessage(content, role, name, toolCalls);
+ }
+
+ private ToolCall merge(ToolCall previous, ToolCall current) {
+ if (previous == null) {
+ return current;
+ }
+ String id = (current.id() != null ? current.id() : previous.id());
+ String type = (current.type() != null ? current.type() : previous.type());
+ ChatCompletionFunction function = merge(previous.function(), current.function());
+ return new ToolCall(id, type, function);
+ }
+
+ private ChatCompletionFunction merge(ChatCompletionFunction previous, ChatCompletionFunction current) {
+ if (previous == null) {
+ return current;
+ }
+ String name = (current.name() != null ? current.name() : previous.name());
+ StringBuilder arguments = new StringBuilder();
+ if (previous.arguments() != null) {
+ arguments.append(previous.arguments());
+ }
+ if (current.arguments() != null) {
+ arguments.append(current.arguments());
+ }
+ return new ChatCompletionFunction(name, arguments.toString());
+ }
+
+ /**
+ * @param chatCompletion the ChatCompletionChunk to check
+ * @return true if the ChatCompletionChunk is a streaming tool function call.
+ */
+ public boolean isStreamingToolFunctionCall(ChatCompletionChunk chatCompletion) {
+
+ var choices = chatCompletion.choices();
+ if (CollectionUtils.isEmpty(choices)) {
+ return false;
+ }
+
+ var choice = choices.get(0);
+ return !CollectionUtils.isEmpty(choice.delta().toolCalls());
+ }
+
+ /**
+ * @param chatCompletion the ChatCompletionChunk to check
+ * @return true if the ChatCompletionChunk is a streaming tool function call and it is
+ * the last one.
+ */
+ public boolean isStreamingToolFunctionCallFinish(ChatCompletionChunk chatCompletion) {
+
+ var choices = chatCompletion.choices();
+ if (CollectionUtils.isEmpty(choices)) {
+ return false;
+ }
+
+ var choice = choices.get(0);
+ return choice.finishReason() == ChatCompletionFinishReason.TOOL_CALL
+ || choice.finishReason() == ChatCompletionFinishReason.TOOL_CALLS;
+ }
+
+}
+// ---
\ No newline at end of file
diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java
index 93338ec2aea..bdf6efea880 100644
--- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java
+++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java
@@ -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,35 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.api;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Predicate;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.ai.model.ModelOptionsUtils;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
-import org.springframework.util.StreamUtils;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.function.client.WebClient;
@@ -71,8 +65,6 @@ public class MistralAiApi {
private WebClient webClient;
- private final ObjectMapper objectMapper;
-
/**
* Create a new client api with DEFAULT_BASE_URL
* @param mistralAiApiKey Mistral api Key.
@@ -87,7 +79,7 @@ public MistralAiApi(String mistralAiApiKey) {
* @param mistralAiApiKey Mistral api Key.
*/
public MistralAiApi(String baseUrl, String mistralAiApiKey) {
- this(baseUrl, mistralAiApiKey, RestClient.builder());
+ this(baseUrl, mistralAiApiKey, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
}
/**
@@ -95,67 +87,22 @@ public MistralAiApi(String baseUrl, String mistralAiApiKey) {
* @param baseUrl api base URL.
* @param mistralAiApiKey Mistral api Key.
* @param restClientBuilder RestClient builder.
+ * @param responseErrorHandler Response error handler.
*/
- public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder) {
-
- this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder,
+ ResponseErrorHandler responseErrorHandler) {
Consumer jsonContentHeaders = headers -> {
headers.setBearerAuth(mistralAiApiKey);
headers.setContentType(MediaType.APPLICATION_JSON);
};
- var responseErrorHandler = new ResponseErrorHandler() {
-
- @Override
- public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
- return response.getStatusCode().isError();
- }
-
- @Override
- public void handleError(@NonNull ClientHttpResponse response) throws IOException {
- if (response.getStatusCode().isError()) {
- String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
- String message = String.format("%s - %s", response.getStatusCode().value(), error);
- if (response.getStatusCode().is4xxClientError()) {
- throw new MistralAiApiClientErrorException(message);
- }
- throw new MistralAiApiException(message);
- }
- }
- };
-
this.restClient = restClientBuilder.baseUrl(baseUrl)
.defaultHeaders(jsonContentHeaders)
.defaultStatusHandler(responseErrorHandler)
.build();
- this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(jsonContentHeaders).build();
- }
-
- public static class MistralAiApiException extends RuntimeException {
-
- public MistralAiApiException(String message) {
- super(message);
- }
-
- public MistralAiApiException(String message, Throwable t) {
- super(message, t);
- }
-
- }
-
- /**
- * Thrown on 4xx client errors, such as 401 - Incorrect API key provided, 401 - You
- * must be a member of an organization to use the API, 429 - Rate limit reached for
- * requests, 429 - You exceeded your current quota , please check your plan and
- * billing details.
- */
- public static class MistralAiApiClientErrorException extends RuntimeException {
-
- public MistralAiApiClientErrorException(String message) {
- super(message);
- }
+ this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(jsonContentHeaders).build();
}
/**
@@ -595,7 +542,7 @@ public enum ChatCompletionFinishReason {
// anticipation of future changes. Based on:
// https://github.com/mistralai/client-python/blob/main/src/mistralai/models/chat_completion.py
@JsonProperty("error") ERROR,
-
+
@JsonProperty("tool_calls") TOOL_CALLS
// @formatter:on
@@ -758,6 +705,8 @@ public ResponseEntity chatCompletionEntity(ChatCompletionRequest
.toEntity(ChatCompletion.class);
}
+ private MIstralAiStreamFunctionCallingHelper chunkMerger = new MIstralAiStreamFunctionCallingHelper();
+
/**
* Creates a streaming chat response for the given chat conversation.
* @param chatRequest The chat completion request. Must have the stream property set
@@ -769,6 +718,8 @@ public Flux chatCompletionStream(ChatCompletionRequest chat
Assert.notNull(chatRequest, "The request body can not be null.");
Assert.isTrue(chatRequest.stream(), "Request must set the steam property to true.");
+ AtomicBoolean isInsideTool = new AtomicBoolean(false);
+
return this.webClient.post()
.uri("/v1/chat/completions")
.body(Mono.just(chatRequest), ChatCompletionRequest.class)
@@ -776,7 +727,26 @@ public Flux chatCompletionStream(ChatCompletionRequest chat
.bodyToFlux(String.class)
.takeUntil(SSE_DONE_PREDICATE)
.filter(SSE_DONE_PREDICATE.negate())
- .map(content -> ModelOptionsUtils.jsonToObject(content, ChatCompletionChunk.class));
+ .map(content -> ModelOptionsUtils.jsonToObject(content, ChatCompletionChunk.class))
+ .map(chunk -> {
+ if (this.chunkMerger.isStreamingToolFunctionCall(chunk)) {
+ isInsideTool.set(true);
+ }
+ return chunk;
+ })
+ .windowUntil(chunk -> {
+ if (isInsideTool.get() && this.chunkMerger.isStreamingToolFunctionCallFinish(chunk)) {
+ isInsideTool.set(false);
+ return true;
+ }
+ return !isInsideTool.get();
+ })
+ .concatMapIterable(window -> {
+ Mono mono1 = window.reduce(new ChatCompletionChunk(null, null, null, null, null),
+ (previous, current) -> this.chunkMerger.merge(previous, current));
+ return List.of(mono1);
+ })
+ .flatMap(mono -> mono);
}
}
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatClientIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatClientIT.java
index 5a805407999..00cbf697394 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatClientIT.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatClientIT.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,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -25,6 +25,7 @@
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
@@ -36,6 +37,8 @@
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
+import org.springframework.ai.mistralai.api.MistralAiApi;
+import org.springframework.ai.model.function.FunctionCallbackWrapper;
import org.springframework.ai.parser.BeanOutputParser;
import org.springframework.ai.parser.ListOutputParser;
import org.springframework.ai.parser.MapOutputParser;
@@ -182,4 +185,58 @@ void beanStreamOutputParserRecords() {
assertThat(actorsFilms.movies()).hasSize(5);
}
+ @Test
+ void functionCallTest() {
+
+ UserMessage userMessage = new UserMessage("What's the weather like in San Francisco?");
+
+ List messages = new ArrayList<>(List.of(userMessage));
+
+ var promptOptions = MistralAiChatOptions.builder()
+ .withModel(MistralAiApi.ChatModel.SMALL.getValue())
+ .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
+ .withName("getCurrentWeather")
+ .withDescription("Get the weather in location")
+ .withResponseConverter((response) -> "" + response.temp() + response.unit())
+ .build()))
+ .build();
+
+ ChatResponse response = chatClient.call(new Prompt(messages, promptOptions));
+
+ logger.info("Response: {}", response);
+
+ assertThat(response.getResult().getOutput().getContent()).containsAnyOf("30.0", "30");
+ }
+
+ @Test
+ void streamFunctionCallTest() {
+
+ UserMessage userMessage = new UserMessage("What's the weather like in Tokyo, Japan?");
+
+ List messages = new ArrayList<>(List.of(userMessage));
+
+ var promptOptions = MistralAiChatOptions.builder()
+ .withModel(MistralAiApi.ChatModel.SMALL.getValue())
+ .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
+ .withName("getCurrentWeather")
+ .withDescription("Get the weather in location")
+ .withResponseConverter((response) -> "" + response.temp() + response.unit())
+ .build()))
+ .build();
+
+ Flux response = streamingChatClient.stream(new Prompt(messages, promptOptions));
+
+ String content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("10.0", "10");
+ }
+
}
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralChatCompletionRequestTest.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java
similarity index 92%
rename from models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralChatCompletionRequestTest.java
rename to models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.java
index df5b285d427..57135164bc3 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralChatCompletionRequestTest.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatCompletionRequestTest.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
import org.junit.jupiter.api.Test;
@@ -31,7 +30,7 @@
*/
@SpringBootTest
@EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+")
-public class MistralChatCompletionRequestTest {
+public class MistralAiChatCompletionRequestTest {
MistralAiChatClient chatClient = new MistralAiChatClient(new MistralAiApi("test"));
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralEmbeddingIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingIT.java
similarity index 95%
rename from models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralEmbeddingIT.java
rename to models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingIT.java
index f456c851627..ba472a0976e 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralEmbeddingIT.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingIT.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,
@@ -28,7 +28,7 @@
@SpringBootTest
@EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+")
-class MistralEmbeddingIT {
+class MistralAiEmbeddingIT {
@Autowired
private MistralAiEmbeddingClient mistralAiEmbeddingClient;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java
new file mode 100644
index 00000000000..549d788eade
--- /dev/null
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiRetryTests.java
@@ -0,0 +1,192 @@
+/*
+ * 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.mistralai;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Flux;
+
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.document.MetadataMode;
+import org.springframework.ai.mistralai.api.MistralAiApi;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletion;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionChunk;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionFinishReason;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionMessage.Role;
+import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest;
+import org.springframework.ai.mistralai.api.MistralAiApi.Embedding;
+import org.springframework.ai.mistralai.api.MistralAiApi.EmbeddingList;
+import org.springframework.ai.mistralai.api.MistralAiApi.EmbeddingRequest;
+import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.retry.TransientAiException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.RetryListener;
+import org.springframework.retry.support.RetryTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Christian Tzolov
+ */
+@SuppressWarnings("unchecked")
+@ExtendWith(MockitoExtension.class)
+public class MistralAiRetryTests {
+
+ private class TestRetryListener implements RetryListener {
+
+ int onErrorRetryCount = 0;
+
+ int onSuccessRetryCount = 0;
+
+ @Override
+ public void onSuccess(RetryContext context, RetryCallback callback, T result) {
+ onSuccessRetryCount = context.getRetryCount();
+ }
+
+ @Override
+ public void onError(RetryContext context, RetryCallback callback,
+ Throwable throwable) {
+ onErrorRetryCount = context.getRetryCount();
+ }
+
+ }
+
+ private TestRetryListener retryListener;
+
+ private RetryTemplate retryTemplate;
+
+ private @Mock MistralAiApi mistralAiApi;
+
+ private MistralAiChatClient chatClient;
+
+ private MistralAiEmbeddingClient embeddingClient;
+
+ @BeforeEach
+ public void beforeEach() {
+ retryTemplate = RetryUtils.DEFAULT_RETRY_TEMPLATE;
+ retryListener = new TestRetryListener();
+ retryTemplate.registerListener(retryListener);
+
+ chatClient = new MistralAiChatClient(mistralAiApi,
+ MistralAiChatOptions.builder()
+ .withTemperature(0.7f)
+ .withTopP(1f)
+ .withSafePrompt(false)
+ .withModel(MistralAiApi.ChatModel.TINY.getValue())
+ .build(),
+ null, retryTemplate);
+ embeddingClient = new MistralAiEmbeddingClient(mistralAiApi, MetadataMode.EMBED,
+ MistralAiEmbeddingOptions.builder().withModel(MistralAiApi.EmbeddingModel.EMBED.getValue()).build(),
+ retryTemplate);
+ }
+
+ @Test
+ public void mistralAiChatTransientError() {
+
+ var choice = new ChatCompletion.Choice(0, new ChatCompletionMessage("Response", Role.ASSISTANT),
+ ChatCompletionFinishReason.STOP);
+ ChatCompletion expectedChatCompletion = new ChatCompletion("id", "chat.completion", 789l, "model",
+ List.of(choice), new MistralAiApi.Usage(10, 10, 10));
+
+ when(mistralAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedChatCompletion)));
+
+ var result = chatClient.call(new Prompt("text"));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput().getContent()).isSameAs("Response");
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void mistralAiChatNonTransientError() {
+ when(mistralAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> chatClient.call(new Prompt("text")));
+ }
+
+ @Test
+ public void mistralAiChatStreamTransientError() {
+
+ var choice = new ChatCompletionChunk.ChunkChoice(0, new ChatCompletionMessage("Response", Role.ASSISTANT),
+ ChatCompletionFinishReason.STOP);
+ ChatCompletionChunk expectedChatCompletion = new ChatCompletionChunk("id", "chat.completion.chunk", 789l,
+ "model", List.of(choice));
+
+ when(mistralAiApi.chatCompletionStream(isA(ChatCompletionRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(Flux.just(expectedChatCompletion));
+
+ var result = chatClient.stream(new Prompt("text"));
+
+ assertThat(result).isNotNull();
+ assertThat(result.collectList().block().get(0).getResult().getOutput().getContent()).isSameAs("Response");
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void mistralAiChatStreamNonTransientError() {
+ when(mistralAiApi.chatCompletionStream(isA(ChatCompletionRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> chatClient.stream(new Prompt("text")));
+ }
+
+ @Test
+ public void mistralAiEmbeddingTransientError() {
+
+ EmbeddingList expectedEmbeddings = new EmbeddingList<>("list",
+ List.of(new Embedding(0, List.of(9.9, 8.8))), "model", new MistralAiApi.Usage(10, 10, 10));
+
+ when(mistralAiApi.embeddings(isA(EmbeddingRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedEmbeddings)));
+
+ var result = embeddingClient
+ .call(new org.springframework.ai.embedding.EmbeddingRequest(List.of("text1", "text2"), null));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput()).isEqualTo(List.of(9.9, 8.8));
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void mistralAiEmbeddingNonTransientError() {
+ when(mistralAiApi.embeddings(isA(EmbeddingRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> embeddingClient
+ .call(new org.springframework.ai.embedding.EmbeddingRequest(List.of("text1", "text2"), null)));
+ }
+
+}
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java
index 224095f9492..7952571d660 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiTestConfiguration.java
@@ -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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai;
import org.springframework.ai.embedding.EmbeddingClient;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MockWeatherService.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MockWeatherService.java
new file mode 100644
index 00000000000..4a6f594a95d
--- /dev/null
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MockWeatherService.java
@@ -0,0 +1,90 @@
+/*
+ * 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.mistralai;
+
+import java.util.function.Function;
+
+import com.fasterxml.jackson.annotation.JsonClassDescription;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+
+/**
+ * @author Christian Tzolov
+ */
+public class MockWeatherService implements Function {
+
+ /**
+ * Weather Function request.
+ */
+ @JsonInclude(Include.NON_NULL)
+ @JsonClassDescription("Weather API request")
+ public record Request(@JsonProperty(required = true,
+ value = "location") @JsonPropertyDescription("The city and state e.g. San Francisco, CA") String location,
+ @JsonProperty(required = true, value = "unit") @JsonPropertyDescription("Temperature unit") Unit unit) {
+ }
+
+ /**
+ * Temperature units.
+ */
+ public enum Unit {
+
+ /**
+ * Celsius.
+ */
+ C("metric"),
+ /**
+ * Fahrenheit.
+ */
+ F("imperial");
+
+ /**
+ * Human readable unit name.
+ */
+ public final String unitName;
+
+ private Unit(String text) {
+ this.unitName = text;
+ }
+
+ }
+
+ /**
+ * Weather Function response.
+ */
+ public record Response(double temp, double feels_like, double temp_min, double temp_max, int pressure, int humidity,
+ Unit unit) {
+ }
+
+ @Override
+ public Response apply(Request request) {
+
+ double temperature = 0;
+ if (request.location().contains("Paris")) {
+ temperature = 15;
+ }
+ else if (request.location().contains("Tokyo")) {
+ temperature = 10;
+ }
+ else if (request.location().contains("San Francisco")) {
+ temperature = 30;
+ }
+
+ return new Response(temperature, 15, 20, 2, 53, 45, Unit.C);
+ }
+
+}
\ No newline at end of file
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java
index c867bdd2c48..ed698b9f4da 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/aot/MistralAiRuntimeHintsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.aot;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java
index b9d0f426dca..362705170d2 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/MistralAiApiIT.java
@@ -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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.api;
import java.util.List;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MistralAiApiToolFunctionCallIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MistralAiApiToolFunctionCallIT.java
index 9539c8b7ed2..b52c9da5dd8 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MistralAiApiToolFunctionCallIT.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MistralAiApiToolFunctionCallIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.api.tool;
import java.util.ArrayList;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MockWeatherService.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MockWeatherService.java
index 82dd94e1e28..1c7c0d4de17 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MockWeatherService.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.api.tool;
import java.util.function.Function;
diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/PaymentStatusFunctionCallingIT.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/PaymentStatusFunctionCallingIT.java
index 65a60cb352d..a7a3deffc8e 100644
--- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/PaymentStatusFunctionCallingIT.java
+++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/PaymentStatusFunctionCallingIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.mistralai.api.tool;
import java.util.ArrayList;
diff --git a/models/spring-ai-ollama/README.md b/models/spring-ai-ollama/README.md
index 2eb9d58a691..0e9c348e3be 100644
--- a/models/spring-ai-ollama/README.md
+++ b/models/spring-ai-ollama/README.md
@@ -1,3 +1,3 @@
-[Ollama Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/ollama-chat.html)
+[Ollama Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/ollama-chat.html)
[Ollama Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/ollama-embeddings.html)
diff --git a/models/spring-ai-ollama/pom.xml b/models/spring-ai-ollama/pom.xml
index e89a7d64c8b..e8f04527e77 100644
--- a/models/spring-ai-ollama/pom.xml
+++ b/models/spring-ai-ollama/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xml
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java
index 9a5adb8a713..5d1adf5bdbf 100644
--- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama;
import java.util.List;
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java
index 78b2f258ab3..45498831b77 100644
--- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama;
import java.util.ArrayList;
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java
index 970d6c4060f..2d89a804eb0 100644
--- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/aot/OllamaRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.ollama.aot;
import org.springframework.ai.ollama.api.OllamaApi;
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java
index 8d1ddfd6edf..9b5488fbb7e 100644
--- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama.api;
import java.io.IOException;
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaModel.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaModel.java
new file mode 100644
index 00000000000..bdb7ee1b084
--- /dev/null
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaModel.java
@@ -0,0 +1,92 @@
+/*
+ * 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.ollama.api;
+
+/**
+ * Helper class for common Ollama models.
+ *
+ * @author Siarhei Blashuk
+ * @since 0.8.1
+ */
+public enum OllamaModel {
+
+ /**
+ * Llama 2 is a collection of language models ranging from 7B to 70B parameters.
+ */
+ LLAMA2("llama2"),
+
+ /**
+ * The 7B parameters model
+ */
+ MISTRAL("mistral"),
+
+ /**
+ * The 2.7B uncensored Dolphin model
+ */
+ DOLPHIN_PHI("dolphin-phi"),
+
+ /**
+ * The Phi-2 2.7B language model
+ */
+ PHI("phi"),
+
+ /**
+ * A fine-tuned Mistral model
+ */
+ NEURAL_CHAT("neural-chat"),
+
+ /**
+ * Starling-7B model
+ */
+ STARLING_LM("starling-lm"),
+
+ /**
+ * Code Llama is based on Llama 2 model
+ */
+ CODELLAMA("codellama"),
+
+ /**
+ * Orca Mini is based on Llama and Llama 2 ranging from 3 billion parameters to 70
+ * billion
+ */
+ ORCA_MINI("orca-mini"),
+
+ /**
+ * Llava is a Large Language and Vision Assistant model
+ */
+ LLAVA("llava"),
+
+ /**
+ * Gemma is a lightweight model with 2 billion and 7 billion
+ */
+ GEMMA("gemma"),
+
+ /**
+ * Uncensored Llama 2 model
+ */
+ LLAMA2_UNCENSORED("llama2-uncensored");
+
+ private final String id;
+
+ OllamaModel(String id) {
+ this.id = id;
+ }
+
+ public String id() {
+ return this.id;
+ }
+
+}
diff --git a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java
index a6dcc8b67bd..ac060d9f23e 100644
--- a/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java
+++ b/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama.api;
import java.util.List;
@@ -44,7 +43,7 @@
@JsonInclude(Include.NON_NULL)
public class OllamaOptions implements ChatOptions, EmbeddingOptions {
- public static final String DEFAULT_MODEL = "mistral";
+ public static final String DEFAULT_MODEL = OllamaModel.MISTRAL.id();
// @formatter:off
/**
@@ -244,6 +243,9 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
*/
@JsonProperty("model") private String model;
+ /**
+ * @param model The ollama model names to use. See the {@link OllamaModel} for the common models.
+ */
public OllamaOptions withModel(String model) {
this.model = model;
return this;
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientIT.java
index 8e1d34b40ac..72941eff8a9 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientIT.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatClientIT.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,
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 66eec826715..1a6b720c760 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
@@ -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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingClientIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingClientIT.java
index 01483eb4f1c..a4fa85b6259 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingClientIT.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingClientIT.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,
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingRequestTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingRequestTests.java
index e20148ebaf2..c4987129c03 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingRequestTests.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaEmbeddingRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java
index 19e7f835ea2..f94480f6ed4 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/aot/OllamaRuntimeHintsTests.java
@@ -1,3 +1,18 @@
+/*
+ * 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.ollama.aot;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaApiIT.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaApiIT.java
index c888291bf3a..48319596c25 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaApiIT.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama.api;
import java.io.IOException;
@@ -129,7 +128,7 @@ public void streamingChat() {
assertThat(responses.stream()
.filter(r -> r.message() != null)
.map(r -> r.message().content())
- .collect(Collectors.joining("\n"))).contains("Sofia");
+ .collect(Collectors.joining(System.lineSeparator()))).contains("Sofia");
ChatResponse lastResponse = responses.get(responses.size() - 1);
assertThat(lastResponse.message().content()).isEmpty();
diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaModelOptionsTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaModelOptionsTests.java
index 6320854ec35..0a847348df2 100644
--- a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaModelOptionsTests.java
+++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaModelOptionsTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.ollama.api;
import java.util.List;
diff --git a/models/spring-ai-openai/README.md b/models/spring-ai-openai/README.md
index fc6a2361e7c..f2795e28e0d 100644
--- a/models/spring-ai-openai/README.md
+++ b/models/spring-ai-openai/README.md
@@ -1,4 +1,7 @@
-[OpenAI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/openai-chat.html)
+[OpenAI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html)
[OpenAI Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/openai-embeddings.html)
+[OpenAI Image Generation](https://docs.spring.io/spring-ai/reference/api/image/openai-image.html)
+
+[OpenAI Transcription Generation](TODO)
\ No newline at end of file
diff --git a/models/spring-ai-openai/pom.xml b/models/spring-ai-openai/pom.xml
index 7fbfce8ea56..cadbf64a567 100644
--- a/models/spring-ai-openai/pom.xml
+++ b/models/spring-ai-openai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-openai
@@ -29,9 +29,9 @@
- org.springframework.retry
- spring-retry
- 2.0.4
+ org.springframework.ai
+ spring-ai-retry
+ ${project.parent.version}
@@ -57,11 +57,6 @@
${victools.version}
-
- org.springframework
- spring-webflux
-
-
org.springframeworkspring-context-support
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionClient.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionClient.java
new file mode 100644
index 00000000000..98f1b8ac787
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionClient.java
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+/*
+* 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.
+*/
+
+package org.springframework.ai.openai;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.ai.chat.metadata.RateLimit;
+import org.springframework.ai.model.ModelClient;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.api.OpenAiAudioApi.StructuredResponse;
+import org.springframework.ai.openai.audio.transcription.AudioTranscription;
+import org.springframework.ai.openai.audio.transcription.AudioTranscriptionPrompt;
+import org.springframework.ai.openai.audio.transcription.AudioTranscriptionResponse;
+import org.springframework.ai.openai.metadata.audio.OpenAiAudioTranscriptionResponseMetadata;
+import org.springframework.ai.openai.metadata.support.OpenAiResponseHeaderExtractor;
+import org.springframework.ai.retry.RetryUtils;
+import org.springframework.core.io.Resource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.Assert;
+
+/**
+ * OpenAI audio transcription client implementation for backed by {@link OpenAiAudioApi}.
+ *
+ * @author Michael Lavelle
+ * @author Christian Tzolov
+ * @see OpenAiAudioApi
+ * @since 0.8.1
+ */
+public class OpenAiAudioTranscriptionClient
+ implements ModelClient {
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ private final OpenAiAudioTranscriptionOptions defaultOptions;
+
+ public final RetryTemplate retryTemplate;
+
+ private final OpenAiAudioApi audioApi;
+
+ /**
+ * OpenAiAudioTranscriptionClient is a client class used to interact with the OpenAI
+ * Audio Transcription API.
+ * @param audioApi The OpenAiAudioApi instance to be used for making API calls.
+ */
+ public OpenAiAudioTranscriptionClient(OpenAiAudioApi audioApi) {
+ this(audioApi,
+ OpenAiAudioTranscriptionOptions.builder()
+ .withModel(OpenAiAudioApi.WhisperModel.WHISPER_1.getValue())
+ .withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.JSON)
+ .withTemperature(0.7f)
+ .build(),
+ RetryUtils.DEFAULT_RETRY_TEMPLATE);
+ }
+
+ /**
+ * OpenAiAudioTranscriptionClient is a client class used to interact with the OpenAI
+ * Audio Transcription API.
+ * @param audioApi The OpenAiAudioApi instance to be used for making API calls.
+ * @param options The OpenAiAudioTranscriptionOptions instance for configuring the
+ * audio transcription.
+ */
+ public OpenAiAudioTranscriptionClient(OpenAiAudioApi audioApi, OpenAiAudioTranscriptionOptions options) {
+ this(audioApi, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
+ }
+
+ /**
+ * OpenAiAudioTranscriptionClient is a client class used to interact with the OpenAI
+ * Audio Transcription API.
+ * @param audioApi The OpenAiAudioApi instance to be used for making API calls.
+ * @param options The OpenAiAudioTranscriptionOptions instance for configuring the
+ * audio transcription.
+ * @param retryTemplate The RetryTemplate instance for retrying failed API calls.
+ */
+ public OpenAiAudioTranscriptionClient(OpenAiAudioApi audioApi, OpenAiAudioTranscriptionOptions options,
+ RetryTemplate retryTemplate) {
+ Assert.notNull(audioApi, "OpenAiAudioApi must not be null");
+ Assert.notNull(options, "OpenAiTranscriptionOptions must not be null");
+ Assert.notNull(retryTemplate, "RetryTemplate must not be null");
+ this.audioApi = audioApi;
+ this.defaultOptions = options;
+ this.retryTemplate = retryTemplate;
+ }
+
+ public String call(Resource audioResource) {
+ AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioResource);
+ return call(transcriptionRequest).getResult().getOutput();
+ }
+
+ @Override
+ public AudioTranscriptionResponse call(AudioTranscriptionPrompt request) {
+
+ return this.retryTemplate.execute(ctx -> {
+
+ Resource audioResource = request.getInstructions();
+
+ OpenAiAudioApi.TranscriptionRequest requestBody = createRequestBody(request);
+
+ if (requestBody.responseFormat().isJsonType()) {
+
+ ResponseEntity transcriptionEntity = this.audioApi.createTranscription(requestBody,
+ StructuredResponse.class);
+
+ var transcription = transcriptionEntity.getBody();
+
+ if (transcription == null) {
+ logger.warn("No transcription returned for request: {}", audioResource);
+ return new AudioTranscriptionResponse(null);
+ }
+
+ AudioTranscription transcript = new AudioTranscription(transcription.text());
+
+ RateLimit rateLimits = OpenAiResponseHeaderExtractor.extractAiResponseHeaders(transcriptionEntity);
+
+ return new AudioTranscriptionResponse(transcript,
+ OpenAiAudioTranscriptionResponseMetadata.from(transcriptionEntity.getBody())
+ .withRateLimit(rateLimits));
+
+ }
+ else {
+
+ ResponseEntity transcriptionEntity = this.audioApi.createTranscription(requestBody,
+ String.class);
+
+ var transcription = transcriptionEntity.getBody();
+
+ if (transcription == null) {
+ logger.warn("No transcription returned for request: {}", audioResource);
+ return new AudioTranscriptionResponse(null);
+ }
+
+ AudioTranscription transcript = new AudioTranscription(transcription);
+
+ RateLimit rateLimits = OpenAiResponseHeaderExtractor.extractAiResponseHeaders(transcriptionEntity);
+
+ return new AudioTranscriptionResponse(transcript,
+ OpenAiAudioTranscriptionResponseMetadata.from(transcriptionEntity.getBody())
+ .withRateLimit(rateLimits));
+ }
+ });
+ }
+
+ OpenAiAudioApi.TranscriptionRequest createRequestBody(AudioTranscriptionPrompt request) {
+
+ OpenAiAudioTranscriptionOptions options = this.defaultOptions;
+
+ if (request.getOptions() != null) {
+ if (request.getOptions() instanceof OpenAiAudioTranscriptionOptions runtimeOptions) {
+ options = this.merge(options, runtimeOptions);
+ }
+ else {
+ throw new IllegalArgumentException("Prompt options are not of type TranscriptionOptions: "
+ + request.getOptions().getClass().getSimpleName());
+ }
+ }
+
+ OpenAiAudioApi.TranscriptionRequest audioTranscriptionRequest = OpenAiAudioApi.TranscriptionRequest.builder()
+ .withFile(toBytes(request.getInstructions()))
+ .withResponseFormat(options.getResponseFormat())
+ .withPrompt(options.getPrompt())
+ .withTemperature(options.getTemperature())
+ .withLanguage(options.getLanguage())
+ .withModel(options.getModel())
+ .build();
+
+ return audioTranscriptionRequest;
+ }
+
+ private byte[] toBytes(Resource resource) {
+ try {
+ return resource.getInputStream().readAllBytes();
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException("Failed to read resource: " + resource, e);
+ }
+ }
+
+ private OpenAiAudioTranscriptionOptions merge(OpenAiAudioTranscriptionOptions source,
+ OpenAiAudioTranscriptionOptions target) {
+
+ if (source == null) {
+ source = new OpenAiAudioTranscriptionOptions();
+ }
+
+ OpenAiAudioTranscriptionOptions merged = new OpenAiAudioTranscriptionOptions();
+ merged.setLanguage(source.getLanguage() != null ? source.getLanguage() : target.getLanguage());
+ merged.setModel(source.getModel() != null ? source.getModel() : target.getModel());
+ merged.setPrompt(source.getPrompt() != null ? source.getPrompt() : target.getPrompt());
+ merged.setResponseFormat(
+ source.getResponseFormat() != null ? source.getResponseFormat() : target.getResponseFormat());
+ merged.setTemperature(source.getTemperature() != null ? source.getTemperature() : target.getTemperature());
+ return merged;
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java
new file mode 100644
index 00000000000..0307657e655
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java
@@ -0,0 +1,204 @@
+/*
+ * 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.openai;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import org.springframework.ai.model.ModelOptions;
+import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptResponseFormat;
+import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptionRequest.GranularityType;
+
+/**
+ * @author Michael Lavelle
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+@JsonInclude(Include.NON_NULL)
+public class OpenAiAudioTranscriptionOptions implements ModelOptions {
+
+ // @formatter:off
+ /**
+ * ID of the model to use.
+ */
+ private @JsonProperty("model") String model;
+
+ /**
+ * The format of the transcript output, in one of these options: json, text, srt, verbose_json, or vtt.
+ */
+ private @JsonProperty("response_format") TranscriptResponseFormat responseFormat;
+
+ private @JsonProperty("prompt") String prompt;
+
+ private @JsonProperty("language") String language;
+
+ /**
+ * What sampling temperature to use, between 0 and 1. Higher values like 0.8 will make the output
+ * more random, while lower values like 0.2 will make it more focused and deterministic.
+ */
+ private @JsonProperty("temperature") Float temperature;
+
+ private @JsonProperty("timestamp_granularities") GranularityType granularityType;
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ protected OpenAiAudioTranscriptionOptions options;
+
+ public Builder() {
+ this.options = new OpenAiAudioTranscriptionOptions();
+ }
+
+ public Builder(OpenAiAudioTranscriptionOptions options) {
+ this.options = options;
+ }
+
+ public Builder withModel(String model) {
+ this.options.model = model;
+ return this;
+ }
+
+ public Builder withLanguage(String language) {
+ this.options.language = language;
+ return this;
+ }
+
+ public Builder withPrompt(String prompt) {
+ this.options.prompt = prompt;
+ return this;
+ }
+
+ public Builder withResponseFormat(TranscriptResponseFormat responseFormat) {
+ this.options.responseFormat = responseFormat;
+ return this;
+ }
+
+ public Builder withTemperature(Float temperature) {
+ this.options.temperature = temperature;
+ return this;
+ }
+
+ public Builder withGranularityType(GranularityType granularityType) {
+ this.options.granularityType = granularityType;
+ return this;
+ }
+
+ public OpenAiAudioTranscriptionOptions build() {
+ return this.options;
+ }
+
+ }
+
+ public String getModel() {
+ return this.model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public String getLanguage() {
+ return this.language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getPrompt() {
+ return this.prompt;
+ }
+
+ public void setPrompt(String prompt) {
+ this.prompt = prompt;
+ }
+
+ public Float getTemperature() {
+ return this.temperature;
+ }
+
+ public void setTemperature(Float temperature) {
+ this.temperature = temperature;
+ }
+
+
+ public TranscriptResponseFormat getResponseFormat() {
+ return this.responseFormat;
+ }
+
+ public void setResponseFormat(TranscriptResponseFormat responseFormat) {
+ this.responseFormat = responseFormat;
+ }
+
+ public GranularityType getGranularityType() {
+ return this.granularityType;
+ }
+
+ public void setGranularityType(GranularityType granularityType) {
+ this.granularityType = granularityType;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((model == null) ? 0 : model.hashCode());
+ result = prime * result + ((prompt == null) ? 0 : prompt.hashCode());
+ result = prime * result + ((language == null) ? 0 : language.hashCode());
+ result = prime * result + ((responseFormat == null) ? 0 : responseFormat.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ OpenAiAudioTranscriptionOptions other = (OpenAiAudioTranscriptionOptions) obj;
+ if (this.model == null) {
+ if (other.model != null)
+ return false;
+ }
+ else if (!model.equals(other.model))
+ return false;
+ if (this.prompt == null) {
+ if (other.prompt != null)
+ return false;
+ }
+ else if (!this.prompt.equals(other.prompt))
+ return false;
+ if (this.language == null) {
+ if (other.language != null)
+ return false;
+ }
+ else if (!this.language.equals(other.language))
+ return false;
+ if (this.responseFormat == null) {
+ if (other.responseFormat != null)
+ return false;
+ }
+ else if (!this.responseFormat.equals(other.responseFormat))
+ return false;
+ return true;
+ }
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatClient.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatClient.java
index 7be58affaee..79c4b6498cc 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatClient.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
@@ -15,11 +15,11 @@
*/
package org.springframework.ai.openai;
-import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -40,17 +40,16 @@
import org.springframework.ai.model.function.FunctionCallbackContext;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion.Choice;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionFinishReason;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.Role;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.ToolCall;
-import org.springframework.ai.openai.api.common.OpenAiApiException;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest;
import org.springframework.ai.openai.metadata.OpenAiChatResponseMetadata;
import org.springframework.ai.openai.metadata.support.OpenAiResponseHeaderExtractor;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.ResponseEntity;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -73,7 +72,7 @@ public class OpenAiChatClient extends
AbstractFunctionCallSupport>
implements ChatClient, StreamingChatClient {
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private static final Logger logger = LoggerFactory.getLogger(OpenAiChatClient.class);
/**
* The default options used for the chat completion requests.
@@ -83,48 +82,59 @@ public class OpenAiChatClient extends
/**
* The retry template used to retry the OpenAI API calls.
*/
- public final RetryTemplate retryTemplate = RetryTemplate.builder()
- .maxAttempts(10)
- .retryOn(OpenAiApiException.class)
- .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
- .withListener(new RetryListener() {
- @Override
- public void onError(RetryContext context,
- RetryCallback callback, Throwable throwable) {
- logger.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
- };
- })
- .build();
+ public final RetryTemplate retryTemplate;
/**
* Low-level access to the OpenAI API.
*/
private final OpenAiApi openAiApi;
+ /**
+ * Creates an instance of the OpenAiChatClient.
+ * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI
+ * Chat API.
+ * @throws IllegalArgumentException if openAiApi is null
+ */
public OpenAiChatClient(OpenAiApi openAiApi) {
this(openAiApi,
OpenAiChatOptions.builder().withModel(OpenAiApi.DEFAULT_CHAT_MODEL).withTemperature(0.7f).build());
}
+ /**
+ * Initializes an instance of the OpenAiChatClient.
+ * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI
+ * Chat API.
+ * @param options The OpenAiChatOptions to configure the chat client.
+ */
public OpenAiChatClient(OpenAiApi openAiApi, OpenAiChatOptions options) {
- this(openAiApi, options, null);
+ this(openAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
+ /**
+ * Initializes a new instance of the OpenAiChatClient.
+ * @param openAiApi The OpenAiApi instance to be used for interacting with the OpenAI
+ * Chat API.
+ * @param options The OpenAiChatOptions to configure the chat client.
+ * @param functionCallbackContext The function callback context.
+ * @param retryTemplate The retry template.
+ */
public OpenAiChatClient(OpenAiApi openAiApi, OpenAiChatOptions options,
- FunctionCallbackContext functionCallbackContext) {
+ FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
super(functionCallbackContext);
Assert.notNull(openAiApi, "OpenAiApi must not be null");
Assert.notNull(options, "Options must not be null");
+ Assert.notNull(retryTemplate, "RetryTemplate must not be null");
this.openAiApi = openAiApi;
this.defaultOptions = options;
+ this.retryTemplate = retryTemplate;
}
@Override
public ChatResponse call(Prompt prompt) {
- return this.retryTemplate.execute(ctx -> {
+ ChatCompletionRequest request = createRequest(prompt, false);
- ChatCompletionRequest request = createRequest(prompt, false);
+ return this.retryTemplate.execute(ctx -> {
ResponseEntity completionEntity = this.callWithFunctionSupport(request);
@@ -137,7 +147,7 @@ public ChatResponse call(Prompt prompt) {
RateLimit rateLimits = OpenAiResponseHeaderExtractor.extractAiResponseHeaders(completionEntity);
List generations = chatCompletion.choices().stream().map(choice -> {
- return new Generation(choice.message().content(), toMap(choice.message()))
+ return new Generation(choice.message().content(), toMap(chatCompletion.id(), choice))
.withGenerationMetadata(ChatGenerationMetadata.from(choice.finishReason().name(), null));
}).toList();
@@ -146,10 +156,26 @@ public ChatResponse call(Prompt prompt) {
});
}
+ private Map toMap(String id, ChatCompletion.Choice choice) {
+ Map map = new HashMap<>();
+
+ var message = choice.message();
+ if (message.role() != null) {
+ map.put("role", message.role().name());
+ }
+ if (choice.finishReason() != null) {
+ map.put("finishReason", choice.finishReason().name());
+ }
+ map.put("id", id);
+ return map;
+ }
+
@Override
public Flux stream(Prompt prompt) {
+
+ ChatCompletionRequest request = createRequest(prompt, true);
+
return this.retryTemplate.execute(ctx -> {
- ChatCompletionRequest request = createRequest(prompt, true);
Flux completionChunks = this.openAiApi.chatCompletionStream(request);
@@ -157,24 +183,56 @@ public Flux stream(Prompt prompt) {
// The rest of the chunks with same ID share the same role.
ConcurrentHashMap roleMap = new ConcurrentHashMap<>();
- return completionChunks.map(chunk -> {
- String chunkId = chunk.id();
- List generations = chunk.choices().stream().map(choice -> {
- if (choice.delta().role() != null) {
- roleMap.putIfAbsent(chunkId, choice.delta().role().name());
- }
- var generation = new Generation(choice.delta().content(), Map.of("role", roleMap.get(chunkId)));
- if (choice.finishReason() != null) {
- generation = generation
- .withGenerationMetadata(ChatGenerationMetadata.from(choice.finishReason().name(), null));
- }
- return generation;
- }).toList();
- return new ChatResponse(generations);
+ // Convert the ChatCompletionChunk into a ChatCompletion to be able to reuse
+ // the function call handling logic.
+ return completionChunks.map(chunk -> chunkToChatCompletion(chunk)).map(chatCompletion -> {
+ try {
+ chatCompletion = handleFunctionCallOrReturn(request, ResponseEntity.of(Optional.of(chatCompletion)))
+ .getBody();
+
+ @SuppressWarnings("null")
+ String id = chatCompletion.id();
+
+ List generations = chatCompletion.choices().stream().map(choice -> {
+ if (choice.message().role() != null) {
+ roleMap.putIfAbsent(id, choice.message().role().name());
+ }
+ String finish = (choice.finishReason() != null ? choice.finishReason().name() : "");
+ var generation = new Generation(choice.message().content(),
+ Map.of("id", id, "role", roleMap.get(id), "finishReason", finish));
+ if (choice.finishReason() != null) {
+ generation = generation.withGenerationMetadata(
+ ChatGenerationMetadata.from(choice.finishReason().name(), null));
+ }
+ return generation;
+ }).toList();
+
+ return new ChatResponse(generations);
+ }
+ catch (Exception e) {
+ logger.error("Error processing chat completion", e);
+ return new ChatResponse(List.of());
+ }
+
});
});
}
+ /**
+ * Convert the ChatCompletionChunk into a ChatCompletion. The Usage is set to null.
+ * @param chunk the ChatCompletionChunk to convert
+ * @return the ChatCompletion
+ */
+ private OpenAiApi.ChatCompletion chunkToChatCompletion(OpenAiApi.ChatCompletionChunk chunk) {
+ List choices = chunk.choices()
+ .stream()
+ .map(cc -> new Choice(cc.finishReason(), cc.index(), cc.delta(), cc.logprobs()))
+ .toList();
+
+ return new OpenAiApi.ChatCompletion(chunk.id(), choices, chunk.created(), chunk.model(),
+ chunk.systemFingerprint(), "chat.completion", null);
+ }
+
/**
* Accessible for testing.
*/
@@ -220,10 +278,6 @@ ChatCompletionRequest createRequest(Prompt prompt, boolean stream) {
// Add the enabled functions definitions to the request's tools parameter.
if (!CollectionUtils.isEmpty(functionsForThisRequest)) {
- if (stream) {
- throw new IllegalArgumentException("Currently tool functions are not supported in streaming mode");
- }
-
request = ModelOptionsUtils.merge(
OpenAiChatOptions.builder().withTools(this.getFunctionTools(functionsForThisRequest)).build(),
request, ChatCompletionRequest.class);
@@ -240,25 +294,6 @@ private List getFunctionTools(Set functionNames)
}).toList();
}
- private Map toMap(ChatCompletionMessage message) {
- Map map = new HashMap<>();
-
- // The tool_calls and tool_call_id are not used by the OpenAiChatClient functions
- // call support! Useful only for users that want to use the tool_calls and
- // tool_call_id in their applications.
- if (message.toolCalls() != null) {
- map.put("tool_calls", message.toolCalls());
- }
- if (message.toolCallId() != null) {
- map.put("tool_call_id", message.toolCallId());
- }
-
- if (message.role() != null) {
- map.put("role", message.role().name());
- }
- return map;
- }
-
@Override
protected ChatCompletionRequest doCreateToolResponseRequest(ChatCompletionRequest previousRequest,
ChatCompletionMessage responseMessage, List conversationHistory) {
@@ -283,7 +318,7 @@ protected ChatCompletionRequest doCreateToolResponseRequest(ChatCompletionReques
// Recursively call chatCompletionWithTools until the model doesn't call a
// functions anymore.
- ChatCompletionRequest newRequest = new ChatCompletionRequest(conversationHistory, previousRequest.stream());
+ ChatCompletionRequest newRequest = new ChatCompletionRequest(conversationHistory, false);
newRequest = ModelOptionsUtils.merge(newRequest, previousRequest, ChatCompletionRequest.class);
return newRequest;
@@ -316,7 +351,9 @@ protected boolean isToolFunctionCall(ResponseEntity chatCompleti
return false;
}
- return !CollectionUtils.isEmpty(choices.get(0).message().toolCalls());
+ var choice = choices.get(0);
+ return !CollectionUtils.isEmpty(choice.message().toolCalls())
+ && choice.finishReason() == ChatCompletionFinishReason.TOOL_CALLS;
}
}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java
index 3ebb1c9dbe1..14faaf6f82d 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai;
import java.util.ArrayList;
@@ -333,7 +332,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -343,7 +341,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -387,7 +384,6 @@ public Set getFunctions() {
return functions;
}
- @Override
public void setFunctions(Set functionNames) {
this.functions = functionNames;
}
@@ -515,7 +511,6 @@ public Integer getTopK() {
throw new UnsupportedOperationException("Unimplemented method 'getTopK'");
}
- @Override
@JsonIgnore
public void setTopK(Integer topK) {
throw new UnsupportedOperationException("Unimplemented method 'setTopK'");
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingClient.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingClient.java
index 1ff64a99bc0..d255853ec55 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingClient.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai;
-import java.time.Duration;
import java.util.List;
import org.slf4j.Logger;
@@ -34,10 +32,7 @@
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiApi.EmbeddingList;
import org.springframework.ai.openai.api.OpenAiApi.Usage;
-import org.springframework.ai.openai.api.common.OpenAiApiException;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
@@ -52,39 +47,60 @@ public class OpenAiEmbeddingClient extends AbstractEmbeddingClient {
private final OpenAiEmbeddingOptions defaultOptions;
- private final RetryTemplate retryTemplate = RetryTemplate.builder()
- .maxAttempts(10)
- .retryOn(OpenAiApiException.class)
- .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
- .withListener(new RetryListener() {
- public void onError(RetryContext context,
- RetryCallback callback, Throwable throwable) {
- logger.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
- };
- })
- .build();
+ private final RetryTemplate retryTemplate;
private final OpenAiApi openAiApi;
private final MetadataMode metadataMode;
+ /**
+ * Constructor for the OpenAiEmbeddingClient class.
+ * @param openAiApi The OpenAiApi instance to use for making API requests.
+ */
public OpenAiEmbeddingClient(OpenAiApi openAiApi) {
this(openAiApi, MetadataMode.EMBED);
}
+ /**
+ * Initializes a new instance of the OpenAiEmbeddingClient class.
+ * @param openAiApi The OpenAiApi instance to use for making API requests.
+ * @param metadataMode The mode for generating metadata.
+ */
public OpenAiEmbeddingClient(OpenAiApi openAiApi, MetadataMode metadataMode) {
this(openAiApi, metadataMode,
- OpenAiEmbeddingOptions.builder().withModel(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build());
+ OpenAiEmbeddingOptions.builder().withModel(OpenAiApi.DEFAULT_EMBEDDING_MODEL).build(),
+ RetryUtils.DEFAULT_RETRY_TEMPLATE);
+ }
+
+ /**
+ * Initializes a new instance of the OpenAiEmbeddingClient class.
+ * @param openAiApi The OpenAiApi instance to use for making API requests.
+ * @param metadataMode The mode for generating metadata.
+ * @param openAiEmbeddingOptions The options for OpenAi embedding.
+ */
+ public OpenAiEmbeddingClient(OpenAiApi openAiApi, MetadataMode metadataMode,
+ OpenAiEmbeddingOptions openAiEmbeddingOptions) {
+ this(openAiApi, metadataMode, openAiEmbeddingOptions, RetryUtils.DEFAULT_RETRY_TEMPLATE);
}
- public OpenAiEmbeddingClient(OpenAiApi openAiApi, MetadataMode metadataMode, OpenAiEmbeddingOptions options) {
+ /**
+ * Initializes a new instance of the OpenAiEmbeddingClient class.
+ * @param openAiApi - The OpenAiApi instance to use for making API requests.
+ * @param metadataMode - The mode for generating metadata.
+ * @param options - The options for OpenAI embedding.
+ * @param retryTemplate - The RetryTemplate for retrying failed API requests.
+ */
+ public OpenAiEmbeddingClient(OpenAiApi openAiApi, MetadataMode metadataMode, OpenAiEmbeddingOptions options,
+ RetryTemplate retryTemplate) {
Assert.notNull(openAiApi, "OpenAiService must not be null");
Assert.notNull(metadataMode, "metadataMode must not be null");
Assert.notNull(options, "options must not be null");
+ Assert.notNull(retryTemplate, "retryTemplate must not be null");
this.openAiApi = openAiApi;
this.metadataMode = metadataMode;
this.defaultOptions = options;
+ this.retryTemplate = retryTemplate;
}
@Override
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java
index 39a73a707a6..59a85aacc32 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageClient.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageClient.java
index 8f28ccda467..69863ef9ffc 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageClient.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageClient.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,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai;
-import java.time.Duration;
import java.util.List;
import org.slf4j.Logger;
@@ -31,13 +29,10 @@
import org.springframework.ai.image.ImageResponseMetadata;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.openai.api.OpenAiImageApi;
-import org.springframework.ai.openai.api.common.OpenAiApiException;
import org.springframework.ai.openai.metadata.OpenAiImageGenerationMetadata;
import org.springframework.ai.openai.metadata.OpenAiImageResponseMetadata;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.ResponseEntity;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
@@ -51,38 +46,32 @@
*/
public class OpenAiImageClient implements ImageClient {
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private final static Logger logger = LoggerFactory.getLogger(OpenAiImageClient.class);
private OpenAiImageOptions defaultOptions;
private final OpenAiImageApi openAiImageApi;
- public final RetryTemplate retryTemplate = RetryTemplate.builder()
- .maxAttempts(10)
- .retryOn(OpenAiApiException.class)
- .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
- .withListener(new RetryListener() {
- public void onError(RetryContext context,
- RetryCallback callback, Throwable throwable) {
- logger.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
- };
- })
- .build();
+ public final RetryTemplate retryTemplate;
public OpenAiImageClient(OpenAiImageApi openAiImageApi) {
+ this(openAiImageApi, OpenAiImageOptions.builder().build(), RetryUtils.DEFAULT_RETRY_TEMPLATE);
+ }
+
+ public OpenAiImageClient(OpenAiImageApi openAiImageApi, OpenAiImageOptions defaultOptions,
+ RetryTemplate retryTemplate) {
Assert.notNull(openAiImageApi, "OpenAiImageApi must not be null");
+ Assert.notNull(defaultOptions, "defaultOptions must not be null");
+ Assert.notNull(retryTemplate, "retryTemplate must not be null");
this.openAiImageApi = openAiImageApi;
+ this.defaultOptions = defaultOptions;
+ this.retryTemplate = retryTemplate;
}
public OpenAiImageOptions getDefaultOptions() {
return this.defaultOptions;
}
- public OpenAiImageClient withDefaultOptions(OpenAiImageOptions defaultOptions) {
- this.defaultOptions = defaultOptions;
- return this;
- }
-
@Override
public ImageResponse call(ImagePrompt imagePrompt) {
return this.retryTemplate.execute(ctx -> {
@@ -130,7 +119,7 @@ private ImageResponse convertResponse(ResponseEntity getJsonContentHeaders(String apiKey) {
+ return (headers) -> {
+ headers.setBearerAuth(apiKey);
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ };
+ };
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
index 6d986f379c8..b07c7579cc8 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.api;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -27,12 +27,13 @@
import reactor.core.publisher.Mono;
import org.springframework.ai.model.ModelOptionsUtils;
-import org.springframework.ai.openai.api.common.ApiUtils;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.function.client.WebClient;
@@ -42,6 +43,7 @@
* OpenAI Embedding API: https://platform.openai.com/docs/api-reference/embeddings.
*
* @author Christian Tzolov
+ * @author Michael Lavelle
*/
public class OpenAiApi {
@@ -50,6 +52,7 @@ public class OpenAiApi {
private static final Predicate SSE_DONE_PREDICATE = "[DONE]"::equals;
private final RestClient restClient;
+
private final WebClient webClient;
/**
@@ -79,11 +82,23 @@ public OpenAiApi(String baseUrl, String openAiToken) {
* @param restClientBuilder RestClient builder.
*/
public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) {
+ this(baseUrl, openAiToken, restClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
+ }
+
+ /**
+ * Create a new chat completion api.
+ *
+ * @param baseUrl api base URL.
+ * @param openAiToken OpenAI apiKey.
+ * @param restClientBuilder RestClient builder.
+ * @param responseErrorHandler Response error handler.
+ */
+ public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
this.restClient = restClientBuilder
.baseUrl(baseUrl)
.defaultHeaders(ApiUtils.getJsonContentHeaders(openAiToken))
- .defaultStatusHandler(ApiUtils.DEFAULT_RESPONSE_ERROR_HANDLER)
+ .defaultStatusHandler(responseErrorHandler)
.build();
this.webClient = WebClient.builder()
@@ -97,7 +112,7 @@ public OpenAiApi(String baseUrl, String openAiToken, RestClient.Builder restClie
* GPT-4 and GPT-4 Turbo and
* GPT-3.5 Turbo.
*/
- enum ChatModel {
+ public enum ChatModel {
/**
* (New) GPT-4 Turbo - latest GPT-4 model intended to reduce cases
* of “laziness” where the model doesn’t complete a task.
@@ -150,6 +165,16 @@ enum ChatModel {
*/
GPT_3_5_TURBO("gpt-3.5-turbo"),
+ /**
+ * (new) The latest GPT-3.5 Turbo model with higher accuracy
+ * at responding in requested formats and a fix for a bug
+ * which caused a text encoding issue for non-English
+ * language function calls.
+ * Returns a maximum of 4,096
+ * Context window: 16k tokens
+ */
+ GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125"),
+
/**
* GPT-3.5 Turbo model with improved instruction following,
* JSON mode, reproducible outputs, parallel function calling,
@@ -169,42 +194,6 @@ public String getValue() {
}
}
- /**
- * OpenAI Embeddings Models:
- * Embeddings.
- */
- enum EmbeddingModel {
-
- /**
- * Most capable embedding model for both english and non-english tasks.
- * DIMENSION: 3072
- */
- TEXT_EMBEDDING_3_LARGE("text-embedding-3-large"),
-
- /**
- * Increased performance over 2nd generation ada embedding model.
- * DIMENSION: 1536
- */
- TEXT_EMBEDDING_3_SMALL("text-embedding-3-small"),
-
- /**
- * Most capable 2nd generation embedding model, replacing 16 first
- * generation models.
- * DIMENSION: 1536
- */
- TEXT_EMBEDDING_ADA_002("text-embedding-ada-002");
-
- public final String value;
-
- EmbeddingModel(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
- }
-
/**
* Represents a tool the model may call. Currently, only functions are supported as a tool.
*
@@ -521,7 +510,7 @@ public enum ChatCompletionFinishReason {
/**
* Only for compatibility with Mistral AI API.
*/
- @JsonProperty("tool_call") TOOL_CAL
+ @JsonProperty("tool_call") TOOL_CALL
}
/**
@@ -685,6 +674,8 @@ public ResponseEntity chatCompletionEntity(ChatCompletionRequest
.toEntity(ChatCompletion.class);
}
+ private OpenAiStreamFunctionCallingHelper chunkMerger = new OpenAiStreamFunctionCallingHelper();
+
/**
* Creates a streaming chat response for the given chat conversation.
*
@@ -696,6 +687,8 @@ public Flux chatCompletionStream(ChatCompletionRequest chat
Assert.notNull(chatRequest, "The request body can not be null.");
Assert.isTrue(chatRequest.stream(), "Request must set the steam property to true.");
+ AtomicBoolean isInsideTool = new AtomicBoolean(false);
+
return this.webClient.post()
.uri("/v1/chat/completions")
.body(Mono.just(chatRequest), ChatCompletionRequest.class)
@@ -705,7 +698,72 @@ public Flux chatCompletionStream(ChatCompletionRequest chat
.takeUntil(SSE_DONE_PREDICATE)
// filters out the "[DONE]" message.
.filter(SSE_DONE_PREDICATE.negate())
- .map(content -> ModelOptionsUtils.jsonToObject(content, ChatCompletionChunk.class));
+ .map(content -> ModelOptionsUtils.jsonToObject(content, ChatCompletionChunk.class))
+ // Detect is the chunk is part of a streaming function call.
+ .map(chunk -> {
+ if (this.chunkMerger.isStreamingToolFunctionCall(chunk)) {
+ isInsideTool.set(true);
+ }
+ return chunk;
+ })
+ // Group all chunks belonging to the same function call.
+ // Flux -> Flux>
+ .windowUntil(chunk -> {
+ if (isInsideTool.get() && this.chunkMerger.isStreamingToolFunctionCallFinish(chunk)) {
+ isInsideTool.set(false);
+ return true;
+ }
+ return !isInsideTool.get();
+ })
+ // Merging the window chunks into a single chunk.
+ // Reduce the inner Flux window into a single Mono,
+ // Flux> -> Flux>
+ .concatMapIterable(window -> {
+ Mono monoChunk = window.reduce(
+ new ChatCompletionChunk(null, null, null, null, null, null),
+ (previous, current) -> this.chunkMerger.merge(previous, current));
+ return List.of(monoChunk);
+ })
+ // Flux> -> Flux
+ .flatMap(mono -> mono);
+ }
+
+ // Embeddings API
+
+ /**
+ * OpenAI Embeddings Models:
+ * Embeddings.
+ */
+ public enum EmbeddingModel {
+
+ /**
+ * Most capable embedding model for both english and non-english tasks.
+ * DIMENSION: 3072
+ */
+ TEXT_EMBEDDING_3_LARGE("text-embedding-3-large"),
+
+ /**
+ * Increased performance over 2nd generation ada embedding model.
+ * DIMENSION: 1536
+ */
+ TEXT_EMBEDDING_3_SMALL("text-embedding-3-small"),
+
+ /**
+ * Most capable 2nd generation embedding model, replacing 16 first
+ * generation models.
+ * DIMENSION: 1536
+ */
+ TEXT_EMBEDDING_ADA_002("text-embedding-ada-002");
+
+ public final String value;
+
+ EmbeddingModel(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
}
/**
@@ -824,5 +882,6 @@ public ResponseEntity> embeddings(EmbeddingRequest<
.toEntity(new ParameterizedTypeReference<>() {
});
}
+
}
// @formatter:on
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 52c38f13be5..65e5ca310af 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
@@ -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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.api;
import java.util.List;
@@ -22,12 +21,13 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.springframework.ai.openai.api.common.ApiUtils;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
/**
@@ -46,7 +46,7 @@ public class OpenAiAudioApi {
* @param openAiToken OpenAI apiKey.
*/
public OpenAiAudioApi(String openAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, openAiToken, RestClient.builder());
+ this(ApiUtils.DEFAULT_BASE_URL, openAiToken, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
}
/**
@@ -54,12 +54,14 @@ public OpenAiAudioApi(String openAiToken) {
* @param baseUrl api base URL.
* @param openAiToken OpenAI apiKey.
* @param restClientBuilder RestClient builder.
+ * @param responseErrorHandler Response error handler.
*/
- public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) {
+ public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder,
+ ResponseErrorHandler responseErrorHandler) {
this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(headers -> {
headers.setBearerAuth(openAiToken);
- }).defaultStatusHandler(ApiUtils.DEFAULT_RESPONSE_ERROR_HANDLER).build();
+ }).defaultStatusHandler(responseErrorHandler).build();
}
/**
@@ -280,7 +282,7 @@ public record TranscriptionRequest(
@JsonProperty("model") String model,
@JsonProperty("language") String language,
@JsonProperty("prompt") String prompt,
- @JsonProperty("response_format") TextualResponseFormat responseFormat,
+ @JsonProperty("response_format") TranscriptResponseFormat responseFormat,
@JsonProperty("temperature") Float temperature,
@JsonProperty("timestamp_granularities") GranularityType granularityType) {
// @formatter:on
@@ -318,7 +320,7 @@ public static class Builder {
private String prompt;
- private TextualResponseFormat responseFormat = TextualResponseFormat.JSON;
+ private TranscriptResponseFormat responseFormat = TranscriptResponseFormat.JSON;
private Float temperature;
@@ -344,7 +346,7 @@ public Builder withPrompt(String prompt) {
return this;
}
- public Builder withResponseFormat(TextualResponseFormat response_format) {
+ public Builder withResponseFormat(TranscriptResponseFormat response_format) {
this.responseFormat = response_format;
return this;
}
@@ -375,7 +377,7 @@ public TranscriptionRequest build() {
* The format of the transcript and translation outputs, in one of these options:
* json, text, srt, verbose_json, or vtt. Defaults to json.
*/
- public enum TextualResponseFormat {
+ public enum TranscriptResponseFormat {
// @formatter:off
@JsonProperty("json") JSON("json", StructuredResponse.class),
@@ -393,7 +395,7 @@ public boolean isJsonType() {
return this == JSON || this == VERBOSE_JSON;
}
- TextualResponseFormat(String value, Class> responseType) {
+ TranscriptResponseFormat(String value, Class> responseType) {
this.value = value;
this.responseType = responseType;
}
@@ -429,7 +431,7 @@ public record TranslationRequest(
@JsonProperty("file") byte[] file,
@JsonProperty("model") String model,
@JsonProperty("prompt") String prompt,
- @JsonProperty("response_format") TextualResponseFormat responseFormat,
+ @JsonProperty("response_format") TranscriptResponseFormat responseFormat,
@JsonProperty("temperature") Float temperature) {
// @formatter:on
@@ -445,7 +447,7 @@ public static class Builder {
private String prompt;
- private TextualResponseFormat responseFormat = TextualResponseFormat.JSON;
+ private TranscriptResponseFormat responseFormat = TranscriptResponseFormat.JSON;
private Float temperature;
@@ -464,7 +466,7 @@ public Builder withPrompt(String prompt) {
return this;
}
- public Builder withResponseFormat(TextualResponseFormat responseFormat) {
+ public Builder withResponseFormat(TranscriptResponseFormat responseFormat) {
this.responseFormat = responseFormat;
return this;
}
@@ -601,7 +603,7 @@ public String getFilename() {
multipartBody.add("response_format", requestBody.responseFormat().getValue());
multipartBody.add("temperature", requestBody.temperature());
if (requestBody.granularityType() != null) {
- Assert.isTrue(requestBody.responseFormat() == TextualResponseFormat.VERBOSE_JSON,
+ Assert.isTrue(requestBody.responseFormat() == TranscriptResponseFormat.VERBOSE_JSON,
"response_format must be set to verbose_json to use timestamp granularities.");
multipartBody.add("timestamp_granularities[]", requestBody.granularityType().getValue());
}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
index be4cd26c526..18b3d0bff4e 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
@@ -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,
@@ -20,9 +20,10 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.springframework.ai.openai.api.common.ApiUtils;
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
/**
@@ -44,11 +45,29 @@ public OpenAiImageApi(String openAiToken) {
this(ApiUtils.DEFAULT_BASE_URL, openAiToken, RestClient.builder());
}
+ /**
+ * Create a new OpenAI Image API with the provided base URL.
+ * @param baseUrl the base URL for the OpenAI API.
+ * @param openAiToken OpenAI apiKey.
+ * @param restClientBuilder the rest client builder to use.
+ */
public OpenAiImageApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) {
+ this(baseUrl, openAiToken, restClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
+ }
+
+ /**
+ * Create a new OpenAI Image API with the provided base URL.
+ * @param baseUrl the base URL for the OpenAI API.
+ * @param openAiToken OpenAI apiKey.
+ * @param restClientBuilder the rest client builder to use.
+ * @param responseErrorHandler the response error handler to use.
+ */
+ public OpenAiImageApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder,
+ ResponseErrorHandler responseErrorHandler) {
this.restClient = restClientBuilder.baseUrl(baseUrl)
.defaultHeaders(ApiUtils.getJsonContentHeaders(openAiToken))
- .defaultStatusHandler(ApiUtils.DEFAULT_RESPONSE_ERROR_HANDLER)
+ .defaultStatusHandler(responseErrorHandler)
.build();
}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelper.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelper.java
new file mode 100644
index 00000000000..5c41320777b
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiStreamFunctionCallingHelper.java
@@ -0,0 +1,201 @@
+/*
+ * 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.openai.api;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion.Choice;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionFinishReason;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage;
+import org.springframework.ai.openai.api.OpenAiApi.LogProbs;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.ChatCompletionFunction;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.Role;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.ToolCall;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Helper class to support Streaming function calling.
+ *
+ * It can merge the streamed ChatCompletionChunk in case of function calling message.
+ *
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+public class OpenAiStreamFunctionCallingHelper {
+
+ /**
+ * Merge the previous and current ChatCompletionChunk into a single one.
+ * @param previous the previous ChatCompletionChunk
+ * @param current the current ChatCompletionChunk
+ * @return the merged ChatCompletionChunk
+ */
+ public ChatCompletionChunk merge(ChatCompletionChunk previous, ChatCompletionChunk current) {
+
+ if (previous == null) {
+ return current;
+ }
+
+ String id = (current.id() != null ? current.id() : previous.id());
+ Long created = (current.created() != null ? current.created() : previous.created());
+ String model = (current.model() != null ? current.model() : previous.model());
+ String systemFingerprint = (current.systemFingerprint() != null ? current.systemFingerprint()
+ : previous.systemFingerprint());
+ String object = (current.object() != null ? current.object() : previous.object());
+
+ ChunkChoice previousChoice0 = (CollectionUtils.isEmpty(previous.choices()) ? null : previous.choices().get(0));
+ ChunkChoice currentChoice0 = (CollectionUtils.isEmpty(current.choices()) ? null : current.choices().get(0));
+
+ ChunkChoice choice = merge(previousChoice0, currentChoice0);
+
+ return new ChatCompletionChunk(id, List.of(choice), created, model, systemFingerprint, object);
+ }
+
+ private ChunkChoice merge(ChunkChoice previous, ChunkChoice current) {
+ if (previous == null) {
+ return current;
+ }
+
+ ChatCompletionFinishReason finishReason = (current.finishReason() != null ? current.finishReason()
+ : previous.finishReason());
+ Integer index = (current.index() != null ? current.index() : previous.index());
+
+ ChatCompletionMessage message = merge(previous.delta(), current.delta());
+
+ LogProbs logprobs = (current.logprobs() != null ? current.logprobs() : previous.logprobs());
+ return new ChunkChoice(finishReason, index, message, logprobs);
+ }
+
+ private ChatCompletionMessage merge(ChatCompletionMessage previous, ChatCompletionMessage current) {
+ String content = (current.content() != null ? current.content()
+ : "" + ((previous.content() != null) ? previous.content() : ""));
+ Role role = (current.role() != null ? current.role() : previous.role());
+ role = (role != null ? role : Role.ASSISTANT); // default to ASSISTANT (if null
+ String name = (current.name() != null ? current.name() : previous.name());
+ String toolCallId = (current.toolCallId() != null ? current.toolCallId() : previous.toolCallId());
+
+ List toolCalls = new ArrayList<>();
+ ToolCall lastPreviousTooCall = null;
+ if (previous.toolCalls() != null) {
+ lastPreviousTooCall = previous.toolCalls().get(previous.toolCalls().size() - 1);
+ if (previous.toolCalls().size() > 1) {
+ toolCalls.addAll(previous.toolCalls().subList(0, previous.toolCalls().size() - 1));
+ }
+ }
+ if (current.toolCalls() != null) {
+ if (current.toolCalls().size() > 1) {
+ throw new IllegalStateException("Currently only one tool call is supported per message!");
+ }
+ var currentToolCall = current.toolCalls().iterator().next();
+ if (currentToolCall.id() != null) {
+ if (lastPreviousTooCall != null) {
+ toolCalls.add(lastPreviousTooCall);
+ }
+ toolCalls.add(currentToolCall);
+ }
+ else {
+ toolCalls.add(merge(lastPreviousTooCall, currentToolCall));
+ }
+ }
+ else {
+ if (lastPreviousTooCall != null) {
+ toolCalls.add(lastPreviousTooCall);
+ }
+ }
+ return new ChatCompletionMessage(content, role, name, toolCallId, toolCalls);
+ }
+
+ private ToolCall merge(ToolCall previous, ToolCall current) {
+ if (previous == null) {
+ return current;
+ }
+ String id = (current.id() != null ? current.id() : previous.id());
+ String type = (current.type() != null ? current.type() : previous.type());
+ ChatCompletionFunction function = merge(previous.function(), current.function());
+ return new ToolCall(id, type, function);
+ }
+
+ private ChatCompletionFunction merge(ChatCompletionFunction previous, ChatCompletionFunction current) {
+ if (previous == null) {
+ return current;
+ }
+ String name = (current.name() != null ? current.name() : previous.name());
+ StringBuilder arguments = new StringBuilder();
+ if (previous.arguments() != null) {
+ arguments.append(previous.arguments());
+ }
+ if (current.arguments() != null) {
+ arguments.append(current.arguments());
+ }
+ return new ChatCompletionFunction(name, arguments.toString());
+ }
+
+ /**
+ * @param chatCompletion the ChatCompletionChunk to check
+ * @return true if the ChatCompletionChunk is a streaming tool function call.
+ */
+ public boolean isStreamingToolFunctionCall(ChatCompletionChunk chatCompletion) {
+
+ if (chatCompletion == null || CollectionUtils.isEmpty(chatCompletion.choices())) {
+ return false;
+ }
+
+ var choice = chatCompletion.choices().get(0);
+ if (choice == null || choice.delta() == null) {
+ return false;
+ }
+ return !CollectionUtils.isEmpty(choice.delta().toolCalls());
+ }
+
+ /**
+ * @param chatCompletion the ChatCompletionChunk to check
+ * @return true if the ChatCompletionChunk is a streaming tool function call and it is
+ * the last one.
+ */
+ public boolean isStreamingToolFunctionCallFinish(ChatCompletionChunk chatCompletion) {
+
+ if (chatCompletion == null || CollectionUtils.isEmpty(chatCompletion.choices())) {
+ return false;
+ }
+
+ var choice = chatCompletion.choices().get(0);
+ if (choice == null || choice.delta() == null) {
+ return false;
+ }
+ return choice.finishReason() == ChatCompletionFinishReason.TOOL_CALLS;
+ }
+
+ /**
+ * Convert the ChatCompletionChunk into a ChatCompletion. The Usage is set to null.
+ * @param chunk the ChatCompletionChunk to convert
+ * @return the ChatCompletion
+ */
+ public ChatCompletion chunkToChatCompletion(ChatCompletionChunk chunk) {
+ List choices = chunk.choices()
+ .stream()
+ .map(chunkChoice -> new Choice(chunkChoice.finishReason(), chunkChoice.index(), chunkChoice.delta(),
+ chunkChoice.logprobs()))
+ .toList();
+
+ return new OpenAiApi.ChatCompletion(chunk.id(), choices, chunk.created(), chunk.model(),
+ chunk.systemFingerprint(), "chat.completion", null);
+ }
+
+}
+// ---
\ No newline at end of file
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/ApiUtils.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/ApiUtils.java
deleted file mode 100644
index 30d12626363..00000000000
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/ApiUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- */
-
-package org.springframework.ai.openai.api.common;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.function.Consumer;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.lang.NonNull;
-import org.springframework.util.StreamUtils;
-import org.springframework.web.client.ResponseErrorHandler;
-
-/**
- * @author Christian Tzolov
- */
-public class ApiUtils {
-
- public static final String DEFAULT_BASE_URL = "https://api.openai.com";
-
- public static Consumer getJsonContentHeaders(String apiKey) {
- return (headers) -> {
- headers.setBearerAuth(apiKey);
- headers.setContentType(MediaType.APPLICATION_JSON);
- };
- };
-
- public static final ResponseErrorHandler DEFAULT_RESPONSE_ERROR_HANDLER = new ResponseErrorHandler() {
-
- @Override
- public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
- return response.getStatusCode().isError();
- }
-
- @Override
- public void handleError(@NonNull ClientHttpResponse response) throws IOException {
- if (response.getStatusCode().isError()) {
- String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
- String message = String.format("%s - %s", response.getStatusCode().value(), error);
- if (response.getStatusCode().is4xxClientError()) {
- throw new OpenAiApiClientErrorException(message);
- }
- throw new OpenAiApiException(message);
- }
- }
- };
-
-}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiClientErrorException.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiClientErrorException.java
index d02ea975c6f..a53bc0bf6fb 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiClientErrorException.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiClientErrorException.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.api.common;
/**
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiException.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiException.java
index ee8d86875bb..bc5cc000770 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiException.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiException.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.api.common;
/**
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscription.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscription.java
new file mode 100644
index 00000000000..d7a02b887b8
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscription.java
@@ -0,0 +1,75 @@
+/*
+ * 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.openai.audio.transcription;
+
+import org.springframework.ai.model.ModelResult;
+import org.springframework.ai.openai.metadata.audio.OpenAiAudioTranscriptionMetadata;
+import org.springframework.lang.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Represents a response returned by the AI.
+ *
+ * @author Michael Lavelle
+ * @since 0.8.1
+ */
+public class AudioTranscription implements ModelResult {
+
+ private String text;
+
+ private OpenAiAudioTranscriptionMetadata transcriptionMetadata;
+
+ public AudioTranscription(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String getOutput() {
+ return this.text;
+ }
+
+ @Override
+ public OpenAiAudioTranscriptionMetadata getMetadata() {
+ return transcriptionMetadata != null ? transcriptionMetadata : OpenAiAudioTranscriptionMetadata.NULL;
+ }
+
+ public AudioTranscription withTranscriptionMetadata(
+ @Nullable OpenAiAudioTranscriptionMetadata transcriptionMetadata) {
+ this.transcriptionMetadata = transcriptionMetadata;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof AudioTranscription that))
+ return false;
+ return Objects.equals(text, that.text) && Objects.equals(transcriptionMetadata, that.transcriptionMetadata);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(text, transcriptionMetadata);
+ }
+
+ @Override
+ public String toString() {
+ return "Transcript{" + "text=" + text + ", transcriptionMetadata=" + transcriptionMetadata + '}';
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionPrompt.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionPrompt.java
new file mode 100644
index 00000000000..ffa9e0bc13c
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionPrompt.java
@@ -0,0 +1,51 @@
+/*
+ * 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.openai.audio.transcription;
+
+import org.springframework.ai.model.ModelOptions;
+import org.springframework.ai.model.ModelRequest;
+import org.springframework.core.io.Resource;
+
+/**
+ * @author Michael Lavelle
+ * @since 0.8.1
+ */
+public class AudioTranscriptionPrompt implements ModelRequest {
+
+ private Resource audioResource;
+
+ private ModelOptions modelOptions;
+
+ public AudioTranscriptionPrompt(Resource audioResource) {
+ this.audioResource = audioResource;
+ }
+
+ public AudioTranscriptionPrompt(Resource audioResource, ModelOptions modelOptions) {
+ this.audioResource = audioResource;
+ this.modelOptions = modelOptions;
+ }
+
+ @Override
+ public Resource getInstructions() {
+ return audioResource;
+ }
+
+ @Override
+ public ModelOptions getOptions() {
+ return modelOptions;
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionResponse.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionResponse.java
new file mode 100644
index 00000000000..ff4f07ed732
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/audio/transcription/AudioTranscriptionResponse.java
@@ -0,0 +1,59 @@
+/*
+ * 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.openai.audio.transcription;
+
+import org.springframework.ai.model.ModelResponse;
+import org.springframework.ai.openai.metadata.audio.OpenAiAudioTranscriptionResponseMetadata;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Michael Lavelle
+ * @since 0.8.1
+ */
+public class AudioTranscriptionResponse implements ModelResponse {
+
+ private AudioTranscription transcript;
+
+ private OpenAiAudioTranscriptionResponseMetadata transcriptionResponseMetadata;
+
+ public AudioTranscriptionResponse(AudioTranscription transcript) {
+ this(transcript, OpenAiAudioTranscriptionResponseMetadata.NULL);
+ }
+
+ public AudioTranscriptionResponse(AudioTranscription transcript,
+ OpenAiAudioTranscriptionResponseMetadata transcriptionResponseMetadata) {
+ this.transcript = transcript;
+ this.transcriptionResponseMetadata = transcriptionResponseMetadata;
+ }
+
+ @Override
+ public AudioTranscription getResult() {
+ return transcript;
+ }
+
+ @Override
+ public List getResults() {
+ return Arrays.asList(transcript);
+ }
+
+ @Override
+ public OpenAiAudioTranscriptionResponseMetadata getMetadata() {
+ return transcriptionResponseMetadata;
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiChatResponseMetadata.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiChatResponseMetadata.java
index 75ef7a395b3..29e7276f7b7 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiChatResponseMetadata.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiChatResponseMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata;
import org.springframework.ai.chat.metadata.*;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageGenerationMetadata.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageGenerationMetadata.java
index 8e9a5d8b0ac..bc4da401bfe 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageGenerationMetadata.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageGenerationMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata;
import org.springframework.ai.image.ImageGenerationMetadata;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageResponseMetadata.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageResponseMetadata.java
index b954affa5f6..023b93bca74 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageResponseMetadata.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiImageResponseMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata;
import org.springframework.ai.image.ImageResponseMetadata;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiRateLimit.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiRateLimit.java
index c740c9d33fe..7f5f214da04 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiRateLimit.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiRateLimit.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata;
import java.time.Duration;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiUsage.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiUsage.java
index 09361b2d6f9..5f1367736ac 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiUsage.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/OpenAiUsage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata;
import org.springframework.ai.chat.metadata.Usage;
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionMetadata.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionMetadata.java
new file mode 100644
index 00000000000..c9868069f21
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionMetadata.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/**
+* @author Michael Lavelle
+* @since 0.8.1
+*/
+package org.springframework.ai.openai.metadata.audio;
+
+import org.springframework.ai.model.ResultMetadata;
+
+public interface OpenAiAudioTranscriptionMetadata extends ResultMetadata {
+
+ OpenAiAudioTranscriptionMetadata NULL = OpenAiAudioTranscriptionMetadata.create();
+
+ /**
+ * Factory method used to construct a new {@link OpenAiAudioTranscriptionMetadata}
+ * @return a new {@link OpenAiAudioTranscriptionMetadata}
+ */
+ static OpenAiAudioTranscriptionMetadata create() {
+ return new OpenAiAudioTranscriptionMetadata() {
+ };
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionResponseMetadata.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionResponseMetadata.java
new file mode 100644
index 00000000000..a58af71b687
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/audio/OpenAiAudioTranscriptionResponseMetadata.java
@@ -0,0 +1,79 @@
+/*
+ * 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.openai.metadata.audio;
+
+import org.springframework.ai.chat.metadata.EmptyRateLimit;
+import org.springframework.ai.chat.metadata.RateLimit;
+import org.springframework.ai.model.ResponseMetadata;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.metadata.OpenAiRateLimit;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+
+/**
+ * Audio transcription metadata implementation for {@literal OpenAI}.
+ *
+ * @author Michael Lavelle
+ * @since 0.8.1
+ * @see RateLimit
+ */
+public class OpenAiAudioTranscriptionResponseMetadata implements ResponseMetadata {
+
+ protected static final String AI_METADATA_STRING = "{ @type: %1$s, rateLimit: %4$s }";
+
+ public static final OpenAiAudioTranscriptionResponseMetadata NULL = new OpenAiAudioTranscriptionResponseMetadata() {
+ };
+
+ public static OpenAiAudioTranscriptionResponseMetadata from(OpenAiAudioApi.StructuredResponse result) {
+ Assert.notNull(result, "OpenAI Transcription must not be null");
+ OpenAiAudioTranscriptionResponseMetadata transcriptionResponseMetadata = new OpenAiAudioTranscriptionResponseMetadata();
+ return transcriptionResponseMetadata;
+ }
+
+ public static OpenAiAudioTranscriptionResponseMetadata from(String result) {
+ Assert.notNull(result, "OpenAI Transcription must not be null");
+ OpenAiAudioTranscriptionResponseMetadata transcriptionResponseMetadata = new OpenAiAudioTranscriptionResponseMetadata();
+ return transcriptionResponseMetadata;
+ }
+
+ @Nullable
+ private RateLimit rateLimit;
+
+ protected OpenAiAudioTranscriptionResponseMetadata() {
+ this(null);
+ }
+
+ protected OpenAiAudioTranscriptionResponseMetadata(@Nullable OpenAiRateLimit rateLimit) {
+ this.rateLimit = rateLimit;
+ }
+
+ @Nullable
+ public RateLimit getRateLimit() {
+ RateLimit rateLimit = this.rateLimit;
+ return rateLimit != null ? rateLimit : new EmptyRateLimit();
+ }
+
+ public OpenAiAudioTranscriptionResponseMetadata withRateLimit(RateLimit rateLimit) {
+ this.rateLimit = rateLimit;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return AI_METADATA_STRING.formatted(getClass().getName(), getRateLimit());
+ }
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiApiResponseHeaders.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiApiResponseHeaders.java
index 488aaa70d97..47d3d5f2d59 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiApiResponseHeaders.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiApiResponseHeaders.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata.support;
/**
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
index 21c28652202..8845ef35f5e 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata.support;
import java.time.Duration;
@@ -52,7 +51,7 @@ public class OpenAiResponseHeaderExtractor {
private static final Logger logger = LoggerFactory.getLogger(OpenAiResponseHeaderExtractor.class);
- public static RateLimit extractAiResponseHeaders(ResponseEntity response) {
+ public static RateLimit extractAiResponseHeaders(ResponseEntity> response) {
Long requestsLimit = getHeaderAsLong(response, REQUESTS_LIMIT_HEADER.getName());
Long requestsRemaining = getHeaderAsLong(response, REQUESTS_REMAINING_HEADER.getName());
@@ -66,7 +65,7 @@ public static RateLimit extractAiResponseHeaders(ResponseEntity
tokensReset);
}
- private static Duration getHeaderAsDuration(ResponseEntity response, String headerName) {
+ private static Duration getHeaderAsDuration(ResponseEntity> response, String headerName) {
var headers = response.getHeaders();
if (headers.containsKey(headerName)) {
var values = headers.get(headerName);
@@ -77,7 +76,7 @@ private static Duration getHeaderAsDuration(ResponseEntity respo
return null;
}
- private static Long getHeaderAsLong(ResponseEntity response, String headerName) {
+ private static Long getHeaderAsLong(ResponseEntity> response, String headerName) {
var headers = response.getHeaders();
if (headers.containsKey(headerName)) {
var values = headers.get(headerName);
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java
index 6eff3af4f1a..300cdfafbb8 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/ChatCompletionRequestTests.java
@@ -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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai;
import java.util.List;
@@ -23,7 +22,7 @@
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallbackWrapper;
import org.springframework.ai.openai.api.OpenAiApi;
-import org.springframework.ai.openai.chat.api.tool.MockWeatherService;
+import org.springframework.ai.openai.api.tool.MockWeatherService;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java
index d43a25dde1d..e3a70725f3f 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiTestConfiguration.java
@@ -1,7 +1,23 @@
+/*
+ * 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.openai;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
@@ -20,6 +36,11 @@ public OpenAiImageApi openAiImageApi() {
return new OpenAiImageApi(getApiKey());
}
+ @Bean
+ public OpenAiAudioApi openAiAudioApi() {
+ return new OpenAiAudioApi(getApiKey());
+ }
+
private String getApiKey() {
String apiKey = System.getenv("OPENAI_API_KEY");
if (!StringUtils.hasText(apiKey)) {
@@ -35,6 +56,12 @@ public OpenAiChatClient openAiChatClient(OpenAiApi api) {
return openAiChatClient;
}
+ @Bean
+ public OpenAiAudioTranscriptionClient openAiTranscriptionClient(OpenAiAudioApi api) {
+ OpenAiAudioTranscriptionClient openAiTranscriptionClient = new OpenAiAudioTranscriptionClient(api);
+ return openAiTranscriptionClient;
+ }
+
@Bean
public OpenAiImageClient openAiImageClient(OpenAiImageApi imageApi) {
OpenAiImageClient openAiImageClient = new OpenAiImageClient(imageApi);
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/acme/AcmeIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/acme/AcmeIT.java
index 9bdb44d8ec2..e38595b90e2 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/acme/AcmeIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/acme/AcmeIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.acme;
import java.util.List;
@@ -100,7 +115,9 @@ void acmeChain() {
private Message getSystemMessage(List similarDocuments) {
- String documents = similarDocuments.stream().map(entry -> entry.getContent()).collect(Collectors.joining("\n"));
+ String documents = similarDocuments.stream()
+ .map(entry -> entry.getContent())
+ .collect(Collectors.joining(System.lineSeparator()));
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemBikePrompt);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("documents", documents));
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/aot/OpenAiRuntimeHintsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/aot/OpenAiRuntimeHintsTests.java
index ed61ba1fdfd..e4399ec8bdd 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/aot/OpenAiRuntimeHintsTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/aot/OpenAiRuntimeHintsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.aot;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/OpenAiApiIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java
similarity index 94%
rename from models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/OpenAiApiIT.java
rename to models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.java
index af0acbd97a6..182a11dcec2 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/OpenAiApiIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/OpenAiApiIT.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,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package org.springframework.ai.openai.chat.api;
+package org.springframework.ai.openai.api;
import java.util.List;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/RestClientBuilderTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/RestClientBuilderTests.java
similarity index 91%
rename from models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/RestClientBuilderTests.java
rename to models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/RestClientBuilderTests.java
index 8930d3cdcce..ffdccf035fb 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/RestClientBuilderTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/RestClientBuilderTests.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,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.springframework.ai.openai.api;
-package org.springframework.ai.openai.chat.api;
-
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/MockWeatherService.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/MockWeatherService.java
similarity index 93%
rename from models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/MockWeatherService.java
rename to models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/MockWeatherService.java
index c80aabf630c..db41af1f0d4 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/MockWeatherService.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/MockWeatherService.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,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package org.springframework.ai.openai.chat.api.tool;
+package org.springframework.ai.openai.api.tool;
import java.util.function.Function;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/OpenAiApiToolFunctionCallIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java
similarity index 97%
rename from models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/OpenAiApiToolFunctionCallIT.java
rename to models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.java
index b213b35d266..4138a24a98c 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/OpenAiApiToolFunctionCallIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/api/tool/OpenAiApiToolFunctionCallIT.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,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.ai.openai.chat.api.tool;
+package org.springframework.ai.openai.api.tool;
import java.util.ArrayList;
import java.util.List;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java
index afb8b22ac8f..bc44f72053a 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/api/OpenAiAudioApiIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.audio.api;
import java.io.File;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientIT.java
new file mode 100644
index 00000000000..9c0845deead
--- /dev/null
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientIT.java
@@ -0,0 +1,67 @@
+/*
+ * 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.openai.audio.transcription;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
+import org.springframework.ai.openai.OpenAiTestConfiguration;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptResponseFormat;
+import org.springframework.ai.openai.testutils.AbstractIT;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.Resource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(classes = OpenAiTestConfiguration.class)
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+class OpenAiTranscriptionClientIT extends AbstractIT {
+
+ @Value("classpath:/speech/jfk.flac")
+ private Resource audioFile;
+
+ @Test
+ void transcriptionTest() {
+ OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
+ .withResponseFormat(TranscriptResponseFormat.TEXT)
+ .withTemperature(0f)
+ .build();
+ AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
+ AudioTranscriptionResponse response = openAiTranscriptionClient.call(transcriptionRequest);
+ assertThat(response.getResults()).hasSize(1);
+ assertThat(response.getResults().get(0).getOutput().toLowerCase().contains("fellow")).isTrue();
+ }
+
+ @Test
+ void transcriptionTestWithOptions() {
+ OpenAiAudioApi.TranscriptResponseFormat responseFormat = OpenAiAudioApi.TranscriptResponseFormat.VTT;
+
+ OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
+ .withLanguage("en")
+ .withPrompt("Ask not this, but ask that")
+ .withTemperature(0f)
+ .withResponseFormat(responseFormat)
+ .build();
+ AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
+ AudioTranscriptionResponse response = openAiTranscriptionClient.call(transcriptionRequest);
+ assertThat(response.getResults()).hasSize(1);
+ assertThat(response.getResults().get(0).getOutput().toLowerCase().contains("fellow")).isTrue();
+ }
+
+}
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientWithTranscriptionResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientWithTranscriptionResponseMetadataTests.java
new file mode 100644
index 00000000000..3b2629714f8
--- /dev/null
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientWithTranscriptionResponseMetadataTests.java
@@ -0,0 +1,165 @@
+/*
+ * 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.openai.audio.transcription;
+
+import java.time.Duration;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.ai.chat.metadata.RateLimit;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.metadata.audio.OpenAiAudioTranscriptionMetadata;
+import org.springframework.ai.openai.metadata.audio.OpenAiAudioTranscriptionResponseMetadata;
+import org.springframework.ai.openai.metadata.support.OpenAiApiResponseHeaders;
+import org.springframework.ai.retry.RetryUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+/**
+ * @author Michael Lavelle
+ */
+@RestClientTest(OpenAiTranscriptionClientWithTranscriptionResponseMetadataTests.Config.class)
+public class OpenAiTranscriptionClientWithTranscriptionResponseMetadataTests {
+
+ private static String TEST_API_KEY = "sk-1234567890";
+
+ @Autowired
+ private OpenAiAudioTranscriptionClient openAiTranscriptionClient;
+
+ @Autowired
+ private MockRestServiceServer server;
+
+ @AfterEach
+ void resetMockServer() {
+ server.reset();
+ }
+
+ @Test
+ void aiResponseContainsAiMetadata() {
+
+ prepareMock();
+
+ Resource audioFile = new ClassPathResource("speech/jfk.flac");
+
+ AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile);
+
+ AudioTranscriptionResponse response = this.openAiTranscriptionClient.call(transcriptionRequest);
+
+ assertThat(response).isNotNull();
+
+ OpenAiAudioTranscriptionResponseMetadata transcriptionResponseMetadata = response.getMetadata();
+
+ assertThat(transcriptionResponseMetadata).isNotNull();
+
+ RateLimit rateLimit = transcriptionResponseMetadata.getRateLimit();
+
+ Duration expectedRequestsReset = Duration.ofDays(2L)
+ .plus(Duration.ofHours(16L))
+ .plus(Duration.ofMinutes(15))
+ .plus(Duration.ofSeconds(29L));
+
+ Duration expectedTokensReset = Duration.ofHours(27L)
+ .plus(Duration.ofSeconds(55L))
+ .plus(Duration.ofMillis(451L));
+
+ assertThat(rateLimit).isNotNull();
+ assertThat(rateLimit.getRequestsLimit()).isEqualTo(4000L);
+ assertThat(rateLimit.getRequestsRemaining()).isEqualTo(999);
+ assertThat(rateLimit.getRequestsReset()).isEqualTo(expectedRequestsReset);
+ assertThat(rateLimit.getTokensLimit()).isEqualTo(725_000L);
+ assertThat(rateLimit.getTokensRemaining()).isEqualTo(112_358L);
+ assertThat(rateLimit.getTokensReset()).isEqualTo(expectedTokensReset);
+
+ response.getResults().forEach(transcript -> {
+ OpenAiAudioTranscriptionMetadata transcriptionMetadata = transcript.getMetadata();
+ assertThat(transcriptionMetadata).isNotNull();
+ });
+ }
+
+ private void prepareMock() {
+
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.set(OpenAiApiResponseHeaders.REQUESTS_LIMIT_HEADER.getName(), "4000");
+ httpHeaders.set(OpenAiApiResponseHeaders.REQUESTS_REMAINING_HEADER.getName(), "999");
+ httpHeaders.set(OpenAiApiResponseHeaders.REQUESTS_RESET_HEADER.getName(), "2d16h15m29s");
+ httpHeaders.set(OpenAiApiResponseHeaders.TOKENS_LIMIT_HEADER.getName(), "725000");
+ httpHeaders.set(OpenAiApiResponseHeaders.TOKENS_REMAINING_HEADER.getName(), "112358");
+ httpHeaders.set(OpenAiApiResponseHeaders.TOKENS_RESET_HEADER.getName(), "27h55s451ms");
+
+ server.expect(requestTo("/v1/audio/transcriptions"))
+ .andExpect(method(HttpMethod.POST))
+ .andExpect(header(HttpHeaders.AUTHORIZATION, "Bearer " + TEST_API_KEY))
+ .andRespond(withSuccess(getJson(), MediaType.APPLICATION_JSON).headers(httpHeaders));
+
+ }
+
+ private String getJson() {
+ return """
+ {
+ "id": "chatcmpl-123",
+ "object": "chat.completion",
+ "created": 1677652288,
+ "model": "gpt-3.5-turbo-0613",
+ "choices": [{
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "I surrender!"
+ },
+ "finish_reason": "stop"
+ }],
+ "usage": {
+ "prompt_tokens": 9,
+ "completion_tokens": 12,
+ "total_tokens": 21
+ }
+ }
+ """;
+ }
+
+ @SpringBootConfiguration
+ static class Config {
+
+ @Bean
+ public OpenAiAudioApi chatCompletionApi(RestClient.Builder builder) {
+ return new OpenAiAudioApi("", TEST_API_KEY, builder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
+ }
+
+ @Bean
+ public OpenAiAudioTranscriptionClient openAiClient(OpenAiAudioApi openAiAudioApi) {
+ return new OpenAiAudioTranscriptionClient(openAiAudioApi);
+ }
+
+ }
+
+}
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/TranscriptionClientTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/TranscriptionClientTests.java
new file mode 100644
index 00000000000..2b4f48e1daa
--- /dev/null
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/TranscriptionClientTests.java
@@ -0,0 +1,85 @@
+/*
+ * 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.openai.audio.transcription;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
+import org.springframework.core.io.Resource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Unit Tests for {@link TranscriptionClient}.
+ *
+ * @author Michael Lavelle
+ */
+class TranscriptionClientTests {
+
+ @Test
+ void transcrbeRequestReturnsResponseCorrectly() {
+
+ Resource mockAudioFile = Mockito.mock(Resource.class);
+
+ OpenAiAudioTranscriptionClient mockClient = Mockito.mock(OpenAiAudioTranscriptionClient.class);
+
+ String mockTranscription = "All your bases are belong to us";
+
+ // Create a mock Transcript
+ AudioTranscription transcript = Mockito.mock(AudioTranscription.class);
+ when(transcript.getOutput()).thenReturn(mockTranscription);
+
+ // Create a mock TranscriptionResponse with the mock Transcript
+ AudioTranscriptionResponse response = Mockito.mock(AudioTranscriptionResponse.class);
+ when(response.getResult()).thenReturn(transcript);
+
+ // Transcript transcript = spy(new Transcript(responseMessage));
+ // TranscriptionResponse response = spy(new
+ // TranscriptionResponse(Collections.singletonList(transcript)));
+
+ doCallRealMethod().when(mockClient).call(any(Resource.class));
+
+ doAnswer(invocationOnMock -> {
+
+ AudioTranscriptionPrompt transcriptionRequest = invocationOnMock.getArgument(0);
+
+ assertThat(transcriptionRequest).isNotNull();
+ assertThat(transcriptionRequest.getInstructions()).isEqualTo(mockAudioFile);
+
+ return response;
+
+ }).when(mockClient).call(any(AudioTranscriptionPrompt.class));
+
+ assertThat(mockClient.call(mockAudioFile)).isEqualTo(mockTranscription);
+
+ verify(mockClient, times(1)).call(eq(mockAudioFile));
+ verify(mockClient, times(1)).call(isA(AudioTranscriptionPrompt.class));
+ verify(response, times(1)).getResult();
+ verify(transcript, times(1)).getOutput();
+ verifyNoMoreInteractions(mockClient, transcript, response);
+ }
+
+}
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/ActorsFilms.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/ActorsFilms.java
index 5c4491d4271..80320186df0 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/ActorsFilms.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/ActorsFilms.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.chat;
import java.util.List;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClient2IT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClient2IT.java
index 44ae97637c9..fc5904be1db 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClient2IT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClient2IT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.chat;
import com.fasterxml.jackson.core.JacksonException;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientIT.java
index a52de3726ac..b23af540b34 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.chat;
import java.util.ArrayList;
@@ -10,6 +25,7 @@
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
@@ -22,7 +38,8 @@
import org.springframework.ai.model.function.FunctionCallbackWrapper;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.OpenAiTestConfiguration;
-import org.springframework.ai.openai.chat.api.tool.MockWeatherService;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.ai.openai.api.tool.MockWeatherService;
import org.springframework.ai.openai.testutils.AbstractIT;
import org.springframework.ai.parser.BeanOutputParser;
import org.springframework.ai.parser.ListOutputParser;
@@ -172,7 +189,7 @@ void functionCallTest() {
List messages = new ArrayList<>(List.of(userMessage));
var promptOptions = OpenAiChatOptions.builder()
- .withModel("gpt-4-turbo-preview")
+ .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
.withName("getCurrentWeather")
.withDescription("Get the weather in location")
@@ -189,4 +206,37 @@ void functionCallTest() {
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("15.0", "15");
}
-}
+ @Test
+ void streamFunctionCallTest() {
+
+ UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
+
+ List messages = new ArrayList<>(List.of(userMessage));
+
+ var promptOptions = OpenAiChatOptions.builder()
+ // .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
+ .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
+ .withName("getCurrentWeather")
+ .withDescription("Get the weather in location")
+ .withResponseConverter((response) -> "" + response.temp() + response.unit())
+ .build()))
+ .build();
+
+ Flux response = openStreamingChatClient.stream(new Prompt(messages, promptOptions));
+
+ String content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("30.0", "30");
+ assertThat(content).containsAnyOf("10.0", "10");
+ assertThat(content).containsAnyOf("15.0", "15");
+ }
+
+}
\ No newline at end of file
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientWithChatResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientWithChatResponseMetadataTests.java
index 4d34cfbd3bc..10aac11a7a7 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientWithChatResponseMetadataTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatClientWithChatResponseMetadataTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.chat;
import java.time.Duration;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java
new file mode 100644
index 00000000000..dcf0f303ff0
--- /dev/null
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiRetryTests.java
@@ -0,0 +1,272 @@
+/*
+ * 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.openai.chat;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Flux;
+
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.document.MetadataMode;
+import org.springframework.ai.image.ImageMessage;
+import org.springframework.ai.image.ImagePrompt;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
+import org.springframework.ai.openai.OpenAiChatClient;
+import org.springframework.ai.openai.OpenAiChatOptions;
+import org.springframework.ai.openai.OpenAiEmbeddingClient;
+import org.springframework.ai.openai.OpenAiEmbeddingOptions;
+import org.springframework.ai.openai.OpenAiImageClient;
+import org.springframework.ai.openai.OpenAiImageOptions;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionFinishReason;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.Role;
+import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest;
+import org.springframework.ai.openai.api.OpenAiApi.Embedding;
+import org.springframework.ai.openai.api.OpenAiApi.EmbeddingList;
+import org.springframework.ai.openai.api.OpenAiApi.EmbeddingRequest;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.ai.openai.api.OpenAiAudioApi.StructuredResponse;
+import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptResponseFormat;
+import org.springframework.ai.openai.api.OpenAiAudioApi.TranscriptionRequest;
+import org.springframework.ai.openai.api.OpenAiImageApi;
+import org.springframework.ai.openai.api.OpenAiImageApi.Data;
+import org.springframework.ai.openai.api.OpenAiImageApi.OpenAiImageRequest;
+import org.springframework.ai.openai.api.OpenAiImageApi.OpenAiImageResponse;
+import org.springframework.ai.openai.audio.transcription.AudioTranscriptionPrompt;
+import org.springframework.ai.openai.audio.transcription.AudioTranscriptionResponse;
+import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.retry.TransientAiException;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.RetryListener;
+import org.springframework.retry.support.RetryTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Christian Tzolov
+ */
+@SuppressWarnings("unchecked")
+@ExtendWith(MockitoExtension.class)
+public class OpenAiRetryTests {
+
+ private class TestRetryListener implements RetryListener {
+
+ int onErrorRetryCount = 0;
+
+ int onSuccessRetryCount = 0;
+
+ @Override
+ public void onSuccess(RetryContext context, RetryCallback callback, T result) {
+ onSuccessRetryCount = context.getRetryCount();
+ }
+
+ @Override
+ public void onError(RetryContext context, RetryCallback callback,
+ Throwable throwable) {
+ onErrorRetryCount = context.getRetryCount();
+ }
+
+ }
+
+ private TestRetryListener retryListener;
+
+ private RetryTemplate retryTemplate;
+
+ private @Mock OpenAiApi openAiApi;
+
+ private @Mock OpenAiAudioApi openAiAudioApi;
+
+ private @Mock OpenAiImageApi openAiImageApi;
+
+ private OpenAiChatClient chatClient;
+
+ private OpenAiEmbeddingClient embeddingClient;
+
+ private OpenAiAudioTranscriptionClient audioTranscriptionClient;
+
+ private OpenAiImageClient imageClient;
+
+ @BeforeEach
+ public void beforeEach() {
+ retryTemplate = RetryUtils.DEFAULT_RETRY_TEMPLATE;
+ retryListener = new TestRetryListener();
+ retryTemplate.registerListener(retryListener);
+
+ chatClient = new OpenAiChatClient(openAiApi, OpenAiChatOptions.builder().build(), null, retryTemplate);
+ embeddingClient = new OpenAiEmbeddingClient(openAiApi, MetadataMode.EMBED,
+ OpenAiEmbeddingOptions.builder().build(), retryTemplate);
+ audioTranscriptionClient = new OpenAiAudioTranscriptionClient(openAiAudioApi,
+ OpenAiAudioTranscriptionOptions.builder()
+ .withModel("model")
+ .withResponseFormat(TranscriptResponseFormat.JSON)
+ .build(),
+ retryTemplate);
+ imageClient = new OpenAiImageClient(openAiImageApi, OpenAiImageOptions.builder().build(), retryTemplate);
+ }
+
+ @Test
+ public void openAiChatTransientError() {
+
+ var choice = new ChatCompletion.Choice(ChatCompletionFinishReason.STOP, 0,
+ new ChatCompletionMessage("Response", Role.ASSISTANT), null);
+ ChatCompletion expectedChatCompletion = new ChatCompletion("id", List.of(choice), 666l, "model", null, null,
+ new OpenAiApi.Usage(10, 10, 10));
+
+ when(openAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedChatCompletion)));
+
+ var result = chatClient.call(new Prompt("text"));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput().getContent()).isSameAs("Response");
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void openAiChatNonTransientError() {
+ when(openAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> chatClient.call(new Prompt("text")));
+ }
+
+ @Test
+ public void openAiChatStreamTransientError() {
+
+ var choice = new ChatCompletionChunk.ChunkChoice(ChatCompletionFinishReason.STOP, 0,
+ new ChatCompletionMessage("Response", Role.ASSISTANT), null);
+ ChatCompletionChunk expectedChatCompletion = new ChatCompletionChunk("id", List.of(choice), 666l, "model", null,
+ null);
+
+ when(openAiApi.chatCompletionStream(isA(ChatCompletionRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(Flux.just(expectedChatCompletion));
+
+ var result = chatClient.stream(new Prompt("text"));
+
+ assertThat(result).isNotNull();
+ assertThat(result.collectList().block().get(0).getResult().getOutput().getContent()).isSameAs("Response");
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void openAiChatStreamNonTransientError() {
+ when(openAiApi.chatCompletionStream(isA(ChatCompletionRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> chatClient.stream(new Prompt("text")));
+ }
+
+ @Test
+ public void openAiEmbeddingTransientError() {
+
+ EmbeddingList expectedEmbeddings = new EmbeddingList<>("list",
+ List.of(new Embedding(0, List.of(9.9, 8.8))), "model", new OpenAiApi.Usage(10, 10, 10));
+
+ when(openAiApi.embeddings(isA(EmbeddingRequest.class))).thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedEmbeddings)));
+
+ var result = embeddingClient
+ .call(new org.springframework.ai.embedding.EmbeddingRequest(List.of("text1", "text2"), null));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput()).isEqualTo(List.of(9.9, 8.8));
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void openAiEmbeddingNonTransientError() {
+ when(openAiApi.embeddings(isA(EmbeddingRequest.class)))
+ .thenThrow(new RuntimeException("Non Transient Error"));
+ assertThrows(RuntimeException.class, () -> embeddingClient
+ .call(new org.springframework.ai.embedding.EmbeddingRequest(List.of("text1", "text2"), null)));
+ }
+
+ @Test
+ public void openAiAudioTranscriptionTransientError() {
+
+ var expectedResponse = new StructuredResponse("nl", 6.7f, "Transcription Text", List.of(), List.of());
+
+ when(openAiAudioApi.createTranscription(isA(TranscriptionRequest.class), isA(Class.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedResponse)));
+
+ AudioTranscriptionResponse result = audioTranscriptionClient
+ .call(new AudioTranscriptionPrompt(new ClassPathResource("speech/jfk.flac")));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput()).isEqualTo(expectedResponse.text());
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void openAiAudioTranscriptionNonTransientError() {
+ when(openAiAudioApi.createTranscription(isA(TranscriptionRequest.class), isA(Class.class)))
+ .thenThrow(new RuntimeException("Transient Error 1"));
+ assertThrows(RuntimeException.class, () -> audioTranscriptionClient
+ .call(new AudioTranscriptionPrompt(new ClassPathResource("speech/jfk.flac"))));
+ }
+
+ @Test
+ public void openAiImageTransientError() {
+
+ var expectedResponse = new OpenAiImageResponse(678l, List.of(new Data("url678", "b64", "prompt")));
+
+ when(openAiImageApi.createImage(isA(OpenAiImageRequest.class)))
+ .thenThrow(new TransientAiException("Transient Error 1"))
+ .thenThrow(new TransientAiException("Transient Error 2"))
+ .thenReturn(ResponseEntity.of(Optional.of(expectedResponse)));
+
+ var result = imageClient.call(new ImagePrompt(List.of(new ImageMessage("Image Message"))));
+
+ assertThat(result).isNotNull();
+ assertThat(result.getResult().getOutput().getUrl()).isEqualTo("url678");
+ assertThat(retryListener.onSuccessRetryCount).isEqualTo(2);
+ assertThat(retryListener.onErrorRetryCount).isEqualTo(2);
+ }
+
+ @Test
+ public void openAiImageNonTransientError() {
+ when(openAiImageApi.createImage(isA(OpenAiImageRequest.class)))
+ .thenThrow(new RuntimeException("Transient Error 1"));
+ assertThrows(RuntimeException.class,
+ () -> imageClient.call(new ImagePrompt(List.of(new ImageMessage("Image Message")))));
+ }
+
+}
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/EmbeddingIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/EmbeddingIT.java
index 17429c479d6..683f54b4826 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/EmbeddingIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/embedding/EmbeddingIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientIT.java
index 7cf49e8fc9f..1a36b449a78 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientIT.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,
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientWithImageResponseMetadataTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientWithImageResponseMetadataTests.java
index 5f660a1f8b0..cea0cbc2e9a 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientWithImageResponseMetadataTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/image/OpenAiImageClientWithImageResponseMetadataTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.image;
import org.junit.jupiter.api.AfterEach;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractorTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractorTests.java
index f268f9d6e5c..050b05a530d 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractorTests.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractorTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.metadata.support;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/testutils/AbstractIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/testutils/AbstractIT.java
index 2e878f802b7..b8e1c86a27e 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/testutils/AbstractIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/testutils/AbstractIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.testutils;
import java.util.List;
@@ -14,6 +29,7 @@
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.image.ImageClient;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
@@ -28,6 +44,9 @@ public abstract class AbstractIT {
@Autowired
protected ChatClient openAiChatClient;
+ @Autowired
+ protected OpenAiAudioTranscriptionClient openAiTranscriptionClient;
+
@Autowired
protected ImageClient openaiImageClient;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java
index 4f655320615..d13c06612bb 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/transformer/MetadataTransformerIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.openai.transformer;
import java.io.IOException;
diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/vectorstore/SimplePersistentVectorStoreIT.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/vectorstore/SimplePersistentVectorStoreIT.java
index af73b4e08b8..169d6e53d3a 100644
--- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/vectorstore/SimplePersistentVectorStoreIT.java
+++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/vectorstore/SimplePersistentVectorStoreIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.openai.vectorstore;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-openai/src/test/resources/speech/jfk.flac b/models/spring-ai-openai/src/test/resources/speech/jfk.flac
new file mode 100644
index 00000000000..e44b7c13897
Binary files /dev/null and b/models/spring-ai-openai/src/test/resources/speech/jfk.flac differ
diff --git a/models/spring-ai-postgresml/pom.xml b/models/spring-ai-postgresml/pom.xml
index 672e19620f8..78ed1e8f2cb 100644
--- a/models/spring-ai-postgresml/pom.xml
+++ b/models/spring-ai-postgresml/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-postgresml
diff --git a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClient.java b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClient.java
index 9513577c6b7..677a7fba4ee 100644
--- a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClient.java
+++ b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java
index 129692730ea..b80e1f639b7 100644
--- a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java
+++ b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.postgresml;
import java.util.Map;
diff --git a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClientIT.java b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClientIT.java
index d68f526946d..7a4539e0e4e 100644
--- a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClientIT.java
+++ b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingClientIT.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,
diff --git a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java
index 62d9edeb6a0..aeceb5c5805 100644
--- a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java
+++ b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.postgresml;
import java.util.Map;
diff --git a/models/spring-ai-stabilityai/pom.xml b/models/spring-ai-stability-ai/pom.xml
similarity index 90%
rename from models/spring-ai-stabilityai/pom.xml
rename to models/spring-ai-stability-ai/pom.xml
index b14b51a17ec..4cac3ac2027 100644
--- a/models/spring-ai-stabilityai/pom.xml
+++ b/models/spring-ai-stability-ai/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-stability-ai
@@ -30,12 +30,11 @@
- org.springframework
- spring-web
- ${spring-framework.version}
+ org.springframework.ai
+ spring-ai-retry
+ ${project.parent.version}
-
org.springframework
diff --git a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java
similarity index 90%
rename from models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java
rename to models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java
index bd07d312af4..e632e5235b5 100644
--- a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java
+++ b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -15,17 +15,24 @@
*/
package org.springframework.ai.stabilityai;
+import java.util.List;
+import java.util.stream.Collectors;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.ai.image.*;
+
+import org.springframework.ai.image.Image;
+import org.springframework.ai.image.ImageClient;
+import org.springframework.ai.image.ImageGeneration;
+import org.springframework.ai.image.ImageOptions;
+import org.springframework.ai.image.ImagePrompt;
+import org.springframework.ai.image.ImageResponse;
+import org.springframework.ai.image.ImageResponseMetadata;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.stabilityai.api.StabilityAiApi;
import org.springframework.ai.stabilityai.api.StabilityAiImageOptions;
import org.springframework.util.Assert;
-import java.util.List;
-import java.util.stream.Collectors;
-
/**
* StabilityAiImageClient is a class that implements the ImageClient interface. It
* provides a client for calling the StabilityAI image generation API.
@@ -50,7 +57,7 @@ public StabilityAiImageClient(StabilityAiApi stabilityAiApi, StabilityAiImageOpt
}
public StabilityAiImageOptions getOptions() {
- return options;
+ return this.options;
}
/**
@@ -159,17 +166,4 @@ private StabilityAiImageOptions convertOptions(ImageOptions runtimeOptions) {
return builder.build();
}
- private ImagePrompt createUpdatedPrompt(ImagePrompt prompt) {
- ImageOptions runtimeImageModelOptions = prompt.getOptions();
- ImageOptionsBuilder imageOptionsBuilder = ImageOptionsBuilder.builder();
-
- if (runtimeImageModelOptions != null) {
- if (runtimeImageModelOptions.getModel() != null) {
- imageOptionsBuilder.withModel(runtimeImageModelOptions.getModel());
- }
- }
- ImageOptions updatedImageModelOptions = imageOptionsBuilder.build();
- return new ImagePrompt(prompt.getInstructions(), updatedImageModelOptions);
- }
-
}
diff --git a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java
similarity index 79%
rename from models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java
rename to models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java
index 2c0fac55a38..648dae1a5d9 100644
--- a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java
+++ b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StabilityAiImageGenerationMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
@@ -35,16 +35,17 @@ public StabilityAiImageGenerationMetadata(String finishReason, Long seed) {
}
public String getFinishReason() {
- return finishReason;
+ return this.finishReason;
}
public Long getSeed() {
- return seed;
+ return this.seed;
}
@Override
public String toString() {
- return "StabilityAiImageGenerationMetadata{" + "finishReason='" + finishReason + '\'' + ", seed=" + seed + '}';
+ return "StabilityAiImageGenerationMetadata{" + "finishReason='" + this.finishReason + '\'' + ", seed="
+ + this.seed + '}';
}
@Override
@@ -53,12 +54,12 @@ public boolean equals(Object o) {
return true;
if (!(o instanceof StabilityAiImageGenerationMetadata that))
return false;
- return Objects.equals(finishReason, that.finishReason) && Objects.equals(seed, that.seed);
+ return Objects.equals(this.finishReason, that.finishReason) && Objects.equals(this.seed, that.seed);
}
@Override
public int hashCode() {
- return Objects.hash(finishReason, seed);
+ return Objects.hash(this.finishReason, this.seed);
}
}
diff --git a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java
similarity index 59%
rename from models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java
rename to models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java
index d8f194ac2c5..e1d7c9efa5a 100644
--- a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java
+++ b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/StyleEnum.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
@@ -20,11 +20,25 @@
*/
public enum StyleEnum {
- THREE_D_MODEL("3d-model"), ANALOG_FILM("analog-film"), ANIME("anime"), CINEMATIC("cinematic"),
- COMIC_BOOK("comic-book"), DIGITAL_ART("digital-art"), ENHANCE("enhance"), FANTASY_ART("fantasy-art"),
- ISOMETRIC("isometric"), LINE_ART("line-art"), LOW_POLY("low-poly"), MODELING_COMPOUND("modeling-compound"),
- NEON_PUNK("neon-punk"), ORIGAMI("origami"), PHOTOGRAPHIC("photographic"), PIXEL_ART("pixel-art"),
+ // @formatter:off
+ THREE_D_MODEL("3d-model"),
+ ANALOG_FILM("analog-film"),
+ ANIME("anime"),
+ CINEMATIC("cinematic"),
+ COMIC_BOOK("comic-book"),
+ DIGITAL_ART("digital-art"),
+ ENHANCE("enhance"),
+ FANTASY_ART("fantasy-art"),
+ ISOMETRIC("isometric"),
+ LINE_ART("line-art"),
+ LOW_POLY("low-poly"),
+ MODELING_COMPOUND("modeling-compound"),
+ NEON_PUNK("neon-punk"),
+ ORIGAMI("origami"),
+ PHOTOGRAPHIC("photographic"),
+ PIXEL_ART("pixel-art"),
TILE_TEXTURE("tile-texture");
+ // @formatter:on
private final String text;
diff --git a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java
similarity index 83%
rename from models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java
rename to models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java
index c4913ccbe49..2ee5b2f7f24 100644
--- a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java
+++ b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
@@ -15,20 +15,18 @@
*/
package org.springframework.ai.stabilityai.api;
+import java.util.List;
+import java.util.function.Consumer;
+
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.springframework.ai.retry.RetryUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
-import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
-import java.io.IOException;
-import java.util.List;
-import java.util.function.Consumer;
-
/**
* Represents the StabilityAI API.
*/
@@ -80,35 +78,12 @@ public StabilityAiApi(String apiKey, String model, String baseUrl, RestClient.Bu
headers.setContentType(MediaType.APPLICATION_JSON);
};
- ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
- @Override
- public boolean hasError(ClientHttpResponse response) throws IOException {
- return response.getStatusCode().isError();
- }
-
- @Override
- public void handleError(ClientHttpResponse response) throws IOException {
- if (response.getStatusCode().isError()) {
- throw new RuntimeException(String.format("%s - %s", response.getStatusCode().value(),
- new ObjectMapper().readValue(response.getBody(), ResponseError.class)));
- }
- }
- };
-
this.restClient = restClientBuilder.baseUrl(baseUrl)
.defaultHeaders(jsonContentHeaders)
- .defaultStatusHandler(responseErrorHandler)
+ .defaultStatusHandler(RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER)
.build();
}
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public record ResponseError(@JsonProperty("id") String id, @JsonProperty("name") String name,
- @JsonProperty("message") String message
-
- ) {
-
- }
-
@JsonInclude(JsonInclude.Include.NON_NULL)
public record GenerateImageRequest(@JsonProperty("text_prompts") List textPrompts,
@JsonProperty("height") Integer height, @JsonProperty("width") Integer width,
diff --git a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java
similarity index 99%
rename from models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java
rename to models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java
index 288cae142a3..3e32017c504 100644
--- a/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java
+++ b/models/spring-ai-stability-ai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java
similarity index 96%
rename from models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java
rename to models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java
index 2e8c2454db3..0b0c49ee749 100644
--- a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java
+++ b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java
similarity index 95%
rename from models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java
rename to models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java
index b7708ccf42b..1148cd6a973 100644
--- a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java
+++ b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageClientIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java
similarity index 92%
rename from models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java
rename to models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java
index 268b184f35c..394d384ff6d 100644
--- a/models/spring-ai-stabilityai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java
+++ b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageTestConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/models/spring-ai-transformers/pom.xml b/models/spring-ai-transformers/pom.xml
index 9c6c8b95544..fdc8f69035a 100644
--- a/models/spring-ai-transformers/pom.xml
+++ b/models/spring-ai-transformers/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-transformers
diff --git a/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java b/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java
index 094dd2438e0..8fa20b199a9 100644
--- a/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java
+++ b/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformers;
import java.io.File;
diff --git a/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/TransformersEmbeddingClient.java b/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/TransformersEmbeddingClient.java
index 954130d9390..d5b1d1933f0 100644
--- a/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/TransformersEmbeddingClient.java
+++ b/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/TransformersEmbeddingClient.java
@@ -1,3 +1,18 @@
+/*
+ * 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.transformers;
import java.nio.FloatBuffer;
diff --git a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/ResourceCacheServiceTests.java b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/ResourceCacheServiceTests.java
index 61521af071c..a8da322227a 100644
--- a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/ResourceCacheServiceTests.java
+++ b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/ResourceCacheServiceTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformers;
import java.io.File;
diff --git a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/TransformersEmbeddingClientTests.java b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/TransformersEmbeddingClientTests.java
index e895bb8f183..d2526bbe8d2 100644
--- a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/TransformersEmbeddingClientTests.java
+++ b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/TransformersEmbeddingClientTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformers;
import java.text.DecimalFormat;
diff --git a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/samples/ONNXSample.java b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/samples/ONNXSample.java
index 887f3fe9d46..be37188b3ff 100644
--- a/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/samples/ONNXSample.java
+++ b/models/spring-ai-transformers/src/test/java/org/springframework/ai/transformers/samples/ONNXSample.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformers.samples;
import java.nio.FloatBuffer;
diff --git a/models/spring-ai-transformers/src/test/resources/Test.py b/models/spring-ai-transformers/src/test/resources/Test.py
index b1403f5949b..2eb6c88aef6 100644
--- a/models/spring-ai-transformers/src/test/resources/Test.py
+++ b/models/spring-ai-transformers/src/test/resources/Test.py
@@ -1,3 +1,19 @@
+#
+# 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.
+#
+
from transformers import AutoTokenizer, AutoModel
import torch
diff --git a/models/spring-ai-vertex-ai-gemini/pom.xml b/models/spring-ai-vertex-ai-gemini/pom.xml
index a64b15303d6..de9f4b3e07b 100644
--- a/models/spring-ai-vertex-ai-gemini/pom.xml
+++ b/models/spring-ai-vertex-ai-gemini/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-vertex-ai-gemini
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/MimeTypeDetector.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/MimeTypeDetector.java
index 5ed35d707a2..c1d7c34bb5d 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/MimeTypeDetector.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/MimeTypeDetector.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini;
import java.io.File;
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java
index 30c3827d4b9..1641bc9ac91 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClient.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini;
import java.util.ArrayList;
@@ -294,7 +293,7 @@ private List toGeminiContent(Prompt prompt) {
.stream()
.filter(m -> m.getMessageType() == MessageType.SYSTEM)
.map(m -> m.getContent())
- .collect(Collectors.joining("\n"));
+ .collect(Collectors.joining(System.lineSeparator()));
List contents = prompt.getInstructions()
.stream()
@@ -334,7 +333,7 @@ static List messageToGeminiParts(Message message, String systemContext) {
List parts = new ArrayList<>(List.of(textPart));
- List mediaParts = userMessage.getMediaData()
+ List mediaParts = userMessage.getMedia()
.stream()
.map(mediaData -> PartMaker.fromMimeTypeAndData(mediaData.getMimeType().toString(),
mediaData.getData()))
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java
index 2c78be4ce1b..3e7e6fe5e93 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini;
import java.util.ArrayList;
@@ -190,7 +189,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -200,7 +198,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -215,7 +212,6 @@ public void setTopK(Float topK) {
this.topK = topK;
}
- @Override
@JsonIgnore
public void setTopK(Integer topK) {
this.topK = (topK != null) ? topK.floatValue() : null;
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHints.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHints.java
index fd69891ec73..8911288fab1 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHints.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHints.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,
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiChatResponseMetadata.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiChatResponseMetadata.java
index 9adcf604dc1..bc62a5d2e65 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiChatResponseMetadata.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiChatResponseMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini.metadata;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiUsage.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiUsage.java
index d989a9e5d64..a250b98e0c1 100644
--- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiUsage.java
+++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/metadata/VertexAiUsage.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini.metadata;
import com.google.cloud.vertexai.api.GenerateContentResponse.UsageMetadata;
diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.java
index 464ab8fd794..8860dc9f9bb 100644
--- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.java
+++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini;
import java.io.IOException;
@@ -29,7 +28,7 @@
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.messages.AssistantMessage;
-import org.springframework.ai.chat.messages.MediaData;
+import org.springframework.ai.chat.messages.Media;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -190,7 +189,7 @@ void multiModalityTest() throws IOException {
byte[] data = new ClassPathResource("/vertex.test.png").getContentAsByteArray();
var userMessage = new UserMessage("Explain what do you see o this picture?",
- List.of(new MediaData(MimeTypeUtils.IMAGE_PNG, data)));
+ List.of(new Media(MimeTypeUtils.IMAGE_PNG, data)));
ChatResponse response = client.call(new Prompt(List.of(userMessage)));
@@ -209,7 +208,7 @@ void multiModalityTest() throws IOException {
// "https://storage.googleapis.com/github-repo/img/gemini/multimodality_usecases_overview/banana-apple.jpg";
// userMessage = new UserMessage("Explain what do you see o this picture?",
- // List.of(new MediaData(MimeTypeDetector.getMimeType(imageUrl), imageUrl)));
+ // List.of(new Media(MimeTypeDetector.getMimeType(imageUrl), imageUrl)));
// response = client.call(new Prompt(List.of(userMessage)));
// assertThat(response.getResult().getOutput().getContent()).contains("bananas",
diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHintsTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHintsTests.java
index 8f84bccd987..2e3f12f12a4 100644
--- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHintsTests.java
+++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/aot/VertexAiGeminiRuntimeHintsTests.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,
diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/MockWeatherService.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/MockWeatherService.java
index b022b8d16ae..a77a8f86a91 100644
--- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/MockWeatherService.java
+++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini.function;
import java.util.function.Function;
diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java
index 3a7e15d0c16..5d7083d790e 100644
--- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.java
+++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatClientFunctionCallingIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.gemini.function;
import java.util.ArrayList;
diff --git a/models/spring-ai-vertex-ai-palm2/README.md b/models/spring-ai-vertex-ai-palm2/README.md
index 33a47804844..ec6eaf6f8f6 100644
--- a/models/spring-ai-vertex-ai-palm2/README.md
+++ b/models/spring-ai-vertex-ai-palm2/README.md
@@ -1,4 +1,4 @@
-[VertexAI PaLM2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/clients/vertexai-chat.html)
+[VertexAI PaLM2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/vertexai-chat.html)
[VertexAI PaLM2 Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/vertexai-embeddings.html)
diff --git a/models/spring-ai-vertex-ai-palm2/pom.xml b/models/spring-ai-vertex-ai-palm2/pom.xml
index adb6d3ad568..bca1c55ffe2 100644
--- a/models/spring-ai-vertex-ai-palm2/pom.xml
+++ b/models/spring-ai-vertex-ai-palm2/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-vertex-ai-palm2
diff --git a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatClient.java b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatClient.java
index d29dcecfb05..67109761595 100644
--- a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatClient.java
+++ b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2;
import java.util.List;
@@ -79,7 +78,7 @@ GenerateMessageRequest createRequest(Prompt prompt) {
.stream()
.filter(m -> m.getMessageType() == MessageType.SYSTEM)
.map(m -> m.getContent())
- .collect(Collectors.joining("\n"));
+ .collect(Collectors.joining(System.lineSeparator()));
List vertexMessages = prompt.getInstructions()
.stream()
diff --git a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatOptions.java b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatOptions.java
index 2683a0152b3..cae09e7bbc8 100644
--- a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatOptions.java
+++ b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -98,7 +97,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -116,7 +114,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -126,7 +123,6 @@ public Integer getTopK() {
return this.topK;
}
- @Override
public void setTopK(Integer topK) {
this.topK = topK;
}
diff --git a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClient.java b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClient.java
index e66f783104d..b864c8b4cf5 100644
--- a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClient.java
+++ b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2;
import java.util.List;
diff --git a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHints.java b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHints.java
index 3514016cd56..65a8952c643 100644
--- a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHints.java
+++ b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2023 - 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.ai.vertexai.palm2.aot;
import org.springframework.ai.vertexai.palm2.api.VertexAiPaLm2Api;
diff --git a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2Api.java b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2Api.java
index d8454fc816f..94e7c329580 100644
--- a/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2Api.java
+++ b/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2Api.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2.api;
import java.io.IOException;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatGenerationClientIT.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatGenerationClientIT.java
index 27be2a2d1f9..b661332679d 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatGenerationClientIT.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatGenerationClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2023 - 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.ai.vertexai.palm2;
import java.util.Arrays;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatRequestTests.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatRequestTests.java
index 6589cafa342..6c5478f6752 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatRequestTests.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatRequestTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClientIT.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClientIT.java
index 738e884eefa..6014d5b0ea7 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClientIT.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2EmbeddingClientIT.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2023 - 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.ai.vertexai.palm2;
import java.util.List;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHintsTests.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHintsTests.java
index 67d6628dbb3..5ed21d4649b 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHintsTests.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/aot/VertexRuntimeHintsTests.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2023 - 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.ai.vertexai.palm2.aot;
import org.junit.jupiter.api.Test;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiIT.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiIT.java
index efe7be56567..d820d49521a 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiIT.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2.api;
import java.util.List;
diff --git a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiTests.java b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiTests.java
index efe83d53852..aedce410cdc 100644
--- a/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiTests.java
+++ b/models/spring-ai-vertex-ai-palm2/src/test/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2ApiTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vertexai.palm2.api;
import java.util.List;
diff --git a/pom.xml b/pom.xml
index 5a43bb1f031..1e57a8dd685 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOTpomhttps://github.com/spring-projects/spring-ai
@@ -22,7 +22,7 @@
models/spring-ai-huggingfacemodels/spring-ai-ollamamodels/spring-ai-openai
- models/spring-ai-stabilityai
+ models/spring-ai-stability-aimodels/spring-ai-mistral-aimodels/spring-ai-vertex-ai-palm2models/spring-ai-vertex-ai-gemini
@@ -59,6 +59,8 @@
vector-stores/spring-ai-qdrantspring-ai-spring-boot-starters/spring-ai-starter-bedrock-aispring-ai-spring-boot-starters/spring-ai-starter-mistral-ai
+ spring-ai-retry
+ vector-stores/spring-ai-elasticsearch-store
@@ -106,15 +108,16 @@
3.2.36.1.44.0.2
- 1.0.0-beta.6
+ 1.0.0-beta.71.0.04.31.12.24.82.16.10.26.01.17.0
- 26.33.0
+ 26.34.01.7.1
+ 2.0.53.25.2
@@ -242,7 +245,7 @@
ossrhremove
- resolve
+ removeremovekeepkeep
@@ -268,6 +271,83 @@
+
+ license
+
+ false
+
+
+
+
+ com.mycila
+ license-maven-plugin
+ 4.1
+
+
+ validate
+
+ check
+
+
+
+
+
+ the original author or authors.
+
+ 2024
+
+
+
+
+
+Copyright 2023 - ${year} 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.
+
+
+
+ **/.antlr/**
+ **/aot.factories
+ **/.sdkmanrc
+ **/*.adoc
+ **/*.puml
+ **/pom.xml
+ **/*.properties
+ **/*.yaml
+ **/*.yml
+ **/*.map
+ **/*.html
+ **/*.xhtml
+ **/*.jsp
+ **/*.js
+ **/*.css
+ **/*.txt
+ **/*.xjb
+ **/*.ftl
+ **/*.xsd
+ **/*.xml
+ **/*.sh
+ **/generated/**
+ **/Dockerfile
+
+
+
+
+
+
+
+
+ javadoc
diff --git a/spring-ai-bom/pom.xml b/spring-ai-bom/pom.xml
index de05f143b1d..c2a2e00e055 100644
--- a/spring-ai-bom/pom.xml
+++ b/spring-ai-bom/pom.xml
@@ -1,34 +1,41 @@
- 4.0.0
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
-
- org.springframework.ai
- spring-ai
- 0.8.1-SNAPSHOT
-
+
+ org.springframework.ai
+ spring-ai
+ 1.0.0-SNAPSHOT
+
- spring-ai-bom
- pom
+ spring-ai-bom
+ pom
- Spring AI BOM
- Bill of Materials POM (BOM) for the Spring AI modules
+ Spring AI BOM
+ Bill of Materials POM (BOM) for the Spring AI modules
- https://github.com/spring-projects/spring-ai
+ https://github.com/spring-projects/spring-ai
-
- https://github.com/spring-projects/spring-ai
- git://github.com/spring-projects/spring-ai.git
- git@github.com:spring-projects/spring-ai.git
-
+
+ https://github.com/spring-projects/spring-ai
+ git://github.com/spring-projects/spring-ai.git
+ git@github.com:spring-projects/spring-ai.git
+
-
-
+
+
+
+
+ org.springframework.ai
+ spring-ai-core
+ ${project.version}
+ org.springframework.ai
- spring-ai-core
+ spring-ai-retry${project.version}
@@ -39,262 +46,306 @@
${project.version}
-
- org.springframework.ai
- spring-ai-tika-document-reader
- ${project.version}
-
-
-
-
- org.springframework.ai
- spring-ai-azure-openai
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-bedrock
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-huggingface
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-ollama
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-openai
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-postgresml
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-stability-ai
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-transformers
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-vertex-ai-palm2
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-vertex-ai-gemini
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-mistral-ai
- ${project.version}
-
-
-
-
- org.springframework.ai
- spring-ai-azure-vector-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-chroma-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-milvus-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-neo4j-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-pgvector-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-pinecone
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-redis
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-weaviate-store
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-qdrant
- ${project.version}
-
-
-
-
- org.springframework.ai
- spring-ai-test
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-spring-boot-autoconfigure
- ${project.version}
-
-
-
-
- org.springframework.ai
- spring-ai-azure-openai-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-azure-vector-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-bedrock-ai-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-chroma-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-milvus-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-neo4j-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-ollama-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-openai-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-pgvector-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-pinecone-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-postgresml-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-redis-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-stability-ai-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-transformers-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-vertex-ai-palm2-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-vertex-ai-gemini-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-weaviate-store-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-mistral-ai-spring-boot-starter
- ${project.version}
-
-
-
- org.springframework.ai
- spring-ai-qdrant-store-spring-boot-starter
- ${project.version}
-
-
-
+
+ org.springframework.ai
+ spring-ai-tika-document-reader
+ ${project.version}
+
+
+
+
+ org.springframework.ai
+ spring-ai-azure-openai
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-bedrock
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-huggingface
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-ollama
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-openai
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-postgresml
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-stability-ai
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-transformers
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-vertex-ai-palm2
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-vertex-ai-gemini
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-mistral-ai
+ ${project.version}
+
+
+
+
+ org.springframework.ai
+ spring-ai-azure-vector-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-chroma-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-milvus-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-neo4j-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-pgvector-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-pinecone
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-redis
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-weaviate-store
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-qdrant
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-elasticsearch-store
+ ${project.version}
+
+
+
+
+ org.springframework.ai
+ spring-ai-test
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-spring-boot-autoconfigure
+ ${project.version}
+
+
+
+
+ org.springframework.ai
+ spring-ai-azure-openai-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-azure-vector-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-bedrock-ai-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-chroma-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-milvus-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-neo4j-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-ollama-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-openai-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-pgvector-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-pinecone-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-postgresml-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-redis-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-stability-ai-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-transformers-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-vertex-ai-palm2-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-vertex-ai-gemini-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-weaviate-store-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-mistral-ai-spring-boot-starter
+ ${project.version}
+
+
+
+ org.springframework.ai
+ spring-ai-qdrant-store-spring-boot-starter
+ ${project.version}
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ flatten-maven-plugin
+ ${flatten-maven-plugin.version}
+
+
+ flatten
+ process-resources
+
+ flatten
+
+
+ true
+ ossrh
+
+ remove
+ keep
+ remove
+ keep
+ keep
+ resolve
+
+
+
+
+ clean
+ clean
+
+ clean
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-ai-core/pom.xml b/spring-ai-core/pom.xml
index 4e52278b1ee..ddd220b8b70 100644
--- a/spring-ai-core/pom.xml
+++ b/spring-ai-core/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOTspring-ai-corejar
@@ -93,6 +93,18 @@
${jsonschema.version}
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
org.springframework.boot
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/ResourceUtils.java b/spring-ai-core/src/main/java/org/springframework/ai/ResourceUtils.java
index 2c17f6532d6..5a5440e1626 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/ResourceUtils.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/ResourceUtils.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai;
import java.io.IOException;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/aot/AiRuntimeHints.java b/spring-ai-core/src/main/java/org/springframework/ai/aot/AiRuntimeHints.java
index 64fd546efcf..e2f0d575ca3 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/aot/AiRuntimeHints.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/aot/AiRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.aot;
import com.fasterxml.jackson.annotation.JsonInclude;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/aot/KnuddelsRuntimeHints.java b/spring-ai-core/src/main/java/org/springframework/ai/aot/KnuddelsRuntimeHints.java
index 2c6ee360537..fb676484d94 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/aot/KnuddelsRuntimeHints.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/aot/KnuddelsRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.aot;
import org.springframework.aot.hint.RuntimeHints;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/aot/SpringAiCoreRuntimeHints.java b/spring-ai-core/src/main/java/org/springframework/ai/aot/SpringAiCoreRuntimeHints.java
index ae06b77abc1..ecf2a3fd94e 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/aot/SpringAiCoreRuntimeHints.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/aot/SpringAiCoreRuntimeHints.java
@@ -1,3 +1,18 @@
+/*
+ * 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.aot;
import org.springframework.ai.chat.messages.*;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatClient.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatClient.java
index 423b9a7ba41..6925c16eedb 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat;
import org.springframework.ai.chat.prompt.Prompt;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatResponse.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatResponse.java
index 46a0c9e7680..0d0db865cc2 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatResponse.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatResponse.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/Generation.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/Generation.java
index cc2863c3fae..d3c42750b29 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/Generation.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/Generation.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat;
import java.util.Map;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/StreamingChatClient.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/StreamingChatClient.java
index 018c6d3798d..a6e4a0b7629 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/StreamingChatClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/StreamingChatClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat;
import reactor.core.publisher.Flux;
@@ -24,6 +23,13 @@
@FunctionalInterface
public interface StreamingChatClient extends StreamingModelClient {
+ default Flux stream(String message) {
+ Prompt prompt = new Prompt(message);
+ return stream(prompt).map(response -> (response.getResult() == null || response.getResult().getOutput() == null
+ || response.getResult().getOutput().getContent() == null) ? ""
+ : response.getResult().getOutput().getContent());
+ }
+
@Override
Flux stream(Prompt prompt);
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java
index db96457c0c0..77b54afeae8 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.io.IOException;
@@ -28,13 +27,20 @@
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
+/**
+ * The AbstractMessage class is an abstract implementation of the Message interface. It
+ * provides a base implementation for message content, media attachments, properties, and
+ * message type.
+ *
+ * @see Message
+ */
public abstract class AbstractMessage implements Message {
protected final MessageType messageType;
protected final String textContent;
- protected final List mediaData;
+ protected final List mediaData;
/**
* Additional options for the message to influence the response, not a generative map.
@@ -47,18 +53,17 @@ protected AbstractMessage(MessageType messageType, String content) {
protected AbstractMessage(MessageType messageType, String content, Map messageProperties) {
Assert.notNull(messageType, "Message type must not be null");
- // Assert.notNull(content, "Content must not be null");
this.messageType = messageType;
this.textContent = content;
this.mediaData = new ArrayList<>();
this.properties = messageProperties;
}
- protected AbstractMessage(MessageType messageType, String textContent, List mediaData) {
+ protected AbstractMessage(MessageType messageType, String textContent, List mediaData) {
this(messageType, textContent, mediaData, Map.of());
}
- protected AbstractMessage(MessageType messageType, String textContent, List mediaData,
+ protected AbstractMessage(MessageType messageType, String textContent, List mediaData,
Map messageProperties) {
Assert.notNull(messageType, "Message type must not be null");
@@ -98,7 +103,7 @@ public String getContent() {
}
@Override
- public List getMediaData() {
+ public List getMedia() {
return this.mediaData;
}
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java
index 3e608d9873d..c5f6831abbc 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.util.Map;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java
index 194aa54afaf..ea4803a5943 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.util.Map;
+/**
+ * Represents a chat message in a chat application.
+ *
+ */
public class ChatMessage extends AbstractMessage {
public ChatMessage(String role, String content) {
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java
index 1faba6a7944..06485ac57d6 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,19 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.util.Map;
+/**
+ * The FunctionMessage class represents a message with a function content in a chat
+ * application.
+ */
public class FunctionMessage extends AbstractMessage {
public FunctionMessage(String content) {
- super(MessageType.SYSTEM, content);
+ super(MessageType.FUNCTION, content);
}
public FunctionMessage(String content, Map properties) {
- super(MessageType.SYSTEM, content, properties);
+ super(MessageType.FUNCTION, content, properties);
}
@Override
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MediaData.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Media.java
similarity index 70%
rename from spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MediaData.java
rename to spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Media.java
index 9acd9b15157..ffe37793862 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MediaData.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Media.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,24 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
/**
+ * The Media class represents the data and metadata of a media attachment in a message. It
+ * consists of a MIME type and the raw data.
+ *
+ * This class is used as a parameter in the constructor of the UserMessage class.
+ *
* @author Christian Tzolov
+ * @since 0.8.1
*/
-public class MediaData {
+public class Media {
private final MimeType mimeType;
private final Object data;
- public MediaData(MimeType mimeType, Object data) {
+ public Media(MimeType mimeType, Object data) {
Assert.notNull(mimeType, "MimeType must not be null");
- // Assert.notNull(data, "Data must not be null");
this.mimeType = mimeType;
this.data = data;
}
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Message.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Message.java
index 10c893ad701..77e3b5aba4c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Message.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/Message.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,17 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.util.List;
import java.util.Map;
+/**
+ * The Message interface represents a message that can be sent or received in a chat
+ * application. Messages can have content, media attachments, properties, and message
+ * types.
+ *
+ * @see Media
+ * @see MessageType
+ */
public interface Message {
String getContent();
- List getMediaData();
+ List getMedia();
Map getProperties();
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MessageType.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MessageType.java
index 6cb07a045ba..632b66dc8a0 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MessageType.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/MessageType.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -15,6 +15,10 @@
*/
package org.springframework.ai.chat.messages;
+/**
+ * The MessageType enum represents the type of a message in a chat application. It can be
+ * one of the following: USER, ASSISTANT, SYSTEM, FUNCTION.
+ */
public enum MessageType {
USER("user"),
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java
index de813b219e6..0c0a20e0422 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import org.springframework.core.io.Resource;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/UserMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/UserMessage.java
index 269668cda87..d981a67edec 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/UserMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/messages/UserMessage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.messages;
import java.util.List;
@@ -35,8 +34,8 @@ public UserMessage(Resource resource) {
super(MessageType.USER, resource);
}
- public UserMessage(String textContent, List mediaDataList) {
- super(MessageType.USER, textContent, mediaDataList);
+ public UserMessage(String textContent, List mediaList) {
+ super(MessageType.USER, textContent, mediaList);
}
@Override
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java
index d9f5fc56eb7..50848657d81 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
import org.springframework.ai.model.ResultMetadata;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java
index b4525a6ab4c..e93db06334b 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
import org.springframework.ai.model.ResponseMetadata;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java
index 480a94d3ec0..80eb2462c8c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
import java.time.Duration;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java
index 027e3027939..48cf590e716 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java
index 6ecb0924603..5e716921a0f 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java
index 22dd64b186f..68938021976 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
import java.time.Duration;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/Usage.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/Usage.java
index 0ea42e62412..d2dffc808bb 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/Usage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/metadata/Usage.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.metadata;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/package-info.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/package-info.java
index 98d92eb7127..4c0f6662671 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/package-info.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/package-info.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
/**
* The org.sf.ai.chat package represents the bounded context for the Chat Model within the
* AI generative model domain. This package extends the core domain defined in
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java
index 19da5511c32..8355bc98b4d 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.springframework.ai.chat.messages.Message;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java
index 5d91bbd027b..38b9cd0f69a 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.springframework.ai.model.ModelOptions;
@@ -25,14 +24,8 @@ public interface ChatOptions extends ModelOptions {
Float getTemperature();
- void setTemperature(Float temperature);
-
Float getTopP();
- void setTopP(Float topP);
-
Integer getTopK();
- void setTopK(Integer topK);
-
}
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java
index f702f635097..d367af422ad 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
public class ChatOptionsBuilder {
@@ -31,7 +30,6 @@ public Float getTemperature() {
return temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -41,7 +39,6 @@ public Float getTopP() {
return topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -51,7 +48,6 @@ public Integer getTopK() {
return topK;
}
- @Override
public void setTopK(Integer topK) {
this.topK = topK;
}
@@ -86,4 +82,4 @@ public ChatOptions build() {
return options;
}
-}
+}
\ No newline at end of file
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java
index 800c4586ecb..ef6d08ce5e1 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.springframework.ai.chat.messages.Message;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java
index 4c7ce981ffc..913c18c85fd 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
public class FunctionPromptTemplate extends PromptTemplate {
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java
index b82bcb05eb1..86aab947fad 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.springframework.ai.model.ModelOptions;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java
index 4ac2a1b92d9..db74d9aaaad 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.antlr.runtime.Token;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java
index 3381eaddd50..7b54aa05e03 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import java.util.Map;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java
index 361de4ade93..dd4424d0731 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java
@@ -1,3 +1,18 @@
+/*
+ * 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.chat.prompt;
import org.springframework.ai.chat.messages.Message;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java
index 47e24620c10..37caa5df888 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java
@@ -1,3 +1,18 @@
+/*
+ * 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.chat.prompt;
import org.springframework.ai.chat.messages.Message;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java
index 86495a49e3e..bd81ed4ddf1 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java
@@ -1,3 +1,18 @@
+/*
+ * 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.chat.prompt;
import java.util.Map;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java
index 539287d070b..8ac1aa85e42 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
import org.springframework.ai.chat.messages.Message;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java
index 1001ee26600..fe13fcf7d8a 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat.prompt;
public enum TemplateFormat {
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/ContentFormatter.java b/spring-ai-core/src/main/java/org/springframework/ai/document/ContentFormatter.java
index cf285dc20c3..8b5ec57c305 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/ContentFormatter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/ContentFormatter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
/**
- * Converts the Document text and metadata into a AI, prompt-friendly text representation.
+ * Converts the Document text and metadata into an AI, prompt-friendly text
+ * representation.
*
* @author Christian Tzolov
*/
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/DefaultContentFormatter.java b/spring-ai-core/src/main/java/org/springframework/ai/document/DefaultContentFormatter.java
index f02a2d0b5d0..7db065225ab 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/DefaultContentFormatter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/DefaultContentFormatter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
import java.util.ArrayList;
@@ -44,7 +43,7 @@ public class DefaultContentFormatter implements ContentFormatter {
private static final String DEFAULT_METADATA_TEMPLATE = String.format("%s: %s", TEMPLATE_KEY_PLACEHOLDER,
TEMPLATE_VALUE_PLACEHOLDER);
- private static final String DEFAULT_METADATA_SEPARATOR = "\n";
+ private static final String DEFAULT_METADATA_SEPARATOR = System.lineSeparator();
private static final String DEFAULT_TEXT_TEMPLATE = String.format("%s\n\n%s", TEMPLATE_METADATA_STRING_PLACEHOLDER,
TEMPLATE_CONTENT_PLACEHOLDER);
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/Document.java b/spring-ai-core/src/main/java/org/springframework/ai/document/Document.java
index 0db6f29acf6..7c54b4fecb4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/Document.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/Document.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentReader.java b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentReader.java
index f46171d330e..9d93a218bba 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentReader.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentReader.java
@@ -1,3 +1,18 @@
+/*
+ * 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.document;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentRetriever.java b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentRetriever.java
index bcab24fc80f..50d0b4b13a9 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentRetriever.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentRetriever.java
@@ -1,3 +1,18 @@
+/*
+ * 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.document;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentTransformer.java b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentTransformer.java
index 1a8243b3dbb..1253d6816e9 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentTransformer.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentTransformer.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentWriter.java b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentWriter.java
index 69ded8404c1..b91dc9a2e38 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentWriter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/DocumentWriter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/MetadataMode.java b/spring-ai-core/src/main/java/org/springframework/ai/document/MetadataMode.java
index 13ef775cb75..3d32a2b5dcc 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/MetadataMode.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/MetadataMode.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
public enum MetadataMode {
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/id/IdGenerator.java b/spring-ai-core/src/main/java/org/springframework/ai/document/id/IdGenerator.java
index 1aab8841c65..198c114d52b 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/id/IdGenerator.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/id/IdGenerator.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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.java b/spring-ai-core/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.java
index 08f34aea5aa..c1591ccba08 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document.id;
import java.io.ByteArrayOutputStream;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/document/id/RandomIdGenerator.java b/spring-ai-core/src/main/java/org/springframework/ai/document/id/RandomIdGenerator.java
index c7006357c8f..0920e9a0424 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/document/id/RandomIdGenerator.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/document/id/RandomIdGenerator.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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingClient.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingClient.java
index 62268cfeb6b..b7749153f75 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/AbstractEmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import java.io.IOException;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/Embedding.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/Embedding.java
index 864dec82599..7a929bfa7b0 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/Embedding.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/Embedding.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingClient.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingClient.java
index 79cbbb45a9e..d9dc2f8a3d4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingClient.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingOptions.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingOptions.java
index c4d5beccb77..f1d1e1883a4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingOptions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingOptions.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import org.springframework.ai.model.ModelOptions;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingRequest.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingRequest.java
index 17cc478bcc3..e5512bfe2a1 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingRequest.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingRequest.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponse.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponse.java
index 73bc0b0c42a..88f1d881a5b 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponse.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponse.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponseMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponseMetadata.java
index e5f7b903a4d..54085c937f2 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponseMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResponseMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import java.util.HashMap;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResultMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResultMetadata.java
index 04f2e2bb053..005c0be7fe0 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResultMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/embedding/EmbeddingResultMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import org.springframework.ai.model.ResultMetadata;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/Image.java b/spring-ai-core/src/main/java/org/springframework/ai/image/Image.java
index fa1f0b8ff9d..8adc3677e09 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/Image.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/Image.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import java.util.Objects;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageClient.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageClient.java
index bf06964e1ff..7ce6a47494c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageClient.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ModelClient;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGeneration.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGeneration.java
index 94f739266a3..431afd81325 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGeneration.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGeneration.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ModelResult;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java
index e140aa814be..164f781d172 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ResultMetadata;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageMessage.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageMessage.java
index 51d378b8c32..2b298bb0715 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageMessage.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageMessage.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import java.util.Objects;
@@ -43,7 +42,7 @@ public Float getWeight() {
@Override
public String toString() {
- return "mageMessage{" + "text='" + text + '\'' + ", weight=" + weight + '}';
+ return "ImageMessage{" + "text='" + text + '\'' + ", weight=" + weight + '}';
}
@Override
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptions.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptions.java
index 428376364db..8914862cbae 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ModelOptions;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java
index 49dc3497d3e..c7b7f3eb115 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
public class ImageOptionsBuilder {
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImagePrompt.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImagePrompt.java
index 5ea58bea469..59ac64c818c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImagePrompt.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImagePrompt.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ModelRequest;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponse.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponse.java
index ad6cda7c9e7..f4029c9f19e 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponse.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponse.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java
index 7378fedca6e..b3506667ee4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/image/ImageResponseMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.image;
import org.springframework.ai.model.ResponseMetadata;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelClient.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelClient.java
index 38de2f149b7..1f114a59b10 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelClient.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptions.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptions.java
index 96b301b7933..124818e80b4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java
index 7ca8e205fbc..458445fc990 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelOptionsUtils.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
import java.beans.PropertyDescriptor;
@@ -36,6 +35,7 @@
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
@@ -61,7 +61,8 @@ public final class ModelOptionsUtils {
private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
- .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+ .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+ .registerModule(new JavaTimeModule());
private final static List BEAN_MERGE_FIELD_EXCISIONS = List.of("class");
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelRequest.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelRequest.java
index 0aac6da82c7..94c2e8aefc5 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelRequest.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelRequest.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResponse.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResponse.java
index 5c8a17b5827..f4a9bf83a05 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResponse.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResponse.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResult.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResult.java
index 5a5613a7280..6ee17815c74 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResult.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ModelResult.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ResponseMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ResponseMetadata.java
index 14af864bb49..554c6768f62 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ResponseMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ResponseMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/ResultMetadata.java b/spring-ai-core/src/main/java/org/springframework/ai/model/ResultMetadata.java
index 78d5f7f6a91..05d2aaca403 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/ResultMetadata.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/ResultMetadata.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/StreamingModelClient.java b/spring-ai-core/src/main/java/org/springframework/ai/model/StreamingModelClient.java
index da1db15048b..4dddced14cb 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/StreamingModelClient.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/StreamingModelClient.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,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
import reactor.core.publisher.Flux;
/**
- * The StreamingModelClient interface provides a generic API for invoking a AI models with
- * streaming response. It abstracts the process of sending requests and receiving a
+ * The StreamingModelClient interface provides a generic API for invoking an AI models
+ * with streaming response. It abstracts the process of sending requests and receiving a
* streaming responses. The interface uses Java generics to accommodate different types of
* requests and responses, enhancing flexibility and adaptability across different AI
* model implementations.
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java
index 46b70e4f2f5..4ae57c06b29 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java
index 47491368de5..f4cdd4ef8e7 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.util.function.Function;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallback.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallback.java
index ab231701575..6f4e8bac482 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallback.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallback.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java
index 074323def65..59f43098753 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java
index dc4eb5ccb6e..dbf28dd8ba1 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java
@@ -1,3 +1,18 @@
+/*
+ * 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.model.function;
import java.util.function.Function;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java
index c66a4f5b182..146b35c4715 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.util.List;
@@ -63,4 +62,4 @@ public static FunctionCallingOptionsBuilder builder() {
return new FunctionCallingOptionsBuilder();
}
-}
+}
\ No newline at end of file
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java
index 948fba58f9b..8b30da67da7 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.util.ArrayList;
@@ -98,7 +97,6 @@ public List getFunctionCallbacks() {
return this.functionCallbacks;
}
- @Override
public void setFunctionCallbacks(List functionCallbacks) {
Assert.notNull(functionCallbacks, "FunctionCallbacks must not be null");
this.functionCallbacks = functionCallbacks;
@@ -109,7 +107,6 @@ public Set getFunctions() {
return this.functions;
}
- @Override
public void setFunctions(Set functions) {
Assert.notNull(functions, "Functions must not be null");
this.functions = functions;
@@ -120,7 +117,6 @@ public Float getTemperature() {
return this.temperature;
}
- @Override
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
@@ -130,7 +126,6 @@ public Float getTopP() {
return this.topP;
}
- @Override
public void setTopP(Float topP) {
this.topP = topP;
}
@@ -140,11 +135,10 @@ public Integer getTopK() {
return this.topK;
}
- @Override
public void setTopK(Integer topK) {
this.topK = topK;
}
}
-}
+}
\ No newline at end of file
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java b/spring-ai-core/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java
index b56b99890e2..7d40ebac71a 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.lang.reflect.GenericArrayType;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/package-info.java b/spring-ai-core/src/main/java/org/springframework/ai/model/package-info.java
index 12eaa53b400..57c2b34db7f 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/model/package-info.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/model/package-info.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
/**
* Provides a set of interfaces and classes for a generic API designed to interact with
* various AI models. This package includes interfaces for handling AI model calls,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java
index a06827f3997..7f2f61ee045 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
import org.springframework.core.convert.support.DefaultConversionService;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java
index 01dbadaf14e..146ce323b5c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
import org.springframework.messaging.converter.MessageConverter;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java
index 1b93cf0fe4a..7be67324d44 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -90,8 +89,8 @@ private void generateSchema() {
SchemaGeneratorConfig config = configBuilder.build();
SchemaGenerator generator = new SchemaGenerator(config);
JsonNode jsonNode = generator.generateSchema(this.clazz);
- ObjectWriter objectWriter = new ObjectMapper()
- .writer(new DefaultPrettyPrinter().withObjectIndenter(new DefaultIndenter().withLinefeed("\n")));
+ ObjectWriter objectWriter = new ObjectMapper().writer(new DefaultPrettyPrinter()
+ .withObjectIndenter(new DefaultIndenter().withLinefeed(System.lineSeparator())));
try {
this.jsonSchema = objectWriter.writeValueAsString(jsonNode);
}
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/FormatProvider.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/FormatProvider.java
index 8d0cb76b099..e6692965fe3 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/FormatProvider.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/FormatProvider.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java
index c5a466ecf54..5e0b99c7413 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java
index 27e30b8d872..20f2857c72f 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
import java.nio.charset.StandardCharsets;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java
index cbc7e6e5a53..d0fca1f4e4e 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java
index 559473f0807..03f9cc0d9b4 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.parser;
@FunctionalInterface
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/reader/EmptyJsonMetadataGenerator.java b/spring-ai-core/src/main/java/org/springframework/ai/reader/EmptyJsonMetadataGenerator.java
index 2218159b892..a56714aef78 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/reader/EmptyJsonMetadataGenerator.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/reader/EmptyJsonMetadataGenerator.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader;
import java.util.Collections;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/reader/ExtractedTextFormatter.java b/spring-ai-core/src/main/java/org/springframework/ai/reader/ExtractedTextFormatter.java
index b58f7594cd6..03669f1b747 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/reader/ExtractedTextFormatter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/reader/ExtractedTextFormatter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader;
import org.springframework.util.StringUtils;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonMetadataGenerator.java b/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonMetadataGenerator.java
index 68721d84c2f..4a4ffb1e9fc 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonMetadataGenerator.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonMetadataGenerator.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader;
import java.util.Map;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonReader.java b/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonReader.java
index 7195a3789a3..99ba29a2dba 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonReader.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/reader/JsonReader.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader;
import java.io.IOException;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/reader/TextReader.java b/spring-ai-core/src/main/java/org/springframework/ai/reader/TextReader.java
index 42355fca609..389a1d703a5 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/reader/TextReader.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/reader/TextReader.java
@@ -1,3 +1,18 @@
+/*
+ * 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.reader;
import java.io.IOException;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/transformer/ContentFormatTransformer.java b/spring-ai-core/src/main/java/org/springframework/ai/transformer/ContentFormatTransformer.java
index 4aa61838bd5..9465766d8fa 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/transformer/ContentFormatTransformer.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/transformer/ContentFormatTransformer.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformer;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/transformer/KeywordMetadataEnricher.java b/spring-ai-core/src/main/java/org/springframework/ai/transformer/KeywordMetadataEnricher.java
index 40280f19269..67807e419dd 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/transformer/KeywordMetadataEnricher.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/transformer/KeywordMetadataEnricher.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformer;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/transformer/SummaryMetadataEnricher.java b/spring-ai-core/src/main/java/org/springframework/ai/transformer/SummaryMetadataEnricher.java
index f0a607dbda0..e882ac49705 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/transformer/SummaryMetadataEnricher.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/transformer/SummaryMetadataEnricher.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformer;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TextSplitter.java b/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TextSplitter.java
index baed887cf73..0b59995beea 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TextSplitter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TextSplitter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TokenTextSplitter.java b/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TokenTextSplitter.java
index efd9a98d9ab..c820b51a3e7 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TokenTextSplitter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/transformer/splitter/TokenTextSplitter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -32,16 +32,21 @@
*/
public class TokenTextSplitter extends TextSplitter {
- private final int defaultChunkSize = 800; // The target size of each text
- // chunk in tokens
+ private final EncodingRegistry registry = Encodings.newLazyEncodingRegistry();
+
+ private final Encoding encoding = registry.getEncoding(EncodingType.CL100K_BASE);
- private int minChunkSizeChars = 350; // The minimum size of each text
- // chunk in characters
+ // The target size of each text chunk in tokens
+ private int defaultChunkSize = 800;
- private int minChunkLengthToEmbed = 5; // Discard chunks shorter than this
+ // The minimum size of each text chunk in characters
+ private int minChunkSizeChars = 350;
- private int maxNumChunks = 10000; // The maximum number of chunks to generate from a
- // text
+ // Discard chunks shorter than this
+ private int minChunkLengthToEmbed = 5;
+
+ // The maximum number of chunks to generate from a text
+ private int maxNumChunks = 10000;
private boolean keepSeparator = true;
@@ -52,9 +57,14 @@ public TokenTextSplitter(boolean keepSeparator) {
this.keepSeparator = keepSeparator;
}
- private final EncodingRegistry registry = Encodings.newLazyEncodingRegistry();
-
- private final Encoding encoding = registry.getEncoding(EncodingType.CL100K_BASE);
+ public TokenTextSplitter(int defaultChunkSize, int minChunkSizeChars, int minChunkLengthToEmbed, int maxNumChunks,
+ boolean keepSeparator) {
+ this.defaultChunkSize = defaultChunkSize;
+ this.minChunkSizeChars = minChunkSizeChars;
+ this.minChunkLengthToEmbed = minChunkLengthToEmbed;
+ this.maxNumChunks = maxNumChunks;
+ this.keepSeparator = keepSeparator;
+ }
@Override
protected List splitText(String text) {
@@ -88,9 +98,10 @@ public List split(String text, int chunkSize) {
chunkText = chunkText.substring(0, lastPunctuation + 1);
}
- String chunk_text_to_append = (this.keepSeparator) ? chunkText.trim() : chunkText.replace("\n", " ").trim();
- if (chunk_text_to_append.length() > this.minChunkLengthToEmbed) {
- chunks.add(chunk_text_to_append);
+ String chunkTextToAppend = (this.keepSeparator) ? chunkText.trim()
+ : chunkText.replace(System.lineSeparator(), " ").trim();
+ if (chunkTextToAppend.length() > this.minChunkLengthToEmbed) {
+ chunks.add(chunkTextToAppend);
}
// Remove the tokens corresponding to the chunk text from the remaining tokens
@@ -101,7 +112,7 @@ public List split(String text, int chunkSize) {
// Handle the remaining tokens
if (!tokens.isEmpty()) {
- String remaining_text = decodeTokens(tokens).replace("\n", " ").trim();
+ String remaining_text = decodeTokens(tokens).replace(System.lineSeparator(), " ").trim();
if (remaining_text.length() > this.minChunkLengthToEmbed) {
chunks.add(remaining_text);
}
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SearchRequest.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SearchRequest.java
index 030374482e1..b430793cdd0 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SearchRequest.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SearchRequest.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import org.springframework.ai.document.Document;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java
index 18b794f4681..0fe4aaccbec 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java
@@ -1,3 +1,18 @@
+/*
+ * 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.vectorstore;
import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java
index ac8dbc8666c..8c4ff0c2a9c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java
@@ -1,3 +1,18 @@
+/*
+ * 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.vectorstore;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/Filter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/Filter.java
index 41cf5b16ed5..d9860e26fc7 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/Filter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/Filter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
/**
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilder.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilder.java
index b0c3e9c2505..d3913c1d424 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilder.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilder.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionConverter.java
index 6b5a4701b30..127f2dc9270 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
-import org.springframework.ai.vectorstore.filter.Filter;
-
/**
* Converters a generic, portable {@link Filter.Expression} into a
* {@link org.springframework.ai.vectorstore.VectorStore} specific expression language
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java
index bbaff204491..c4fd1a9d62e 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterHelper.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterHelper.java
index 48d2b79a3a7..555d2ca8756 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterHelper.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/FilterHelper.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseListener.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseListener.java
index 962a36c6796..65bca7a3a1c 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseListener.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseListener.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseVisitor.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseVisitor.java
index 555a6962913..99b0de1b689 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseVisitor.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersBaseVisitor.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersLexer.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersLexer.java
index 85e6e4b3f94..87fa8abfdd6 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersLexer.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersLexer.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersListener.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersListener.java
index 77444e52747..c16c841b7dc 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersListener.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersListener.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersParser.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersParser.java
index ac829094f5f..ab66cff95a0 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersParser.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersParser.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersVisitor.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersVisitor.java
index 27413bd6e3f..3f099b18229 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersVisitor.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/antlr4/FiltersVisitor.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
// Generated from org/springframework/ai/vectorstore/filter/antlr4/Filters.g4 by ANTLR 4.13.1
package org.springframework.ai.vectorstore.filter.antlr4;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/AbstractFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/AbstractFilterExpressionConverter.java
index 71cc25d27ec..6662481e5e7 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/AbstractFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/AbstractFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import java.util.List;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/ChromaFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/ChromaFilterExpressionConverter.java
index 30cc5006dd2..3d106638c1e 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/ChromaFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/ChromaFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import org.springframework.ai.vectorstore.filter.Filter;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverter.java
index 3a32552a36d..066eba4ae88 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverter.java
index 5eeabe96a3a..fc81c218ce5 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverter.java
index eb4614c6192..4f8c6c061cd 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PrintFilterExpressionConverter.java b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PrintFilterExpressionConverter.java
index 6860cc7ffde..b2e93fcf746 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PrintFilterExpressionConverter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/vectorstore/filter/converter/PrintFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
diff --git a/spring-ai-core/src/main/java/org/springframework/ai/writer/FileDocumentWriter.java b/spring-ai-core/src/main/java/org/springframework/ai/writer/FileDocumentWriter.java
index 02735ac15f1..023cfa6a1d9 100644
--- a/spring-ai-core/src/main/java/org/springframework/ai/writer/FileDocumentWriter.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/writer/FileDocumentWriter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.writer;
import java.io.FileWriter;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/TestConfiguration.java b/spring-ai-core/src/test/java/org/springframework/ai/TestConfiguration.java
index 41538cf52b6..203ac200ff3 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/TestConfiguration.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/TestConfiguration.java
@@ -1,3 +1,18 @@
+/*
+ * 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;
import org.springframework.boot.SpringBootConfiguration;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/aot/AiRuntimeHintsTests.java b/spring-ai-core/src/test/java/org/springframework/ai/aot/AiRuntimeHintsTests.java
index 72cdec4a083..02addaecfeb 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/aot/AiRuntimeHintsTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/aot/AiRuntimeHintsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.aot;
import java.util.Set;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/aot/KnuddelsRuntimeHintsTest.java b/spring-ai-core/src/test/java/org/springframework/ai/aot/KnuddelsRuntimeHintsTest.java
index e11ab5bf036..eb45821b8d5 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/aot/KnuddelsRuntimeHintsTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/aot/KnuddelsRuntimeHintsTest.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.aot;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/aot/SpringAiCoreRuntimeHintsTest.java b/spring-ai-core/src/test/java/org/springframework/ai/aot/SpringAiCoreRuntimeHintsTest.java
index 97d15db306e..372d6f076ae 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/aot/SpringAiCoreRuntimeHintsTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/aot/SpringAiCoreRuntimeHintsTest.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.aot;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatBuilderTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatBuilderTests.java
new file mode 100644
index 00000000000..fb4ca1acf60
--- /dev/null
+++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatBuilderTests.java
@@ -0,0 +1,110 @@
+/*
+ * 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.chat;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+
+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.function.FunctionCallback;
+import org.springframework.ai.model.function.FunctionCallbackWrapper;
+import org.springframework.ai.model.function.FunctionCallingOptions;
+import org.springframework.ai.model.function.FunctionCallingOptionsBuilder;
+
+/**
+ * Unit Tests for {@link Prompt}.
+ *
+ * @author youngmon
+ * @since 0.8.1
+ */
+public class ChatBuilderTests {
+
+ @Test
+ void createNewChatOptionsTest() {
+ Float temperature = 1.1f;
+ Float topP = 2.2f;
+ Integer topK = 111;
+
+ ChatOptions options = ChatOptionsBuilder.builder()
+ .withTemperature(temperature)
+ .withTopK(topK)
+ .withTopP(topP)
+ .build();
+
+ assertThat(options.getTemperature()).isEqualTo(temperature);
+ assertThat(options.getTopP()).isEqualTo(topP);
+ assertThat(options.getTopK()).isEqualTo(topK);
+ }
+
+ @Test
+ void duplicateChatOptionsTest() {
+ Float initTemperature = 1.1f;
+ Float initTopP = 2.2f;
+ Integer initTopK = 111;
+
+ ChatOptions options = ChatOptionsBuilder.builder()
+ .withTemperature(initTemperature)
+ .withTopP(initTopP)
+ .withTopK(initTopK)
+ .build();
+
+ }
+
+ @Test
+ void createFunctionCallingOptionTest() {
+ Float temperature = 1.1f;
+ Float topP = 2.2f;
+ Integer topK = 111;
+ List functionCallbacks = new ArrayList<>();
+ Set functions = new HashSet<>();
+
+ String func = "func";
+ FunctionCallback cb = FunctionCallbackWrapper.builder(i -> i)
+ .withName("cb")
+ .withDescription("cb")
+ .build();
+
+ functions.add(func);
+ functionCallbacks.add(cb);
+
+ FunctionCallingOptions options = FunctionCallingOptions.builder()
+ .withFunctionCallbacks(functionCallbacks)
+ .withFunctions(functions)
+ .withTopK(topK)
+ .withTopP(topP)
+ .withTemperature(temperature)
+ .build();
+
+ // Callback Functions
+ assertThat(options.getFunctionCallbacks()).isNotNull();
+ assertThat(options.getFunctionCallbacks().size()).isEqualTo(1);
+ assertThat(options.getFunctionCallbacks().contains(cb));
+
+ // Functions
+ assertThat(options.getFunctions()).isNotNull();
+ assertThat(options.getFunctions().size()).isEqualTo(1);
+ assertThat(options.getFunctions().contains(func));
+
+ }
+
+}
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatClientTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatClientTests.java
index 1a85939955c..14a74b0c7a8 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatClientTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/ChatClientTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chat;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/document/ContentFormatterTests.java b/spring-ai-core/src/test/java/org/springframework/ai/document/ContentFormatterTests.java
index e4db79ae01c..b20d7595b40 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/document/ContentFormatterTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/document/ContentFormatterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.document;
import java.util.Map;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/document/id/IdGeneratorProviderTest.java b/spring-ai-core/src/test/java/org/springframework/ai/document/id/IdGeneratorProviderTest.java
index 87431126471..2e74d671bfe 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/document/id/IdGeneratorProviderTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/document/id/IdGeneratorProviderTest.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,
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/document/id/JdkSha256HexIdGeneratorTest.java b/spring-ai-core/src/test/java/org/springframework/ai/document/id/JdkSha256HexIdGeneratorTest.java
index 95ab6948220..4fc94f62ee9 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/document/id/JdkSha256HexIdGeneratorTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/document/id/JdkSha256HexIdGeneratorTest.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,
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/embedding/AbstractEmbeddingClientTests.java b/spring-ai-core/src/test/java/org/springframework/ai/embedding/AbstractEmbeddingClientTests.java
index 202775b1cbd..ad42fc2716b 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/embedding/AbstractEmbeddingClientTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/embedding/AbstractEmbeddingClientTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.embedding;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/metadata/PromptMetadataTests.java b/spring-ai-core/src/test/java/org/springframework/ai/metadata/PromptMetadataTests.java
index aef94a6b030..ebeabb4fa0c 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/metadata/PromptMetadataTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/metadata/PromptMetadataTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/metadata/UsageTests.java b/spring-ai-core/src/test/java/org/springframework/ai/metadata/UsageTests.java
index 0e44b63d64f..18d7d63922d 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/metadata/UsageTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/metadata/UsageTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.metadata;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/model/ModelOptionsUtilsTests.java b/spring-ai-core/src/test/java/org/springframework/ai/model/ModelOptionsUtilsTests.java
index b6e4c6803e5..7b03f7e2d71 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/model/ModelOptionsUtilsTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/model/ModelOptionsUtilsTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model;
import java.util.Map;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/model/function/TypeResolverHelperTests.java b/spring-ai-core/src/test/java/org/springframework/ai/model/function/TypeResolverHelperTests.java
index dacaf8bc9de..76622a22281 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/model/function/TypeResolverHelperTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/model/function/TypeResolverHelperTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.model.function;
import java.util.function.Function;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/parser/BeanOutputParserTest.java b/spring-ai-core/src/test/java/org/springframework/ai/parser/BeanOutputParserTest.java
index c9b3e49d23a..8df495e4008 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/parser/BeanOutputParserTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/parser/BeanOutputParserTest.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
@@ -123,7 +123,7 @@ void normalizesLineEndings() {
String formatOutput = parser.getFormat();
// validate that output contains \n line endings
- assertThat(formatOutput).contains("\n").doesNotContain("\r\n").doesNotContain("\r");
+ assertThat(formatOutput).contains(System.lineSeparator()).doesNotContain("\r\n").doesNotContain("\r");
}
}
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/prompt/ChatTests.java b/spring-ai-core/src/test/java/org/springframework/ai/prompt/ChatTests.java
index c0cafdc4309..836f3cfc8c0 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/prompt/ChatTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/prompt/ChatTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.prompt;
public class ChatTests {
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTemplateTest.java b/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTemplateTest.java
index 52dcd7712a6..b60fb46a98d 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTemplateTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTemplateTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.prompt;
import org.junit.jupiter.api.Disabled;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTests.java b/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTests.java
index b08ed9aec70..4d3ff521757 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/prompt/PromptTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.prompt;
import org.assertj.core.api.Assertions;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/prompt/parsers/ListOutputParserTest.java b/spring-ai-core/src/test/java/org/springframework/ai/prompt/parsers/ListOutputParserTest.java
index b06bbb14ca1..43ccfb54ff5 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/prompt/parsers/ListOutputParserTest.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/prompt/parsers/ListOutputParserTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.prompt.parsers;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/reader/JsonReaderTests.java b/spring-ai-core/src/test/java/org/springframework/ai/reader/JsonReaderTests.java
index 61a119dcf3e..3af00b620a0 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/reader/JsonReaderTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/reader/JsonReaderTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/reader/TextReaderTests.java b/spring-ai-core/src/test/java/org/springframework/ai/reader/TextReaderTests.java
index c7187861fbe..64f245733fa 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/reader/TextReaderTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/reader/TextReaderTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.reader;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/transformer/splitter/TextSplitterTests.java b/spring-ai-core/src/test/java/org/springframework/ai/transformer/splitter/TextSplitterTests.java
index 43e724fdcec..8e25c9e8b6c 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/transformer/splitter/TextSplitterTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/transformer/splitter/TextSplitterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.transformer.splitter;
import java.util.ArrayList;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilderTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilderTests.java
index d5f8e077a38..18d0b3424db 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilderTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionBuilderTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java
index 27e62f1d8fa..8253fb234c4 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterHelperTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterHelperTests.java
index e8842a4035d..472e9b1d881 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterHelperTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/FilterHelperTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/SearchRequestTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/SearchRequestTests.java
index 8c9a014a682..5535766b793 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/SearchRequestTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/SearchRequestTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverterTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverterTests.java
index 3b23b430b33..7dff91cd4ef 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverterTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/MilvusFilterExpressionConverterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverterTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverterTests.java
index 5c6049ec095..b6856d12b15 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverterTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PgVectorFilterExpressionConverterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import java.util.List;
diff --git a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverterTests.java b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverterTests.java
index a4c8fce2b77..e86b927f017 100644
--- a/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverterTests.java
+++ b/spring-ai-core/src/test/java/org/springframework/ai/vectorstore/filter/converter/PineconeFilterExpressionConverterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter.converter;
import java.util.List;
diff --git a/spring-ai-docs/pom.xml b/spring-ai-docs/pom.xml
index 4b360a28f85..ee2be101337 100644
--- a/spring-ai-docs/pom.xml
+++ b/spring-ai-docs/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOTspring-ai-docsSpring AI Docs
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/embeddings-api.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/embeddings-api.jpg
index cc13a837eef..41b383ff318 100644
Binary files a/spring-ai-docs/src/main/antora/modules/ROOT/images/embeddings-api.jpg and b/spring-ai-docs/src/main/antora/modules/ROOT/images/embeddings-api.jpg differ
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-class-diagram.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-class-diagram.jpg
new file mode 100644
index 00000000000..6fbefde8c94
Binary files /dev/null and b/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-class-diagram.jpg differ
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-pipeline.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-pipeline.jpg
new file mode 100644
index 00000000000..7c188fbab2c
Binary files /dev/null and b/spring-ai-docs/src/main/antora/modules/ROOT/images/etl-pipeline.jpg differ
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/mistral-ai-function-calling-flow.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/mistral-ai-function-calling-flow.jpg
new file mode 100644
index 00000000000..88e980877a2
Binary files /dev/null and b/spring-ai-docs/src/main/antora/modules/ROOT/images/mistral-ai-function-calling-flow.jpg differ
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/images/spring-ai-chat-completions-clients.jpg b/spring-ai-docs/src/main/antora/modules/ROOT/images/spring-ai-chat-completions-clients.jpg
index bf529080ba0..f20701c8274 100644
Binary files a/spring-ai-docs/src/main/antora/modules/ROOT/images/spring-ai-chat-completions-clients.jpg and b/spring-ai-docs/src/main/antora/modules/ROOT/images/spring-ai-chat-completions-clients.jpg differ
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc
index c10738151fa..5687ff79ab9 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc
@@ -2,6 +2,25 @@
* xref:concepts.adoc[AI Concepts]
* xref:getting-started.adoc[Getting Started]
* xref:api/index.adoc[]
+** xref:api/chatclient.adoc[]
+*** xref:api/chat/openai-chat.adoc[OpenAI]
+**** xref:api/chat/functions/openai-chat-functions.adoc[Function Calling]
+*** xref:api/chat/ollama-chat.adoc[Ollama]
+*** xref:api/chat/azure-openai-chat.adoc[Azure OpenAI]
+**** xref:api/chat/functions/azure-open-ai-chat-functions.adoc[Function Calling]
+*** xref:api/bedrock-chat.adoc[Amazon Bedrock]
+**** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic]
+**** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2]
+**** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere]
+**** xref:api/chat/bedrock/bedrock-titan.adoc[Titan]
+**** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2]
+*** xref:api/chat/huggingface.adoc[HuggingFace]
+*** xref:api/chat/google-vertexai.adoc[Google VertexAI]
+**** xref:api/chat/vertexai-palm2-chat.adoc[VertexAI PaLM2 ]
+**** xref:api/chat/vertexai-gemini-chat.adoc[VertexAI Gemini]
+***** xref:api/chat/functions/vertexai-gemini-chat-functions.adoc[Function Calling]
+*** xref:api/chat/mistralai-chat.adoc[Mistral AI]
+**** xref:api/chat/functions/mistralai-chat-functions.adoc[Function Calling]
** xref:api/embeddings.adoc[]
*** xref:api/embeddings/openai-embeddings.adoc[OpenAI]
*** xref:api/embeddings/ollama-embeddings.adoc[Ollama]
@@ -13,27 +32,11 @@
**** xref:api/embeddings/bedrock-titan-embedding.adoc[Titan]
*** xref:api/embeddings/onnx.adoc[Transformers (ONNX)]
*** xref:api/embeddings/mistralai-embeddings.adoc[Mistral AI]
-** xref:api/chatclient.adoc[]
-*** xref:api/clients/openai-chat.adoc[OpenAI]
-**** xref:api/clients/functions/openai-chat-functions.adoc[Function Calling]
-*** xref:api/clients/ollama-chat.adoc[Ollama]
-*** xref:api/clients/azure-openai-chat.adoc[Azure OpenAI]
-**** xref:api/clients/functions/azure-open-ai-chat-functions.adoc[Function Calling]
-*** xref:api/bedrock-chat.adoc[Amazon Bedrock]
-**** xref:api/clients/bedrock/bedrock-anthropic.adoc[Anthropic]
-**** xref:api/clients/bedrock/bedrock-llama2.adoc[Llama2]
-**** xref:api/clients/bedrock/bedrock-cohere.adoc[Cohere]
-**** xref:api/clients/bedrock/bedrock-titan.adoc[Titan]
-*** xref:api/clients/huggingface.adoc[HuggingFace]
-*** xref:api/clients/google-vertexai.adoc[Google VertexAI]
-**** xref:api/clients/vertexai-palm2-chat.adoc[VertexAI PaLM2 ]
-**** xref:api/clients/vertexai-gemini-chat.adoc[VertexAI Gemini]
-***** xref:api/clients/functions/vertexai-gemini-chat-functions.adoc[Function Calling]
-*** xref:api/clients/mistralai-chat.adoc[Mistral AI]
-**** xref:api/clients/functions/mistralai-chat-functions.adoc[Function Calling]
** xref:api/imageclient.adoc[]
-*** xref:api/clients/image/openai-image.adoc[OpenAI]
-*** xref:api/clients/image/stabilityai-image.adoc[Stability]
+*** xref:api/image/openai-image.adoc[OpenAI]
+*** xref:api/image/stabilityai-image.adoc[Stability]
+** xref:api/transcriptions.adoc[]
+*** xref:api/transcriptions/openai-transcriptions.adoc[OpenAI]
** xref:api/vectordbs.adoc[]
*** xref:api/vectordbs/azure.adoc[]
*** xref:api/vectordbs/chroma.adoc[]
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc
index 47fdd44714e..45fa5dc5e2b 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/bedrock.adoc
@@ -72,6 +72,7 @@ Here are the supported `` and `` combinations:
| Model | Chat | Chat Streaming | Embedding
| llama2 | Yes | Yes | No
+| jurassic2 | Yes | No | No
| cohere | Yes | Yes | Yes
| anthropic | Yes | Yes | No
| jurassic2 (WIP) | Yes | No | No
@@ -84,11 +85,13 @@ Next, you can use the `spring.ai.bedrock...*` properties
For more information, refer to the documentation below for each supported model.
-* xref:api/clients/bedrock/bedrock-anthropic.adoc[Spring AI Bedrock Anthropic Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true`
-* xref:api/clients/bedrock/bedrock-llama2.adoc[Spring AI Bedrock Llama2 Chat]: `spring.ai.bedrock.llama2.chat.enabled=true`
-* xref:api/clients/bedrock/bedrock-cohere.adoc[Spring AI Bedrock Cohere Chat]: `spring.ai.bedrock.cohere.chat.enabled=true`
+* xref:api/chat/bedrock/bedrock-anthropic.adoc[Spring AI Bedrock Anthropic Chat]: `spring.ai.bedrock.anthropic.chat.enabled=true`
+* xref:api/chat/bedrock/bedrock-llama2.adoc[Spring AI Bedrock Llama2 Chat]: `spring.ai.bedrock.llama2.chat.enabled=true`
+* xref:api/chat/bedrock/bedrock-cohere.adoc[Spring AI Bedrock Cohere Chat]: `spring.ai.bedrock.cohere.chat.enabled=true`
* xref:api/embeddings/bedrock-cohere-embedding.adoc[Spring AI Bedrock Cohere Embeddings]: `spring.ai.bedrock.cohere.embedding.enabled=true`
-* xref:api/clients/bedrock/bedrock-titan.adoc[Spring AI Bedrock Titan Chat]: `spring.ai.bedrock.titan.chat.enabled=true`
+* xref:api/chat/bedrock/bedrock-titan.adoc[Spring AI Bedrock Titan Chat]: `spring.ai.bedrock.titan.chat.enabled=true`
* xref:api/embeddings/bedrock-titan-embedding.adoc[Spring AI Bedrock Titan Embeddings]: `spring.ai.bedrock.titan.embedding.enabled=true`
+* xref:api/chat/bedrock/bedrock-jurassic2.adoc[Spring AI Bedrock Ai21 Jurassic2 Chat]: `spring.ai.bedrock.jurassic2.chat.enabled=true`
-// * xref:api/clients/bedrock/bedrock-jurassic2-chat.adoc[(WIP)Spring AI Bedrock Jurassic Chat]: `spring.ai.bedrock.jurassic2.chat.enabled=true`
+
+// * xref:api/chat/bedrock/bedrock-jurassic2-chat.adoc[(WIP)Spring AI Bedrock Jurassic Chat]: `spring.ai.bedrock.jurassic2.chat.enabled=true`
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/azure-openai-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/azure-openai-chat.adoc
similarity index 92%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/azure-openai-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/azure-openai-chat.adoc
index cec77120b5b..7c02eb93231 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/azure-openai-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/azure-openai-chat.adoc
@@ -95,7 +95,7 @@ The prefix `spring.ai.azure.openai.chat` is the property prefix that configures
| Property | Description | Default
| spring.ai.azure.openai.chat.enabled | Enable Azure OpenAI chat client. | true
-| spring.ai.azure.openai.chat.options.model | * In use with Azure, this actually refers to the "Deployment Name" of your model, which you can find at https://oai.azure.com/portal. It's important to note that within an Azure OpenAI deployment, the "Deployment Name" is distinct from the model itself. The confusion around these terms stems from the intention to make the Azure OpenAI client library compatible with the original OpenAI endpoint. The deployment structures offered by Azure OpenAI and Sam Altman's OpenAI differ significantly. To clarify this distinction, we plan to rename this attribute to `deployment-name` in future updates.
+| spring.ai.azure.openai.chat.options.deployment-name | * In use with Azure, this refers to the "Deployment Name" of your model, which you can find at https://oai.azure.com/portal. It's important to note that within an Azure OpenAI deployment, the "Deployment Name" is distinct from the model itself. The confusion around these terms stems from the intention to make the Azure OpenAI client library compatible with the original OpenAI endpoint. The deployment structures offered by Azure OpenAI and Sam Altman's OpenAI differ significantly.
Deployments model name to provide as part of this completions request.
| gpt-35-turbo
| spring.ai.azure.openai.chat.options.maxTokens | The maximum number of tokens to generate. | -
@@ -111,7 +111,7 @@ Deployments model name to provide as part of this completions request.
TIP: All properties prefixed with `spring.ai.azure.openai.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java[AzureOpenAiChatOptions.java] provides model configurations, such as the model to use, the temperature, the frequency penalty, etc.
@@ -135,13 +135,13 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java[AzureOpenAiChatOptions.java] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Function Calling
+== Function Calling
You can register custom Java functions with the AzureOpenAiChatClient and have the model intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
This is a powerful technique to connect the LLM capabilities with external tools and APIs.
-Read more about xref:api/clients/functions/azure-open-ai-chat-functions.adoc[Azure OpenAI Function Calling].
+Read more about xref:api/chat/functions/azure-open-ai-chat-functions.adoc[Azure OpenAI Function Calling].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-azure-openai-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -210,7 +210,7 @@ dependencies {
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
-TIP: The `spring-ai-azure-openai` dependency also provide the access to the `AzureOpenAiChatClient`. For more information about the `AzureOpenAiChatClient` refer to the link:../clients/azure-openai-chat.html[Azure OpenAI Chat] section.
+TIP: The `spring-ai-azure-openai` dependency also provide the access to the `AzureOpenAiChatClient`. For more information about the `AzureOpenAiChatClient` refer to the link:../chat/azure-openai-chat.html[Azure OpenAI Chat] section.
Next, create an `AzureOpenAiChatClient` instance and use it to generate text responses:
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-anthropic.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc
similarity index 99%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-anthropic.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc
index 3a05998fc94..192eb5976c7 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-anthropic.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-anthropic.adoc
@@ -89,7 +89,7 @@ Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/lat
TIP: All properties prefixed with `spring.ai.bedrock.anthropic.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.java[AnthropicChatOptions.java] provides model configurations, such as temperature, topK, topP, etc.
@@ -111,7 +111,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/anthropic/AnthropicChatOptions.java[AnthropicChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-cohere.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc
similarity index 99%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-cohere.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc
index 98b106e7203..c24d251c745 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-cohere.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-cohere.adoc
@@ -88,7 +88,7 @@ Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/lat
TIP: All properties prefixed with `spring.ai.bedrock.cohere.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.java[BedrockCohereChatOptions.java] provides model configurations, such as temperature, topK, topP, etc.
@@ -110,7 +110,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereChatOptions.java[BedrockCohereChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc
new file mode 100644
index 00000000000..f61756327da
--- /dev/null
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-jurassic2.adoc
@@ -0,0 +1,216 @@
+= Jurassic-2 Chat
+
+https://aws.amazon.com/bedrock/jurassic/[AI21 Labs Jurassic on Amazon Bedrock
+] Jurassic is AI21 Labs’ family of reliable FMs for the enterprise, powering sophisticated language generation tasks – such as question answering, text generation, search, and summarization – across thousands of live applications.
+
+
+== Prerequisites
+
+Refer to the xref:api/bedrock.adoc[Spring AI documentation on Amazon Bedrock] for setting up API access.
+
+=== Add Repositories and BOM
+
+Spring AI artifacts are published in Spring Milestone and Snapshot repositories. Refer to the xref:getting-started.adoc#repositories[Repositories] section to add these repositories to your build system.
+
+To help with dependency management, Spring AI provides a BOM (bill of materials) to ensure that a consistent version of Spring AI is used throughout the entire project. Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build system.
+
+
+== Auto-configuration
+
+Add the `spring-ai-bedrock-ai-spring-boot-starter` dependency to your project's Maven `pom.xml` file:
+
+[source,xml]
+----
+
+ org.springframework.ai
+ spring-ai-bedrock-ai-spring-boot-starter
+
+----
+
+or to your Gradle `build.gradle` build file.
+
+[source,gradle]
+----
+dependencies {
+ implementation 'org.springframework.ai:spring-ai-bedrock-ai-spring-boot-starter'
+}
+----
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+
+=== Enable Jurassic-2
+
+By default the Bedrock Jurassic-2 model is disabled.
+To enable it set the `spring.ai.bedrock.jurassic2.chat.enabled` property to `true`.
+Exporting environment variable is one way to set this configuration property:
+
+[source,shell]
+----
+export SPRING_AI_BEDROCK_JURASSIC2_CHAT_ENABLED=true
+----
+
+=== Chat Properties
+
+The prefix `spring.ai.bedrock.aws` is the property prefix to configure the connection to AWS Bedrock.
+
+[cols="3,3,3"]
+|====
+| Property | Description | Default
+
+| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1
+| spring.ai.bedrock.aws.access-key | AWS access key. | -
+| spring.ai.bedrock.aws.secret-key | AWS secret key. | -
+|====
+
+
+The prefix `spring.ai.bedrock.jurassic2.chat` is the property prefix that configures the chat client implementation for Jurassic-2.
+
+[cols="2,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.bedrock.jurassic2.chat.enabled | Enable or disable support for Jurassic-2 | false
+| spring.ai.bedrock.jurassic2.chat.model | The model id to use (See Below) | ai21.j2-mid-v1
+| spring.ai.bedrock.jurassic2.chat.options.temperature | Controls the randomness of the output. Values can range over [0.0,1.0], inclusive. A value closer to 1.0 will produce responses that are more varied, while a value closer to 0.0 will typically result in less surprising responses from the model. This value specifies default to be used by the backend while making the call to the model. | 0.7
+| spring.ai.bedrock.jurassic2.chat.options.top-p | The maximum cumulative probability of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least topP. | AWS Bedrock default
+| spring.ai.bedrock.jurassic2.chat.options.max-tokens | Specify the maximum number of tokens to use in the generated response. The model truncates the response once the generated text exceeds maxTokens. | 500
+|====
+
+Look at https://github.com/spring-projects/spring-ai/blob/4ba9a3cd689b9fd3a3805f540debe398a079c6ef/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java#L164[Ai21Jurassic2ChatBedrockApi#Ai21Jurassic2ChatModel] for other model IDs. The other value supported is `ai21.j2-ultra-v1`.
+Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html[AWS Bedrock documentation for base model IDs].
+
+TIP: All properties prefixed with `spring.ai.bedrock.jurassic2.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
+
+== Runtime Options [[chat-options]]
+
+The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatOptions.java[BedrockAi21Jurassic2ChatOptions.java] provides model configurations, such as temperature, topP, maxTokens, etc.
+
+On start-up, the default options can be configured with the `BedrockAi21Jurassic2ChatClient(api, options)` constructor or the `spring.ai.bedrock.jurassic2.chat.options.*` properties.
+
+At run-time you can override the default options by adding new, request specific, options to the `Prompt` call.
+For example to override the default temperature for a specific request:
+
+[source,java]
+----
+ChatResponse response = chatClient.call(
+ new Prompt(
+ "Generate the names of 5 famous pirates.",
+ BedrockAi21Jurassic2ChatOptions.builder()
+ .withTemperature(0.4)
+ .build()
+ ));
+----
+
+TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatOptions.java[BedrockAi21Jurassic2ChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
+
+== Sample Controller
+
+https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
+
+Add a `application.properties` file, under the `src/main/resources` directory, to enable and configure the Jurassic-2 Chat client:
+
+[source]
+----
+spring.ai.bedrock.aws.region=eu-central-1
+spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID}
+spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY}
+
+spring.ai.bedrock.jurassic2.chat.enabled=true
+spring.ai.bedrock.jurassic2.chat.options.temperature=0.8
+----
+
+TIP: replace the `regions`, `access-key` and `secret-key` with your AWS credentials.
+
+This will create a `BedrockAi21Jurassic2ChatClient` implementation that you can inject into your class.
+Here is an example of a simple `@Controller` class that uses the chat client for text generations.
+
+[source,java]
+----
+@RestController
+public class ChatController {
+
+ private final BedrockAi21Jurassic2ChatClient chatClient;
+
+ @Autowired
+ public ChatController(BedrockAi21Jurassic2ChatClient chatClient) {
+ this.chatClient = chatClient;
+ }
+
+ @GetMapping("/ai/generate")
+ public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
+ return Map.of("generation", chatClient.call(message));
+ }
+
+}
+----
+
+== Manual Configuration
+
+The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatClient.java[BedrockAi21Jurassic2ChatClient] implements the `ChatClient` uses the <> to connect to the Bedrock Jurassic-2 service.
+
+Add the `spring-ai-bedrock` dependency to your project's Maven `pom.xml` file:
+
+[source,xml]
+----
+
+ org.springframework.ai
+ spring-ai-bedrock
+
+----
+
+or to your Gradle `build.gradle` build file.
+
+[source,gradle]
+----
+dependencies {
+ implementation 'org.springframework.ai:spring-ai-bedrock'
+}
+----
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+
+Next, create an https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/BedrockAi21Jurassic2ChatClient.java[BedrockAi21Jurassic2ChatClient] and use it for text generations:
+
+[source,java]
+----
+Ai21Jurassic2ChatBedrockApi api = new Ai21Jurassic2ChatBedrockApi(Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(),
+ EnvironmentVariableCredentialsProvider.create(), Region.US_EAST_1.id(), new ObjectMapper());
+
+BedrockAi21Jurassic2ChatClient chatClient = new BedrockAi21Jurassic2ChatClient(api,
+ BedrockAi21Jurassic2ChatOptions.builder()
+ .withTemperature(0.5f)
+ .withMaxTokens(100)
+ .withTopP(0.9f).build());
+
+ChatResponse response = chatClient.call(
+ new Prompt("Generate the names of 5 famous pirates."));
+
+----
+
+== Low-level Client [[low-level-api]]
+
+https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java[Ai21Jurassic2ChatBedrockApi] provides a lightweight Java client on top of AWS Bedrock https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-jurassic2.html[Jurassic-2 and Jurassic-2 Chat models].
+
+The `Ai21Jurassic2ChatBedrockApi` supports the `ai21.j2-mid-v1` and `ai21.j2-ultra-v1` models and only support synchronous ( `chatCompletion()`).
+
+Here is a simple snippet on how to use the API programmatically:
+
+
+[source,java]
+----
+Ai21Jurassic2ChatBedrockApi jurassic2ChatApi = new Ai21Jurassic2ChatBedrockApi(
+ Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id(),
+ Region.US_EAST_1.id());
+
+Ai21Jurassic2ChatRequest request = Ai21Jurassic2ChatRequest.builder("Hello, my name is")
+ .withTemperature(0.9f)
+ .withTopP(0.9f)
+ .withMaxTokens(20)
+ .build();
+
+Ai21Jurassic2ChatResponse response = jurassic2ChatApi.chatCompletion(request);
+
+
+----
+
+Follow the https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/jurassic2/api/Ai21Jurassic2ChatBedrockApi.java[Ai21Jurassic2ChatBedrockApi.java]'s JavaDoc for further information.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-llama2.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc
similarity index 99%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-llama2.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc
index 25f4823db9e..8b317cd4e35 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-llama2.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-llama2.adoc
@@ -86,7 +86,7 @@ Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/lat
TIP: All properties prefixed with `spring.ai.bedrock.llama2.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java[BedrockLlama2ChatOptions.java] provides model configurations, such as temperature, topK, topP, etc.
@@ -108,7 +108,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/llama2/BedrockLlama2ChatOptions.java[BedrockLlama2ChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-titan.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc
similarity index 98%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-titan.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc
index e7ac7343511..31f54dd5f8c 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/bedrock/bedrock-titan.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/bedrock/bedrock-titan.adoc
@@ -1,6 +1,6 @@
= Titan Chat
-link:https://aws.amazon.com/bedrock/titan/[Amazon Titan] foundation models (FMs) provide customers with a breadth of high-performing image, multimodal, and text model choices, via a fully managed API.
+link:https://aws.amazon.com/bedrock/titan/[Amazon Titan] foundation models (FMs) provide customers with a breadth of high-performing image, multimodal embeddings, and text model choices, via a fully managed API.
Amazon Titan models are created by AWS and pretrained on large datasets, making them powerful, general-purpose models built to support a variety of use cases, while also supporting the responsible use of AI.
Use them as is or privately customize them with your own data.
@@ -84,7 +84,7 @@ Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/lat
TIP: All properties prefixed with `spring.ai.bedrock.titan.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.java[BedrockTitanChatOptions.java] provides model configurations, such as temperature, topP, etc.
@@ -106,7 +106,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanChatOptions.java[BedrockTitanChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -201,7 +201,7 @@ Flux response = chatClient.stream(
new Prompt("Generate the names of 5 famous pirates."));
----
-=== Low-level TitanChatBedrockApi Client [[low-level-api]]
+== Low-level TitanChatBedrockApi Client [[low-level-api]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/api/TitanChatBedrockApi.java[TitanChatBedrockApi] provides is lightweight Java client on top of AWS Bedrock link:https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html[Bedrock Titan models].
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/azure-open-ai-chat-functions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/azure-open-ai-chat-functions.adoc
similarity index 100%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/azure-open-ai-chat-functions.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/azure-open-ai-chat-functions.adoc
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/mistralai-chat-functions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/mistralai-chat-functions.adoc
similarity index 89%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/mistralai-chat-functions.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/mistralai-chat-functions.adoc
index f5a446bb300..d4ebe26cf92 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/mistralai-chat-functions.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/mistralai-chat-functions.adoc
@@ -1,4 +1,4 @@
-= Mistral Function Calling
+= Mistral AI Function Calling
You can register custom Java functions with the `MistralAiChatClient` and have the Mistral AI models intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
This allows you to connect the LLM capabilities with external tools and APIs.
@@ -6,7 +6,7 @@ The `mistral_small_latest` and `mistral_large_latest` models are trained to dete
The MistralAI API does not call the function directly; instead, the model generates JSON that you can use to call the function in your code and return the result back to the model to complete the conversation.
-NOTE: Currently the MistralAI API doesn't support parallel function calling, similarly to the OpenAI API, Azure OpenAI API, and Vertex AI Gemini API.
+NOTE: As of March 13, 2024, Mistral AI has integrated support for parallel function calling into their `mistral_large_latest`` model, a feature that was absent at the time of the first Spring AI Mistral AI.
Spring AI provides flexible and user-friendly ways to register and call custom functions.
In general, the custom functions need to provide a function `name`, `description`, and the function call `signature` (as JSON schema) to let the model know what arguments the function expects.
@@ -191,3 +191,17 @@ NOTE: The in-prompt registered functions are enabled by default for the duration
This approach allows to dynamically chose different functions to be called based on the user input.
The https://github.com/spring-projects/spring-ai/blob/main/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusPromptIT.java[PaymentStatusPromptIT.java] integration test provides a complete example of how to register a function with the `MistralAiChatClient` and use it in a prompt request.
+
+
+== Appendices
+
+=== https://spring.io/blog/2024/03/06/function-calling-in-java-and-spring-ai-using-the-latest-mistral-ai-api[(Blog) Function Calling in Java and Spring AI using the latest Mistral AI API]
+
+=== Mistral AI API Function Calling Flow
+
+The following diagram illustrates the flow of the Mistral AI low-level API for link:https://docs.mistral.ai/guides/function-calling[Function Calling]:
+
+image:mistral-ai-function-calling-flow.jpg[title="Mistral AI API Function Calling Flow", width=800, link=https://docs.mistral.ai/guides/function-calling]
+
+The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/api/tool/PaymentStatusFunctionCallingIT.java[PaymentStatusFunctionCallingIT.java] provides a complete example on how to use the Mistral AI API function calling.
+It is based on the https://docs.mistral.ai/guides/function-calling[Mistral AI Function Calling tutorial].
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/openai-chat-functions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/openai-chat-functions.adoc
similarity index 100%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/openai-chat-functions.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/openai-chat-functions.adoc
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/vertexai-gemini-chat-functions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/vertexai-gemini-chat-functions.adoc
similarity index 98%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/vertexai-gemini-chat-functions.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/vertexai-gemini-chat-functions.adoc
index 9324d390b8d..7375ca682ca 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/functions/vertexai-gemini-chat-functions.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/functions/vertexai-gemini-chat-functions.adoc
@@ -108,7 +108,7 @@ static class Config {
public record Request(String location, Unit unit) {}
----
-It is a best practice to annotate the request object with information such that the generats JSON schema of that function is as descriptive as possible to help the AI model pick the correct funciton to invoke.
+It is a best practice to annotate the request object with information such that the generates JSON schema of that function is as descriptive as possible to help the AI model pick the correct function to invoke.
The link:https://github.com/spring-projects/spring-ai/blob/main/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/gemini/tool/FunctionCallWithFunctionBeanIT.java[FunctionCallWithFunctionBeanIT.java] demonstrates this approach.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/google-vertexai.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/google-vertexai.adoc
similarity index 75%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/google-vertexai.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/google-vertexai.adoc
index 68257e3dddf..55d20942970 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/google-vertexai.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/google-vertexai.adoc
@@ -5,5 +5,5 @@ link:https://cloud.google.com/vertex-ai/docs/reference[VertexAI API] provides hi
Spring AI provides integration with VertexAI API through the following clients:
-* xref:api/clients/vertexai-palm2-chat.adoc[]
-* xref:api/clients/vertexai-gemini-chat.adoc[]
\ No newline at end of file
+* xref:api/chat/vertexai-palm2-chat.adoc[]
+* xref:api/chat/vertexai-gemini-chat.adoc[]
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/huggingface.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/huggingface.adoc
similarity index 100%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/huggingface.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/huggingface.adoc
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/mistralai-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/mistralai-chat.adoc
similarity index 90%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/mistralai-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/mistralai-chat.adoc
index faf9d3b9720..5395ae05b53 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/mistralai-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/mistralai-chat.adoc
@@ -49,6 +49,24 @@ TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Man
=== Chat Properties
+==== Retry Properties
+
+The prefix `spring.ai.retry` is used as the property prefix that lets you configure the retry mechanism for the Mistral AI Chat client.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10
+| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec.
+| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5
+| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min.
+| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for `4xx` client error codes | false
+| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). | empty
+|====
+
+==== Connection Properties
+
The prefix `spring.ai.mistralai` is used as the property prefix that lets you connect to OpenAI.
[cols="3,5,1"]
@@ -59,6 +77,8 @@ The prefix `spring.ai.mistralai` is used as the property prefix that lets you co
| spring.ai.mistralai.api-key | The API Key | -
|====
+==== Configuration Properties
+
The prefix `spring.ai.mistralai.chat` is the property prefix that lets you configure the chat client implementation for MistralAI.
[cols="3,5,1"]
@@ -88,7 +108,7 @@ This is useful if you want to use different MistralAI accounts for different mod
TIP: All properties prefixed with `spring.ai.mistralai.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java[MistralAiChatOptions.java] provides model configurations, such as the model to use, the temperature, the frequency penalty, etc.
@@ -111,7 +131,13 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java[MistralAiChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Function Calling
+
+You can register custom Java functions with the MistralAiChatClient and have the Mistral AI model intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
+This is a powerful technique to connect the LLM capabilities with external tools and APIs.
+Read more about xref:api/chat/functions/mistralai-chat-functions.adoc[Mistral AI Function Calling].
+
+== Sample Controller (Auto-configuration)
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-mistralai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/ollama-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc
similarity index 97%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/ollama-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc
index 6eac5cea9c0..caf8130479e 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/ollama-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/ollama-chat.adoc
@@ -61,7 +61,6 @@ NOTE: The `options` properties are based on the link:https://github.com/jmorganc
| Property | Description | Default
| spring.ai.ollama.chat.enabled | Enable Ollama chat client. | true
-| spring.ai.ollama.chat.model (DEPRECATED) | The name of the model to use. Deprecated use the `spring.ai.ollama.chat.options.model` instead | mistral
| spring.ai.ollama.chat.options.model | The name of the https://github.com/ollama/ollama?tab=readme-ov-file#model-library[supported models] to use. | mistral
| spring.ai.ollama.chat.options.numa | Whether to use NUMA. | false
| spring.ai.ollama.chat.options.num-ctx | Sets the size of the context window used to generate the next token. | 2048
@@ -103,7 +102,7 @@ NOTE: The list of options for chat is to be reviewed. This https://github.com/sp
TIP: All properties prefixed with `spring.ai.ollama.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions.java] provides model configurations, such as the model to use, the temperature, etc.
@@ -125,7 +124,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-openai-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -134,7 +133,7 @@ Add a `application.properties` file, under the `src/main/resources` directory, t
[source,application.properties]
----
spring.ai.ollama.base-url=http://localhost:11434
-spring.ai.ollama.chat.model=mistral
+spring.ai.ollama.chat.options.model=mistral
spring.ai.ollama.chat.options.temperature=0.7
----
@@ -219,7 +218,7 @@ Flux response = chatClient.stream(
The `OllamaOptions` provides the configuration information for all chat requests.
-=== Low-level OpenAiApi Client [[low-level-api]]
+== Low-level OpenAiApi Client [[low-level-api]]
The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java[OllamaApi] provides is lightweight Java client for Ollama Chat API link:https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-chat-completion[Ollama Chat Completion API].
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/openai-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/openai-chat.adoc
similarity index 92%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/openai-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/openai-chat.adoc
index 2d184853c39..e098ba29ac2 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/openai-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/openai-chat.adoc
@@ -49,6 +49,24 @@ TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Man
=== Chat Properties
+==== Retry Properties
+
+The prefix `spring.ai.retry` is used as the property prefix that lets you configure the retry mechanism for the OpenAI Chat client.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10
+| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec.
+| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5
+| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min.
+| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for `4xx` client error codes | false
+| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). | empty
+|====
+
+==== Connection Properties
+
The prefix `spring.ai.openai` is used as the property prefix that lets you connect to OpenAI.
[cols="3,5,1"]
@@ -59,6 +77,9 @@ The prefix `spring.ai.openai` is used as the property prefix that lets you conne
| spring.ai.openai.api-key | The API Key | -
|====
+
+==== Configuration Properties
+
The prefix `spring.ai.openai.chat` is the property prefix that lets you configure the chat client implementation for OpenAI.
[cols="3,5,1"]
@@ -91,7 +112,7 @@ This is useful if you want to use different OpenAI accounts for different models
TIP: All properties prefixed with `spring.ai.openai.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java[OpenAiChatOptions.java] provides model configurations, such as the model to use, the temperature, the frequency penalty, etc.
@@ -114,13 +135,13 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatOptions.java[OpenAiChatOptions] you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Function Calling
+== Function Calling
You can register custom Java functions with the OpenAiChatClient and have the OpenAI model intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
This is a powerful technique to connect the LLM capabilities with external tools and APIs.
-Read more about xref:api/clients/functions/openai-chat-functions.adoc[OpenAI Function Calling].
+Read more about xref:api/chat/functions/openai-chat-functions.adoc[OpenAI Function Calling].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-openai-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -196,7 +217,7 @@ var openAiApi = new OpenAiApi(System.getenv("OPENAI_API_KEY"));
var chatClient = new OpenAiChatClient(openAiApi)
.withDefaultOptions(OpenAiChatOptions.builder()
- .withModel("gpt-35-turbo")
+ .withModel("gpt-3.5-turbo")
.withTemperature(0.4)
.withMaxTokens(200)
.build());
@@ -212,7 +233,7 @@ Flux response = chatClient.stream(
The `OpenAiChatOptions` provides the configuration information for the chat requests.
The `OpenAiChatOptions.Builder` is fluent options builder.
-=== Low-level OpenAiApi Client [[low-level-api]]
+== Low-level OpenAiApi Client [[low-level-api]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java[OpenAiApi] provides is lightweight Java client for OpenAI Chat API link:https://platform.openai.com/docs/api-reference/chat[OpenAI Chat API].
@@ -241,7 +262,7 @@ Flux streamResponse = openAiApi.chatCompletionStream(
Follow the https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java[OpenAiApi.java]'s JavaDoc for further information.
-==== OpenAiApi Samples
+=== Low-level API Examples
* The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/OpenAiApiIT.java[OpenAiApiIT.java] test provides some general examples how to use the lightweight library.
* The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/api/tool/OpenAiApiToolFunctionCallIT.java[OpenAiApiToolFunctionCallIT.java] test shows how to use the low-level API to call tool functions.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-gemini-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc
similarity index 82%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-gemini-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc
index 4cbed2693b7..f1d047ad963 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-gemini-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc
@@ -1,7 +1,5 @@
= VertexAI Gemini Chat
-
-
The https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/overview[Vertex AI Gemini API] allows developers to build generative AI applications using the Gemini model.
The Vertex AI Gemini API supports multimodal prompts as input and output text or code.
A multimodal model is a model that is capable of processing information from multiple modalities, including images, videos, and text. For example, you can send the model a photo of a plate of cookies and ask it to give you a recipe for those cookies.
@@ -64,7 +62,7 @@ The prefix `spring.ai.vertex.ai.gemini.chat` is the property prefix that lets yo
|====
| Property | Description | Default
-| spring.ai.vertex.ai.gemini.chat.model | This is the https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini[Vertex AI Gemini Chat model] to use | gemini-pro-vision
+| spring.ai.vertex.ai.gemini.chat.options.model | This is the https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini[Vertex AI Gemini Chat model] to use | gemini-pro-vision
| spring.ai.vertex.ai.gemini.chat.options.temperature | Controls the randomness of the output. Values can range over [0.0,1.0], inclusive. A value closer to 1.0 will produce responses that are more varied, while a value closer to 0.0 will typically result in less surprising responses from the generative. This value specifies default to be used by the backend while making the call to the generative. | 0.8
| spring.ai.vertex.ai.gemini.chat.options.topK | The maximum number of tokens to consider when sampling. The generative uses combined Top-k and nucleus sampling. Top-k sampling considers the set of topK most probable tokens. | -
| spring.ai.vertex.ai.gemini.chat.options.topP | The maximum cumulative probability of tokens to consider when sampling. The generative uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least topP. | -
@@ -79,13 +77,13 @@ The prefix `spring.ai.vertex.ai.gemini.chat` is the property prefix that lets yo
TIP: All properties prefixed with `spring.ai.vertex.ai.gemini.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java[VertexAiGeminiChatOptions.java] provides model configurations, such as the temperature, the topK, etc.
On start-up, the default options can be configured with the `VertexAiGeminiChatClient(api, options)` constructor or the `spring.ai.vertex.ai.chat.options.*` properties.
-At run-time you can override the default options by adding new, request specific, options to the `Prompt` call.
+At runtime you can override the default options by adding new, request specific, options to the `Prompt` call.
For example to override the default temperature for a specific request:
[source,java]
@@ -101,14 +99,34 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific `VertexAiChatPaLm2Options` you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Function Calling
+== Function Calling
You can register custom Java functions with the VertexAiGeminiChatClient and have the Gemini Pro model intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
This is a powerful technique to connect the LLM capabilities with external tools and APIs.
-Read more about xref:api/clients/functions/vertexai-gemini-chat-functions.adoc[Vertex AI Gemini Function Calling].
+Read more about xref:api/chat/functions/vertexai-gemini-chat-functions.adoc[Vertex AI Gemini Function Calling].
+
+== Multimodal
+Multimodality refers to a model's ability to simultaneously understand and process information from various sources, including text, images, audio, and other data formats. This paradigm represents a significant advancement in AI models.
+
+Google's Gemini AI models support this capability by comprehending and integrating text, code, audio, images, and video. For more details, refer to the blog post https://blog.google/technology/ai/google-gemini-ai/#introducing-gemini[Introducing Gemini].
+Spring AI's `Message` interface supports multimodal AI models by introducing the Media type.
+This type contains data and information about media attachments in messages, using Spring's `org.springframework.util.MimeType` and a `java.lang.Object` for the raw media data.
-=== Sample Controller (Auto-configuration)
+Below is a simple code example extracted from https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.java[VertexAiGeminiChatClientIT.java], demonstrating the combination of user text with an image.
+
+
+[source,java]
+----
+byte[] data = new ClassPathResource("/vertex-test.png").getContentAsByteArray();
+
+var userMessage = new UserMessage("Explain what do you see o this picture?",
+ List.of(new Media(MimeTypeUtils.IMAGE_PNG, data)));
+
+ChatResponse response = chatClient.call(new Prompt(List.of(userMessage)));
+----
+
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-vertex-ai-palm2-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -195,6 +213,3 @@ ChatResponse response = chatClient.call(
The `VertexAiGeminiChatOptions` provides the configuration information for the chat requests.
The `VertexAiGeminiChatOptions.Builder` is fluent options builder.
-=== Multi-modal
-
-https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatClientIT.java[VertexAiGeminiChatClientIT.java]
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-palm2-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-palm2-chat.adoc
similarity index 99%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-palm2-chat.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-palm2-chat.adoc
index cc8240ce1a6..f67a467f059 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/vertexai-palm2-chat.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-palm2-chat.adoc
@@ -77,7 +77,7 @@ The prefix `spring.ai.vertex.ai.chat` is the property prefix that lets you confi
TIP: All properties prefixed with `spring.ai.vertex.ai.chat.options` can be overridden at runtime by adding a request specific <> to the `Prompt` call.
-=== Chat Options [[chat-options]]
+== Runtime Options [[chat-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/VertexAiPaLm2ChatOptions.java[VertexAiPaLm2ChatOptions.java] provides model configurations, such as the temperature, the topK, etc.
@@ -99,7 +99,7 @@ ChatResponse response = chatClient.call(
TIP: In addition to the model specific `VertexAiPaLm2ChatOptions` you can use a portable https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptions.java[ChatOptions] instance, created with the https://github.com/spring-projects/spring-ai/blob/main/spring-ai-core/src/main/java/org/springframework/ai/chat/ChatOptionsBuilder.java[ChatOptionsBuilder#builder()].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-vertex-ai-palm2-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc
index 128f8aea7b4..ab414d52e54 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc
@@ -175,18 +175,19 @@ The `ChatClient` and `StreamingChatClient` implementations are provided for the
image::spring-ai-chat-completions-clients.jpg[align="center", width="800px"]
-* xref:api/clients/openai-chat.adoc[OpenAI Chat Completion] (streaming & function-calling support)
-* xref:api/clients/azure-openai-chat.adoc[Microsoft Azure Open AI Chat Completion] (streaming & function-calling support)
-* xref:api/clients/ollama-chat.adoc[Ollama Chat Completion]
-* xref:api/clients/huggingface.adoc[HuggingFace Chat Completion] (no streaming support)
-* xref:api/clients/vertexai-palm2-chat.adoc[Google Vertex AI PaLM2 Chat Completion] (no streaming support)
-* xref:api/clients/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support)
+* xref:api/chat/openai-chat.adoc[OpenAI Chat Completion] (streaming & function-calling support)
+* xref:api/chat/azure-openai-chat.adoc[Microsoft Azure Open AI Chat Completion] (streaming & function-calling support)
+* xref:api/chat/ollama-chat.adoc[Ollama Chat Completion]
+* xref:api/chat/huggingface.adoc[HuggingFace Chat Completion] (no streaming support)
+* xref:api/chat/vertexai-palm2-chat.adoc[Google Vertex AI PaLM2 Chat Completion] (no streaming support)
+* xref:api/chat/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support)
* xref:api/bedrock.adoc[Amazon Bedrock]
-** xref:api/clients/bedrock/bedrock-cohere.adoc[Cohere Chat Completion]
-** xref:api/clients/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion]
-** xref:api/clients/bedrock/bedrock-titan.adoc[Titan Chat Completion]
-** xref:api/clients/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion]
-* xref:api/clients/mistralai-chat.adoc[Mistral AI Chat Completion] (streaming & function-calling support)
+** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere Chat Completion]
+** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion]
+** xref:api/chat/bedrock/bedrock-titan.adoc[Titan Chat Completion]
+** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion]
+** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2 Chat Completion]
+* xref:api/chat/mistralai-chat.adoc[Mistral AI Chat Completion] (streaming & function-calling support)
== Chat Model API
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/azure-openai-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/azure-openai-embeddings.adoc
index e2e31fcee58..b470a97cce5 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/azure-openai-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/azure-openai-embeddings.adoc
@@ -74,13 +74,13 @@ The prefix `spring.ai.azure.openai.embeddings` is the property prefix that confi
| spring.ai.azure.openai.embedding.enabled | Enable Azure OpenAI embedding client. | true
| spring.ai.azure.openai.embedding.metadata-mode | Document content extraction mode | EMBED
-| spring.ai.azure.openai.embedding.options.model | This is the value of the 'Deployment Name' as presented in the Azure AI Portal | text-embedding-ada-002
+| spring.ai.azure.openai.embedding.options.deployment-name | This is the value of the 'Deployment Name' as presented in the Azure AI Portal | text-embedding-ada-002
| spring.ai.azure.openai.embedding.options.user | An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. | -
|====
TIP: All properties prefixed with `spring.ai.azure.openai.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== Embedding Options [[embedding-options]]
+== Runtime Options [[embedding-options]]
The `AzureOpenAiEmbeddingOptions` provides the configuration information for the embedding requests.
The `AzureOpenAiEmbeddingOptions` offers a builder to create the options.
@@ -100,7 +100,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
----
-=== Sample Code
+== Sample Code
This will create a `EmbeddingClient` implementation that you can inject into your class.
Here is an example of a simple `@Controller` class that uses the `EmbeddingClient` implementation.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-cohere-embedding.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-cohere-embedding.adoc
index d8b811553c5..2d596bb4b96 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-cohere-embedding.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-cohere-embedding.adoc
@@ -69,7 +69,7 @@ The prefix `spring.ai.bedrock.cohere.embedding` (defined in `BedrockCohereEmbedd
| Property | Description | Default
| spring.ai.bedrock.cohere.embedding.enabled | Enable or disable support for Cohere | false
| spring.ai.bedrock.cohere.embedding.model | The model id to use. See the https://github.com/spring-projects/spring-ai/blob/056b95a00efa5b014a1f488329fbd07a46c02378/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/api/CohereEmbeddingBedrockApi.java#L150[CohereEmbeddingModel] for the supported models. | cohere.embed-multilingual-v3
-| spring.ai.bedrock.cohere.embedding.options.input-type | Prepends special tokens to differentiate each type from one another. You should not mix different types together, except when mixing types for for search and retrieval. In this case, embed your corpus with the search_document type and embedded queries with type search_query type. | SEARCH_DOCUMENT
+| spring.ai.bedrock.cohere.embedding.options.input-type | Prepends special tokens to differentiate each type from one another. You should not mix different types together, except when mixing types for search and retrieval. In this case, embed your corpus with the search_document type and embedded queries with type search_query type. | SEARCH_DOCUMENT
| spring.ai.bedrock.cohere.embedding.options.truncate | Specifies how the API handles inputs longer than the maximum token length. If you specify LEFT or RIGHT, the model discards the input until the remaining input is exactly the maximum input token length for the model. | NONE
|====
@@ -79,7 +79,7 @@ Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/lat
TIP: All properties prefixed with `spring.ai.bedrock.cohere.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== Embedding Options [[embedding-options]]
+== Runtime Options [[embedding-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java[BedrockCohereEmbeddingOptions.java] provides model configurations, such as `input-type` or `truncate`.
@@ -97,7 +97,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
.build()));
----
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-titan-embedding.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-titan-embedding.adoc
index 70c9836f048..6d5d675a06c 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-titan-embedding.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/bedrock-titan-embedding.adoc
@@ -1,7 +1,7 @@
= Titan Embeddings
Provides Bedrock Titan Embedding client.
-link:https://aws.amazon.com/bedrock/titan/[Amazon Titan] foundation models (FMs) provide customers with a breadth of high-performing image, multimodal, and text model choices, via a fully managed API.
+link:https://aws.amazon.com/bedrock/titan/[Amazon Titan] foundation models (FMs) provide customers with a breadth of high-performing image, multimodal embeddings, and text model choices, via a fully managed API.
Amazon Titan models are created by AWS and pretrained on large datasets, making them powerful, general-purpose models built to support a variety of use cases, while also supporting the responsible use of AI.
Use them as is or privately customize them with your own data.
@@ -82,7 +82,7 @@ Supported values are: `amazon.titan-embed-image-v1` and `amazon.titan-embed-text
Model ID values can also be found in the https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids-arns.html[AWS Bedrock documentation for base model IDs].
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-bedrock-ai-spring-boot-starter` to your pom (or gradle) dependencies.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/mistralai-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/mistralai-embeddings.adoc
index 3c0379eecc9..b049c030f51 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/mistralai-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/mistralai-embeddings.adoc
@@ -49,6 +49,24 @@ TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Man
=== Embedding Properties
+==== Retry Properties
+
+The prefix `spring.ai.retry` is used as the property prefix that lets you configure the retry mechanism for the Mistral AI Embedding client.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10
+| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec.
+| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5
+| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min.
+| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for `4xx` client error codes | false
+| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). | empty
+|====
+
+==== Connection Properties
+
The prefix `spring.ai.mistralai` is used as the property prefix that lets you connect to MistralAI.
[cols="3,5,1"]
@@ -59,6 +77,8 @@ The prefix `spring.ai.mistralai` is used as the property prefix that lets you co
| spring.ai.mistralai.api-key | The API Key | -
|====
+==== Configuration Properties
+
The prefix `spring.ai.mistralai.embedding` is property prefix that configures the `EmbeddingClient` implementation for MistralAI.
[cols="3,5,1"]
@@ -80,7 +100,7 @@ This is useful if you want to use different MistralAI accounts for different mod
TIP: All properties prefixed with `spring.ai.mistralai.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== Embedding Options [[embedding-options]]
+== Runtime Options [[embedding-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java[MistralAiEmbeddingOptions.java] provides the MistralAI configurations, such as the model to use and etc.
@@ -100,7 +120,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
.build()));
----
-=== Sample Controller (Auto-configuration)
+== Sample Controller
This will create a `EmbeddingClient` implementation that you can inject into your class.
Here is an example of a simple `@Controller` class that uses the `EmbeddingClient` implementation.
@@ -155,7 +175,7 @@ dependencies {
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
NOTE: The `spring-ai-mistralai` dependency provides access also to the `MistralAiChatClient`.
-For more information about the `MistralAiChatClient` refer to the link:../clients/mistralai-chat.html[MistralAI Chat Client] section.
+For more information about the `MistralAiChatClient` refer to the link:../chat/mistralai-chat.html[MistralAI Chat Client] section.
Next, create an `MistralAiEmbeddingClient` instance and use it to compute the similarity between two input texts:
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/ollama-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/ollama-embeddings.adoc
index 8f7441b9936..ff25355177f 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/ollama-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/ollama-embeddings.adoc
@@ -108,9 +108,9 @@ NOTE: The `spring.ai.ollama.embedding.options.*` properties are based on the htt
TIP: All properties prefixed with `spring.ai.ollama.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== Embedding Options [[embedding-options]]
+== Runtime Options [[embedding-options]]
-The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions.java] provides the Ollama configurations, such as the model to use, the low level GPU and CPU tunning, etc.
+The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions.java] provides the Ollama configurations, such as the model to use, the low level GPU and CPU tuning, etc.
The default options can be configured using the `spring.ai.ollama.embedding.options` properties as well.
@@ -127,7 +127,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
.withModel("Different-Embedding-Model-Deployment-Name"));
----
-=== Sample Controller (Auto-configuration)
+== Sample Controller
This will create a `EmbeddingClient` implementation that you can inject into your class.
Here is an example of a simple `@Controller` class that uses the `EmbeddingClient` implementation.
@@ -177,7 +177,7 @@ dependencies {
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
NOTE: The `spring-ai-ollama` dependency provides access also to the `OllamaChatClient`.
-For more information about the `OllamaChatClient` refer to the link:../clients/ollama-chat.html[Ollama Chat Client] section.
+For more information about the `OllamaChatClient` refer to the link:../chat/ollama-chat.html[Ollama Chat Client] section.
Next, create an `OllamaEmbeddingClient` instance and use it to compute the similarity between two input texts:
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/openai-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/openai-embeddings.adoc
index 9a9d3c2e5b7..92d55a9d663 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/openai-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/openai-embeddings.adoc
@@ -50,6 +50,24 @@ TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Man
=== Embedding Properties
+==== Retry Properties
+
+The prefix `spring.ai.retry` is used as the property prefix that lets you configure the retry mechanism for the OpenAI Embedding client.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10
+| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec.
+| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5
+| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min.
+| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for `4xx` client error codes | false
+| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). | empty
+|====
+
+==== Connection Properties
+
The prefix `spring.ai.openai` is used as the property prefix that lets you connect to OpenAI.
[cols="3,5,1"]
@@ -60,6 +78,8 @@ The prefix `spring.ai.openai` is used as the property prefix that lets you conne
| spring.ai.openai.api-key | The API Key | -
|====
+==== Configuration Properties
+
The prefix `spring.ai.openai.embedding` is property prefix that configures the `EmbeddingClient` implementation for OpenAI.
[cols="3,5,1"]
@@ -82,7 +102,7 @@ This is useful if you want to use different OpenAI accounts for different models
TIP: All properties prefixed with `spring.ai.openai.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== Embedding Options [[embedding-options]]
+== Runtime Options [[embedding-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java[OpenAiEmbeddingOptions.java] provides the OpenAI configurations, such as the model to use and etc.
@@ -102,7 +122,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
.build()));
----
-=== Sample Controller (Auto-configuration)
+== Sample Controller
This will create a `EmbeddingClient` implementation that you can inject into your class.
Here is an example of a simple `@Controller` class that uses the `EmbeddingClient` implementation.
@@ -157,7 +177,7 @@ dependencies {
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
NOTE: The `spring-ai-openai` dependency provides access also to the `OpenAiChatClient`.
-For more information about the `OpenAiChatClient` refer to the link:../clients/openai-chat.html[OpenAI Chat Client] section.
+For more information about the `OpenAiChatClient` refer to the link:../chat/openai-chat.html[OpenAI Chat Client] section.
Next, create an `OpenAiEmbeddingClient` instance and use it to compute the similarity between two input texts:
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/postgresml-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/postgresml-embeddings.adoc
index 7cf230ad683..a8a506a3fea 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/postgresml-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/postgresml-embeddings.adoc
@@ -59,7 +59,7 @@ The prefix `spring.ai.postgresml.embedding` is property prefix that configures t
TIP: All properties prefixed with `spring.ai.postgresml.embedding.options` can be overridden at runtime by adding a request specific <> to the `EmbeddingRequest` call.
-=== EmbeddingOptions [[embedding-options]]
+== Runtime Options [[embedding-options]]
Use the https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java[PostgresMlEmbeddingOptions.java] to configure the `PostgresMlEmbeddingClient` with options, such as the model to use and etc.
@@ -82,7 +82,7 @@ EmbeddingResponse embeddingResponse = embeddingClient.call(
.build()));
----
-=== Sample Controller (Auto-configuration)
+== Sample Controller
This will create a `EmbeddingClient` implementation that you can inject into your class.
Here is an example of a simple `@Controller` class that uses the `EmbeddingClient` implementation.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings.adoc
index 267ab827326..d66b940713c 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings.adoc
@@ -72,7 +72,7 @@ The prefix `spring.ai.vertex.ai.embedding` is the property prefix that lets you
|====
-=== Sample Controller (Auto-configuration)
+== Sample Controller
https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-vertex-ai-palm2-spring-boot-starter` to your pom (or gradle) dependencies.
@@ -146,7 +146,7 @@ EmbeddingResponse embeddingResponse = embeddingClient
.embedForResponse(List.of("Hello World", "World is big and salvation is near"));
----
-=== Low-level VertexAiPaLm2Api Client [[low-level-api]]
+== Low-level VertexAiPaLm2Api Client [[low-level-api]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-vertex-ai-palm2/src/main/java/org/springframework/ai/vertexai/palm2/api/VertexAiPaLm2Api.java[VertexAiPaLm2Api] provides is lightweight Java client for VertexAiPaLm2Api Chat API.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/etl-pipeline.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/etl-pipeline.adoc
index a7fa6e6d7b8..87b237a4cec 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/etl-pipeline.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/etl-pipeline.adoc
@@ -18,6 +18,8 @@ The `Document` class contains text and metadata and is created from PDFs, text f
To construct a simple ETL pipeline, you can chain together an instance of each type.
+image::etl-pipeline.jpg[align="center"]
+
Let's say we have the following instances of those three ETL types
* `PagePdfDocumentReader` an implementation of `DocumentReader`
@@ -44,6 +46,10 @@ spring boot new --from ai-rag --name myrag
. Consult the generated `README.md` file for guidance on obtaining an OpenAI API Key and running your first AI RAG application.
== ETL Interfaces and Implementations
+
+The ETL pipeline is composed of the following interfaces and implementations.
+Detailed ETL class diagram is shown in the <> section.
+
=== DocumentReader
Provides a source of documents from diverse origins.
@@ -209,9 +215,18 @@ public interface DocumentWriter extends Consumer> {
}
```
+==== FileDocumentWriter
+Persist documents to a file .
-== Available Implementations
-
-There is an implementation for each of the Vector Stores that Spring AI supports, e.g. `PineconeVectorStore`.
+==== VectorStore
+Provides integration with various vector stores.
See xref:api/vectordbs.adoc[Vector DB Documentation] for a full listing.
+
+[[etl-class-diagram]]
+=== ETL Class Diagram
+
+The following class diagram illustrates the ETL interfaces and implementations.
+
+// image::etl-class-diagram.jpg[align="center", width="800px"]
+image::etl-class-diagram.jpg[align="center"]
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/functions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/functions.adoc
index e23b43c1b09..c8a7e5f9288 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/functions.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/functions.adoc
@@ -5,7 +5,7 @@ The integration of function support in AI models, such as ChatGPT, permits the m
Spring AI currently supports Function invocation for the following AI Models
-* OpenAI: Refer to the xref:api/clients/functions/openai-chat-functions.adoc[Open AI function invocation docs].
-* VertexAI Gemini: Refer to the xref:api/clients/functions/vertexai-gemini-chat-functions.adoc[Vertex AI Gemini function invocation docs].
-* Azure OpenAI: Refer to the xref:api/clients/functions/azure-open-ai-chat-functions.adoc[Azure OpenAI function invocation docs].
-* Mistral AI: Refer to the xref:api/clients/functions/mistralai-chat-functions.adoc[Mistral AI function invocation docs].
\ No newline at end of file
+* OpenAI: Refer to the xref:api/chat/functions/openai-chat-functions.adoc[Open AI function invocation docs].
+* VertexAI Gemini: Refer to the xref:api/chat/functions/vertexai-gemini-chat-functions.adoc[Vertex AI Gemini function invocation docs].
+* Azure OpenAI: Refer to the xref:api/chat/functions/azure-open-ai-chat-functions.adoc[Azure OpenAI function invocation docs].
+* Mistral AI: Refer to the xref:api/chat/functions/mistralai-chat-functions.adoc[Mistral AI function invocation docs].
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/generic-model.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/generic-model.adoc
index 2bebd053b17..197fccb9901 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/generic-model.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/generic-model.adoc
@@ -31,7 +31,7 @@ public interface ModelClient, TRes extends ModelRes
== StreamingModelClient
-The StreamingModelClient interface provides a generic API for invoking a AI models with streaming response. It abstracts the process of sending requests and receiving a streaming responses. The interface uses Java generics to accommodate different types of requests and responses, enhancing flexibility and adaptability across different AI model implementations.
+The StreamingModelClient interface provides a generic API for invoking an AI models with streaming response. It abstracts the process of sending requests and receiving a streaming responses. The interface uses Java generics to accommodate different types of requests and responses, enhancing flexibility and adaptability across different AI model implementations.
[source,java]
----
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/openai-image.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/openai-image.adoc
similarity index 82%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/openai-image.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/openai-image.adoc
index 3ac1ccd5b71..0fcef6cd701 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/openai-image.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/openai-image.adoc
@@ -1,7 +1,7 @@
= OpenAI Image Generation
-Spring AI supports ChatGPT's DALL-E, the Image generation model from OpenAI.
+Spring AI supports DALL-E, the Image generation model from OpenAI.
== Prerequisites
@@ -41,14 +41,6 @@ TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Man
=== Image Generation Properties
-The prefix `spring.ai.openai` is used as the property prefix that lets you connect to OpenAI.
-
-[cols="3,5,1"]
-|====
-| Property | Description | Default
-| spring.ai.openai.base-url | The URL to connect to | https://api.openai.com
-| spring.ai.openai.api-key | The API Key | -
-|====
The prefix `spring.ai.openai.image` is the property prefix that lets you configure the `ImageClient` implementation for OpenAI.
@@ -69,13 +61,44 @@ The prefix `spring.ai.openai.image` is the property prefix that lets you configu
| `spring.ai.openai.image.options.user` | A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. | -
|====
-=== Image Options [[image-options]]
+==== Connection Properties
+
+The prefix `spring.ai.openai` is used as the property prefix that lets you connect to OpenAI.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+| spring.ai.openai.base-url | The URL to connect to | https://api.openai.com
+| spring.ai.openai.api-key | The API Key | -
+|====
+
+==== Configuration Properties
+
+
+==== Retry Properties
+
+The prefix `spring.ai.retry` is used as the property prefix that lets you configure the retry mechanism for the OpenAI Image client.
+
+[cols="3,5,1"]
+|====
+| Property | Description | Default
+
+| spring.ai.retry.max-attempts | Maximum number of retry attempts. | 10
+| spring.ai.retry.backoff.initial-interval | Initial sleep duration for the exponential backoff policy. | 2 sec.
+| spring.ai.retry.backoff.multiplier | Backoff interval multiplier. | 5
+| spring.ai.retry.backoff.max-interval | Maximum backoff duration. | 3 min.
+| spring.ai.retry.on-client-errors | If false, throw a NonTransientAiException, and do not attempt retry for `4xx` client error codes | false
+| spring.ai.retry.exclude-on-http-codes | List of HTTP status codes that should not trigger a retry (e.g. to throw NonTransientAiException). | empty
+|====
+
+
+== Runtime Options [[image-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageOptions.java[OpenAiImageOptions.java] provides model configurations, such as the model to use, the quality, the size, etc.
On start-up, the default options can be configured with the `OpenAiImageClient(OpenAiImageApi openAiImageApi)` constructor and the `withDefaultOptions(OpenAiImageOptions defaultOptions)` method. Alternatively, use the `spring.ai.openai.image.options.*` properties described previously.
-At run-time you can override the default options by adding new, request specific, options to the `ImagePrompt` call.
+At runtime you can override the default options by adding new, request specific, options to the `ImagePrompt` call.
For example to override the OpenAI specific options such as quality and the number of images to create, use the following code example:
[source,java]
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/stabilityai-image.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/stabilityai-image.adoc
similarity index 98%
rename from spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/stabilityai-image.adoc
rename to spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/stabilityai-image.adoc
index 07d5a4fe5a7..6cb28510eb7 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/image/stabilityai-image.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/image/stabilityai-image.adoc
@@ -74,13 +74,13 @@ The prefix `spring.ai.stabilityai.image` is the property prefix that lets you co
|====
-=== Image Options [[image-options]]
+== Runtime Options [[image-options]]
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-stabilityai/src/main/java/org/springframework/ai/stabilityai/api/StabilityAiImageOptions.java[StabilityAiImageOptions.java] provides model configurations, such as the model to use, the style, the size, etc.
On start-up, the default options can be configured with the `StabilityAiImageClient(StabilityAiApi stabilityAiApi, StabilityAiImageOptions options)` constructor. Alternatively, use the `spring.ai.openai.image.options.*` properties described previously.
-At run-time you can override the default options by adding new, request specific, options to the `ImagePrompt` call.
+At runtime, you can override the default options by adding new, request specific, options to the `ImagePrompt` call.
For example to override the Stability AI specific options such as quality and the number of images to create, use the following code example:
[source,java]
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/imageclient.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/imageclient.adoc
index 204cf40094d..3d73ce0613a 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/imageclient.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/imageclient.adoc
@@ -159,8 +159,8 @@ public class ImageGeneration implements ModelResult {
`ImageClient` implementations are provided for the following Model providers:
-* xref:api/clients/image/openai-image.adoc[OpenAI Image Generation]
-* xref:api/clients/image/stabilityai-image.adoc[StabilityAI Image Generation]
+* xref:api/image/openai-image.adoc[OpenAI Image Generation]
+* xref:api/image/stabilityai-image.adoc[StabilityAI Image Generation]
== API Docs
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/output-parser.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/output-parser.adoc
index 4fd5a6eb1f3..d919c5e1fec 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/output-parser.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/output-parser.adoc
@@ -43,7 +43,7 @@ public interface FormatProvider {
The `Parser` interface parses text strings to produce instances of the type T.
-The `FormatProvider` provides text instructions for the AI Model to format the output so that it an be parsed into the type T by the `Parser`.
+The `FormatProvider` provides text instructions for the AI Model to format the output so that it can be parsed into the type T by the `Parser`.
These text instructions are most often appended to the end of the user input to the AI Model.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/prompt.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/prompt.adoc
index 39290a10665..054d829bdce 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/prompt.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/prompt.adoc
@@ -45,16 +45,19 @@ public class Prompt {
=== Message
-The `Message` interface encapsulates a textual message, a collection of attributes as a `Map`, and a categorization known as `MessageType`. The interface is defined as follows:
+The `Message` interface encapsulates a textual message, a collection of attributes as a `Map`, a categorization known as `MessageType`, and a list of media objects for those models that are multimodal.
+The interface is defined as follows:
```java
public interface Message {
- String getContent();
+ String getContent();
- Map getProperties();
+ List getMedia();
- MessageType getMessageType();
+ Map getProperties();
+
+ MessageType getMessageType();
}
```
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions.adoc
new file mode 100644
index 00000000000..703f19908ec
--- /dev/null
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions.adoc
@@ -0,0 +1,5 @@
+[[Transcription]]
+= Transcription API
+
+Spring AI provides support for OpenAI's Transcription API.
+When additional providers for Transcription are implemented, a common `AudioTranscriptionClient` interface will be extracted.
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions/openai-transcriptions.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions/openai-transcriptions.adoc
new file mode 100644
index 00000000000..5592aa26652
--- /dev/null
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/transcriptions/openai-transcriptions.adoc
@@ -0,0 +1,118 @@
+== OpenAI Transcriptions
+
+Spring AI supports https://platform.openai.com/docs/api-reference/audio/createTranscription[OpenAI's Transcription model].
+
+== Prerequisites
+
+
+You will need to create an API key with OpenAI to access ChatGPT models.
+Create an account at https://platform.openai.com/signup[OpenAI signup page] and generate the token on the https://platform.openai.com/account/api-keys[API Keys page].
+The Spring AI project defines a configuration property named `spring.ai.openai.api-key` that you should set to the value of the `API Key` obtained from openai.com.
+Exporting an environment variable is one way to set that configuration property:
+
+
+== Auto-configuration
+
+Spring AI provides Spring Boot auto-configuration for the OpenAI Image Generation Client.
+To enable it add the following dependency to your project's Maven `pom.xml` file:
+
+[source, xml]
+----
+
+ org.springframework.ai
+ spring-ai-openai-spring-boot-starter
+
+----
+
+or to your Gradle `build.gradle` build file.
+
+[source,groovy]
+----
+dependencies {
+ implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
+}
+----
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+
+=== Transcription Properties
+
+The prefix `spring.ai.openai.audio.transcription` is used as the property prefix that lets you configure the retry mechanism for the OpenAI Image client.
+
+[cols="3,5,2"]
+|====
+| Property | Description | Default
+
+| spring.ai.openai.audio.transcription.options.model | ID of the model to use. Only whisper-1 (which is powered by our open source Whisper V2 model) is currently available. | whisper-1
+| spring.ai.openai.audio.transcription.options.response-format | The format of the transcript output, in one of these options: json, text, srt, verbose_json, or vtt. | json
+| spring.ai.openai.audio.transcription.options.prompt | An optional text to guide the model's style or continue a previous audio segment. The prompt should match the audio language. |
+| spring.ai.openai.audio.transcription.options.language | The language of the input audio. Supplying the input language in ISO-639-1 format will improve accuracy and latency. |
+| spring.ai.openai.audio.transcription.options.temperature | The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit. | 0
+| spring.ai.openai.audio.transcription.options.timestamp_granularities | The timestamp granularities to populate for this transcription. response_format must be set verbose_json to use timestamp granularities. Either or both of these options are supported: word, or segment. Note: There is no additional latency for segment timestamps, but generating word timestamps incurs additional latency. | segment
+|====
+
+== Runtime Options [[image-options]]
+
+The `OpenAiAudioTranscriptionOptions` class provides the options to use when making a transcription.
+On start-up, the options specified by `spring.ai.openai.audio.transcription` are used but you can override these at runtime.
+
+For example:
+
+[source,java]
+----
+OpenAiAudioApi.TranscriptResponseFormat responseFormat = OpenAiAudioApi.TranscriptResponseFormat.VTT;
+
+OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
+ .withLanguage("en")
+ .withPrompt("Ask not this, but ask that")
+ .withTemperature(0f)
+ .withResponseFormat(responseFormat)
+ .build();
+AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
+AudioTranscriptionResponse response = openAiTranscriptionClient.call(transcriptionRequest);
+----
+
+== Manual Configuration
+
+Add the `spring-ai-openai` dependency to your project's Maven `pom.xml` file:
+
+[source, xml]
+----
+
+ org.springframework.ai
+ spring-ai-openai
+
+----
+
+or to your Gradle `build.gradle` build file.
+
+[source,groovy]
+----
+dependencies {
+ implementation 'org.springframework.ai:spring-ai-openai'
+}
+----
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+
+Next, create a `OpenAiAudioTranscriptionClient`
+
+[source,java]
+----
+var openAiAudioApi = new OpenAiAudioApi(System.getenv("OPENAI_API_KEY"));
+
+var openAiAudioTranscriptionClient = new OpenAiAudioTranscriptionClient(openAiAudioApi);
+
+var transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
+ .withResponseFormat(TranscriptResponseFormat.TEXT)
+ .withTemperature(0f)
+ .build();
+
+var audioFile = new FileSystemResource("/path/to/your/resource/speech/jfk.flac");
+
+AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
+AudioTranscriptionResponse response = openAiTranscriptionClient.call(transcriptionRequest);
+----
+
+== Example Code
+* The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/audio/transcription/OpenAiTranscriptionClientIT.java[OpenAiTranscriptionClientIT.java] test provides some general examples how to use the library.
\ No newline at end of file
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc
index c179b27a160..ae4b474a3dc 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/chroma.adoc
@@ -12,7 +12,7 @@ link:https://docs.trychroma.com/[Chroma] is the open-source embedding database.
1. OpenAI Account: Create an account at link:https://platform.openai.com/signup[OpenAI Signup] and generate the token at link:https://platform.openai.com/account/api-keys[API Keys].
-2. Access to ChromeDB. The <> appendix shows how to set up a DB locally with a Docker container.
+2. Access to ChromeDB. The <> appendix shows how to set up a DB locally with a Docker container.
On startup, the `ChromaVectorStore` creates the required collection if one is not provisioned already.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc
index 9129eb9706f..e7ff7ac3e2e 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/milvus.adoc
@@ -2,9 +2,190 @@
link:https://milvus.io/[Milvus] is an open-source vector database that has garnered significant attention in the fields of data science and machine learning. One of its standout features lies in its robust support for vector indexing and querying. Milvus employs state-of-the-art, cutting-edge algorithms to accelerate the search process, making it exceptionally efficient at retrieving similar vectors, even when handling extensive datasets.
-Milvus's popularity also comes from its ease of integration with popular Python-based frameworks such as PyTorch and TensorFlow, allowing for seamless inclusion in existing machine learning workflows.
+== Prerequisites
+
+* A running Milvus instance. The following options are available:
+** link:https://milvus.io/docs/install_standalone-docker.md[Milvus Standalone]: Docker, Operator, Helm,DEB/RPM, Docker Compose.
+** link:https://milvus.io/docs/install_cluster-milvusoperator.md[Milvus Cluster]: Operator, Helm.
+* If required, an API key for the xref:api/embeddings.adoc#available-implementations[EmbeddingClient] to generate the embeddings stored by the `MilvusVectorStore`.
+
+== Dependencies
+
+Then add the Milvus VectorStore boot starter dependency to your project:
+
+[source,xml]
+----
+
+ org.springframework.ai
+ spring-ai-milvus-store-spring-boot-starter
+
+----
+
+or to your Gradle `build.gradle` build file.
+
+[source,groovy]
+----
+dependencies {
+ implementation 'org.springframework.ai:spring-ai-milvus-store-spring-boot-starter'
+}
+----
+
+The Vector Store, also requires an `EmbeddingClient` instance to calculate embeddings for the documents.
+You can pick one of the available xref:api/embeddings.adoc#available-implementations[EmbeddingClient Implementations].
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+Refer to the xref:getting-started.adoc#repositories[Repositories] section to add Milestone and/or Snapshot Repositories to your build file.
+
+To connect to and configure the `MilvusVectorStore`, you need to provide access details for your instance.
+A simple configuration can either be provided via Spring Boot's `application.yml`
+
+[yml]
+----
+spring:
+ ai:
+ vectorstore:
+ milvus:
+ client:
+ host: "localhost"
+ port: 19530
+ username: "root"
+ password: "milvus"
+ databaseName: "default"
+ collectionName: "vector_store"
+ embeddingDimension: 1536
+ indexType: IVF_FLAT
+ metricType: COSINE
+----
+
+TIP: Check the list of xref:#milvus-properties[configuration parameters] to learn about the default values and configuration options.
+
+Now you can Auto-wire the Milvus Vector Store in your application and use it
+
+[source,java]
+----
+@Autowired VectorStore vectorStore;
+
+// ...
+
+List documents = List.of(
+ new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
+ new Document("The World is Big and Salvation Lurks Around the Corner"),
+ new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));
+
+// Add the documents to PGVector
+vectorStore.add(documents);
+
+// Retrieve documents similar to a query
+List results = vectorStore.similaritySearch(SearchRequest.query("Spring").withTopK(5));
+----
+
+=== Manual Configuration
+
+Instead of using the Spring Boot auto-configuration, you can manually configure the `MilvusVectorStore`.
+To add the following dependencies to your project:
+
+[source,xml]
+----
+
+ org.springframework.ai
+ spring-ai-milvus-store
+
+----
+
+TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
+
+To configure MilvusVectorStore in your application, you can use the following setup:
+
+[source,java]
+----
+ @Bean
+ public VectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingClient embeddingClient) {
+ MilvusVectorStoreConfig config = MilvusVectorStoreConfig.builder()
+ .withCollectionName("test_vector_store")
+ .withDatabaseName("default")
+ .withIndexType(IndexType.IVF_FLAT)
+ .withMetricType(MetricType.COSINE)
+ .build();
+ return new MilvusVectorStore(milvusClient, embeddingClient, config);
+ }
+
+ @Bean
+ public MilvusServiceClient milvusClient() {
+ return new MilvusServiceClient(ConnectParam.newBuilder()
+ .withAuthorization("minioadmin", "minioadmin")
+ .withUri(milvusContainer.getEndpoint())
+ .build());
+ }
+----
+
+== Metadata filtering
+
+You can leverage the generic, portable link:https://docs.spring.io/spring-ai/reference/api/vectordbs.html#_metadata_filters[metadata filters] with the Milvus store.
+
+For example, you can use either the text expression language:
+
+[source,java]
+----
+vectorStore.similaritySearch(
+ SearchRequest.defaults()
+ .withQuery("The World")
+ .withTopK(TOP_K)
+ .withSimilarityThreshold(SIMILARITY_THRESHOLD)
+ .withFilterExpression("author in ['john', 'jill'] && article_type == 'blog'"));
+----
+
+or programmatically using the `Filter.Expression` DSL:
+
+[source,java]
+----
+FilterExpressionBuilder b = new FilterExpressionBuilder();
+
+vectorStore.similaritySearch(SearchRequest.defaults()
+ .withQuery("The World")
+ .withTopK(TOP_K)
+ .withSimilarityThreshold(SIMILARITY_THRESHOLD)
+ .withFilterExpression(b.and(
+ b.in("john", "jill"),
+ b.eq("article_type", "blog")).build()));
+----
+
+NOTE: These filter expressions are converted into the equivalent PgVector filters.
+
+[[milvus-properties]]
+== Milvus VectorStore properties
+
+You can use the following properties in your Spring Boot configuration to customize the Milvus vector store.
+
+[cols="4,5,1"]
+|===
+|Property| Description | Default value
+
+|spring.ai.vectorstore.milvus.database-name | The name of the Milvus database to use. | default
+|spring.ai.vectorstore.milvus.collection-name | Milvus collection name to store the vectors | vector_store
+|spring.ai.vectorstore.milvus.embedding-dimension | The dimension of the vectors to be stored in the Milvus collection. | 1536
+|spring.ai.vectorstore.milvus.index-type | The type of the index to be created for the Milvus collection. | IVF_FLAT
+|spring.ai.vectorstore.milvus.metric-type | The metric type to be used for the Milvus collection. | COSINE
+|spring.ai.vectorstore.milvus.index-parameters | The index parameters to be used for the Milvus collection. | {"nlist":1024}
+|spring.ai.vectorstore.milvus.client.host | The name or address of the host. | localhost
+|spring.ai.vectorstore.milvus.client.port | The connection port. | 19530
+|spring.ai.vectorstore.milvus.client.uri | The uri of Milvus instance | -
+|spring.ai.vectorstore.milvus.client.token | Token serving as the key for identification and authentication purposes. | -
+|spring.ai.vectorstore.milvus.client.connect-timeout-ms | Connection timeout value of client channel. The timeout value must be greater than zero . | 10000
+|spring.ai.vectorstore.milvus.client.keep-alive-time-ms | Keep-alive time value of client channel. The keep-alive value must be greater than zero. | 55000
+|spring.ai.vectorstore.milvus.client.keep-alive-timeout-ms | The keep-alive timeout value of client channel. The timeout value must be greater than zero. | 20000
+|spring.ai.vectorstore.milvus.client.rpc-deadline-ms | Deadline for how long you are willing to wait for a reply from the server. With a deadline setting, the client will wait when encounter fast RPC fail caused by network fluctuations. The deadline value must be larger than or equal to zero. | 0
+|spring.ai.vectorstore.milvus.client.client-key-path | The client.key path for tls two-way authentication, only takes effect when "secure" is true | -
+|spring.ai.vectorstore.milvus.client.client-pem-path | The client.pem path for tls two-way authentication, only takes effect when "secure" is true | -
+|spring.ai.vectorstore.milvus.client.ca-pem-path | The ca.pem path for tls two-way authentication, only takes effect when "secure" is true | -
+|spring.ai.vectorstore.milvus.client.server-pem-path | server.pem path for tls one-way authentication, only takes effect when "secure" is true. | -
+|spring.ai.vectorstore.milvus.client.server-name | Sets the target name override for SSL host name checking, only takes effect when "secure" is True. Note: this value is passed to grpc.ssl_target_name_override | -
+|spring.ai.vectorstore.milvus.client.secure | Secure the authorization for this connection, set to True to enable TLS. | false
+|spring.ai.vectorstore.milvus.client.idle-timeout-ms | Idle timeout value of client channel. The timeout value must be larger than zero. | 24h
+|spring.ai.vectorstore.milvus.client.username | The username and password for this connection. | root
+|spring.ai.vectorstore.milvus.client.password | The password for this connection. | milvus
+|===
+
-In the e-commerce industry, Milvus is used in recommendation systems, which suggest products based on user preferences. In image and video analysis, it excels in tasks like object recognition, image similarity search, and content-based image retrieval. Additionally, it is commonly used in natural language processing for document clustering, semantic search, and question-answering systems.
== Starting Milvus Store
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc
index cf01482c960..7ee62d0f19e 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/pgvector.adoc
@@ -6,9 +6,9 @@ link:https://github.com/pgvector/pgvector[PGvector] is an open-source extension
== Prerequisites
-First you need an access to PostgreSQL instance with enabled `vector`, `hstore` and `uuid-ossp` extensions.
+First you need access to PostgreSQL instance with enabled `vector`, `hstore` and `uuid-ossp` extensions.
-TIP: The <> appendix shows how to set up a DB locally with a Docker container.
+TIP: The <> appendix shows how to set up a DB locally with a Docker container.
On startup, the `PgVectorStore` will attempt to install the required database extensions and create the required `vector_store` table with an index.
@@ -200,7 +200,7 @@ You can use the following properties in your Spring Boot configuration to custom
|`spring.ai.vectorstore.pgvector.index-type`| Nearest neighbor search index type. Options are `NONE` - exact nearest neighbor search, `IVFFlat` - index divides vectors into lists, and then searches a subset of those lists that are closest to the query vector. It has faster build times and uses less memory than HNSW, but has lower query performance (in terms of speed-recall tradeoff). `HNSW` - creates a multilayer graph. It has slower build times and uses more memory than IVFFlat, but has better query performance (in terms of speed-recall tradeoff). There’s no training step like IVFFlat, so the index can be created without any data in the table.| HNSW
|`spring.ai.vectorstore.pgvector.distance-type`| Search distance type. Defaults to `COSINE_DISTANCE`. But if vectors are normalized to length 1, you can use `EUCLIDEAN_DISTANCE` or `NEGATIVE_INNER_PRODUCT` for best performance.| COSINE_DISTANCE
-|`spring.ai.vectorstore.pgvector.dimension`| Embeddings dimension. If not specified explicitly the PgVectorStore will retrieve the dimensions form the provided `EmbeddingClient`. Dimensions are set to the embedding column the on table creation. If you change the dimensions your would have to to re-create the vector_store table as well. | -
+|`spring.ai.vectorstore.pgvector.dimension`| Embeddings dimension. If not specified explicitly the PgVectorStore will retrieve the dimensions form the provided `EmbeddingClient`. Dimensions are set to the embedding column the on table creation. If you change the dimensions your would have to re-create the vector_store table as well. | -
|spring.ai.vectorstore.pgvector.remove-existing-vector-store-table| Deletes the existing `vector_store` table on start up. | false
|===
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/contribution-guidelines.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/contribution-guidelines.adoc
index eabf39fd806..73cd31e5d54 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/contribution-guidelines.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/contribution-guidelines.adoc
@@ -17,7 +17,7 @@ you'll need to develop a low-level client API class. This often involves utilizi
`RestClient` class from the Spring Framework, similar to the `OpenAiApi` class.
. *Create a ModelClient implementation*
-Ensure your client conforms to the link:https://docs.spring.io/spring-ai/reference/api/clients/generic-model.html[Generic Model API].
+Ensure your client conforms to the link:https://docs.spring.io/spring-ai/reference/api/chat/generic-model.html[Generic Model API].
Use existing request and response classes if your model's inputs and outputs are supported.
If not, create new classes for the Generic Model API and establish a new Java package.
@@ -30,7 +30,7 @@ Existing tests can serve as a useful reference for structuring and implementing
. *Document Your Contribution*: Ensure your documentation follows the existing format,
For an example of the suggested structure and formatting, refer to the
-link:https://docs.spring.io/spring-ai/reference/api/clients/openai-chat.html[Open AI Chat documentation].
+link:https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html[Open AI Chat documentation].
By following these guidelines, we can greatly expand the framework's range of supported models
while following a common implementation and documentation pattern.
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc
index a0f687710a0..b411d51e2da 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/getting-started.adoc
@@ -135,26 +135,28 @@ Each of the following sections in the documentation shows which dependencies you
** xref:api/embeddings/bedrock-cohere-embedding.adoc[Spring AI Bedrock Cohere Embeddings]
** xref:api/embeddings/bedrock-titan-embedding.adoc[Spring AI Bedrock Titan Embeddings]
** xref:api/embeddings/vertexai-embeddings.adoc[Spring AI VertexAI Embeddings]
+** xref:api/embeddings/mistralai-embeddings.adoc[Spring AI MistralAI Embeddings]
=== Chat Models
* xref:api/chatclient.adoc[Chat Completion API]
-** xref:api/clients/openai-chat.adoc[OpenAI Chat Completion] (streaming and function-calling support)
-** xref:api/clients/azure-openai-chat.adoc[Microsoft Azure Open AI Chat Completion] (streaming and function-calling support)
-** xref:api/clients/ollama-chat.adoc[Ollama Chat Completion]
-** xref:api/clients/huggingface.adoc[HuggingFace Chat Completion] (no streaming support)
-** xref:api/clients/vertexai-palm2-chat.adoc[Google Vertex AI PaLM2 Chat Completion] (no streaming support)
-** xref:api/clients/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support)
+** xref:api/chat/openai-chat.adoc[OpenAI Chat Completion] (streaming and function-calling support)
+** xref:api/chat/azure-openai-chat.adoc[Microsoft Azure Open AI Chat Completion] (streaming and function-calling support)
+** xref:api/chat/ollama-chat.adoc[Ollama Chat Completion]
+** xref:api/chat/huggingface.adoc[HuggingFace Chat Completion] (no streaming support)
+** xref:api/chat/vertexai-palm2-chat.adoc[Google Vertex AI PaLM2 Chat Completion] (no streaming support)
+** xref:api/chat/vertexai-gemini-chat.adoc[Google Vertex AI Gemini Chat Completion] (streaming, multi-modality & function-calling support)
** xref:api/bedrock.adoc[Amazon Bedrock]
-*** xref:api/clients/bedrock/bedrock-cohere.adoc[Cohere Chat Completion]
-*** xref:api/clients/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion]
-*** xref:api/clients/bedrock/bedrock-titan.adoc[Titan Chat Completion]
-*** xref:api/clients/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion]
-// ** xref:api/clients/bedrock/bedrock-jurassic.adoc[Jurassic2 Chat Completion] (WIP, no streaming support)
+*** xref:api/chat/bedrock/bedrock-cohere.adoc[Cohere Chat Completion]
+*** xref:api/chat/bedrock/bedrock-llama2.adoc[Llama2 Chat Completion]
+*** xref:api/chat/bedrock/bedrock-titan.adoc[Titan Chat Completion]
+*** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic Chat Completion]
+*** xref:api/chat/bedrock/bedrock-jurassic2.adoc[Jurassic2 Chat Completion]
+** xref:api/chat/mistralai-chat.adoc[MistralAI Chat Completion] (streaming and function-calling support)
=== Image Generation Models
* xref:api/imageclient.adoc[]
-** xref:api/clients/image/openai-image.adoc[OpenAI Image Generation]
-** xref:api/clients/image/stabilityai-image.adoc[StabilityAI Image Generation]
+** xref:api/image/openai-image.adoc[OpenAI Image Generation]
+** xref:api/image/stabilityai-image.adoc[StabilityAI Image Generation]
=== Vector Databases
* xref:api/vectordbs.adoc[Vector Database API]
@@ -181,7 +183,9 @@ You can clone these projects on GitHub to get started.
=== Azure OpenAI
* https://github.com/rd-1-2022/ai-azure-openai-helloworld
-* https://github.com/rd-1-2022/ai-azure-stuff-prompt
-* https://github.com/rd-1-2022/ai-azure-prompt-template
-* https://github.com/rd-1-2022/ai-azure-openai-prompt-roles
-* https://github.com/rd-1-2022/ai-azure-retrieval-augmented-generation
+* https://github.com/Azure-Samples/spring-ai-azure-workshop
+
+// * https://github.com/rd-1-2022/ai-azure-stuff-prompt
+// * https://github.com/rd-1-2022/ai-azure-prompt-template
+// * https://github.com/rd-1-2022/ai-azure-openai-prompt-roles
+// * https://github.com/rd-1-2022/ai-azure-retrieval-augmented-generation
diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/upgrade-notes.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/upgrade-notes.adoc
index e5c9e31c086..5072f31bee3 100644
--- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/upgrade-notes.adoc
+++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/upgrade-notes.adoc
@@ -68,7 +68,7 @@ The following OpenAi Autoconfiguration chat properties has changed
* from `spring.ai.openai.model` to `spring.ai.openai.chat.options.model`.
* from `spring.ai.openai.temperature` to `spring.ai.openai.chat.options.temperature`.
-Find updated documentation about the OpenAi properties: https://docs.spring.io/spring-ai/reference/api/clients/openai-chat.html
+Find updated documentation about the OpenAi properties: https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html
=== December 27, 2023 Update
diff --git a/spring-ai-retry/pom.xml b/spring-ai-retry/pom.xml
new file mode 100644
index 00000000000..75834506deb
--- /dev/null
+++ b/spring-ai-retry/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ org.springframework.ai
+ spring-ai
+ 1.0.0-SNAPSHOT
+
+ spring-ai-retry
+ jar
+ Spring AI Retry
+ Spring AI utility project helping with remote call retry
+ https://github.com/spring-projects/spring-ai
+
+
+ https://github.com/spring-projects/spring-ai
+ git://github.com/spring-projects/spring-ai.git
+ git@github.com:spring-projects/spring-ai.git
+
+
+
+
+
+
+ org.springframework.ai
+ spring-ai-core
+ ${project.parent.version}
+
+
+
+ org.springframework.retry
+ spring-retry
+ ${spring-retry.version}
+
+
+
+ org.springframework
+ spring-webflux
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
diff --git a/spring-ai-retry/src/main/java/org/springframework/ai/retry/NonTransientAiException.java b/spring-ai-retry/src/main/java/org/springframework/ai/retry/NonTransientAiException.java
new file mode 100644
index 00000000000..fcd824693c3
--- /dev/null
+++ b/spring-ai-retry/src/main/java/org/springframework/ai/retry/NonTransientAiException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.retry;
+
+/**
+ * Root of the hierarchy of Model access exceptions that are considered non-transient -
+ * where a retry of the same operation would fail unless the cause of the Exception is
+ * corrected.
+ *
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+public class NonTransientAiException extends RuntimeException {
+
+ public NonTransientAiException(String message) {
+ super(message);
+ }
+
+ public NonTransientAiException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java b/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java
new file mode 100644
index 00000000000..bbc584335c3
--- /dev/null
+++ b/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java
@@ -0,0 +1,84 @@
+/*
+ * 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.retry;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.lang.NonNull;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.RetryListener;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.client.ResponseErrorHandler;
+
+/**
+ * RetryUtils is a utility class for configuring and handling retry operations. It
+ * provides a default RetryTemplate and a default ResponseErrorHandler.
+ *
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+public abstract class RetryUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(RetryUtils.class);
+
+ public static final RetryTemplate DEFAULT_RETRY_TEMPLATE = RetryTemplate.builder()
+ .maxAttempts(10)
+ .retryOn(TransientAiException.class)
+ .exponentialBackoff(Duration.ofMillis(2000), 5, Duration.ofMillis(3 * 60000))
+ .withListener(new RetryListener() {
+ @Override
+ public void onError(RetryContext context,
+ RetryCallback callback, Throwable throwable) {
+ logger.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
+ };
+ })
+ .build();
+
+ public static final ResponseErrorHandler DEFAULT_RESPONSE_ERROR_HANDLER = new ResponseErrorHandler() {
+
+ @Override
+ public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
+ return response.getStatusCode().isError();
+ }
+
+ @Override
+ public void handleError(@NonNull ClientHttpResponse response) throws IOException {
+ if (response.getStatusCode().isError()) {
+ String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
+ String message = String.format("%s - %s", response.getStatusCode().value(), error);
+ /**
+ * Thrown on 4xx client errors, such as 401 - Incorrect API key provided,
+ * 401 - You must be a member of an organization to use the API, 429 -
+ * Rate limit reached for requests, 429 - You exceeded your current quota
+ * , please check your plan and billing details.
+ */
+ if (response.getStatusCode().is4xxClientError()) {
+ throw new NonTransientAiException(message);
+ }
+ throw new TransientAiException(message);
+ }
+ }
+ };
+
+}
diff --git a/spring-ai-retry/src/main/java/org/springframework/ai/retry/TransientAiException.java b/spring-ai-retry/src/main/java/org/springframework/ai/retry/TransientAiException.java
new file mode 100644
index 00000000000..94a7104840f
--- /dev/null
+++ b/spring-ai-retry/src/main/java/org/springframework/ai/retry/TransientAiException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.retry;
+
+/**
+ * Root of the hierarchy of Model access exceptions that are considered transient - where
+ * a previously failed operation might be able to succeed when the operation is retried
+ * without any intervention by application-level functionality.
+ *
+ * @author Christian Tzolov
+ * @since 0.8.1
+ */
+public class TransientAiException extends RuntimeException {
+
+ public TransientAiException(String message) {
+ super(message);
+ }
+
+ public TransientAiException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/pom.xml b/spring-ai-spring-boot-autoconfigure/pom.xml
index 19161a0887c..80c6aacf12d 100644
--- a/spring-ai-spring-boot-autoconfigure/pom.xml
+++ b/spring-ai-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOTspring-ai-spring-boot-autoconfigurejar
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiAutoConfiguration.java
index 5cf9d1e705a..a9b13e30407 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.openai;
import java.util.List;
@@ -38,7 +37,7 @@
import org.springframework.util.CollectionUtils;
@AutoConfiguration
-@ConditionalOnClass(OpenAIClientBuilder.class)
+@ConditionalOnClass({ OpenAIClientBuilder.class, AzureOpenAiChatClient.class })
@EnableConfigurationProperties({ AzureOpenAiChatProperties.class, AzureOpenAiEmbeddingProperties.class,
AzureOpenAiConnectionProperties.class })
public class AzureOpenAiAutoConfiguration {
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiChatProperties.java
index fb37ce61f6b..5ce9c26698c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.openai;
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
@@ -25,7 +24,7 @@ public class AzureOpenAiChatProperties {
public static final String CONFIG_PREFIX = "spring.ai.azure.openai.chat";
- public static final String DEFAULT_CHAT_MODEL = "gpt-35-turbo";
+ public static final String DEFAULT_DEPLOYMENT_NAME = "gpt-35-turbo";
private static final Double DEFAULT_TEMPERATURE = 0.7;
@@ -36,7 +35,7 @@ public class AzureOpenAiChatProperties {
@NestedConfigurationProperty
private AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
- .withModel(DEFAULT_CHAT_MODEL)
+ .withDeploymentName(DEFAULT_DEPLOYMENT_NAME)
.withTemperature(DEFAULT_TEMPERATURE.floatValue())
.build();
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiConnectionProperties.java
index 09cf9a2bfcf..16d0803fba9 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.openai;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiEmbeddingProperties.java
index 3f43304c4a1..e320eec2f29 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/azure/openai/AzureOpenAiEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.openai;
import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingOptions;
@@ -34,7 +33,7 @@ public class AzureOpenAiEmbeddingProperties {
@NestedConfigurationProperty
private AzureOpenAiEmbeddingOptions options = AzureOpenAiEmbeddingOptions.builder()
- .withModel("text-embedding-ada-002")
+ .withDeploymentName("text-embedding-ada-002")
.build();
private MetadataMode metadataMode = MetadataMode.EMBED;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
index a1363c3f12d..9cfd634d13b 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java
index 76725bc71fc..334cb53cc4f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/BedrockAwsConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java
index 930a9957e59..d573ab0a55a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfiguration.java
@@ -5,7 +5,7 @@
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.anthropic;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatProperties.java
index 660224911f6..ed1800b5c2e 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatProperties.java
@@ -5,7 +5,7 @@
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.anthropic;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java
index 16282743d24..32c94dff494 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatProperties.java
index a98d093ee0e..0381d591b9f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.cohere;
import org.springframework.ai.bedrock.cohere.BedrockCohereChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java
index 6478b915375..7412eb2aef4 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.cohere;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingProperties.java
index b0af032970d..77b1677bd60 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.cohere;
import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java
new file mode 100644
index 00000000000..75cd6962dc4
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatAutoConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * 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.autoconfigure.bedrock.jurrasic2;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
+import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
+import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatClient;
+import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+
+/**
+ * {@link AutoConfiguration Auto-configuration} for Bedrock Jurassic2 Chat Client.
+ *
+ * @author Ahmed Yousri
+ * @since 1.0.0
+ */
+@AutoConfiguration
+@ConditionalOnClass(Ai21Jurassic2ChatBedrockApi.class)
+@EnableConfigurationProperties({ BedrockAi21Jurassic2ChatProperties.class, BedrockAwsConnectionProperties.class })
+@ConditionalOnProperty(prefix = BedrockAi21Jurassic2ChatProperties.CONFIG_PREFIX, name = "enabled",
+ havingValue = "true")
+@Import(BedrockAwsConnectionConfiguration.class)
+public class BedrockAi21Jurassic2ChatAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi(AwsCredentialsProvider credentialsProvider,
+ BedrockAi21Jurassic2ChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
+ return new Ai21Jurassic2ChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
+ new ObjectMapper());
+ }
+
+ @Bean
+ public BedrockAi21Jurassic2ChatClient jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi,
+ BedrockAi21Jurassic2ChatProperties properties) {
+
+ return BedrockAi21Jurassic2ChatClient.builder(ai21Jurassic2ChatBedrockApi)
+ .withOptions(properties.getOptions())
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatProperties.java
new file mode 100644
index 00000000000..217c7c7eba1
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/jurrasic2/BedrockAi21Jurassic2ChatProperties.java
@@ -0,0 +1,76 @@
+/*
+ * 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.autoconfigure.bedrock.jurrasic2;
+
+import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatOptions;
+import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+/**
+ * Configuration properties for Bedrock Ai21Jurassic2.
+ *
+ * @author Ahmed Yousri
+ * @since 1.0.0
+ */
+@ConfigurationProperties(BedrockAi21Jurassic2ChatProperties.CONFIG_PREFIX)
+public class BedrockAi21Jurassic2ChatProperties {
+
+ public static final String CONFIG_PREFIX = "spring.ai.bedrock.jurassic2.chat";
+
+ /**
+ * Enable Bedrock Ai21Jurassic2 chat client. Disabled by default.
+ */
+ private boolean enabled = false;
+
+ /**
+ * The generative id to use. See the {@link Ai21Jurassic2ChatModel} for the supported
+ * models.
+ */
+ private String model = Ai21Jurassic2ChatModel.AI21_J2_MID_V1.id();
+
+ @NestedConfigurationProperty
+ private BedrockAi21Jurassic2ChatOptions options = BedrockAi21Jurassic2ChatOptions.builder()
+ .withTemperature(0.7f)
+ .withMaxTokens(500)
+ .build();
+
+ public boolean isEnabled() {
+ return this.enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getModel() {
+ return this.model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ public BedrockAi21Jurassic2ChatOptions getOptions() {
+ return this.options;
+ }
+
+ public void setOptions(BedrockAi21Jurassic2ChatOptions options) {
+ this.options = options;
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java
index 7f37803f352..b40b7f8a3de 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.llama2;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java
index 81968601d7f..a81f3a4af0c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatProperties.java
@@ -5,7 +5,7 @@
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.llama2;
import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java
index 94716a0753e..c1415d218c3 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatProperties.java
index 61fb2d0a19e..b196e9797a6 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.titan;
import org.springframework.ai.bedrock.titan.BedrockTitanChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java
index a7d7986efa4..d3c08b35b14 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.titan;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingProperties.java
index 1a6b1e5c141..3e80cfed813 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.titan;
import org.springframework.ai.bedrock.titan.BedrockTitanEmbeddingClient.InputType;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatAutoConfiguration.java
index cd6c3fe2077..42c3b1e73ea 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.huggingface;
import org.springframework.ai.huggingface.HuggingfaceChatClient;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatProperties.java
index 0c7178bea44..4495a512334 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/huggingface/HuggingfaceChatProperties.java
@@ -1,3 +1,18 @@
+/*
+ * 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.autoconfigure.huggingface;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java
index cffaec36644..1328f3488ba 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfiguration.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,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import java.util.List;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.mistralai.MistralAiChatClient;
import org.springframework.ai.mistralai.MistralAiEmbeddingClient;
import org.springframework.ai.mistralai.api.MistralAiApi;
@@ -31,9 +31,11 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
+import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
/**
@@ -41,7 +43,7 @@
* @author Christian Tzolov
* @since 0.8.1
*/
-@AutoConfiguration(after = { RestClientAutoConfiguration.class })
+@AutoConfiguration(after = { RestClientAutoConfiguration.class, SpringAiRetryAutoConfiguration.class })
@EnableConfigurationProperties({ MistralAiEmbeddingProperties.class, MistralAiCommonProperties.class,
MistralAiChatProperties.class })
@ConditionalOnClass(MistralAiApi.class)
@@ -52,13 +54,15 @@ public class MistralAiAutoConfiguration {
@ConditionalOnProperty(prefix = MistralAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
public MistralAiEmbeddingClient mistralAiEmbeddingClient(MistralAiCommonProperties commonProperties,
- MistralAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder) {
+ MistralAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder,
+ RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
var mistralAiApi = mistralAiApi(embeddingProperties.getApiKey(), commonProperties.getApiKey(),
- embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder);
+ embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder,
+ responseErrorHandler);
return new MistralAiEmbeddingClient(mistralAiApi, embeddingProperties.getMetadataMode(),
- embeddingProperties.getOptions());
+ embeddingProperties.getOptions(), retryTemplate);
}
@Bean
@@ -67,20 +71,22 @@ public MistralAiEmbeddingClient mistralAiEmbeddingClient(MistralAiCommonProperti
matchIfMissing = true)
public MistralAiChatClient mistralAiChatClient(MistralAiCommonProperties commonProperties,
MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
- List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext) {
+ List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
+ RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
var mistralAiApi = mistralAiApi(chatProperties.getApiKey(), commonProperties.getApiKey(),
- chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder);
+ chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder, responseErrorHandler);
if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) {
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
}
- return new MistralAiChatClient(mistralAiApi, chatProperties.getOptions(), functionCallbackContext);
+ return new MistralAiChatClient(mistralAiApi, chatProperties.getOptions(), functionCallbackContext,
+ retryTemplate);
}
private MistralAiApi mistralAiApi(String apiKey, String commonApiKey, String baseUrl, String commonBaseUrl,
- RestClient.Builder restClientBuilder) {
+ RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
var resolvedApiKey = StringUtils.hasText(apiKey) ? apiKey : commonApiKey;
var resoledBaseUrl = StringUtils.hasText(baseUrl) ? baseUrl : commonBaseUrl;
@@ -88,7 +94,7 @@ private MistralAiApi mistralAiApi(String apiKey, String commonApiKey, String bas
Assert.hasText(resolvedApiKey, "Mistral API key must be set");
Assert.hasText(resoledBaseUrl, "Mistral base URL must be set");
- return new MistralAiApi(resoledBaseUrl, resolvedApiKey, restClientBuilder);
+ return new MistralAiApi(resoledBaseUrl, resolvedApiKey, restClientBuilder, responseErrorHandler);
}
@Bean
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiChatProperties.java
index 1a53bf52e02..4f9e004018d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2024-204 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import org.springframework.ai.mistralai.MistralAiChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiCommonProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiCommonProperties.java
index 142d8d5ccb7..0bc7132be21 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiCommonProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiCommonProperties.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiEmbeddingProperties.java
index 5c46ec6f7d1..dbb5d8f3c3f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2024-204 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import org.springframework.ai.document.MetadataMode;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiParentProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiParentProperties.java
index f3844ad6df4..31c632af80a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiParentProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/mistralai/MistralAiParentProperties.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
/**
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java
index 41647f2e2c7..aa454fb8385 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaChatProperties.java
index c8f91ee2ac1..f3bc8ad7887 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import org.springframework.ai.ollama.api.OllamaOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaConnectionProperties.java
index 0949567bc65..160849ed89e 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingProperties.java
index 9f170a25ef5..69f809ea158 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import org.springframework.ai.ollama.api.OllamaOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAudioTranscriptionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAudioTranscriptionProperties.java
new file mode 100644
index 00000000000..ab27093f80b
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAudioTranscriptionProperties.java
@@ -0,0 +1,49 @@
+/*
+ * 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.autoconfigure.openai;
+
+import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+@ConfigurationProperties(OpenAiAudioTranscriptionProperties.CONFIG_PREFIX)
+public class OpenAiAudioTranscriptionProperties extends OpenAiParentProperties {
+
+ public static final String CONFIG_PREFIX = "spring.ai.openai.audio.transcription";
+
+ public static final String DEFAULT_TRANSCRIPTION_MODEL = OpenAiAudioApi.WhisperModel.WHISPER_1.getValue();
+
+ private static final Double DEFAULT_TEMPERATURE = 0.7;
+
+ private static final OpenAiAudioApi.TranscriptResponseFormat DEFAULT_RESPONSE_FORMAT = OpenAiAudioApi.TranscriptResponseFormat.TEXT;
+
+ @NestedConfigurationProperty
+ private OpenAiAudioTranscriptionOptions options = OpenAiAudioTranscriptionOptions.builder()
+ .withModel(DEFAULT_TRANSCRIPTION_MODEL)
+ .withTemperature(DEFAULT_TEMPERATURE.floatValue())
+ .withResponseFormat(DEFAULT_RESPONSE_FORMAT)
+ .build();
+
+ public OpenAiAudioTranscriptionOptions getOptions() {
+ return options;
+ }
+
+ public void setOptions(OpenAiAudioTranscriptionOptions options) {
+ this.options = options;
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java
index 2e376668d25..ae1daff1f00 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,17 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import java.util.List;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.function.FunctionCallbackContext;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiEmbeddingClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -33,18 +35,20 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
+import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
+import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClient;
-@AutoConfiguration(after = { RestClientAutoConfiguration.class })
-@ConditionalOnClass(OpenAiApi.class)
-@EnableConfigurationProperties({ OpenAiConnectionProperties.class, OpenAiChatProperties.class,
- OpenAiEmbeddingProperties.class, OpenAiImageProperties.class })
/**
* @author Christian Tzolov
*/
+@AutoConfiguration(after = { RestClientAutoConfiguration.class, SpringAiRetryAutoConfiguration.class })
+@ConditionalOnClass(OpenAiApi.class)
+@EnableConfigurationProperties({ OpenAiConnectionProperties.class, OpenAiChatProperties.class,
+ OpenAiEmbeddingProperties.class, OpenAiImageProperties.class, OpenAiAudioTranscriptionProperties.class })
public class OpenAiAutoConfiguration {
@Bean
@@ -53,16 +57,17 @@ public class OpenAiAutoConfiguration {
matchIfMissing = true)
public OpenAiChatClient openAiChatClient(OpenAiConnectionProperties commonProperties,
OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
- List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext) {
+ List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
+ RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
var openAiApi = openAiApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(),
- chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder);
+ chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler);
if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) {
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
}
- return new OpenAiChatClient(openAiApi, chatProperties.getOptions(), functionCallbackContext);
+ return new OpenAiChatClient(openAiApi, chatProperties.getOptions(), functionCallbackContext, retryTemplate);
}
@Bean
@@ -70,17 +75,18 @@ public OpenAiChatClient openAiChatClient(OpenAiConnectionProperties commonProper
@ConditionalOnProperty(prefix = OpenAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
public OpenAiEmbeddingClient openAiEmbeddingClient(OpenAiConnectionProperties commonProperties,
- OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder) {
+ OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder,
+ RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
var openAiApi = openAiApi(embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(),
- embeddingProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder);
+ embeddingProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler);
return new OpenAiEmbeddingClient(openAiApi, embeddingProperties.getMetadataMode(),
- embeddingProperties.getOptions());
+ embeddingProperties.getOptions(), retryTemplate);
}
private OpenAiApi openAiApi(String baseUrl, String commonBaseUrl, String apiKey, String commonApiKey,
- RestClient.Builder restClientBuilder) {
+ RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
String resolvedBaseUrl = StringUtils.hasText(baseUrl) ? baseUrl : commonBaseUrl;
Assert.hasText(resolvedBaseUrl, "OpenAI base URL must be set");
@@ -88,7 +94,7 @@ private OpenAiApi openAiApi(String baseUrl, String commonBaseUrl, String apiKey,
String resolvedApiKey = StringUtils.hasText(apiKey) ? apiKey : commonApiKey;
Assert.hasText(resolvedApiKey, "OpenAI API key must be set");
- return new OpenAiApi(resolvedBaseUrl, resolvedApiKey, restClientBuilder);
+ return new OpenAiApi(resolvedBaseUrl, resolvedApiKey, restClientBuilder, responseErrorHandler);
}
@Bean
@@ -96,7 +102,9 @@ private OpenAiApi openAiApi(String baseUrl, String commonBaseUrl, String apiKey,
@ConditionalOnProperty(prefix = OpenAiImageProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
public OpenAiImageClient openAiImageClient(OpenAiConnectionProperties commonProperties,
- OpenAiImageProperties imageProperties, RestClient.Builder restClientBuilder) {
+ OpenAiImageProperties imageProperties, RestClient.Builder restClientBuilder, RetryTemplate retryTemplate,
+ ResponseErrorHandler responseErrorHandler) {
+
String apiKey = StringUtils.hasText(imageProperties.getApiKey()) ? imageProperties.getApiKey()
: commonProperties.getApiKey();
@@ -106,9 +114,32 @@ public OpenAiImageClient openAiImageClient(OpenAiConnectionProperties commonProp
Assert.hasText(apiKey, "OpenAI API key must be set");
Assert.hasText(baseUrl, "OpenAI base URL must be set");
- var openAiImageApi = new OpenAiImageApi(baseUrl, apiKey, restClientBuilder);
+ var openAiImageApi = new OpenAiImageApi(baseUrl, apiKey, restClientBuilder, responseErrorHandler);
+
+ return new OpenAiImageClient(openAiImageApi, imageProperties.getOptions(), retryTemplate);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public OpenAiAudioTranscriptionClient openAiAudioTranscriptionClient(OpenAiConnectionProperties commonProperties,
+ OpenAiAudioTranscriptionProperties transcriptionProperties, RetryTemplate retryTemplate,
+ ResponseErrorHandler responseErrorHandler) {
+
+ String apiKey = StringUtils.hasText(transcriptionProperties.getApiKey()) ? transcriptionProperties.getApiKey()
+ : commonProperties.getApiKey();
+
+ String baseUrl = StringUtils.hasText(transcriptionProperties.getBaseUrl())
+ ? transcriptionProperties.getBaseUrl() : commonProperties.getBaseUrl();
+
+ Assert.hasText(apiKey, "OpenAI API key must be set");
+ Assert.hasText(baseUrl, "OpenAI base URL must be set");
+
+ var openAiAudioApi = new OpenAiAudioApi(baseUrl, apiKey, RestClient.builder(), responseErrorHandler);
+
+ OpenAiAudioTranscriptionClient openAiChatClient = new OpenAiAudioTranscriptionClient(openAiAudioApi,
+ transcriptionProperties.getOptions(), retryTemplate);
- return new OpenAiImageClient(openAiImageApi).withDefaultOptions(imageProperties.getOptions());
+ return openAiChatClient;
}
@Bean
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiChatProperties.java
index 34d6b7cafe3..5e9940b4238 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import org.springframework.ai.openai.OpenAiChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiConnectionProperties.java
index ebdb74f50f0..b065deb53a5 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiEmbeddingProperties.java
index 966c579e497..fa796d92f3f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiEmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import org.springframework.ai.document.MetadataMode;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiImageProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiImageProperties.java
index 0108bb7536a..99fadafaf4d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiImageProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiImageProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import org.springframework.ai.openai.OpenAiImageOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiParentProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiParentProperties.java
index 1250e3698a9..e4ba3a470da 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiParentProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/openai/OpenAiParentProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
/**
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfiguration.java
index 9eb79519215..78ac62dc4ea 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfiguration.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,
@@ -15,7 +15,6 @@
*/
package org.springframework.ai.autoconfigure.postgresml;
-import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.postgresml.PostgresMlEmbeddingClient;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -41,7 +40,7 @@ public class PostgresMlAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = PostgresMlEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
- public EmbeddingClient postgresMlEmbeddingClient(JdbcTemplate jdbcTemplate,
+ public PostgresMlEmbeddingClient postgresMlEmbeddingClient(JdbcTemplate jdbcTemplate,
PostgresMlEmbeddingProperties embeddingProperties) {
return new PostgresMlEmbeddingClient(jdbcTemplate, embeddingProperties.getOptions());
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingProperties.java
index 7e6e2fe5a46..c0b13b5404c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingProperties.java
@@ -5,7 +5,7 @@
* 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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfiguration.java
new file mode 100644
index 00000000000..df0b43d23bc
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfiguration.java
@@ -0,0 +1,108 @@
+/*
+ * 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.autoconfigure.retry;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.ai.retry.NonTransientAiException;
+import org.springframework.ai.retry.TransientAiException;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.lang.NonNull;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.RetryListener;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.client.ResponseErrorHandler;
+
+/**
+ * @author Christian Tzolov
+ */
+@AutoConfiguration
+@ConditionalOnClass(RetryTemplate.class)
+@EnableConfigurationProperties({ SpringAiRetryProperties.class })
+public class SpringAiRetryAutoConfiguration {
+
+ private static final Logger logger = LoggerFactory.getLogger(SpringAiRetryAutoConfiguration.class);
+
+ @Bean
+ @ConditionalOnMissingBean
+ public RetryTemplate retryTemplate(SpringAiRetryProperties properties) {
+ return RetryTemplate.builder()
+ .maxAttempts(properties.getMaxAttempts())
+ .retryOn(NonTransientAiException.class)
+ .exponentialBackoff(properties.getBackoff().getInitialInterval(), properties.getBackoff().getMultiplier(),
+ properties.getBackoff().getMaxInterval())
+ .withListener(new RetryListener() {
+ @Override
+ public void onError(RetryContext context,
+ RetryCallback callback, Throwable throwable) {
+ logger.warn("Retry error. Retry count:" + context.getRetryCount(), throwable);
+ };
+ })
+ .build();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public ResponseErrorHandler responseErrorHandler(SpringAiRetryProperties properties) {
+
+ return new ResponseErrorHandler() {
+
+ @Override
+ public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
+ return response.getStatusCode().isError();
+ }
+
+ @Override
+ public void handleError(@NonNull ClientHttpResponse response) throws IOException {
+ if (response.getStatusCode().isError()) {
+ String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
+ String message = String.format("%s - %s", response.getStatusCode().value(), error);
+ /**
+ * Thrown on 4xx client errors, such as 401 - Incorrect API key
+ * provided, 401 - You must be a member of an organization to use the
+ * API, 429 - Rate limit reached for requests, 429 - You exceeded your
+ * current quota , please check your plan and billing details.
+ */
+ // onClientErrors - If true, do not throw a NonTransientAiException,
+ // and do not attempt retry for 4xx client error codes, false by
+ // default.
+ if (!properties.isOnClientErrors() && response.getStatusCode().is4xxClientError()) {
+ throw new NonTransientAiException(message);
+ }
+ // Explicitly configured non-transient codes
+ if (!CollectionUtils.isEmpty(properties.getExcludeOnHttpCodes())
+ && properties.getExcludeOnHttpCodes().contains(response.getStatusCode().value())) {
+ throw new NonTransientAiException(message);
+ }
+ throw new TransientAiException(message);
+ }
+ }
+ };
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryProperties.java
new file mode 100644
index 00000000000..1f70659d4fb
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryProperties.java
@@ -0,0 +1,131 @@
+/*
+ * 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.autoconfigure.retry;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+/**
+ * @author Christian Tzolov
+ */
+@ConfigurationProperties(SpringAiRetryProperties.CONFIG_PREFIX)
+public class SpringAiRetryProperties {
+
+ public static final String CONFIG_PREFIX = "spring.ai.retry";
+
+ /**
+ * Maximum number of retry attempts.
+ */
+ private int maxAttempts = 10;
+
+ /**
+ * Exponential Backoff properties.
+ */
+ @NestedConfigurationProperty
+ private Backoff backoff = new Backoff();
+
+ /**
+ * If false, throw a NonTransientAiException, and do not attempt retry for 4xx client
+ * error codes. False by default. If true, throw a TransientAiException, and attempt
+ * retry for 4xx client.
+ */
+ private boolean onClientErrors = false;
+
+ /**
+ * List of HTTP status codes that should not trigger a retry (e.g. throw
+ * NonTransientAiException).
+ */
+ private List excludeOnHttpCodes = new ArrayList<>();
+
+ /**
+ * Exponential Backoff properties.
+ */
+ public static class Backoff {
+
+ /**
+ * Initial sleep duration.
+ */
+ private Duration initialInterval = Duration.ofMillis(2000);
+
+ /**
+ * Backoff interval multiplier.
+ */
+ private int multiplier = 5;
+
+ /**
+ * Maximum backoff duration.
+ */
+ private Duration maxInterval = Duration.ofMillis(3 * 60000);
+
+ public Duration getInitialInterval() {
+ return initialInterval;
+ }
+
+ public void setInitialInterval(Duration initialInterval) {
+ this.initialInterval = initialInterval;
+ }
+
+ public int getMultiplier() {
+ return multiplier;
+ }
+
+ public void setMultiplier(int multiplier) {
+ this.multiplier = multiplier;
+ }
+
+ public Duration getMaxInterval() {
+ return maxInterval;
+ }
+
+ public void setMaxInterval(Duration maxInterval) {
+ this.maxInterval = maxInterval;
+ }
+
+ }
+
+ public int getMaxAttempts() {
+ return this.maxAttempts;
+ }
+
+ public void setMaxAttempts(int maxAttempts) {
+ this.maxAttempts = maxAttempts;
+ }
+
+ public Backoff getBackoff() {
+ return this.backoff;
+ }
+
+ public List getExcludeOnHttpCodes() {
+ return this.excludeOnHttpCodes;
+ }
+
+ public void setExcludeOnHttpCodes(List onHttpCodes) {
+ this.excludeOnHttpCodes = onHttpCodes;
+ }
+
+ public boolean isOnClientErrors() {
+ return this.onClientErrors;
+ }
+
+ public void setOnClientErrors(boolean onClientErrors) {
+ this.onClientErrors = onClientErrors;
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiConnectionProperties.java
index 413437ebbbe..1cf0d557171 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.stabilityai;
import org.springframework.ai.stabilityai.api.StabilityAiApi;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java
index 2a1d9493d7b..fa1660983f2 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageAutoConfiguration.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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageProperties.java
index 63aff1221b5..4b81fe9e71c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImageProperties.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,
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiParentProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiParentProperties.java
index f0f46a2f348..f8b62cd8ea2 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiParentProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiParentProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.stabilityai;
/**
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfiguration.java
index 336cab5afb6..adbacb01dc8 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.transformers;
import ai.djl.huggingface.tokenizers.HuggingFaceTokenizer;
import ai.onnxruntime.OrtSession;
-import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.transformers.TransformersEmbeddingClient;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -33,7 +31,7 @@
*/
@AutoConfiguration
@EnableConfigurationProperties({ TransformersEmbeddingClientProperties.class })
-@ConditionalOnClass({ OrtSession.class, HuggingFaceTokenizer.class })
+@ConditionalOnClass({ OrtSession.class, HuggingFaceTokenizer.class, TransformersEmbeddingClient.class })
public class TransformersEmbeddingClientAutoConfiguration {
@Bean
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientProperties.java
index b2e75b6da40..230f86b5ad8 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.transformers;
import java.io.File;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfiguration.java
index 3b73763c06f..b36626fc73d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.azure;
import com.azure.core.credential.AzureKeyCredential;
@@ -22,7 +21,6 @@
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.azure.AzureVectorStore;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -34,7 +32,7 @@
* @author Christian Tzolov
*/
@AutoConfiguration
-@ConditionalOnClass({ EmbeddingClient.class, SearchIndexClient.class })
+@ConditionalOnClass({ EmbeddingClient.class, SearchIndexClient.class, AzureVectorStore.class })
@EnableConfigurationProperties({ AzureVectorStoreProperties.class })
@ConditionalOnProperty(prefix = "spring.ai.vectorstore.azure", value = { "url", "api-key", "index-name" })
public class AzureVectorStoreAutoConfiguration {
@@ -49,7 +47,7 @@ public SearchIndexClient searchIndexClient(AzureVectorStoreProperties properties
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(SearchIndexClient searchIndexClient, EmbeddingClient embeddingClient,
+ public AzureVectorStore vectorStore(SearchIndexClient searchIndexClient, EmbeddingClient embeddingClient,
AzureVectorStoreProperties properties) {
var vectorStore = new AzureVectorStore(searchIndexClient, embeddingClient);
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreProperties.java
index b7f2f06ed75..8b21a0db267 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.azure;
import org.springframework.ai.vectorstore.azure.AzureVectorStore;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaApiProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaApiProperties.java
index 7fd59999520..7cc7c1e3fd3 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaApiProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaApiProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.chroma;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java
index 681bc834253..392ce9160ad 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,20 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.chroma;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.ai.chroma.ChromaApi;
import org.springframework.ai.embedding.EmbeddingClient;
-import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.ai.vectorsore.ChromaVectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
-import org.springframework.ai.chroma.ChromaApi;
-import org.springframework.ai.vectorsore.ChromaVectorStore;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
@@ -64,7 +62,7 @@ else if (StringUtils.hasText(apiProperties.getUsername()) && StringUtils.hasText
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(EmbeddingClient embeddingClient, ChromaApi chromaApi,
+ public ChromaVectorStore vectorStore(EmbeddingClient embeddingClient, ChromaApi chromaApi,
ChromaVectorStoreProperties storeProperties) {
return new ChromaVectorStore(embeddingClient, chromaApi, storeProperties.getCollectionName());
}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreProperties.java
index e73cc1dadf2..73a4e9c813e 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.chroma;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusServiceClientProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusServiceClientProperties.java
index df445f23a50..ecd3ebd516b 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusServiceClientProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusServiceClientProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.milvus;
import java.util.concurrent.TimeUnit;
@@ -58,13 +57,13 @@ public class MilvusServiceClientProperties {
/**
* Keep-alive time value of client channel. The keep-alive value must be greater than
- * zero. Default is 55000 ms.
+ * zero.
*/
private long keepAliveTimeMs = 55000;
/**
* The keep-alive timeout value of client channel. The timeout value must be greater
- * than zero. Default value is 20000 ms.
+ * than zero.
*/
private long keepAliveTimeoutMs = 20000;
@@ -122,12 +121,12 @@ public class MilvusServiceClientProperties {
private long idleTimeoutMs = TimeUnit.MILLISECONDS.convert(24, TimeUnit.HOURS);
/**
- * The username and password for this connection
+ * The username and password for this connection.
*/
private String username = "root";
/**
- * The password for this connection
+ * The password for this connection.
*/
private String password = "milvus";
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfiguration.java
index 0b8d50dd25b..dd744cd6ac8 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.milvus;
import java.util.concurrent.TimeUnit;
@@ -26,7 +25,6 @@
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.MilvusVectorStore;
import org.springframework.ai.vectorstore.MilvusVectorStore.MilvusVectorStoreConfig;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -44,7 +42,7 @@ public class MilvusVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingClient embeddingClient,
+ public MilvusVectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingClient embeddingClient,
MilvusVectorStoreProperties properties) {
MilvusVectorStoreConfig config = MilvusVectorStoreConfig.builder()
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreProperties.java
index bf2a61d49dc..346197c2af0 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.milvus;
import org.springframework.ai.vectorstore.MilvusVectorStore;
@@ -29,18 +28,33 @@ public class MilvusVectorStoreProperties {
public static final String CONFIG_PREFIX = "spring.ai.vectorstore.milvus";
/**
- * The database name
+ * The name of the Milvus database to connect to.
*/
private String databaseName = MilvusVectorStore.DEFAULT_DATABASE_NAME;
+ /**
+ * Milvus collection name to store the vectors.
+ */
private String collectionName = MilvusVectorStore.DEFAULT_COLLECTION_NAME;
+ /**
+ * The dimension of the vectors to be stored in the Milvus collection.
+ */
private int embeddingDimension = MilvusVectorStore.OPENAI_EMBEDDING_DIMENSION_SIZE;
+ /**
+ * The type of the index to be created for the Milvus collection.
+ */
private MilvusIndexType indexType = MilvusIndexType.IVF_FLAT;
+ /**
+ * The metric type to be used for the Milvus collection.
+ */
private MilvusMetricType metricType = MilvusMetricType.COSINE;
+ /**
+ * The index parameters to be used for the Milvus collection.
+ */
private String indexParameters = "{\"nlist\":1024}";
public enum MilvusMetricType {
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfiguration.java
index 0aad48b4631..28be1a7d179 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.neo4j;
import org.neo4j.driver.Driver;
+
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.Neo4jVectorStore;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -37,7 +36,7 @@ public class Neo4jVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(Driver driver, EmbeddingClient embeddingClient,
+ public Neo4jVectorStore vectorStore(Driver driver, EmbeddingClient embeddingClient,
Neo4jVectorStoreProperties properties) {
Neo4jVectorStore.Neo4jVectorStoreConfig config = Neo4jVectorStore.Neo4jVectorStoreConfig.builder()
.withDatabaseName(properties.getDatabaseName())
@@ -46,6 +45,8 @@ public VectorStore vectorStore(Driver driver, EmbeddingClient embeddingClient,
.withLabel(properties.getLabel())
.withEmbeddingProperty(properties.getEmbeddingProperty())
.withIndexName(properties.getIndexName())
+ .withIdProperty(properties.getIdProperty())
+ .withConstraintName(properties.getConstraintName())
.build();
return new Neo4jVectorStore(driver, embeddingClient, config);
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreProperties.java
index 7c39f05b182..5b13b56c40a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.neo4j;
import org.springframework.ai.vectorstore.Neo4jVectorStore;
@@ -39,6 +38,10 @@ public class Neo4jVectorStoreProperties {
private String indexName = Neo4jVectorStore.DEFAULT_INDEX_NAME;
+ private String idProperty = Neo4jVectorStore.DEFAULT_ID_PROPERTY;
+
+ private String constraintName = Neo4jVectorStore.DEFAULT_CONSTRAINT_NAME;
+
public String getDatabaseName() {
return this.databaseName;
}
@@ -87,4 +90,20 @@ public void setIndexName(String indexName) {
this.indexName = indexName;
}
+ public String getIdProperty() {
+ return this.idProperty;
+ }
+
+ public void setIdProperty(String idProperty) {
+ this.idProperty = idProperty;
+ }
+
+ public String getConstraintName() {
+ return this.constraintName;
+ }
+
+ public void setConstraintName(String constraintName) {
+ this.constraintName = constraintName;
+ }
+
}
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfiguration.java
index e3136409211..0ad62f41750 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pgvector;
import javax.sql.DataSource;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreProperties.java
index c99382a89ed..b15e22eacbc 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pgvector;
import org.springframework.ai.vectorstore.PgVectorStore;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfiguration.java
index 4d5fef2543e..871b7dc550b 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pinecone;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.PineconeVectorStore;
import org.springframework.ai.vectorstore.PineconeVectorStore.PineconeVectorStoreConfig;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -36,7 +34,7 @@ public class PineconeVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(EmbeddingClient embeddingClient, PineconeVectorStoreProperties properties) {
+ public PineconeVectorStore vectorStore(EmbeddingClient embeddingClient, PineconeVectorStoreProperties properties) {
var config = PineconeVectorStoreConfig.builder()
.withApiKey(properties.getApiKey())
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreProperties.java
index d5a8779eb08..8016e24a6de 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pinecone;
import java.time.Duration;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfiguration.java
index f0f9beda97c..d887d9731af 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfiguration.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,11 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import org.springframework.ai.embedding.EmbeddingClient;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore.QdrantVectorStoreConfig;
import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -37,7 +35,7 @@ public class QdrantVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(EmbeddingClient embeddingClient, QdrantVectorStoreProperties properties) {
+ public QdrantVectorStore vectorStore(EmbeddingClient embeddingClient, QdrantVectorStoreProperties properties) {
var config = QdrantVectorStoreConfig.builder()
.withCollectionName(properties.getCollectionName())
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreProperties.java
index d67c537ab55..c843f769305 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreProperties.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
index 507eeab8fcf..67e807d82e8 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.redis;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.RedisVectorStore;
import org.springframework.ai.vectorstore.RedisVectorStore.RedisVectorStoreConfig;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -36,7 +34,7 @@ public class RedisVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(EmbeddingClient embeddingClient, RedisVectorStoreProperties properties) {
+ public RedisVectorStore vectorStore(EmbeddingClient embeddingClient, RedisVectorStoreProperties properties) {
var config = RedisVectorStoreConfig.builder()
.withURI(properties.getUri())
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreProperties.java
index f2faa3dd465..7e82cf30e4d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.redis;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java
index 95ffbd48d7e..3f3e706060a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,11 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.weaviate;
import org.springframework.ai.embedding.EmbeddingClient;
-import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.WeaviateVectorStore;
import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig;
import org.springframework.ai.vectorstore.WeaviateVectorStore.WeaviateVectorStoreConfig.MetadataField;
@@ -37,7 +35,7 @@ public class WeaviateVectorStoreAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public VectorStore vectorStore(EmbeddingClient embeddingClient, WeaviateVectorStoreProperties properties) {
+ public WeaviateVectorStore vectorStore(EmbeddingClient embeddingClient, WeaviateVectorStoreProperties properties) {
WeaviateVectorStoreConfig.Builder configBuilder = WeaviateVectorStore.WeaviateVectorStoreConfig.builder()
.withScheme(properties.getScheme())
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java
index 6a28b999ac5..54bfc73efad 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.weaviate;
import java.util.Map;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java
index fe4269de527..93b93beacd3 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2024-20424 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini;
import java.io.IOException;
@@ -40,7 +39,7 @@
* @author Christian Tzolov
* @since 0.8.0
*/
-@ConditionalOnClass(VertexAI.class)
+@ConditionalOnClass({ VertexAI.class, VertexAiGeminiChatClient.class })
@EnableConfigurationProperties({ VertexAiGeminiChatProperties.class, VertexAiGeminiConnectionProperties.class })
public class VertexAiGeminiAutoConfiguration {
@@ -64,7 +63,9 @@ public VertexAI vertexAi(VertexAiGeminiConnectionProperties connectionProperties
@Bean
@ConditionalOnMissingBean
public VertexAiGeminiChatClient vertexAiGeminiChat(VertexAI vertexAi, VertexAiGeminiChatProperties chatProperties,
- List toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext) {
+ List toolFunctionCallbacks, ApplicationContext context) {
+
+ FunctionCallbackContext functionCallbackContext = springAiFunctionManager(context);
if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) {
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
@@ -73,9 +74,11 @@ public VertexAiGeminiChatClient vertexAiGeminiChat(VertexAI vertexAi, VertexAiGe
return new VertexAiGeminiChatClient(vertexAi, chatProperties.getOptions(), functionCallbackContext);
}
- @Bean
- @ConditionalOnMissingBean
- public FunctionCallbackContext springAiFunctionManager(ApplicationContext context) {
+ /**
+ * Because of the OPEN_API_SCHEMA type, the FunctionCallbackContext instance must
+ * different from the other JSON schema types.
+ */
+ private FunctionCallbackContext springAiFunctionManager(ApplicationContext context) {
FunctionCallbackContext manager = new FunctionCallbackContext();
manager.setSchemaType(SchemaType.OPEN_API_SCHEMA);
manager.setApplicationContext(context);
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiChatProperties.java
index 7412f25d76a..a47f4cf3249 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiChatProperties.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini;
import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiConnectionProperties.java
index 6cf3aaa842c..35dcef985d3 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiConnectionProperties.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java
index 5f2e6b53309..c1ac9fa7545 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2AutoConfiguration.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.palm2;
import org.springframework.ai.vertexai.palm2.VertexAiPaLm2ChatClient;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2ConnectionProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2ConnectionProperties.java
index 08e32df145a..6c4ae48fbdc 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2ConnectionProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2ConnectionProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.palm2;
import org.springframework.ai.vertexai.palm2.api.VertexAiPaLm2Api;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2EmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2EmbeddingProperties.java
index 6811c2cba69..2e01dbeab59 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2EmbeddingProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPalm2EmbeddingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.palm2;
import org.springframework.ai.vertexai.palm2.api.VertexAiPaLm2Api;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPlam2ChatProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPlam2ChatProperties.java
index b5b6d1efcbd..881f8e8dc0e 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPlam2ChatProperties.java
+++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPlam2ChatProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.palm2;
import org.springframework.ai.vertexai.palm2.VertexAiPaLm2ChatOptions;
diff --git a/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index e8b9f4540b9..4c136de2508 100644
--- a/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/spring-ai-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -5,6 +5,7 @@ org.springframework.ai.autoconfigure.transformers.TransformersEmbeddingClientAut
org.springframework.ai.autoconfigure.huggingface.HuggingfaceChatAutoConfiguration
org.springframework.ai.autoconfigure.vertexai.palm2.VertexAiPalm2AutoConfiguration
org.springframework.ai.autoconfigure.vertexai.gemini.VertexAiGeminiAutoConfiguration
+org.springframework.ai.autoconfigure.bedrock.jurrasic2.BedrockAi21Jurassic2ChatAutoConfiguration
org.springframework.ai.autoconfigure.bedrock.llama2.BedrockLlama2ChatAutoConfiguration
org.springframework.ai.autoconfigure.bedrock.cohere.BedrockCohereChatAutoConfiguration
org.springframework.ai.autoconfigure.bedrock.cohere.BedrockCohereEmbeddingAutoConfiguration
@@ -22,3 +23,5 @@ org.springframework.ai.autoconfigure.vectorstore.azure.AzureVectorStoreAutoConfi
org.springframework.ai.autoconfigure.vectorstore.weaviate.WeaviateVectorStoreAutoConfiguration
org.springframework.ai.autoconfigure.vectorstore.neo4j.Neo4jVectorStoreAutoConfiguration
org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration
+org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration
+org.springframework.ai.autoconfigure.postgresml.PostgresMlAutoConfiguration
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationIT.java
index ea83f1cfa95..ce707525060 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure;
import java.util.List;
@@ -57,11 +56,11 @@ public class AzureOpenAiAutoConfigurationIT {
"spring.ai.azure.openai.api-key=" + System.getenv("AZURE_OPENAI_API_KEY"),
"spring.ai.azure.openai.endpoint=" + System.getenv("AZURE_OPENAI_ENDPOINT"),
- "spring.ai.azure.openai.chat.options.model=" + CHAT_MODEL_NAME,
+ "spring.ai.azure.openai.chat.options.deployment-name=" + CHAT_MODEL_NAME,
"spring.ai.azure.openai.chat.options.temperature=0.8",
"spring.ai.azure.openai.chat.options.maxTokens=123",
- "spring.ai.azure.openai.embedding.options.model=" + EMBEDDING_MODEL_NAME
+ "spring.ai.azure.openai.embedding.options.deployment-name=" + EMBEDDING_MODEL_NAME
// @formatter:on
).withConfiguration(AutoConfigurations.of(AzureOpenAiAutoConfiguration.class));
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationPropertyTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationPropertyTests.java
index c439b03212c..48d1e9f3433 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationPropertyTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/AzureOpenAiAutoConfigurationPropertyTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure;
import org.junit.jupiter.api.Test;
@@ -39,7 +38,7 @@ public void embeddingPropertiesTest() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.azure.openai.api-key=TEST_API_KEY",
"spring.ai.azure.openai.endpoint=TEST_ENDPOINT",
- "spring.ai.azure.openai.embedding.options.model=MODEL_XYZ")
+ "spring.ai.azure.openai.embedding.options.deployment-name=MODEL_XYZ")
.withConfiguration(AutoConfigurations.of(AzureOpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(AzureOpenAiEmbeddingProperties.class);
@@ -48,7 +47,7 @@ public void embeddingPropertiesTest() {
assertThat(connectionProperties.getApiKey()).isEqualTo("TEST_API_KEY");
assertThat(connectionProperties.getEndpoint()).isEqualTo("TEST_ENDPOINT");
- assertThat(chatProperties.getOptions().getModel()).isEqualTo("MODEL_XYZ");
+ assertThat(chatProperties.getOptions().getDeploymentName()).isEqualTo("MODEL_XYZ");
});
}
@@ -60,7 +59,7 @@ public void chatPropertiesTest() {
"spring.ai.azure.openai.api-key=API_KEY",
"spring.ai.azure.openai.endpoint=ENDPOINT",
- "spring.ai.azure.openai.chat.options.model=MODEL_XYZ",
+ "spring.ai.azure.openai.chat.options.deployment-name=MODEL_XYZ",
"spring.ai.azure.openai.chat.options.frequencyPenalty=-1.5",
"spring.ai.azure.openai.chat.options.logitBias.myTokenId=-5",
"spring.ai.azure.openai.chat.options.maxTokens=123",
@@ -81,9 +80,9 @@ public void chatPropertiesTest() {
assertThat(connectionProperties.getEndpoint()).isEqualTo("ENDPOINT");
assertThat(connectionProperties.getApiKey()).isEqualTo("API_KEY");
- assertThat(embeddingProperties.getOptions().getModel()).isEqualTo("text-embedding-ada-002");
+ assertThat(embeddingProperties.getOptions().getDeploymentName()).isEqualTo("text-embedding-ada-002");
- assertThat(chatProperties.getOptions().getModel()).isEqualTo("MODEL_XYZ");
+ assertThat(chatProperties.getOptions().getDeploymentName()).isEqualTo("MODEL_XYZ");
assertThat(chatProperties.getOptions().getFrequencyPenalty()).isEqualTo(-1.5f);
assertThat(chatProperties.getOptions().getLogitBias().get("myTokenId")).isEqualTo(-5);
assertThat(chatProperties.getOptions().getMaxTokens()).isEqualTo(123);
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionBeanIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionBeanIT.java
index c8d6007ba88..4fd729fb8b9 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionBeanIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionBeanIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.tool;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionWrapperIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionWrapperIT.java
index 098e1f014de..ff070a957f2 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionWrapperIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithFunctionWrapperIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.tool;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithPromptFunctionIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithPromptFunctionIT.java
index c3ee02132f7..898eefe801a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithPromptFunctionIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/FunctionCallWithPromptFunctionIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.tool;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/MockWeatherService.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/MockWeatherService.java
index 0ab898c1045..80f855a156c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/MockWeatherService.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/azure/tool/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.azure.tool;
import java.util.function.Function;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfigurationIT.java
index 8ba95a5d5f4..f8aca8b9a44 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/anthropic/BedrockAnthropicChatAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.anthropic;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfigurationIT.java
index 3514e9173df..e515f6afde5 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereChatAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.cohere;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfigurationIT.java
index 936fb748e68..040dc25b17a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/cohere/BedrockCohereEmbeddingAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.cohere;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/jurassic2/BedrockAi21Jurassic2ChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/jurassic2/BedrockAi21Jurassic2ChatAutoConfigurationIT.java
new file mode 100644
index 00000000000..057e464835c
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/jurassic2/BedrockAi21Jurassic2ChatAutoConfigurationIT.java
@@ -0,0 +1,134 @@
+/*
+ * 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.autoconfigure.bedrock.jurassic2;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
+import org.springframework.ai.autoconfigure.bedrock.jurrasic2.BedrockAi21Jurassic2ChatAutoConfiguration;
+import org.springframework.ai.autoconfigure.bedrock.jurrasic2.BedrockAi21Jurassic2ChatProperties;
+import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ChatClient;
+import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
+import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.chat.prompt.SystemPromptTemplate;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import software.amazon.awssdk.regions.Region;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Ahmed Yousri
+ * @since 1.0.0
+ */
+@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
+@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
+public class BedrockAi21Jurassic2ChatAutoConfigurationIT {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withPropertyValues("spring.ai.bedrock.jurassic2.chat.enabled=true",
+ "spring.ai.bedrock.aws.access-key=" + System.getenv("AWS_ACCESS_KEY_ID"),
+ "spring.ai.bedrock.aws.secret-key=" + System.getenv("AWS_SECRET_ACCESS_KEY"),
+ "spring.ai.bedrock.aws.region=" + Region.US_EAST_1.id(),
+ "spring.ai.bedrock.jurassic2.chat.model="
+ + Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatModel.AI21_J2_ULTRA_V1.id(),
+ "spring.ai.bedrock.jurassic2.chat.options.temperature=0.5",
+ "spring.ai.bedrock.jurassic2.chat.options.maxGenLen=500")
+ .withConfiguration(AutoConfigurations.of(BedrockAi21Jurassic2ChatAutoConfiguration.class));
+
+ private final Message systemMessage = new SystemPromptTemplate("""
+ You are a helpful AI assistant. Your name is {name}.
+ You are an AI assistant that helps people find information.
+ Your name is {name}
+ You should reply to the user's request with your name and also in the style of a {voice}.
+ """).createMessage(Map.of("name", "Bob", "voice", "pirate"));
+
+ private final UserMessage userMessage = new UserMessage(
+ "Tell me about 3 famous pirates from the Golden Age of Piracy and why they did.");
+
+ @Test
+ public void chatCompletion() {
+ contextRunner.run(context -> {
+ BedrockAi21Jurassic2ChatClient ai21Jurassic2ChatClient = context
+ .getBean(BedrockAi21Jurassic2ChatClient.class);
+ ChatResponse response = ai21Jurassic2ChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
+ assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
+ });
+ }
+
+ @Test
+ public void propertiesTest() {
+
+ new ApplicationContextRunner()
+ .withPropertyValues("spring.ai.bedrock.jurassic2.chat.enabled=true",
+ "spring.ai.bedrock.aws.access-key=ACCESS_KEY", "spring.ai.bedrock.aws.secret-key=SECRET_KEY",
+ "spring.ai.bedrock.jurassic2.chat.model=MODEL_XYZ",
+ "spring.ai.bedrock.aws.region=" + Region.US_EAST_1.id(),
+ "spring.ai.bedrock.jurassic2.chat.options.temperature=0.55",
+ "spring.ai.bedrock.jurassic2.chat.options.maxTokens=123")
+ .withConfiguration(AutoConfigurations.of(BedrockAi21Jurassic2ChatAutoConfiguration.class))
+ .run(context -> {
+ var chatProperties = context.getBean(BedrockAi21Jurassic2ChatProperties.class);
+ var awsProperties = context.getBean(BedrockAwsConnectionProperties.class);
+
+ assertThat(chatProperties.isEnabled()).isTrue();
+ assertThat(awsProperties.getRegion()).isEqualTo(Region.US_EAST_1.id());
+
+ assertThat(chatProperties.getOptions().getTemperature()).isEqualTo(0.55f);
+ assertThat(chatProperties.getOptions().getMaxTokens()).isEqualTo(123);
+ assertThat(chatProperties.getModel()).isEqualTo("MODEL_XYZ");
+
+ assertThat(awsProperties.getAccessKey()).isEqualTo("ACCESS_KEY");
+ assertThat(awsProperties.getSecretKey()).isEqualTo("SECRET_KEY");
+ });
+ }
+
+ @Test
+ public void chatCompletionDisabled() {
+
+ // It is disabled by default
+ new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(BedrockAi21Jurassic2ChatAutoConfiguration.class))
+ .run(context -> {
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatProperties.class)).isEmpty();
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatClient.class)).isEmpty();
+ });
+
+ // Explicitly enable the chat auto-configuration.
+ new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.jurassic2.chat.enabled=true")
+ .withConfiguration(AutoConfigurations.of(BedrockAi21Jurassic2ChatAutoConfiguration.class))
+ .run(context -> {
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatProperties.class)).isNotEmpty();
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatClient.class)).isNotEmpty();
+ });
+
+ // Explicitly disable the chat auto-configuration.
+ new ApplicationContextRunner().withPropertyValues("spring.ai.bedrock.jurassic2.chat.enabled=false")
+ .withConfiguration(AutoConfigurations.of(BedrockAi21Jurassic2ChatAutoConfiguration.class))
+ .run(context -> {
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatProperties.class)).isEmpty();
+ assertThat(context.getBeansOfType(BedrockAi21Jurassic2ChatClient.class)).isEmpty();
+ });
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java
index da91e6b3e04..3c55877bcaf 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/llama2/BedrockLlama2ChatAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.llama2;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfigurationIT.java
index 85a71ec5c20..93c6541787c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanChatAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.titan;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfigurationIT.java
index ff3da4740f7..637598fcd9c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/titan/BedrockTitanEmbeddingAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.bedrock.titan;
import java.util.Base64;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfigurationIT.java
index 8a97f4ca24d..25816e8c0e4 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import java.util.List;
@@ -25,6 +24,7 @@
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import reactor.core.publisher.Flux;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -48,7 +48,8 @@ public class MistralAiAutoConfigurationIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.mistralai.apiKey=" + System.getenv("MISTRAL_AI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
@Test
void generate() {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiPropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiPropertiesTests.java
index 65ac7c72fdc..ee4cf9aa7ba 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiPropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/MistralAiPropertiesTests.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,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai;
import org.junit.jupiter.api.Test;
+
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -34,8 +35,8 @@ public void embeddingProperties() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.mistralai.base-url=TEST_BASE_URL", "spring.ai.mistralai.api-key=abc123",
"spring.ai.mistralai.embedding.options.model=MODEL_XYZ")
- .withConfiguration(
- AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(MistralAiEmbeddingProperties.class);
var connectionProperties = context.getBean(MistralAiCommonProperties.class);
@@ -56,8 +57,8 @@ public void embeddingOverrideConnectionProperties() {
new ApplicationContextRunner().withPropertyValues("spring.ai.mistralai.base-url=TEST_BASE_URL",
"spring.ai.mistralai.api-key=abc123", "spring.ai.mistralai.embedding.base-url=TEST_BASE_URL2",
"spring.ai.mistralai.embedding.api-key=456", "spring.ai.mistralai.embedding.options.model=MODEL_XYZ")
- .withConfiguration(
- AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(MistralAiEmbeddingProperties.class);
var connectionProperties = context.getBean(MistralAiCommonProperties.class);
@@ -80,8 +81,8 @@ public void embeddingOptionsTest() {
"spring.ai.mistralai.embedding.options.model=MODEL_XYZ",
"spring.ai.mistralai.embedding.options.encodingFormat=MyEncodingFormat")
- .withConfiguration(
- AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
.run(context -> {
var connectionProperties = context.getBean(MistralAiCommonProperties.class);
var embeddingProperties = context.getBean(MistralAiEmbeddingProperties.class);
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanIT.java
index 33fdaad50a0..d4259f3ee38 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai.tool;
import java.util.List;
@@ -27,6 +26,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.ai.autoconfigure.mistralai.MistralAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -49,7 +49,8 @@ class PaymentStatusBeanIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.mistralai.apiKey=" + System.getenv("MISTRAL_AI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class))
.withUserConfiguration(Config.class);
@Test
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanOpenAiIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanOpenAiIT.java
index 98bc1283ed2..15796f921b2 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanOpenAiIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusBeanOpenAiIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai.tool;
import java.util.List;
@@ -27,6 +26,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -56,7 +56,8 @@ class PaymentStatusBeanOpenAiIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("MISTRAL_AI_API_KEY"),
"spring.ai.openai.chat.base-url=https://api.mistral.ai")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withUserConfiguration(Config.class);
@Test
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusPromptIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusPromptIT.java
index 1992d28af7b..58bd9e84cc6 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusPromptIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/PaymentStatusPromptIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai.tool;
import java.util.List;
@@ -27,6 +26,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.ai.autoconfigure.mistralai.MistralAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -47,7 +47,8 @@ public class PaymentStatusPromptIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.mistralai.apiKey=" + System.getenv("MISTRAL_AI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
public record Transaction(@JsonProperty(required = true, value = "transaction_id") String id) {
}
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/WeatherServicePromptIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/WeatherServicePromptIT.java
index 97bc1a28a93..6bf052f5697 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/WeatherServicePromptIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/mistralai/tool/WeatherServicePromptIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.mistralai.tool;
import java.util.List;
@@ -30,6 +29,7 @@
import org.springframework.ai.autoconfigure.mistralai.MistralAiAutoConfiguration;
import org.springframework.ai.autoconfigure.mistralai.tool.WeatherServicePromptIT.MyWeatherService.Request;
import org.springframework.ai.autoconfigure.mistralai.tool.WeatherServicePromptIT.MyWeatherService.Response;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
@@ -55,7 +55,8 @@ public class WeatherServicePromptIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.mistralai.api-key=" + System.getenv("MISTRAL_AI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, MistralAiAutoConfiguration.class));
@Test
void promptFunctionCall() {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationIT.java
index d699699493b..affa261979f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import com.github.dockerjava.api.DockerClient;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationTests.java
index d8d16f16306..fff87017aac 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaChatAutoConfigurationTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import org.junit.jupiter.api.Test;
@@ -36,7 +35,7 @@ public void propertiesTest() {
new ApplicationContextRunner().withPropertyValues(
// @formatter:off
"spring.ai.ollama.base-url=TEST_BASE_URL",
- "spring.ai.ollama.chat.model=MODEL_XYZ",
+ "spring.ai.ollama.chat.options.model=MODEL_XYZ",
"spring.ai.ollama.chat.options.temperature=0.55",
"spring.ai.ollama.chat.options.topP=0.56",
"spring.ai.ollama.chat.options.topK=123")
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationIT.java
index 6f8f7a0bbcf..58d211260ed 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationTests.java
index 760885f975d..487485a062c 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaEmbeddingAutoConfigurationTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.ollama;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaImage.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaImage.java
index a3d01974a45..16ef622d392 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaImage.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/ollama/OllamaImage.java
@@ -1,3 +1,18 @@
+/*
+ * 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.autoconfigure.ollama;
public class OllamaImage {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfigurationIT.java
index 1ec2d1859ab..41bbfb8c7b1 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import java.util.List;
@@ -28,10 +27,14 @@
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.openai.OpenAiImageClient;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
import reactor.core.publisher.Flux;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.embedding.EmbeddingResponse;
+import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiEmbeddingClient;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -47,7 +50,8 @@ public class OpenAiAutoConfigurationIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class));
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class));
@Test
void generate() {
@@ -59,6 +63,17 @@ void generate() {
});
}
+ @Test
+ void transcribe() {
+ contextRunner.run(context -> {
+ OpenAiAudioTranscriptionClient client = context.getBean(OpenAiAudioTranscriptionClient.class);
+ Resource audioFile = new ClassPathResource("/speech/jfk.flac");
+ String response = client.call(audioFile);
+ assertThat(response).isNotEmpty();
+ logger.info("Response: " + response);
+ });
+ }
+
@Test
void generateStreaming() {
contextRunner.run(context -> {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java
index 5c3237a12b3..e14a6a562de 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/OpenAiPropertiesTests.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,19 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiEmbeddingClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ResponseFormat;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ToolChoiceBuilder;
import org.springframework.ai.openai.api.OpenAiApi.FunctionTool.Type;
+import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -52,7 +53,8 @@ public void chatProperties() {
"spring.ai.openai.chat.options.model=MODEL_XYZ",
"spring.ai.openai.chat.options.temperature=0.55")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -68,6 +70,33 @@ public void chatProperties() {
});
}
+ @Test
+ public void transcriptionProperties() {
+
+ new ApplicationContextRunner().withPropertyValues(
+ // @formatter:off
+ "spring.ai.openai.base-url=TEST_BASE_URL",
+ "spring.ai.openai.api-key=abc123",
+ "spring.ai.openai.audio.transcription.options.model=MODEL_XYZ",
+ "spring.ai.openai.audio.transcription.options.temperature=0.55")
+ // @formatter:on
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .run(context -> {
+ var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
+ var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
+
+ assertThat(connectionProperties.getApiKey()).isEqualTo("abc123");
+ assertThat(connectionProperties.getBaseUrl()).isEqualTo("TEST_BASE_URL");
+
+ assertThat(transcriptionProperties.getApiKey()).isNull();
+ assertThat(transcriptionProperties.getBaseUrl()).isNull();
+
+ assertThat(transcriptionProperties.getOptions().getModel()).isEqualTo("MODEL_XYZ");
+ assertThat(transcriptionProperties.getOptions().getTemperature()).isEqualTo(0.55f);
+ });
+ }
+
@Test
public void chatOverrideConnectionProperties() {
@@ -80,7 +109,8 @@ public void chatOverrideConnectionProperties() {
"spring.ai.openai.chat.options.model=MODEL_XYZ",
"spring.ai.openai.chat.options.temperature=0.55")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -96,6 +126,35 @@ public void chatOverrideConnectionProperties() {
});
}
+ @Test
+ public void transcriptionOverrideConnectionProperties() {
+
+ new ApplicationContextRunner().withPropertyValues(
+ // @formatter:off
+ "spring.ai.openai.base-url=TEST_BASE_URL",
+ "spring.ai.openai.api-key=abc123",
+ "spring.ai.openai.audio.transcription.base-url=TEST_BASE_URL2",
+ "spring.ai.openai.audio.transcription.api-key=456",
+ "spring.ai.openai.audio.transcription.options.model=MODEL_XYZ",
+ "spring.ai.openai.audio.transcription.options.temperature=0.55")
+ // @formatter:on
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .run(context -> {
+ var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
+ var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
+
+ assertThat(connectionProperties.getApiKey()).isEqualTo("abc123");
+ assertThat(connectionProperties.getBaseUrl()).isEqualTo("TEST_BASE_URL");
+
+ assertThat(transcriptionProperties.getApiKey()).isEqualTo("456");
+ assertThat(transcriptionProperties.getBaseUrl()).isEqualTo("TEST_BASE_URL2");
+
+ assertThat(transcriptionProperties.getOptions().getModel()).isEqualTo("MODEL_XYZ");
+ assertThat(transcriptionProperties.getOptions().getTemperature()).isEqualTo(0.55f);
+ });
+ }
+
@Test
public void embeddingProperties() {
@@ -105,7 +164,8 @@ public void embeddingProperties() {
"spring.ai.openai.api-key=abc123",
"spring.ai.openai.embedding.options.model=MODEL_XYZ")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -131,7 +191,8 @@ public void embeddingOverrideConnectionProperties() {
"spring.ai.openai.embedding.api-key=456",
"spring.ai.openai.embedding.options.model=MODEL_XYZ")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -155,7 +216,8 @@ public void imageProperties() {
"spring.ai.openai.image.options.model=MODEL_XYZ",
"spring.ai.openai.image.options.n=3")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -182,7 +244,8 @@ public void imageOverrideConnectionProperties() {
"spring.ai.openai.image.options.model=MODEL_XYZ",
"spring.ai.openai.image.options.n=3")
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -250,7 +313,8 @@ public void chatOptionsTest() {
"spring.ai.openai.chat.options.user=userXYZ"
)
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var chatProperties = context.getBean(OpenAiChatProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -288,6 +352,42 @@ public void chatOptionsTest() {
});
}
+ @Test
+ public void transcriptionOptionsTest() {
+
+ new ApplicationContextRunner().withPropertyValues(
+ // @formatter:off
+ "spring.ai.openai.api-key=API_KEY",
+ "spring.ai.openai.base-url=TEST_BASE_URL",
+
+ "spring.ai.openai.audio.transcription.options.model=MODEL_XYZ",
+ "spring.ai.openai.audio.transcription.options.language=en",
+ "spring.ai.openai.audio.transcription.options.prompt=Er, yes, I think so",
+ "spring.ai.openai.audio.transcription.options.responseFormat=JSON",
+ "spring.ai.openai.audio.transcription.options.temperature=0.55"
+ )
+ // @formatter:on
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .run(context -> {
+ var transcriptionProperties = context.getBean(OpenAiAudioTranscriptionProperties.class);
+ var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
+ var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
+
+ assertThat(connectionProperties.getBaseUrl()).isEqualTo("TEST_BASE_URL");
+ assertThat(connectionProperties.getApiKey()).isEqualTo("API_KEY");
+
+ assertThat(embeddingProperties.getOptions().getModel()).isEqualTo("text-embedding-ada-002");
+
+ assertThat(transcriptionProperties.getOptions().getModel()).isEqualTo("MODEL_XYZ");
+ assertThat(transcriptionProperties.getOptions().getLanguage()).isEqualTo("en");
+ assertThat(transcriptionProperties.getOptions().getPrompt()).isEqualTo("Er, yes, I think so");
+ assertThat(transcriptionProperties.getOptions().getResponseFormat())
+ .isEqualTo(OpenAiAudioApi.TranscriptResponseFormat.JSON);
+ assertThat(transcriptionProperties.getOptions().getTemperature()).isEqualTo(0.55f);
+ });
+ }
+
@Test
public void embeddingOptionsTest() {
@@ -301,7 +401,8 @@ public void embeddingOptionsTest() {
"spring.ai.openai.embedding.options.user=userXYZ"
)
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
var embeddingProperties = context.getBean(OpenAiEmbeddingProperties.class);
@@ -333,7 +434,8 @@ public void imageOptionsTest() {
"spring.ai.openai.image.options.user=userXYZ"
)
// @formatter:on
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
var imageProperties = context.getBean(OpenAiImageProperties.class);
var connectionProperties = context.getBean(OpenAiConnectionProperties.class);
@@ -359,7 +461,8 @@ void embeddingActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.embedding.enabled=false")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isEmpty();
@@ -367,7 +470,8 @@ void embeddingActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isNotEmpty();
@@ -376,7 +480,8 @@ void embeddingActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.embedding.enabled=true")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiEmbeddingProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiEmbeddingClient.class)).isNotEmpty();
@@ -388,7 +493,8 @@ void chatActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.chat.enabled=false")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isEmpty();
@@ -396,7 +502,8 @@ void chatActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isNotEmpty();
@@ -405,7 +512,8 @@ void chatActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.chat.enabled=true")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiChatProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiChatClient.class)).isNotEmpty();
@@ -418,7 +526,8 @@ void imageActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.image.enabled=false")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isEmpty();
@@ -426,7 +535,8 @@ void imageActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isNotEmpty();
@@ -435,7 +545,8 @@ void imageActivation() {
new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.api-key=API_KEY", "spring.ai.openai.base-url=TEST_BASE_URL",
"spring.ai.openai.image.enabled=true")
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.run(context -> {
assertThat(context.getBeansOfType(OpenAiImageProperties.class)).isNotEmpty();
assertThat(context.getBeansOfType(OpenAiImageClient.class)).isNotEmpty();
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackInPromptIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackInPromptIT.java
index febe06d9b84..67770f6af82 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackInPromptIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackInPromptIT.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,18 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai.tool;
import java.util.List;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.Generation;
+import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallbackWrapper;
@@ -43,7 +47,8 @@ public class FunctionCallbackInPromptIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class));
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class));
@Test
void functionCallTest() {
@@ -69,4 +74,39 @@ void functionCallTest() {
});
}
+ @Test
+ void streamingFunctionCallTest() {
+
+ contextRunner.withPropertyValues("spring.ai.openai.chat.options.model=gpt-4-turbo-preview").run(context -> {
+
+ OpenAiChatClient chatClient = context.getBean(OpenAiChatClient.class);
+
+ UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
+
+ var promptOptions = OpenAiChatOptions.builder()
+ .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
+ .withName("CurrentWeatherService")
+ .withDescription("Get the weather in location")
+ .withResponseConverter((response) -> "" + response.temp() + response.unit())
+ .build()))
+ .build();
+
+ Flux response = chatClient.stream(new Prompt(List.of(userMessage), promptOptions));
+
+ String content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("30.0", "30");
+ assertThat(content).containsAnyOf("10.0", "10");
+ assertThat(content).containsAnyOf("15.0", "15");
+ });
+ }
+
}
\ No newline at end of file
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWithPlainFunctionBeanIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWithPlainFunctionBeanIT.java
index c005b075044..d5437a62fdf 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWithPlainFunctionBeanIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWithPlainFunctionBeanIT.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,19 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai.tool;
import java.util.List;
import java.util.function.Function;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.Generation;
+import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallingOptions;
@@ -48,7 +52,8 @@ class FunctionCallbackWithPlainFunctionBeanIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withUserConfiguration(Config.class);
@Test
@@ -97,6 +102,52 @@ void functionCallWithPortableFunctionCallingOptions() {
});
}
+ @Test
+ void streamFunctionCallTest() {
+ contextRunner.withPropertyValues("spring.ai.openai.chat.options.model=gpt-4-turbo-preview").run(context -> {
+
+ OpenAiChatClient chatClient = context.getBean(OpenAiChatClient.class);
+
+ // Test weatherFunction
+ UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
+
+ Flux response = chatClient.stream(new Prompt(List.of(userMessage),
+ OpenAiChatOptions.builder().withFunction("weatherFunction").build()));
+
+ String content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("30.0", "30");
+ assertThat(content).containsAnyOf("10.0", "10");
+ assertThat(content).containsAnyOf("15.0", "15");
+
+ // Test weatherFunctionTwo
+ response = chatClient.stream(new Prompt(List.of(userMessage),
+ OpenAiChatOptions.builder().withFunction("weatherFunctionTwo").build()));
+
+ content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("30.0", "30");
+ assertThat(content).containsAnyOf("10.0", "10");
+ assertThat(content).containsAnyOf("15.0", "15");
+ });
+ }
+
@Configuration
static class Config {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWrapperIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWrapperIT.java
index 3a68d86f8d0..44e2c3af740 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWrapperIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/FunctionCallbackWrapperIT.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,18 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai.tool;
import java.util.List;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
+import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.Generation;
+import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallbackWrapper;
@@ -46,7 +50,8 @@ public class FunctionCallbackWrapperIT {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"))
- .withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
+ RestClientAutoConfiguration.class, OpenAiAutoConfiguration.class))
.withUserConfiguration(Config.class);
@Test
@@ -67,6 +72,34 @@ void functionCallTest() {
});
}
+ @Test
+ void streamFunctionCallTest() {
+ contextRunner.withPropertyValues("spring.ai.openai.chat.options.model=gpt-4-turbo-preview").run(context -> {
+
+ OpenAiChatClient chatClient = context.getBean(OpenAiChatClient.class);
+
+ UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
+
+ Flux response = chatClient.stream(
+ new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withFunction("WeatherInfo").build()));
+
+ String content = response.collectList()
+ .block()
+ .stream()
+ .map(ChatResponse::getResults)
+ .flatMap(List::stream)
+ .map(Generation::getOutput)
+ .map(AssistantMessage::getContent)
+ .collect(Collectors.joining());
+ logger.info("Response: {}", content);
+
+ assertThat(content).containsAnyOf("30.0", "30");
+ assertThat(content).containsAnyOf("10.0", "10");
+ assertThat(content).containsAnyOf("15.0", "15");
+
+ });
+ }
+
@Configuration
static class Config {
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/MockWeatherService.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/MockWeatherService.java
index b3df54c4bf2..11de44d2bb0 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/MockWeatherService.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/openai/tool/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.openai.tool;
import java.util.function.Function;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfigurationIT.java
index 7386c1f36ba..c08bbde2866 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlAutoConfigurationIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.postgresml;
import java.time.Duration;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingPropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingPropertiesTests.java
index 5ca2a8d7d50..6f5a84d2f7b 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingPropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/postgresml/PostgresMlEmbeddingPropertiesTests.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.postgresml;
import java.util.Map;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfigurationIT.java
new file mode 100644
index 00000000000..f15e605fc50
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryAutoConfigurationIT.java
@@ -0,0 +1,44 @@
+/*
+ * 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.autoconfigure.retry;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Christian Tzolov
+ */
+public class SpringAiRetryAutoConfigurationIT {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
+ AutoConfigurations.of(SpringAiRetryAutoConfiguration.class, RestClientAutoConfiguration.class));
+
+ @Test
+ void testRetryAutoConfiguration() {
+ this.contextRunner.run((context) -> {
+ assertThat(context).hasSingleBean(RetryTemplate.class);
+ assertThat(context).hasSingleBean(ResponseErrorHandler.class);
+ });
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryPropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryPropertiesTests.java
new file mode 100644
index 00000000000..eba635f5923
--- /dev/null
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/retry/SpringAiRetryPropertiesTests.java
@@ -0,0 +1,75 @@
+/*
+ * 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.autoconfigure.retry;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit Tests for {@link SpringAiRetryProperties}.
+ *
+ * @author Christian Tzolov
+ */
+public class SpringAiRetryPropertiesTests {
+
+ @Test
+ public void retryDefaultProperties() {
+
+ new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class))
+ .run(context -> {
+ var retryProperties = context.getBean(SpringAiRetryProperties.class);
+
+ assertThat(retryProperties.getMaxAttempts()).isEqualTo(10);
+ assertThat(retryProperties.isOnClientErrors()).isFalse(); // do not retry
+ // on 4xx
+ // errors
+ assertThat(retryProperties.getExcludeOnHttpCodes()).isEmpty();
+ assertThat(retryProperties.getBackoff().getInitialInterval().toMillis()).isEqualTo(2000);
+ assertThat(retryProperties.getBackoff().getMultiplier()).isEqualTo(5);
+ assertThat(retryProperties.getBackoff().getMaxInterval().toMillis()).isEqualTo(3 * 60000);
+ });
+ }
+
+ @Test
+ public void retryCustomProperties() {
+
+ new ApplicationContextRunner().withPropertyValues(
+ // @formatter:off
+ "spring.ai.retry.max-attempts=100",
+ "spring.ai.retry.on-client-errors=false",
+ "spring.ai.retry.exclude-on-http-codes=404,500",
+ "spring.ai.retry.backoff.initial-interval=1000",
+ "spring.ai.retry.backoff.multiplier=2",
+ "spring.ai.retry.backoff.max-interval=60000" )
+ // @formatter:on
+ .withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class))
+ .run(context -> {
+ var retryProperties = context.getBean(SpringAiRetryProperties.class);
+
+ assertThat(retryProperties.getMaxAttempts()).isEqualTo(100);
+ assertThat(retryProperties.isOnClientErrors()).isFalse();
+ assertThat(retryProperties.getExcludeOnHttpCodes()).containsExactly(404, 500);
+ assertThat(retryProperties.getBackoff().getInitialInterval().toMillis()).isEqualTo(1000);
+ assertThat(retryProperties.getBackoff().getMultiplier()).isEqualTo(2);
+ assertThat(retryProperties.getBackoff().getMaxInterval().toMillis()).isEqualTo(60000);
+ });
+ }
+
+}
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiAutoConfigurationIT.java
index 7236d343a53..f1b2042913d 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiAutoConfigurationIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.autoconfigure.stabilityai;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImagePropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImagePropertiesTests.java
index 784220722f7..63802bec599 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImagePropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/stabilityai/StabilityAiImagePropertiesTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.stabilityai;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfigurationIT.java
index 23abc2a2060..257becedd3b 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/transformers/TransformersEmbeddingClientAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.transformers;
import java.io.File;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfigurationIT.java
index 5be2e730cb8..09d2b412744 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.azure;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfigurationIT.java
index 294cfdd1bac..def4dd9707a 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.chroma;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfigurationIT.java
index ff4eb64cbcd..a8500ed3918 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/milvus/MilvusVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.milvus;
import java.io.File;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java
index b81f35e8098..fcd3281bed4 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.neo4j;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfigurationIT.java
index 373286d9b3c..b068685a1be 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pgvector;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStorePropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStorePropertiesTests.java
index 8b3798db5ee..db36d5e2e83 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStorePropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pgvector/PgVectorStorePropertiesTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pgvector;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfigurationIT.java
index bca64f5c02c..a137636ba03 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pinecone;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStorePropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStorePropertiesTests.java
index 4584e0effe7..4baeac0e171 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStorePropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/pinecone/PineconeVectorStorePropertiesTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.pinecone;
import java.time.Duration;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfigurationIT.java
index 9146852a186..832a312e3ef 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreAutoConfigurationIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreCloudAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreCloudAutoConfigurationIT.java
index 6573b723f6e..40261466e2e 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreCloudAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStoreCloudAutoConfigurationIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import java.io.IOException;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStorePropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStorePropertiesTests.java
index b861fd70305..324d73b88bf 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStorePropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/qdrant/QdrantVectorStorePropertiesTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.qdrant;
import org.junit.jupiter.api.Test;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfigurationIT.java
index 4071a2d02a7..c27725f9cfe 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStoreAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.redis;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStorePropertiesTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStorePropertiesTests.java
index dc5eb724467..028a51a25f5 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStorePropertiesTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/redis/RedisVectorStorePropertiesTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.redis;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationTests.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationTests.java
index 3bc741f64c2..87b69c46150 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationTests.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/weaviate/WeaviateVectorStoreAutoConfigurationTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vectorstore.weaviate;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfigurationIT.java
index 0101beefbee..5fd24735290 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/VertexAiGeminiAutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini;
import java.util.stream.Collectors;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java
index fc15b15f8eb..cc259066745 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionBeanIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini.tool;
import java.util.List;
@@ -38,7 +37,6 @@
import org.springframework.context.annotation.Description;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertThat;
@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_PROJECT_ID", matches = ".*")
@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_LOCATION", matches = ".*")
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionWrapperIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionWrapperIT.java
index 6ea4f8e41ac..cbad663c9c2 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionWrapperIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithFunctionWrapperIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini.tool;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithPromptFunctionIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithPromptFunctionIT.java
index 5605b4a8d9c..a2dc42154e3 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithPromptFunctionIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/FunctionCallWithPromptFunctionIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini.tool;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/MockWeatherService.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/MockWeatherService.java
index 8cc1526878c..1e25d6d54c0 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/MockWeatherService.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/gemini/tool/MockWeatherService.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.gemini.tool;
import java.util.function.Function;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPaLm2AutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPaLm2AutoConfigurationIT.java
index 34c7e3b20a0..0ea8f663e3f 100644
--- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPaLm2AutoConfigurationIT.java
+++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vertexai/palm2/VertexAiPaLm2AutoConfigurationIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.autoconfigure.vertexai.palm2;
import java.util.List;
diff --git a/spring-ai-spring-boot-autoconfigure/src/test/resources/speech/jfk.flac b/spring-ai-spring-boot-autoconfigure/src/test/resources/speech/jfk.flac
new file mode 100644
index 00000000000..e44b7c13897
Binary files /dev/null and b/spring-ai-spring-boot-autoconfigure/src/test/resources/speech/jfk.flac differ
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-azure-openai/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-azure-openai/pom.xml
index 033525f45a6..61a3a6d9d57 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-azure-openai/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-azure-openai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-azure-openai-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-azure-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-azure-store/pom.xml
index 15da3f8694b..d688bba563c 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-azure-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-azure-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-azure-vector-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-bedrock-ai/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-bedrock-ai/pom.xml
index 5165276c8e4..781dc92a6b0 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-bedrock-ai/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-bedrock-ai/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-bedrock-ai-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-chroma-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-chroma-store/pom.xml
index d22a25d59b6..6dd309936f9 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-chroma-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-chroma-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-chroma-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-milvus-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-milvus-store/pom.xml
index eed7a8feaf0..825e9f03040 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-milvus-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-milvus-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-milvus-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-mistral-ai/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-mistral-ai/pom.xml
index 632126b3410..05a61791490 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-mistral-ai/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-mistral-ai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-mistral-ai-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store/pom.xml
index aba068b13c0..cc294111481 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-neo4j-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-neo4j-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-ollama/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-ollama/pom.xml
index 0d14843d05b..fc35584038d 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-ollama/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-ollama/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-ollama-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-openai/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-openai/pom.xml
index bf335d2165d..95b60e64261 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-openai/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-openai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-openai-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store/pom.xml
index d1a8aaa23d3..a194100e6fe 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-pgvector-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-pgvector-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store/pom.xml
index 9e9507bd25d..1a46b3bd7de 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-pinecone-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-pinecone-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding/pom.xml
index 494c4a8a024..0378542fa4d 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-postgresml-embedding/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-postgresml-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store/pom.xml
index 561129c7eaf..4a578cca655 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-qdrant-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-qdrant-store-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-redis/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-redis/pom.xml
index c9338d314b5..5d6794fb20f 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-redis/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-redis/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-redis-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-stability-ai/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-stability-ai/pom.xml
index 070c5634ad6..b2a74b1663d 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-stability-ai/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-stability-ai/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-stability-ai-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-transformers/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-transformers/pom.xml
index 92d8d39a749..5cab1733dce 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-transformers/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-transformers/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-transformers-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini/pom.xml
index 5bec1e30dfa..3ef367efa41 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-gemini/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-vertex-ai-gemini-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2/pom.xml
index c19de4a88f5..eec7a61c030 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-vertex-ai-palm2/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-vertex-ai-palm2-spring-boot-starter
diff --git a/spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store/pom.xml b/spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store/pom.xml
index 2867d458a08..ea237a2e159 100644
--- a/spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store/pom.xml
+++ b/spring-ai-spring-boot-starters/spring-ai-starter-weaviate-store/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-weaviate-store-spring-boot-starter
diff --git a/spring-ai-test/README.md b/spring-ai-test/README.md
index cacd5c36511..feae3b35cb2 100644
--- a/spring-ai-test/README.md
+++ b/spring-ai-test/README.md
@@ -1,2 +1,2 @@
TODO:
- Documentation and sample tests using the `BasicEvaluationTest``.
\ No newline at end of file
+ Documentation and sample tests using the `BasicEvaluationTest`.
\ No newline at end of file
diff --git a/spring-ai-test/pom.xml b/spring-ai-test/pom.xml
index 3f42baaddef..5c1f04db0cf 100644
--- a/spring-ai-test/pom.xml
+++ b/spring-ai-test/pom.xml
@@ -4,7 +4,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOTspring-ai-testjar
diff --git a/spring-ai-test/src/main/java/org/springframework/ai/evaluation/BasicEvaluationTest.java b/spring-ai-test/src/main/java/org/springframework/ai/evaluation/BasicEvaluationTest.java
index f7bf74db4b0..bdc0750bd68 100644
--- a/spring-ai-test/src/main/java/org/springframework/ai/evaluation/BasicEvaluationTest.java
+++ b/spring-ai-test/src/main/java/org/springframework/ai/evaluation/BasicEvaluationTest.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.evaluation;
import org.slf4j.Logger;
diff --git a/vector-stores/spring-ai-azure/pom.xml b/vector-stores/spring-ai-azure/pom.xml
index 5e2d75daa9f..08f680f83e2 100644
--- a/vector-stores/spring-ai-azure/pom.xml
+++ b/vector-stores/spring-ai-azure/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-azure-vector-store
diff --git a/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverter.java b/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverter.java
index 6e7f23995a2..2bcb1f3f0eb 100644
--- a/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverter.java
+++ b/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.azure;
import java.text.ParseException;
diff --git a/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java b/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java
index 89353e66470..1aa684040ba 100644
--- a/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java
+++ b/vector-stores/spring-ai-azure/src/main/java/org/springframework/ai/vectorstore/azure/AzureVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.azure;
import java.util.ArrayList;
diff --git a/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverterTests.java b/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverterTests.java
index 3839d937088..65d67fcc651 100644
--- a/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverterTests.java
+++ b/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureAiSearchFilterExpressionConverterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.azure;
import java.util.Date;
@@ -45,7 +44,7 @@
public class AzureAiSearchFilterExpressionConverterTests {
private static String format(String text) {
- return text.trim().replace(" " + System.lineSeparator(), System.lineSeparator()) + "\n";
+ return text.trim().replace(" " + System.lineSeparator(), System.lineSeparator()) + System.lineSeparator();
}
@Test
diff --git a/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureVectorStoreIT.java b/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureVectorStoreIT.java
index 1783d5d4bdd..7e4cbbbd7fb 100644
--- a/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureVectorStoreIT.java
+++ b/vector-stores/spring-ai-azure/src/test/java/org/springframework/ai/vectorstore/azure/AzureVectorStoreIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.azure;
import java.io.IOException;
diff --git a/vector-stores/spring-ai-chroma/pom.xml b/vector-stores/spring-ai-chroma/pom.xml
index 9813cbf7c1e..795ca758142 100644
--- a/vector-stores/spring-ai-chroma/pom.xml
+++ b/vector-stores/spring-ai-chroma/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-chroma-store
diff --git a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/chroma/ChromaApi.java b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/chroma/ChromaApi.java
index 7c7d91b6832..7917d8550bb 100644
--- a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/chroma/ChromaApi.java
+++ b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/chroma/ChromaApi.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chroma;
import java.util.ArrayList;
diff --git a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/ChromaVectorStore.java b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/ChromaVectorStore.java
index c1f5c99ebc1..f1b1817e29b 100644
--- a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/ChromaVectorStore.java
+++ b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/ChromaVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorsore;
import java.util.ArrayList;
diff --git a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/JsonUtils.java b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/JsonUtils.java
index 9ccd0f0b036..7db15be9e0d 100644
--- a/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/JsonUtils.java
+++ b/vector-stores/spring-ai-chroma/src/main/java/org/springframework/ai/vectorsore/JsonUtils.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorsore;
import java.util.List;
diff --git a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/chroma/ChromaApiIT.java b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/chroma/ChromaApiIT.java
index 371310d6a65..a53814d569b 100644
--- a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/chroma/ChromaApiIT.java
+++ b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/chroma/ChromaApiIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.chroma;
import java.util.List;
diff --git a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/BasicAuthChromaWhereIT.java b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/BasicAuthChromaWhereIT.java
index 250a6c91884..24d672e1531 100644
--- a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/BasicAuthChromaWhereIT.java
+++ b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/BasicAuthChromaWhereIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.util.List;
diff --git a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/ChromaVectorStoreIT.java b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/ChromaVectorStoreIT.java
index aea5e30e1b2..879b0326b99 100644
--- a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/ChromaVectorStoreIT.java
+++ b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/ChromaVectorStoreIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.util.Collections;
diff --git a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/TokenSecuredChromaWhereIT.java b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/TokenSecuredChromaWhereIT.java
index f667877f5bf..837815eb6cc 100644
--- a/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/TokenSecuredChromaWhereIT.java
+++ b/vector-stores/spring-ai-chroma/src/test/java/org/springframework/ai/vectorstore/TokenSecuredChromaWhereIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.util.List;
diff --git a/vector-stores/spring-ai-elasticsearch-store/pom.xml b/vector-stores/spring-ai-elasticsearch-store/pom.xml
new file mode 100644
index 00000000000..11aac09f9b7
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/pom.xml
@@ -0,0 +1,78 @@
+
+
+ 4.0.0
+
+ org.springframework.ai
+ spring-ai
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+ spring-ai-elasticsearch-store
+ jar
+ Spring AI Vector Store - Elasticsearch
+ Spring AI Elasticsearch Vector Store
+ https://github.com/spring-projects/spring-ai
+
+
+ https://github.com/spring-projects/spring-ai
+ git://github.com/spring-projects/spring-ai.git
+ git@github.com:spring-projects/spring-ai.git
+
+
+
+
+ 4.0.3
+
+
+
+
+ org.springframework.ai
+ spring-ai-core
+ ${parent.version}
+
+
+
+ co.elastic.clients
+ elasticsearch-java
+ 8.12.2
+
+
+
+
+ org.springframework.ai
+ spring-ai-openai
+ ${parent.version}
+ test
+
+
+
+
+ org.springframework.ai
+ spring-ai-test
+ ${parent.version}
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.testcontainers
+ elasticsearch
+ test
+
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
+ test
+
+
+
+
+
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverter.java b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverter.java
new file mode 100644
index 00000000000..d1ce3840ca2
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverter.java
@@ -0,0 +1,151 @@
+/*
+ * 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.vectorstore;
+
+import org.springframework.ai.vectorstore.filter.Filter;
+import org.springframework.ai.vectorstore.filter.Filter.Expression;
+import org.springframework.ai.vectorstore.filter.Filter.Key;
+import org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.regex.Pattern;
+
+/**
+ * @author Jemin Huh
+ * @since 1.0.0
+ */
+public class ElasticsearchAiSearchFilterExpressionConverter extends AbstractFilterExpressionConverter {
+
+ private static final Pattern DATE_FORMAT_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z");
+
+ private final SimpleDateFormat dateFormat;
+
+ public ElasticsearchAiSearchFilterExpressionConverter() {
+ this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ @Override
+ protected void doExpression(Expression expression, StringBuilder context) {
+ if (expression.type() == Filter.ExpressionType.IN || expression.type() == Filter.ExpressionType.NIN) {
+ context.append(getOperationSymbol(expression));
+ context.append("(");
+ this.convertOperand(expression.left(), context);
+ this.convertOperand(expression.right(), context);
+ context.append(")");
+ }
+ else {
+ this.convertOperand(expression.left(), context);
+ context.append(getOperationSymbol(expression));
+ this.convertOperand(expression.right(), context);
+ }
+ }
+
+ @Override
+ protected void doStartValueRange(Filter.Value listValue, StringBuilder context) {
+ }
+
+ @Override
+ protected void doEndValueRange(Filter.Value listValue, StringBuilder context) {
+ }
+
+ @Override
+ protected void doAddValueRangeSpitter(Filter.Value listValue, StringBuilder context) {
+ context.append(" OR ");
+ }
+
+ private String getOperationSymbol(Expression exp) {
+ return switch (exp.type()) {
+ case AND -> " AND ";
+ case OR -> " OR ";
+ case EQ, IN -> "";
+ case NE -> " NOT ";
+ case LT -> "<";
+ case LTE -> "<=";
+ case GT -> ">";
+ case GTE -> ">=";
+ case NIN -> "NOT ";
+ default -> throw new RuntimeException("Not supported expression type: " + exp.type());
+ };
+ }
+
+ @Override
+ public void doKey(Key key, StringBuilder context) {
+ var identifier = hasOuterQuotes(key.key()) ? removeOuterQuotes(key.key()) : key.key();
+ var prefixedIdentifier = withMetaPrefix(identifier);
+ context.append(prefixedIdentifier.trim()).append(":");
+ }
+
+ public String withMetaPrefix(String identifier) {
+ return "metadata." + identifier;
+ }
+
+ @Override
+ protected void doValue(Filter.Value filterValue, StringBuilder context) {
+ if (filterValue.value() instanceof List list) {
+ int c = 0;
+ for (Object v : list) {
+ context.append(v);
+ if (c++ < list.size() - 1) {
+ this.doAddValueRangeSpitter(filterValue, context);
+ }
+ }
+ }
+ else {
+ this.doSingleValue(filterValue.value(), context);
+ }
+ }
+
+ @Override
+ protected void doSingleValue(Object value, StringBuilder context) {
+ if (value instanceof Date date) {
+ context.append(this.dateFormat.format(date));
+ }
+ else if (value instanceof String text) {
+ if (DATE_FORMAT_PATTERN.matcher(text).matches()) {
+ try {
+ Date date = this.dateFormat.parse(text);
+ context.append(this.dateFormat.format(date));
+ }
+ catch (ParseException e) {
+ throw new IllegalArgumentException("Invalid date type:" + text, e);
+ }
+ }
+ else {
+ context.append(text);
+ }
+ }
+ else {
+ context.append(value);
+ }
+ }
+
+ @Override
+ public void doStartGroup(Filter.Group group, StringBuilder context) {
+ context.append("(");
+ }
+
+ @Override
+ public void doEndGroup(Filter.Group group, StringBuilder context) {
+ context.append(")");
+ }
+
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchVectorStore.java b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchVectorStore.java
new file mode 100644
index 00000000000..6e84bbddeea
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/ElasticsearchVectorStore.java
@@ -0,0 +1,216 @@
+/*
+ * 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.vectorstore;
+
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.query_dsl.Query;
+import co.elastic.clients.elasticsearch.core.BulkRequest;
+import co.elastic.clients.elasticsearch.core.BulkResponse;
+import co.elastic.clients.elasticsearch.core.search.Hit;
+import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
+import co.elastic.clients.json.JsonData;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.endpoints.BooleanResponse;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.elasticsearch.client.RestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.embedding.EmbeddingClient;
+import org.springframework.ai.vectorstore.filter.Filter;
+import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author Jemin Huh
+ * @since 1.0.0
+ */
+public class ElasticsearchVectorStore implements VectorStore, InitializingBean {
+
+ // divided by 2 to get score in the range [0, 1]
+ public static final String COSINE_SIMILARITY_FUNCTION = "(cosineSimilarity(params.query_vector, 'embedding') + 1.0) / 2";
+
+ private static final Logger logger = LoggerFactory.getLogger(ElasticsearchVectorStore.class);
+
+ private static final String INDEX_NAME = "spring-ai-document-index";
+
+ private final EmbeddingClient embeddingClient;
+
+ private final ElasticsearchClient elasticsearchClient;
+
+ private final String index;
+
+ private final FilterExpressionConverter filterExpressionConverter;
+
+ private String similarityFunction;
+
+ public ElasticsearchVectorStore(RestClient restClient, EmbeddingClient embeddingClient) {
+ this(INDEX_NAME, restClient, embeddingClient);
+ }
+
+ public ElasticsearchVectorStore(String index, RestClient restClient, EmbeddingClient embeddingClient) {
+ Objects.requireNonNull(embeddingClient, "RestClient must not be null");
+ Objects.requireNonNull(embeddingClient, "EmbeddingClient must not be null");
+ this.elasticsearchClient = new ElasticsearchClient(new RestClientTransport(restClient, new JacksonJsonpMapper(
+ new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false))));
+ this.embeddingClient = embeddingClient;
+ this.index = index;
+ this.filterExpressionConverter = new ElasticsearchAiSearchFilterExpressionConverter();
+ // the potential functions for vector fields at
+ // https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-score-query.html#vector-functions
+ this.similarityFunction = COSINE_SIMILARITY_FUNCTION;
+ }
+
+ public ElasticsearchVectorStore withSimilarityFunction(String similarityFunction) {
+ this.similarityFunction = similarityFunction;
+ return this;
+ }
+
+ @Override
+ public void add(List documents) {
+ BulkRequest.Builder builkRequestBuilder = new BulkRequest.Builder();
+ for (Document document : documents) {
+ if (Objects.isNull(document.getEmbedding()) || document.getEmbedding().isEmpty()) {
+ logger.info("Calling EmbeddingClient for document id = " + document.getId());
+ document.setEmbedding(this.embeddingClient.embed(document));
+ }
+ builkRequestBuilder
+ .operations(op -> op.index(idx -> idx.index(this.index).id(document.getId()).document(document)));
+ }
+ bulkRequest(builkRequestBuilder.build());
+ }
+
+ @Override
+ public Optional delete(List idList) {
+ BulkRequest.Builder builkRequestBuilder = new BulkRequest.Builder();
+ for (String id : idList)
+ builkRequestBuilder.operations(op -> op.delete(idx -> idx.index(this.index).id(id)));
+ return Optional.of(bulkRequest(builkRequestBuilder.build()).errors());
+ }
+
+ private BulkResponse bulkRequest(BulkRequest bulkRequest) {
+ try {
+ return this.elasticsearchClient.bulk(bulkRequest);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public List similaritySearch(SearchRequest searchRequest) {
+ Assert.notNull(searchRequest, "The search request must not be null.");
+ return similaritySearch(this.embeddingClient.embed(searchRequest.getQuery()), searchRequest.getTopK(),
+ Double.valueOf(searchRequest.getSimilarityThreshold()).floatValue(),
+ searchRequest.getFilterExpression());
+ }
+
+ public List similaritySearch(List embedding, int topK, double similarityThreshold,
+ Filter.Expression filterExpression) {
+ return similaritySearch(new co.elastic.clients.elasticsearch.core.SearchRequest.Builder()
+ .query(getElasticsearchSimilarityQuery(embedding, filterExpression))
+ .size(topK)
+ .minScore(similarityThreshold)
+ .build());
+ }
+
+ private Query getElasticsearchSimilarityQuery(List embedding, Filter.Expression filterExpression) {
+ return Query.of(queryBuilder -> queryBuilder.scriptScore(scriptScoreQueryBuilder -> scriptScoreQueryBuilder
+ .query(queryBuilder2 -> queryBuilder2.queryString(queryStringQuerybuilder -> queryStringQuerybuilder
+ .query(getElasticsearchQueryString(filterExpression))))
+ .script(scriptBuilder -> scriptBuilder
+ .inline(inlineScriptBuilder -> inlineScriptBuilder.source(this.similarityFunction)
+ .params("query_vector", JsonData.of(embedding))))));
+ }
+
+ private String getElasticsearchQueryString(Filter.Expression filterExpression) {
+ return Objects.isNull(filterExpression) ? "*"
+ : this.filterExpressionConverter.convertExpression(filterExpression);
+
+ }
+
+ private List similaritySearch(co.elastic.clients.elasticsearch.core.SearchRequest searchRequest) {
+ try {
+ return this.elasticsearchClient.search(searchRequest, Document.class)
+ .hits()
+ .hits()
+ .stream()
+ .map(this::toDocument)
+ .collect(Collectors.toList());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Document toDocument(Hit hit) {
+ Document document = hit.source();
+ document.getMetadata().put("distance", 1 - hit.score().floatValue());
+ return document;
+ }
+
+ public boolean exists(String targetIndex) {
+ try {
+ BooleanResponse response = this.elasticsearchClient.indices()
+ .exists(existRequestBuilder -> existRequestBuilder.index(targetIndex));
+ return response.value();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public CreateIndexResponse createIndexMapping(String index, String mappingJson) {
+ try {
+ return this.elasticsearchClient.indices()
+ .create(createIndexBuilder -> createIndexBuilder.index(index)
+ .mappings(typeMappingBuilder -> typeMappingBuilder.withJson(new StringReader(mappingJson))));
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ if (!exists(this.index)) {
+ createIndexMapping(this.index, """
+ {
+ "properties": {
+ "embedding": {
+ "type": "dense_vector",
+ "dims": 1536,
+ "index": true,
+ "similarity": "cosine"
+ }
+ }
+ }
+ """);
+ }
+ }
+
+}
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverterTest.java b/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverterTest.java
new file mode 100644
index 00000000000..ae47a14ceac
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchAiSearchFilterExpressionConverterTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.vectorstore;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.ai.vectorstore.filter.Filter;
+import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
+
+import java.util.Date;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.*;
+
+class ElasticsearchAiSearchFilterExpressionConverterTest {
+
+ final FilterExpressionConverter converter = new ElasticsearchAiSearchFilterExpressionConverter();
+
+ @Test
+ public void testDate() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(EQ, new Filter.Key("activationDate"),
+ new Filter.Value(new Date(1704637752148L))));
+ assertThat(vectorExpr).isEqualTo("metadata.activationDate:2024-01-07T14:29:12Z");
+
+ vectorExpr = converter.convertExpression(
+ new Filter.Expression(EQ, new Filter.Key("activationDate"), new Filter.Value("1970-01-01T00:00:02Z")));
+ assertThat(vectorExpr).isEqualTo("metadata.activationDate:1970-01-01T00:00:02Z");
+ }
+
+ @Test
+ public void testEQ() {
+ String vectorExpr = converter
+ .convertExpression(new Filter.Expression(EQ, new Filter.Key("country"), new Filter.Value("BG")));
+ assertThat(vectorExpr).isEqualTo("metadata.country:BG");
+ }
+
+ @Test
+ public void tesEqAndGte() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(AND,
+ new Filter.Expression(EQ, new Filter.Key("genre"), new Filter.Value("drama")),
+ new Filter.Expression(GTE, new Filter.Key("year"), new Filter.Value(2020))));
+ assertThat(vectorExpr).isEqualTo("metadata.genre:drama AND metadata.year:>=2020");
+ }
+
+ @Test
+ public void tesIn() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(IN, new Filter.Key("genre"),
+ new Filter.Value(List.of("comedy", "documentary", "drama"))));
+ assertThat(vectorExpr).isEqualTo("(metadata.genre:comedy OR documentary OR drama)");
+ }
+
+ @Test
+ public void testNe() {
+ String vectorExpr = converter.convertExpression(
+ new Filter.Expression(OR, new Filter.Expression(GTE, new Filter.Key("year"), new Filter.Value(2020)),
+ new Filter.Expression(AND,
+ new Filter.Expression(EQ, new Filter.Key("country"), new Filter.Value("BG")),
+ new Filter.Expression(NE, new Filter.Key("city"), new Filter.Value("Sofia")))));
+ assertThat(vectorExpr).isEqualTo("metadata.year:>=2020 OR metadata.country:BG AND metadata.city: NOT Sofia");
+ }
+
+ @Test
+ public void testGroup() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(AND,
+ new Filter.Group(new Filter.Expression(OR,
+ new Filter.Expression(GTE, new Filter.Key("year"), new Filter.Value(2020)),
+ new Filter.Expression(EQ, new Filter.Key("country"), new Filter.Value("BG")))),
+ new Filter.Expression(NIN, new Filter.Key("city"), new Filter.Value(List.of("Sofia", "Plovdiv")))));
+ assertThat(vectorExpr)
+ .isEqualTo("(metadata.year:>=2020 OR metadata.country:BG) AND NOT (metadata.city:Sofia OR Plovdiv)");
+ }
+
+ @Test
+ public void tesBoolean() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(AND,
+ new Filter.Expression(AND, new Filter.Expression(EQ, new Filter.Key("isOpen"), new Filter.Value(true)),
+ new Filter.Expression(GTE, new Filter.Key("year"), new Filter.Value(2020))),
+ new Filter.Expression(IN, new Filter.Key("country"), new Filter.Value(List.of("BG", "NL", "US")))));
+
+ assertThat(vectorExpr)
+ .isEqualTo("metadata.isOpen:true AND metadata.year:>=2020 AND (metadata.country:BG OR NL OR US)");
+ }
+
+ @Test
+ public void testDecimal() {
+ String vectorExpr = converter.convertExpression(new Filter.Expression(AND,
+ new Filter.Expression(GTE, new Filter.Key("temperature"), new Filter.Value(-15.6)),
+ new Filter.Expression(LTE, new Filter.Key("temperature"), new Filter.Value(20.13))));
+
+ assertThat(vectorExpr).isEqualTo("metadata.temperature:>=-15.6 AND metadata.temperature:<=20.13");
+ }
+
+ @Test
+ public void testComplexIdentifiers() {
+ String vectorExpr = converter
+ .convertExpression(new Filter.Expression(EQ, new Filter.Key("\"country 1 2 3\""), new Filter.Value("BG")));
+ assertThat(vectorExpr).isEqualTo("metadata.country 1 2 3:BG");
+
+ vectorExpr = converter
+ .convertExpression(new Filter.Expression(EQ, new Filter.Key("'country 1 2 3'"), new Filter.Value("BG")));
+ assertThat(vectorExpr).isEqualTo("metadata.country 1 2 3:BG");
+ }
+
+}
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchVectorStoreIT.java b/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchVectorStoreIT.java
new file mode 100644
index 00000000000..6884fe1c0c1
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/java/org/springframework/ai/vectorstore/ElasticsearchVectorStoreIT.java
@@ -0,0 +1,490 @@
+/*
+ * 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.vectorstore;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HttpHost;
+import org.awaitility.Awaitility;
+import org.elasticsearch.client.RestClient;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.testcontainers.elasticsearch.ElasticsearchContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.shaded.com.fasterxml.jackson.core.type.TypeReference;
+import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.springframework.ai.ResourceUtils;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.embedding.EmbeddingClient;
+import org.springframework.ai.openai.OpenAiEmbeddingClient;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.DefaultResourceLoader;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+
+@Testcontainers
+@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
+class ElasticsearchVectorStoreIT {
+
+ @Container
+ private static final ElasticsearchContainer elasticsearchContainer = new ElasticsearchContainer(
+ "docker.elastic.co/elasticsearch/elasticsearch:8.12.2")
+ .withEnv("xpack.security.enabled", "false");
+
+ private static final String DEFAULT = "default cosine similarity";
+
+ protected final ObjectMapper objectMapper = new ObjectMapper();
+
+ private List documents = List.of(
+ new Document("1", getText("classpath:/test/data/spring.ai.txt"), Map.of("meta1", "meta1")),
+ new Document("2", getText("classpath:/test/data/time.shelter.txt"), Map.of()),
+ new Document("3", getText("classpath:/test/data/great.depression.txt"), Map.of("meta2", "meta2")));
+
+ @BeforeAll
+ public static void beforeAll() {
+ Awaitility.setDefaultPollInterval(2, TimeUnit.SECONDS);
+ Awaitility.setDefaultPollDelay(Duration.ZERO);
+ Awaitility.setDefaultTimeout(Duration.ofMinutes(1));
+ }
+
+ private String getText(String uri) {
+ var resource = new DefaultResourceLoader().getResource(uri);
+ try {
+ return resource.getContentAsString(StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private ApplicationContextRunner getContextRunner() {
+ return new ApplicationContextRunner().withUserConfiguration(TestApplication.class);
+ }
+
+ @BeforeEach
+ void cleanDatabase() {
+ getContextRunner().run(context -> {
+ // Generating test data for documents with embedding values
+ // EmbeddingClient embeddingClient = context.getBean(EmbeddingClient.class);
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/documents.json"),
+ // objectMapper.writeValueAsString(documents.stream()
+ // .peek(document ->
+ // document.setEmbedding(embeddingClient.embed(document.getContent())))
+ // .collect(Collectors.toList())));
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/greatDepressionEmbeddingValues.json"),
+ // objectMapper.writeValueAsString(embeddingClient.embed("Great
+ // Depression")));
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/updateEmbeddingValues.json"),
+ // objectMapper.writeValueAsString(embeddingClient.embed("FooBar")));
+ // Document updateDocument = new Document("1", "The World is Big and Salvation
+ // Lurks Around the
+ // Corner",
+ // Map.of("meta2", "meta2"));
+ // updateDocument.setEmbedding(
+ // embeddingClient.embed("The World is Big and Salvation Lurks Around the
+ // Corner"));
+ // Files.writeString(Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/updateDocument.json"),
+ // objectMapper.writeValueAsString(updateDocument));
+ //
+ // var bgDocument = new Document("1", "The World is Big and Salvation Lurks
+ // Around the Corner",
+ // Map.of("country", "BG", "year", 2020, "activationDate", new Date(1000)));
+ // var nlDocument = new Document("2", "The World is Big and Salvation Lurks
+ // Around the Corner",
+ // Map.of("country", "NL", "activationDate", new Date(2000)));
+ // var bgDocument2 = new Document("3", "The World is Big and Salvation Lurks
+ // Around the Corner",
+ // Map.of("country", "BG", "year", 2023, "activationDate", new Date(3000)));
+ // Files.writeString(Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/searchDocuments.json"),
+ // objectMapper.writeValueAsString(List.of(bgDocument, nlDocument,
+ // bgDocument2).stream()
+ // .peek(document ->
+ // document.setEmbedding(embeddingClient.embed(document.getContent())))
+ // .collect(Collectors.toList())));
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/theWorldEmbeddingValues.json"),
+ // objectMapper.writeValueAsString(embeddingClient.embed("The World")));
+ //
+ // Document document = new Document(UUID.randomUUID().toString(), "Spring AI
+ // rocks!!",
+ // Collections.singletonMap("meta1", "meta1"));
+ // document.setEmbedding(embeddingClient.embed(document.getContent()));
+ // Files.writeString(Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/springAIRocksDocuments.json"),
+ // objectMapper.writeValueAsString(document));
+ //
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/springEmbeddingValues.json"),
+ // objectMapper.writeValueAsString(embeddingClient.embed("Spring")));
+ // Files.writeString(
+ // Path.of(System.getProperty("user.dir"),
+ // "src/test/resources/depressionEmbeddingValues.json"),
+ // objectMapper.writeValueAsString(embeddingClient.embed("Depression")));
+
+ VectorStore vectorStore = context.getBean(VectorStore.class);
+ vectorStore.delete(List.of("_all"));
+ });
+ }
+
+ @ParameterizedTest(name = "{0} : {displayName} ")
+ @ValueSource(strings = {DEFAULT, """
+ double value = dotProduct(params.query_vector, 'embedding');
+ return sigmoid(1, Math.E, -value);
+ """, "1 / (1 + l1norm(params.query_vector, 'embedding'))",
+ "1 / (1 + l2norm(params.query_vector, 'embedding'))"})
+ public void addAndSearchTest(String similarityFunction) {
+
+ getContextRunner().run(context -> {
+ ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
+ if (!DEFAULT.equals(similarityFunction))
+ vectorStore.withSimilarityFunction(similarityFunction);
+
+ this.documents = objectMapper.readValue(ResourceUtils.getText("documents.json"),
+ new TypeReference>() {
+ });
+ vectorStore.add(documents);
+
+ // List embedding =
+ // vectorStore.similaritySearch(SearchRequest.query("Great
+ // Depression").withTopK(1))
+ List embedding = objectMapper.readValue(
+ ResourceUtils.getText("greatDepressionEmbeddingValues.json"), new TypeReference>() {
+ });
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(embedding, 1, 0, null), hasSize(1));
+
+ List results = vectorStore.similaritySearch(embedding, 1, 0, null);
+
+ assertThat(results).hasSize(1);
+ Document resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(documents.get(2).getId());
+ assertThat(resultDoc.getContent()).contains("The Great Depression (1929–1939) was an economic shock");
+ assertThat(resultDoc.getMetadata()).hasSize(2);
+ assertThat(resultDoc.getMetadata()).containsKey("meta2");
+ assertThat(resultDoc.getMetadata()).containsKey("distance");
+
+ // Remove all documents from the store
+ vectorStore.delete(documents.stream().map(Document::getId).toList());
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(embedding, 1, 0, null), hasSize(0));
+ });
+ }
+
+ @ParameterizedTest(name = "{0} : {displayName} ")
+ @ValueSource(strings = {DEFAULT, """
+ double value = dotProduct(params.query_vector, 'embedding');
+ return sigmoid(1, Math.E, -value);
+ """, "1 / (1 + l1norm(params.query_vector, 'embedding'))",
+ "1 / (1 + l2norm(params.query_vector, 'embedding'))"})
+ public void searchWithFilters(String similarityFunction) {
+
+ getContextRunner().run(context -> {
+ ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
+ if (!DEFAULT.equals(similarityFunction))
+ vectorStore.withSimilarityFunction(similarityFunction);
+
+ var bgDocument = new Document("1", "The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "BG", "year", 2020, "activationDate", new Date(1000)));
+ var nlDocument = new Document("2", "The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "NL", "activationDate", new Date(2000)));
+ var bgDocument2 = new Document("3", "The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "BG", "year", 2023, "activationDate", new Date(3000)));
+
+ // vectorStore.add(List.of(bgDocument, nlDocument, bgDocument2));
+ this.documents = objectMapper.readValue(ResourceUtils.getText("searchDocuments.json"),
+ new TypeReference>() {
+ });
+ vectorStore.add(documents);
+
+ List embedding = objectMapper.readValue(ResourceUtils.getText("theWorldEmbeddingValues.json"),
+ new TypeReference>() {
+ });
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(SearchRequest.query("The World").withTopK(5)),
+ hasSize(3));
+// Awaitility.await().until(() -> vectorStore.similaritySearch(embedding, 5, 0, null), hasSize(3));
+
+ List results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'NL'"));
+// List results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country == 'NL'"));
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(nlDocument.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'BG'"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country == 'BG'"));
+
+ assertThat(results).hasSize(2);
+ assertThat(results.get(0).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+ assertThat(results.get(1).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'BG' && year == 2020"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country == 'BG' && year == 2020"));
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(bgDocument.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country in ['BG']"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country in ['BG']"));
+
+ assertThat(results).hasSize(2);
+ assertThat(results.get(0).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+ assertThat(results.get(1).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country in ['BG','NL']"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country in ['BG','NL']"));
+
+ assertThat(results).hasSize(3);
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country not in ['BG']"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("country not in ['BG']"));
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(nlDocument.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("NOT(country not in ['BG'])"));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("NOT(country not in ['BG'])"));
+
+ assertThat(results).hasSize(2);
+ assertThat(results.get(0).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+ assertThat(results.get(1).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("activationDate > " +
+ ZonedDateTime.parse("1970-01-01T00:00:02Z").toInstant().toEpochMilli()));
+// results = vectorStore.similaritySearch(embedding, 5,
+// SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL,
+// new FilterExpressionTextParser().parse("activationDate > " +
+// ZonedDateTime.parse("1970-01-01T00:00:02Z").toInstant().toEpochMilli()));
+
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(bgDocument2.getId());
+
+ // Remove all documents from the store
+ vectorStore.delete(documents.stream().map(Document::getId).toList());
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(embedding, 1, 0, null), hasSize(0));
+ });
+ }
+
+ @ParameterizedTest(name = "{0} : {displayName} ")
+ @ValueSource(strings = {DEFAULT, """
+ double value = dotProduct(params.query_vector, 'embedding');
+ return sigmoid(1, Math.E, -value);
+ """, "1 / (1 + l1norm(params.query_vector, 'embedding'))",
+ "1 / (1 + l2norm(params.query_vector, 'embedding'))"})
+ public void documentUpdateTest(String similarityFunction) {
+
+ getContextRunner().run(context -> {
+ ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
+ if (!DEFAULT.equals(similarityFunction))
+ vectorStore.withSimilarityFunction(similarityFunction);
+
+ // Document document = new Document(UUID.randomUUID().toString(), "Spring AI
+ // rocks!!",
+ // Collections.singletonMap("meta1", "meta1"));
+ Document document = objectMapper.readValue(ResourceUtils.getText("springAIRocksDocuments.json"),
+ Document.class);
+ vectorStore.add(List.of(document));
+
+ // SearchRequest springSearchRequest =
+ // SearchRequest.query("Spring").withTopK(5);
+ List springEmbedding = objectMapper.readValue(ResourceUtils.getText("springEmbeddingValues.json"),
+ new TypeReference>() {
+ });
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(springEmbedding, 5, 0, null), hasSize(1));
+
+ List results = vectorStore.similaritySearch(springEmbedding, 5, 0, null);
+
+ assertThat(results).hasSize(1);
+ Document resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(document.getId());
+ assertThat(resultDoc.getContent()).isEqualTo("Spring AI rocks!!");
+ assertThat(resultDoc.getMetadata()).containsKey("meta1");
+ assertThat(resultDoc.getMetadata()).containsKey("distance");
+
+ // Document sameIdDocument = new Document(document.getId(),
+ // "The World is Big and Salvation Lurks Around the Corner",
+ // Collections.singletonMap("meta2", "meta2"));
+ Document sameIdDocument = objectMapper.readValue(
+ ResourceUtils.getText("updateDocument.json").replace("\"1\"", "\"" + document.getId() + "\""),
+ Document.class);
+
+ vectorStore.add(List.of(sameIdDocument));
+ // SearchRequest fooBarSearchRequest =
+ // SearchRequest.query("FooBar").withTopK(5);
+ List updateEmbedding = objectMapper.readValue(ResourceUtils.getText("updateEmbeddingValues.json"),
+ new TypeReference>() {
+ });
+ Awaitility.await()
+ .until(() -> vectorStore.similaritySearch(updateEmbedding, 5, 0, null).get(0).getContent(),
+ equalTo("The World is Big and Salvation Lurks Around the Corner"));
+
+ results = vectorStore.similaritySearch(updateEmbedding, 5, 0, null);
+
+ assertThat(results).hasSize(1);
+ resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(document.getId());
+ assertThat(resultDoc.getContent()).isEqualTo("The World is Big and Salvation Lurks Around the Corner");
+ assertThat(resultDoc.getMetadata()).containsKey("meta2");
+ assertThat(resultDoc.getMetadata()).containsKey("distance");
+
+ // Remove all documents from the store
+ vectorStore.delete(List.of(document.getId()));
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(updateEmbedding, 5, 0, null), hasSize(0));
+
+ });
+ }
+
+ @ParameterizedTest(name = "{0} : {displayName} ")
+ @ValueSource(strings = {DEFAULT, """
+ double value = dotProduct(params.query_vector, 'embedding');
+ return sigmoid(1, Math.E, -value);
+ """, "1 / (1 + l1norm(params.query_vector, 'embedding'))",
+ "1 / (1 + l2norm(params.query_vector, 'embedding'))"})
+ public void searchThresholdTest(String similarityFunction) {
+
+ getContextRunner().run(context -> {
+ ElasticsearchVectorStore vectorStore = context.getBean(ElasticsearchVectorStore.class);
+ if (!DEFAULT.equals(similarityFunction))
+ vectorStore.withSimilarityFunction(similarityFunction);
+
+ this.documents = objectMapper.readValue(ResourceUtils.getText("documents.json"),
+ new TypeReference>() {
+ });
+ vectorStore.add(documents);
+
+ List embedding = objectMapper.readValue(ResourceUtils.getText("depressionEmbeddingValues.json"),
+ new TypeReference>() {
+ });
+
+ Awaitility.await()
+ .until(() -> vectorStore.similaritySearch(embedding, 50,
+ SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL, null),
+ hasSize(3));
+
+ List fullResult = vectorStore.similaritySearch(embedding, 50,
+ SearchRequest.SIMILARITY_THRESHOLD_ACCEPT_ALL, null);
+
+ List distances = fullResult.stream().map(doc -> (Float) doc.getMetadata().get("distance")).toList();
+
+ assertThat(distances).hasSize(3);
+
+ float threshold = (distances.get(0) + distances.get(1)) / 2;
+
+ List results = vectorStore.similaritySearch(embedding, 50, 1 - threshold, null);
+
+ assertThat(results).hasSize(1);
+ Document resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(documents.get(2).getId());
+ assertThat(resultDoc.getContent()).contains("The Great Depression (1929–1939) was an economic shock");
+ assertThat(resultDoc.getMetadata()).containsKey("meta2");
+ assertThat(resultDoc.getMetadata()).containsKey("distance");
+
+ // Remove all documents from the store
+ vectorStore.delete(documents.stream().map(Document::getId).toList());
+
+ Awaitility.await().until(() -> vectorStore.similaritySearch(embedding, 1, 0, null), hasSize(0));
+ });
+ }
+
+ @SpringBootConfiguration
+ @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
+ public static class TestApplication {
+
+ @Bean
+ public ElasticsearchVectorStore vectorStore(EmbeddingClient embeddingClient) {
+ return new ElasticsearchVectorStore(
+ RestClient.builder(HttpHost.create(elasticsearchContainer.getHttpHostAddress())).build(),
+ embeddingClient);
+ }
+
+ @Bean
+ public EmbeddingClient embeddingClient() {
+ return new OpenAiEmbeddingClient(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
+ }
+
+ }
+
+}
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/depressionEmbeddingValues.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/depressionEmbeddingValues.json
new file mode 100644
index 00000000000..d558d838646
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/depressionEmbeddingValues.json
@@ -0,0 +1 @@
+[-0.009833804,-0.0045277267,0.036474936,-0.023907408,-0.031032804,0.0073025804,-0.02302148,-0.024173187,-0.0017908409,-0.027337218,-0.014060948,0.024084594,0.011865111,0.012459949,-0.0013557867,0.019313237,0.050953534,-0.0028460447,0.019199332,-0.04047427,-0.02690691,0.019490423,-0.012301748,-0.0021404661,-0.018351372,3.7236675E-4,0.010789341,-0.039436467,0.010390674,-0.015453122,0.0049675265,-0.017111072,-0.016946543,-0.033108406,0.0034203161,-0.02380616,0.002684679,-5.1613235E-5,0.009992006,-0.0063090753,-0.012605495,0.014896252,-0.014263446,-0.014693754,-0.018528558,0.00994771,-0.004992839,-0.014174853,-0.016731389,0.007840466,0.039208658,0.025945043,-0.009492089,-0.0020803495,0.01089059,-0.0076442957,0.0031513737,0.0047428804,0.0038094919,0.0030548708,0.010188175,4.156744E-4,-0.023540381,0.02465412,0.0055781845,0.011536052,-0.0060970853,0.015225311,0.0063596996,-0.010181848,0.024856618,0.016655453,-0.0025154036,0.0039455453,0.004034138,9.816402E-4,0.0149721885,-0.008694754,0.0017623645,0.012959866,0.01532656,-0.01584546,-0.010359033,0.004676436,-0.003306411,0.008587177,-0.002757452,0.021743212,-0.0014016652,-0.019996667,-0.014098916,0.012232139,0.020211821,0.022869607,0.018364029,-0.008131556,0.016073272,0.044068605,0.002123064,-0.048599496,-0.011586677,0.01549109,-0.0192373,-0.013858451,0.0022749375,-0.01685795,-0.007777185,0.007321565,0.00595154,-0.0063280594,-0.01379517,0.017300915,-0.006394504,-0.04186644,0.018629806,-0.016845293,4.79746E-4,-0.005359866,-0.0016848458,-0.028299082,0.017579349,0.017693255,0.03450058,-0.024919897,-7.751873E-4,-0.006160366,-0.040651456,-0.022489924,-0.0010116985,0.014288758,0.01464313,0.034348708,0.010036303,-0.013187676,-0.030729057,0.031817485,-0.013099083,-0.009935053,-0.0013462947,-0.029615318,-0.010017318,0.018996835,-0.041917067,-0.03460183,-0.0022591173,0.012934553,0.013390174,-0.010783013,0.017554037,-0.019490423,0.0014190674,-0.032855283,0.022084927,-0.0077202325,-0.0113588665,0.008928892,-0.0023888424,0.01640233,-5.32348E-4,-0.021692587,2.825874E-4,-0.013440798,0.015225311,0.0039740214,-0.004752373,0.015579683,0.0028159865,0.002865029,-0.012972522,-0.0063312235,0.02341382,0.02126228,-0.03270341,0.037386175,0.004540383,0.0016468775,0.004053122,0.012213155,-0.016364362,-0.0066887587,-0.044802662,0.009276935,0.004790341,0.009213654,-0.016984511,-0.0052396334,0.009776852,9.398157E-5,0.009068109,-0.017857784,0.0013114903,0.011998001,0.006381848,-0.013276269,-0.6824179,-0.03652556,-0.005106744,0.014073604,-0.014212822,0.026957532,0.023439132,0.019933388,-0.007637968,-0.016060615,0.0087390505,0.0019506243,-0.017035136,-0.02113572,0.0067457114,-0.006720399,-0.026299415,-0.0058186506,0.011719566,-0.001491049,-0.009643963,0.01532656,-0.020173853,0.007986011,0.014465944,0.018528558,0.017288258,-3.923397E-4,-0.0038158197,0.02465412,-0.016478267,0.03153905,0.0111120725,-0.0060116565,0.056952536,-0.011966361,-0.0056889253,0.039993335,0.024793336,0.040778015,-0.013554703,-0.0103337215,0.007802497,-0.020718066,0.00961865,-0.0029298915,0.026501913,0.0023809324,0.033690587,-0.0068596164,0.013731889,0.0067710234,-0.008852955,0.005758534,0.026020981,0.0031228974,0.01787044,0.0010868442,0.019249957,0.020781348,-0.009859117,0.030399997,-0.017680598,-0.015035469,-0.013149708,0.021806493,-0.020452289,-0.0152379675,0.010112239,0.004761865,0.030804994,-0.0028270606,-0.004888426,0.0037019148,0.030804994,0.015972022,0.021743212,0.018401997,-0.003398168,-0.0051700245,-0.008764362,-0.004644796,-0.023818815,0.005106744,0.046296082,-0.020920565,1.3140611E-4,-0.0032146543,0.007948043,0.0016389674,-3.429017E-4,0.0053535383,-0.0138204815,-0.006460949,-0.013655952,0.011396835,-0.008593504,-0.011618317,0.022945544,0.0076949205,-0.006043297,0.0018952538,-0.007365861,0.016819982,0.016782014,-0.006084429,-0.016731389,0.016440298,0.044625476,-0.023768192,0.005970524,-0.022451956,-0.03293122,-0.01555437,0.0062268106,-0.02690691,0.026856285,-0.012149874,0.00743547,0.0048124893,0.0069861775,-0.003524729,0.009884429,-0.008897251,-0.0030390506,0.0024995834,-0.01037169,-0.009061781,-0.013263613,0.003939217,0.005293422,0.017756535,0.029995002,-6.181723E-4,0.013364862,-0.0058123227,0.013744545,-0.009561698,0.019262614,-0.022249456,-0.012320732,0.0017639466,0.009118734,0.032829974,-0.004682764,-0.032754038,-0.0025343879,-0.025603328,-0.020566193,-0.0038917565,0.009928726,-0.013807826,-0.022097584,0.03260216,0.009878101,-0.02550208,0.009808492,-0.008536552,-0.0026024145,-0.011871439,0.028425643,0.01979417,-0.016452955,-0.002670441,-0.013883762,-0.022021648,0.007346877,0.038044292,-0.018503245,-0.007213988,-0.009504746,0.008625145,0.009378185,0.0016247293,-4.3579566E-5,0.034323394,-0.0011888841,-0.02113572,0.023135385,0.0010156535,0.006188842,-0.0041037467,-0.02928626,5.541007E-4,0.022755701,-0.008220149,0.020629473,0.027843462,-0.0028333885,0.008947876,-0.03245029,0.035690255,-0.0084796,-7.7993335E-4,-0.0054231468,0.012529558,0.00469542,-0.0012648209,0.017073104,0.025046458,0.026830971,-0.033766527,-0.007783513,0.016782014,0.029893752,-0.0107577015,0.0014522896,-0.022186177,0.016452955,0.006600166,-0.005211157,-0.007929059,-0.016921232,0.0014056202,0.005125728,0.019414486,0.002230641,0.022350706,-0.01741482,-0.013706577,1.3130723E-4,-0.0021673604,0.0077202325,-0.009384512,-7.4987503E-4,0.01917402,0.021199,0.01565562,0.01346611,-0.018237468,-0.0040942547,0.014605161,-0.0055908407,0.008435303,-0.019465111,0.0054041627,0.020680098,-0.023641631,0.022970855,0.009055453,-0.0055971686,0.0038854284,-0.006802664,0.009726227,0.0021942547,-0.008017652,0.02262914,0.020464944,-0.012548542,0.008403663,-0.019363862,0.0150607815,-0.0016848458,-0.011536052,-0.016490923,-0.015199998,0.003825312,0.0027115734,0.022401331,0.017629974,0.022148209,-0.021072438,-8.8118226E-4,0.005220649,0.013238301,-0.0054832636,0.02064213,0.006027477,-0.0063312235,0.008454287,-0.012624479,0.0023129056,0.003512073,-0.048675433,0.009897085,-0.0114791,-0.0017781847,0.0027321398,0.023008823,-0.0044074934,-0.003293755,-0.0042018313,0.024198499,0.005938884,-0.011915736,-0.004366361,-0.0051921727,0.0038601162,0.027286593,0.032273103,0.0014443796,0.023350539,-0.0047333883,1.7229131E-5,-0.009922397,-0.0025913403,0.015579683,0.0059895082,0.002148376,0.013681265,-0.0010963363,-0.015225311,8.0089504E-4,-0.002126228,0.0037683593,0.0122637795,-0.024995835,-0.041891754,-0.017503412,0.0035848457,0.0013747709,0.0020898415,0.0032083262,0.0093592,-0.008871939,-0.017237633,-0.0064166524,-0.0057901745,5.216694E-4,0.0026941714,-0.002971024,-0.00743547,-0.01431407,-0.013921731,0.066925555,0.036069937,-0.011251289,0.009719899,0.01346611,0.0071696914,-0.0036544544,-0.036044627,0.016326394,0.024413653,0.0077139046,-0.024603495,0.0029109074,-0.0020819316,0.010960199,0.009954037,-0.0034804328,-0.021819148,0.007327893,-0.012738383,0.0049548703,-0.010839966,0.0038126558,0.028881263,0.004752373,0.0034171522,0.019414486,0.024932554,0.028780015,-0.015617651,-0.0077328887,0.0072835963,-0.011466444,0.03042531,-0.0055592004,-0.009314903,0.018161532,0.041107073,0.024540214,-0.010707077,0.012776352,0.0012054953,0.016769357,-0.010289425,4.678809E-4,-0.023527725,-0.002138884,0.011080432,-0.0047492087,-0.0015440466,0.012732056,-0.0037968357,-0.012675103,-0.0078088255,0.014212822,0.028476268,0.0071633635,-0.0013162363,-0.015908742,-0.011744878,-0.014162197,-0.03224779,0.004701748,-0.004897918,1.298241E-4,-0.03293122,0.0039961697,-0.0014032472,-0.038930222,-0.032273103,0.011757535,-0.016832639,-0.0149721885,0.014681098,0.005214321,-0.010738716,-0.007251956,-0.013377517,-0.0033855117,0.02527427,-0.016237801,-0.003597502,0.009504746,7.550166E-4,-0.0073342207,-0.0077012484,0.026451288,-0.006701415,-0.008732722,0.01725029,0.005116236,-0.003410824,0.023692254,-0.020135885,-0.010953871,-0.003099167,0.010302081,0.008042963,-0.014364695,-0.006103413,0.027919399,-0.036702745,-0.011181681,-0.024008658,0.0085618645,-0.009302247,0.02086994,0.02074338,-0.0103337215,-0.015073437,0.0129535375,-0.025324894,-0.011814487,0.019870106,0.0065305573,0.012035969,0.008859283,0.0066318065,7.455245E-4,-0.010093255,-0.0047333883,-0.020958534,0.0301975,0.0155923385,-0.017111072,-0.01487094,0.015199998,-0.019199332,-0.01770591,7.232774E-5,9.325978E-4,0.017921064,-0.02670441,-0.013162363,-0.045789838,0.003413988,-0.016617484,0.012801664,0.02517302,-0.026096918,-0.0026293087,-6.1065773E-4,-0.01754138,-0.025388174,0.015541714,-0.035639632,-0.02726128,0.0026973353,-0.01565562,0.009757868,-0.00857452,0.017718567,-0.0144406315,0.0128649445,-0.017389508,-0.028906576,0.0053725224,-0.0036829305,-0.0016611156,0.0014396335,0.02759034,0.028476268,0.019148707,-0.013782513,0.00825179,-0.014212822,0.031412486,-0.0051352205,-0.011441131,0.025097083,0.011181681,0.015010157,0.024995835,-0.027615651,0.024514902,0.023527725,-0.006606494,-0.019591672,-0.029007824,-0.04900449,-0.004888426,-0.011352539,-0.004682764,0.01878168,-0.024046626,-0.005359866,0.04070208,-0.0017228142,-0.021629307,-0.009574354,0.013504079,-0.013655952,0.014630473,0.023350539,-0.03191873,-0.02122431,-0.025995668,0.023363195,-0.008226478,0.024021314,-0.0036386342,0.022616485,-0.012061281,0.003518401,-0.0075367186,0.01066278,-0.026096918,-0.011789175,0.003099167,-0.01904746,0.008701081,-0.023793504,-0.01369392,-0.04751107,0.018376684,0.006720399,-0.028881263,0.036399,-0.008289758,-0.02074338,-0.012972522,-0.0011358866,0.012086594,-5.983971E-4,0.035639632,0.011213321,0.0023018317,-0.033310905,0.028223146,1.12421934E-4,-0.021300249,0.020566193,-0.0046701077,0.013200332,-0.0034171522,0.0041164025,-0.0041860114,-0.026020981,-0.011447459,0.019072771,0.0059262277,0.0093592,0.0072203157,-0.012497918,-0.0017370523,0.016630141,-0.021793837,-0.014820315,-0.015731556,-0.01838934,-0.020996502,0.011131057,-0.018591838,0.01741482,0.008593504,-0.013643296,-0.018439965,0.0039866776,-0.013985012,0.0148835955,0.0042271437,0.023983344,-0.009852788,0.0017497084,-2.8550425E-5,0.009707243,-0.00127194,0.015364529,-0.03212123,0.025995668,-0.004053122,-0.028425643,-0.0024726891,-0.022818983,0.020692755,0.007245628,-0.010770357,0.010960199,-0.01379517,-0.006593838,0.01656686,6.703788E-4,-0.025527392,0.0054421313,-0.026476601,-0.02283164,-0.016541548,-0.018224811,0.008745378,-0.022540547,-0.0073721893,-0.028881263,0.0021689425,0.03201998,-0.007916402,-0.02703347,0.017465444,0.023856783,-0.013086427,0.027792837,0.01962964,0.010245129,-6.4506655E-4,0.029919066,-0.0152379675,-0.027008157,-0.0012893421,-0.02860283,-0.018996835,-0.033310905,0.008612489,0.018034969,-0.013238301,0.026957532,0.025248958,-0.0023160698,-0.014339383,-0.010896918,-0.017452788,0.03629775,-0.018984178,0.004382181,-0.0023065777,-2.986053E-4,0.0035753537,-0.004246128,0.019427143,0.0145292245,-0.023553038,-0.02908376,-0.0031339715,0.02093322,5.8613654E-4,0.0032716068,-0.001390591,-0.0090934215,-1.532577E-5,0.033513404,-0.007524063,0.015997333,-0.014288758,0.0119790165,0.010839966,-0.012238467,0.016731389,-0.017262947,-0.0033475435,-0.014668441,-0.013554703,0.0023192337,0.0028318067,0.012548542,0.014111573,0.0026166525,-0.033564027,-6.794754E-4,-0.025375519,0.031184677,0.022578517,0.0043283924,0.0027875102,-0.016035303,-0.011846127,0.0057996665,0.030754369,-0.004363197,-0.0040214816,0.0026403829,-0.0062363027,0.010517235,0.0045150705,-0.041233636,-0.011333554,-0.008625145,0.007131723,-0.0048124893,-0.010586844,-0.0062457947,-0.0040721064,-0.0062268106,0.0065621976,-0.014073604,0.0030580347,0.017098418,0.0021721064,-0.026577849,-0.01079567,-5.137593E-4,0.012206826,-2.1337425E-4,-0.008593504,0.015604994,-0.01731357,-0.009612322,-0.036601495,-0.009605994,-0.0017307242,-0.03746211,0.018034969,0.043385174,8.2660274E-4,0.0072203157,-0.017883096,0.0015677768,0.003613322,-0.0015131972,-0.01493422,-1.396128E-4,0.026451288,-0.010257784,-0.014010323,-0.008226478,0.0043062447,-0.019022146,0.0075177345,-0.02370491,-0.011694253,-0.028476268,0.0018351373,0.015301248,-0.021528058,0.007669608,-0.011517068,-0.031007491,-0.0013154454,-0.0124219805,0.0054737716,-0.017111072,-0.007865778,0.021123063,-0.01431407,0.0068786005,7.0449096E-5,0.021338217,0.0024505411,0.02569192,0.22558266,-0.010200832,-0.022705078,0.017908407,0.014149541,0.01258651,0.022363363,-0.01973089,0.0039550373,0.023097416,0.022363363,-0.022844294,0.00984646,0.0023192337,-0.010219816,0.0048156534,-0.03837335,-0.0040942547,-0.024704745,-0.020604162,0.0067773517,-0.0033443794,0.009188342,-0.0067710234,0.03979084,-0.005078268,-0.016718732,0.0045308904,0.03450058,-0.005008659,-0.009295919,0.009530057,-3.3242087E-4,0.008327726,-0.024983179,-0.005954704,-0.004135387,-0.017187009,5.4579513E-4,0.03531057,-0.012384012,0.020338383,-0.0062426305,0.014946876,0.007783513,0.02024979,-0.002993172,-0.005970524,0.01056786,0.015896086,-0.013934387,-0.0016152372,0.012194171,0.026451288,-0.0042081596,0.024603495,-0.0023049957,0.0098021645,-1.5305994E-4,-0.01043497,1.1014778E-4,0.0157189,-0.009662947,0.034449957,-0.010972855,0.004382181,-0.033969022,0.011169025,0.0011501248,-0.015073437,0.009346544,-0.01043497,-0.017300915,-0.009479433,-0.0024964195,-0.016604828,0.032171853,0.019870106,0.009485761,0.026552537,-0.014124229,-0.008182181,-0.006296419,0.016655453,-0.006897585,-0.03300716,0.018604495,0.0073089087,-0.013073771,-0.007599999,0.006492589,-0.016630141,-1.8203059E-4,-0.0070621143,0.024641464,0.02817252,0.014655786,0.01363064,-0.01685795,0.0049453783,-0.0046416316,0.055484425,0.023844128,0.024641464,-0.013757201,-0.009416153,-0.016377019,0.008289758,-2.467943E-4,0.011485428,-0.014681098,-0.0058945874,-0.0014214404,-0.01346611,-0.024438966,0.0032652786,0.015680932,-0.004777685,0.0046511237,-0.01731357,-0.009441465,-0.020237135,0.0019205661,0.0024457949,-0.022186177,-0.012016985,-0.013111739,9.58701E-4,0.0046036635,-0.052295085,0.020047292,-0.020756034,0.012365028,-0.006283763,-0.010618484,0.02426178,0.015124062,0.005233305,-0.023426477,0.0076189837,0.012890257,-0.020629473,-0.011453788,0.0040119896,0.0010409658,-0.013478766,-3.8047458E-4,-0.013149708,-0.0046258112,0.004084762,-0.028147208,-0.0035880096,-0.006574854,-0.0032273103,0.005669941,0.0018999998,-0.021705244,-0.04568859,-0.026375351,0.016440298,-0.045308907,-0.009428808,0.016604828,-0.018212155,-0.0143520385,0.012883929,-0.16139083,0.009384512,0.012099249,-0.02635004,0.017908407,0.0139976675,-0.0024679431,0.0011453788,-8.8118226E-4,0.022224145,0.015959365,0.00446761,-0.03323497,0.014212822,0.014655786,-0.0099603655,0.006827976,2.1179224E-4,0.0056351367,0.01128293,0.024578182,-0.026071604,0.0026451289,-0.0070937546,-0.0028254786,0.0123333875,-0.010194504,0.049687922,-0.009219983,0.0042366358,-0.017756535,-0.0074228137,0.026375351,0.025603328,0.004034138,0.017997,-0.012504245,-0.0125991665,0.0041037467,-0.0035310572,0.007948043,0.016971856,0.006103413,-0.0010836802,-0.0061350535,0.027666276,0.0059199,-0.0067520393,0.009612322,0.003606994,0.008878267,-0.0023651123,-0.0016199832,0.0022686094,0.028881263,0.016377019,0.012662447,0.006821648,-0.01969292,-0.024312405,-0.00805562,-0.02380616,-0.014668441,-0.0023587842,0.0074987505,-0.022122895,-0.011396835,-0.007024146,-0.014162197,-0.010226144,-0.004265112,-0.025464112,-0.0019791005,-0.017237633,-0.008220149,0.020300414,-0.013896419,0.035791505,-0.0020629475,0.012054954,4.7223145E-4,0.024413653,-0.008599833,-0.011485428,-0.0074607823,0.011909408,0.006479933,-0.0036639464,-0.013428142,-0.027311904,0.015465777,-0.023211323,-0.021350872,0.0036323061,-0.031159366,0.010384345,-0.01875637,0.016212488,-0.011662614,0.02057885,0.004113239,-0.0084796,-0.009207327,-0.007758201,0.032855283,-0.0043980014,-0.001170691,0.0062521226,0.021831805,2.8535593E-4,-0.0049327225,-9.373438E-4,-9.1915065E-4,0.006625478,0.006682431,0.020502912,0.020553537,0.006796336,0.012770024,0.009909741,0.07021615,-0.003404496,-0.011188009,0.009757868,-0.010972855,-0.017427476,-0.08965594,-0.02076869,0.011624645,0.013263613,0.011586677,0.0061856783,-0.0038094919,0.028223146,6.826394E-4,0.020224478,-7.957535E-4,-0.013782513,-0.0047428804,-0.011884096,0.023135385,-0.0132889245,-0.03293122,-0.0058218148,-0.016427642,0.023553038,-0.028096585,0.006381848,-0.0011113654,-0.016883263,-0.013238301,8.3609484E-4,-0.022945544,0.011460116,3.253018E-4,0.0084796,0.006258451,0.0011880932,0.0064546205,-0.0046194834,-0.023274602,-0.002978934,-0.033741213,-0.0010298917,0.022388674,-0.021806493,0.0024299747,0.010194504,0.0103147365,-0.026527226,-0.0044264775,-0.021021813,-0.024565527,-0.0033570356,0.01346611,-0.0033507075,-3.5318482E-4,-0.021730557,-0.017326226,-0.0067710234,0.014073604,-0.021566026,0.019806826,0.025286926,-0.019123396,-0.009612322,0.023628974,0.014390008,0.00340766,0.024059283,0.021123063,0.009257951,0.004581515,-0.013516735,0.009789508,-0.025033804,-0.025755202,0.018617151,-0.018515902,-7.652997E-4,-0.024831306,0.004926394,-0.017629974,-0.013617984,0.018528558,-0.0056034965,-0.023907408,-0.015453122,0.012928225,0.0050371354,0.0070621143,0.020920565,-0.004258784,0.015896086,-0.00658751,-0.0087200655,0.016997168,0.0517129,0.037816484,-0.028273769,-1.9666422E-4,0.0038885926,0.009954037,-0.012447293,0.020692755,-0.010080598,0.0041891756,-0.0064451285,-0.049384177,0.025084428,0.02002198,-0.014200166,0.016731389,-0.0018525394,-0.010061614,-0.009580682,0.005321898,0.024514902,-0.011263946,-3.779038E-4,0.0063185673,-0.0082960855,-0.031235302,-0.0072393,0.029539382,-0.0034994169,0.006517901,0.0011343047,-0.014111573,0.002110408,0.0169592,0.02283164,-0.012858617,-0.009998334,-0.00942248,0.02612223,-0.024957867,-0.022287425,0.0051542046,-0.021895086,-0.0062078265,0.03404496,-0.023211323,-0.024704745,0.004508742,0.011396835,0.019933388,0.025945043,-0.00684696,-0.015339216,0.017883096,-0.01754138,-0.015706243,-0.007998667,-0.012833305,0.01216253,3.8413298E-5,0.009232638,0.024274437,0.020616818,-2.1080348E-4,-0.01402298,-0.023135385,-0.023692254,-0.0056446292,0.015136718,-0.006486261,-0.009087093,0.01656686,0.004265112,-0.0010267276,-0.0035532054,0.019490423,0.012921898,-0.018452622,-1.5563071E-4,0.003936053,-0.032981846,-1.6532055E-4,-0.010200832,0.015883429,0.010118567,0.015035469,0.006150874,-0.0030596168,0.0070051616,-0.023198666,0.004394837,-9.6265605E-4,0.027691588,-0.024198499,0.010681764,0.039411154,0.0063786837,-0.028577516,0.004454954,0.004989675,0.006935553,-0.004869442,-0.0023888424,0.00766328,0.0069861775,0.012504245,0.025615985,-0.008637801,-8.0801407E-4,0.0084796,4.8449205E-4,0.009504746,-0.009903413,-0.00573955,-0.02481865,-0.0071507073,0.0112892585,-0.02318601,-0.030551871,-0.009770524,0.003534221,0.016098583,0.016389674,-0.011333554,0.013769858,-0.013985012,0.0021056617,-0.013871106,-0.003948709,-0.005410491,0.011352539,0.0056825974,0.02748909,0.013478766,-0.011713238,0.015921397,-0.0030089922,0.0033538714,-0.024970522,-0.0122637795,-5.4975017E-4,0.00916303,0.0033190672,-0.038601164,-0.009916069,0.02436303,-0.0085618645,-0.0035532054,0.008833971,6.4506655E-4,0.024438966,-0.0062552867,-0.0104919225,0.014263446,0.008428975,0.013061115,-0.010415986,0.02211024,-0.009922397,0.0012505827,0.00994771,-0.016554203,-0.0045467108,-0.01952839,-0.017060447,0.018503245,-0.012573854,0.022312738,0.014769691,0.0012308075,1.3526226E-4,-5.101998E-4,0.02862814,-4.0222728E-4,-0.029817816,-0.007524063,0.02726128,0.001909492,-0.006394504,-0.04196769,-0.0037557033,-0.014301415,-0.024223812,-0.003714571,0.028982513,-0.023540381,0.0015788508,-0.028273769,0.001808243,0.022135552,-0.028147208,0.011991672,-0.023008823,-0.026755035,0.0089985,0.018186843,0.0011089924,-0.0062109903,-0.011687926]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/documents.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/documents.json
new file mode 100644
index 00000000000..c0ecf58c445
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/documents.json
@@ -0,0 +1,4633 @@
+[
+ {
+ "embedding": [
+ -0.0019326741,
+ -0.0018253033,
+ -0.0053208186,
+ -0.024023786,
+ -0.009659962,
+ 0.02425557,
+ -0.01405705,
+ -0.0061320644,
+ -0.01396161,
+ -0.024760043,
+ 0.013927524,
+ 0.008630565,
+ -0.019892568,
+ 0.0030370592,
+ -0.0069092247,
+ -0.0040630465,
+ 0.02571445,
+ -0.02163777,
+ 0.01141198,
+ -0.01080525,
+ 0.008501039,
+ 0.016456703,
+ -0.02780051,
+ -0.015215973,
+ -0.025878062,
+ 0.017901948,
+ 0.017520184,
+ -0.043057386,
+ -0.014752405,
+ -0.014970555,
+ 0.042048443,
+ -1.6339959E-4,
+ -0.025100902,
+ 0.006564956,
+ 0.022196779,
+ 0.00587642,
+ 0.009919015,
+ 0.00730803,
+ 0.027446017,
+ -0.01211415,
+ 0.012318667,
+ 0.011139292,
+ -0.0071376003,
+ -0.031386353,
+ -0.0376309,
+ 0.0024405548,
+ -0.006585408,
+ 0.0047243144,
+ 0.020069815,
+ 0.022946669,
+ -0.003943746,
+ 0.028032295,
+ -0.038012665,
+ 0.024910022,
+ -0.0059820865,
+ -0.012161871,
+ -0.027159695,
+ 0.00687173,
+ 0.0137025565,
+ -0.01306174,
+ 0.0039062514,
+ 0.005757119,
+ -0.03261345,
+ 0.0010592212,
+ 0.002493388,
+ 0.0016991852,
+ 0.007205772,
+ 0.01651124,
+ 0.0017929216,
+ -0.01012353,
+ 0.028904896,
+ 0.02229222,
+ 0.0075534494,
+ -0.01007581,
+ 0.018774549,
+ 0.004025552,
+ -0.010498476,
+ 0.0029024198,
+ -0.011091572,
+ 0.015570467,
+ -0.0035381229,
+ -0.00920321,
+ -0.009666779,
+ 0.017711066,
+ 0.005958226,
+ 0.0040971325,
+ -0.012161871,
+ -0.0022104746,
+ 0.020969683,
+ -0.007512546,
+ -0.018351883,
+ 0.011671034,
+ 0.028959433,
+ 0.019333558,
+ -0.02617802,
+ 0.013484406,
+ 2.0014851E-4,
+ 0.022892132,
+ -0.020846974,
+ -0.04188483,
+ -0.019347193,
+ 0.001011501,
+ -0.032504372,
+ -0.0067217518,
+ -0.024201034,
+ -0.005825291,
+ 0.030622829,
+ 0.017029347,
+ -0.0020383405,
+ 0.024732774,
+ -0.017520184,
+ 0.03255891,
+ 0.0034256391,
+ -0.042048443,
+ -0.004414132,
+ -0.010866605,
+ 0.018788183,
+ -0.036840107,
+ -0.0120937,
+ 0.0014784785,
+ 0.013988879,
+ 0.029995646,
+ 0.011602862,
+ -0.013477589,
+ 0.0016369784,
+ -8.340409E-5,
+ -0.02925939,
+ -0.0075670835,
+ -0.022033166,
+ -0.023901077,
+ 0.029832033,
+ -0.013845718,
+ 0.011125658,
+ 0.0062956773,
+ -0.038176276,
+ 0.0032160105,
+ -0.018174635,
+ 0.0062854514,
+ -0.014179761,
+ -0.0100553585,
+ 0.007505729,
+ 0.0281141,
+ 7.5841264E-4,
+ -0.02568718,
+ 6.506158E-4,
+ 0.022455832,
+ -4.050371E-5,
+ -0.028386788,
+ 0.038012665,
+ 0.018038291,
+ -0.0105052935,
+ -0.018788183,
+ -0.016402164,
+ 0.007894309,
+ 0.017711066,
+ 0.010757529,
+ 0.0024831623,
+ 0.006186602,
+ -0.01865184,
+ 0.025782622,
+ 0.028632209,
+ 0.018529128,
+ -0.0030745538,
+ -0.01240729,
+ 0.003630155,
+ 0.022742154,
+ 0.018488226,
+ -0.02901397,
+ -0.006121839,
+ -0.033322435,
+ -0.006196828,
+ 0.01672939,
+ -0.019129042,
+ 0.011991441,
+ -0.0043221,
+ 0.0023110283,
+ 0.0038176277,
+ -0.0013711079,
+ -0.0045300242,
+ -0.016129477,
+ 0.027459651,
+ -0.0026058718,
+ 0.008794178,
+ 0.01483421,
+ -0.013518493,
+ 0.013279891,
+ -0.009980369,
+ 0.0058457423,
+ 4.5675188E-4,
+ -0.009428177,
+ 0.020424308,
+ 0.015965864,
+ 0.016129477,
+ -0.0031376127,
+ -0.6108204,
+ -0.02605531,
+ 0.017097518,
+ -0.05025634,
+ 0.006067301,
+ -0.008466953,
+ 0.0065819994,
+ 0.005361722,
+ 0.0065479134,
+ 0.027555091,
+ -0.02515544,
+ 0.015625006,
+ -8.4362755E-4,
+ -0.0069092247,
+ -0.024432817,
+ -0.022251315,
+ 0.014493351,
+ -0.030486485,
+ 0.008337426,
+ 0.01872001,
+ -0.020260695,
+ 0.023901077,
+ -0.014316104,
+ -0.024310108,
+ -0.01308901,
+ -0.014029782,
+ 0.012932214,
+ 0.0216105,
+ -0.004574336,
+ 0.017956484,
+ -0.04455717,
+ 0.03923976,
+ 0.02615075,
+ -0.015679542,
+ 0.037167333,
+ -0.0022479692,
+ -0.023410238,
+ 0.03564028,
+ 0.009244113,
+ 0.04035778,
+ -0.012754967,
+ -0.002321254,
+ 0.016211284,
+ -0.03013199,
+ -0.0011350625,
+ 0.021133296,
+ 0.034822218,
+ 0.01012353,
+ -0.023464777,
+ -0.0052015176,
+ 0.019169945,
+ 0.003916477,
+ -1.1685094E-4,
+ -0.009005511,
+ 0.0035313056,
+ -0.0026229147,
+ 0.025918966,
+ 0.00628886,
+ -0.012475462,
+ 0.013498041,
+ 0.0036846926,
+ -7.477608E-4,
+ -0.020069815,
+ -0.03149543,
+ -0.029368466,
+ 0.016415799,
+ 0.023083014,
+ -0.01865184,
+ 0.013941159,
+ -0.042266592,
+ 0.0033455372,
+ 0.010621185,
+ 0.011657399,
+ -0.020996952,
+ 0.026477976,
+ 0.035176713,
+ 0.033567857,
+ 0.018992698,
+ -0.028359521,
+ 0.02107876,
+ 0.006568365,
+ -0.009394092,
+ -0.009407725,
+ -0.029586615,
+ 0.024923656,
+ 0.0018423463,
+ -0.007757965,
+ -0.017601991,
+ 0.016456703,
+ -0.020656092,
+ 0.030677365,
+ 0.021010587,
+ -0.010266691,
+ -0.039348833,
+ 0.0023655659,
+ 0.015065995,
+ 0.0016548735,
+ -0.0020076632,
+ 0.020574287,
+ -0.04562065,
+ -0.008514673,
+ -0.012039162,
+ 0.019292654,
+ 0.01629309,
+ 0.02360112,
+ 0.004898153,
+ -0.020465212,
+ 0.008773726,
+ 0.01840642,
+ -0.013675288,
+ -0.0052049262,
+ 0.00912822,
+ -0.022537638,
+ 0.00881463,
+ 0.007417105,
+ -0.020233426,
+ 0.005020862,
+ -0.012782236,
+ 0.036267463,
+ -0.018679107,
+ 0.013218536,
+ 0.008487404,
+ -2.6714872E-4,
+ -0.0057196245,
+ 0.014588792,
+ 0.037876323,
+ 0.0023059153,
+ -0.0011742614,
+ -0.011861915,
+ -0.011739206,
+ 7.4222183E-4,
+ -0.02306938,
+ 0.013804815,
+ -0.016538508,
+ 0.023246625,
+ -0.002784823,
+ 0.013082192,
+ 0.014152491,
+ 0.0022224048,
+ 0.00293821,
+ -0.022224048,
+ -0.022346757,
+ -0.010034908,
+ -0.0025240656,
+ -0.030541021,
+ -0.027405113,
+ -0.034222305,
+ 0.005334453,
+ 0.02129691,
+ 0.0037324128,
+ -0.013450321,
+ 0.014002513,
+ -0.001869615,
+ 0.0020383405,
+ 7.187877E-4,
+ -0.0071239662,
+ -0.04169395,
+ -0.020206159,
+ -0.03149543,
+ -0.03277706,
+ 0.0054571624,
+ 0.027350577,
+ -0.011309722,
+ -0.002989339,
+ -0.019428998,
+ -0.00490497,
+ -0.0022241091,
+ 0.029313928,
+ -0.005917323,
+ -0.02904124,
+ 0.033404242,
+ -0.016770294,
+ -0.0065717734,
+ 0.0148887485,
+ -0.0017417927,
+ 0.020956049,
+ -0.032177147,
+ 0.004652734,
+ 0.004134627,
+ -0.010709809,
+ -0.027691435,
+ 0.01651124,
+ -0.017779239,
+ -0.004069864,
+ 0.04431175,
+ -0.0059889033,
+ 0.04946555,
+ 0.007948847,
+ -0.004986776,
+ 0.0046152393,
+ -0.024650969,
+ 0.033104286,
+ -0.019306289,
+ 0.027432382,
+ -0.033949617,
+ 0.005958226,
+ -0.0068580955,
+ 0.0043425513,
+ -0.0032552094,
+ 0.028414058,
+ 0.021883188,
+ 0.03569482,
+ 0.00216105,
+ 0.021569597,
+ 0.003355763,
+ -0.011166561,
+ -0.0032126019,
+ -0.011882367,
+ 0.008637383,
+ 0.01573408,
+ 0.020424308,
+ 0.0015568763,
+ -0.0020451578,
+ -0.0073557505,
+ -0.003858531,
+ -0.023451142,
+ -7.809946E-4,
+ 0.0028035704,
+ -0.041912097,
+ 0.009980369,
+ 0.006551322,
+ 0.03364966,
+ -0.014916017,
+ -0.018488226,
+ 0.013559395,
+ 0.0054230765,
+ 0.009973552,
+ 0.031768117,
+ 0.01053938,
+ -0.027459651,
+ 0.008821447,
+ 0.016361263,
+ 0.017915582,
+ -0.007471643,
+ 0.012918579,
+ -0.009291833,
+ 0.035994776,
+ -0.007096697,
+ 0.013886621,
+ -0.019483536,
+ -0.003504037,
+ -3.65998E-4,
+ 0.015284145,
+ -0.0053242273,
+ 0.042239323,
+ 0.0054776142,
+ 0.031549968,
+ 0.0063365805,
+ -0.0059548174,
+ 0.028059565,
+ -0.03591297,
+ -0.01585679,
+ -7.443522E-4,
+ -0.002178093,
+ 0.014466083,
+ -0.022783058,
+ -0.023342067,
+ -0.0010796728,
+ 0.019674417,
+ 0.033949617,
+ 0.006510419,
+ -0.008971425,
+ 0.01762926,
+ 0.025741719,
+ 0.0034443864,
+ -0.0018798409,
+ 0.004870884,
+ -0.006380892,
+ -0.0017179325,
+ -0.04812938,
+ -0.0037937677,
+ 0.013729826,
+ 0.0015602849,
+ -0.04076681,
+ 0.026137115,
+ 0.01301402,
+ 0.006210462,
+ 0.016279455,
+ 0.012666344,
+ 0.040685005,
+ -0.020860609,
+ -0.028386788,
+ 0.0018270075,
+ 0.0023076197,
+ 0.00842605,
+ -0.003166586,
+ -0.008194265,
+ 0.004400498,
+ -0.031168204,
+ -0.015215973,
+ 0.0011947129,
+ 0.01313673,
+ -0.015843155,
+ 0.019088138,
+ -0.027950488,
+ -0.0015321639,
+ 0.01663395,
+ -0.020778803,
+ 0.0083033405,
+ -0.021187834,
+ 0.033567857,
+ 0.014766038,
+ -0.004288014,
+ -0.016620316,
+ 0.030650098,
+ -0.011125658,
+ -0.01937446,
+ -0.00607071,
+ 0.0060059465,
+ -0.019510804,
+ -7.746035E-4,
+ -0.007451191,
+ -8.896436E-4,
+ -0.0012091995,
+ 0.04120311,
+ 0.005637818,
+ 0.024419183,
+ -0.01235957,
+ 0.013150364,
+ 0.022878498,
+ -0.009884929,
+ -0.020083448,
+ 0.0052969586,
+ 0.012939031,
+ 0.016933907,
+ 0.0070694285,
+ -0.0077647823,
+ 0.016933907,
+ -0.027827779,
+ 0.022592176,
+ -0.010559831,
+ 7.345525E-4,
+ 0.010464391,
+ -0.007873857,
+ -0.036212925,
+ 6.395379E-4,
+ 0.011984624,
+ -0.015229608,
+ 0.019892568,
+ 0.015256877,
+ 0.01563864,
+ 0.0024712323,
+ -0.0030251292,
+ -0.015270511,
+ 0.027759608,
+ 0.002955253,
+ 0.01906087,
+ 0.027309673,
+ 0.021446887,
+ -0.0034154134,
+ 0.022537638,
+ 0.012277763,
+ -0.008337426,
+ -0.038857996,
+ 0.012080065,
+ 0.0013293525,
+ 0.012086882,
+ 0.00275585,
+ -0.0037767247,
+ 0.035122175,
+ 0.0066229026,
+ 0.03613112,
+ -0.0076079867,
+ -0.008787361,
+ 0.0065717734,
+ 0.016224917,
+ -0.0035619831,
+ -6.8555394E-4,
+ 0.010839336,
+ -0.028195908,
+ -0.006728569,
+ 0.0026143934,
+ -0.010191702,
+ -0.035858434,
+ 0.0027200598,
+ 0.033840545,
+ -0.017997388,
+ 0.0025274742,
+ 0.004380046,
+ 0.041584875,
+ -0.0017469055,
+ 0.0018133732,
+ -0.0046697767,
+ -0.031768117,
+ -0.023096647,
+ -0.033758737,
+ -0.013293525,
+ -0.002658705,
+ -0.0010345089,
+ -0.015215973,
+ -0.0026160977,
+ 0.010362132,
+ 0.005579872,
+ 0.011384712,
+ -0.003139317,
+ -0.028250445,
+ -0.03613112,
+ -0.005528743,
+ 0.0035347142,
+ 0.022333123,
+ 0.016606681,
+ -0.017274765,
+ -0.021337813,
+ 0.010941594,
+ 0.015502295,
+ -0.016088573,
+ 0.0035517572,
+ -0.020028912,
+ -0.0060809357,
+ -0.010784798,
+ 0.0016540213,
+ -0.008957791,
+ 8.828264E-4,
+ 0.02792322,
+ -0.021569597,
+ -9.1094733E-4,
+ 0.0142479325,
+ 0.0014077502,
+ -0.010443939,
+ 0.014479716,
+ 0.012632257,
+ 0.020560652,
+ 0.0040494124,
+ -0.008616931,
+ -0.0027609628,
+ -0.02758236,
+ -7.354046E-4,
+ -0.020846974,
+ 0.01872001,
+ -0.034658607,
+ 0.02083334,
+ 0.0110029485,
+ -0.02039704,
+ -0.0036778753,
+ 0.011766474,
+ 0.019483536,
+ 0.014152491,
+ 1.9642035E-4,
+ 0.0034972196,
+ -0.009823575,
+ 0.018120097,
+ 0.02605531,
+ -5.666791E-4,
+ -0.0020383405,
+ 0.00808519,
+ -0.020410674,
+ 0.020792438,
+ 0.03948518,
+ -0.019088138,
+ 0.021774113,
+ 0.013845718,
+ 0.004475487,
+ -0.03744002,
+ 0.0043766377,
+ -0.004727723,
+ 5.4111466E-4,
+ -0.009959918,
+ -0.01551593,
+ 0.0037085526,
+ -0.013116278,
+ -0.021855919,
+ 0.001789513,
+ -0.003841488,
+ -0.01872001,
+ -0.013484406,
+ 0.018897258,
+ -0.019892568,
+ -0.0067047086,
+ 0.0060229893,
+ -0.031304546,
+ 5.0676237E-5,
+ 0.04248474,
+ -0.022796692,
+ 0.024787312,
+ -0.023342067,
+ 0.030677365,
+ 0.0085623935,
+ -0.014629695,
+ 0.0048231636,
+ -0.0069024074,
+ 0.007505729,
+ 0.008685103,
+ 0.041094035,
+ 0.017042981,
+ 0.026873372,
+ 0.0035688002,
+ 0.037003722,
+ -7.8909E-4,
+ -3.9332004E-5,
+ -0.023901077,
+ -0.017601991,
+ 0.0015014866,
+ 0.0038926168,
+ 0.0030677365,
+ 9.6889347E-4,
+ 0.021951359,
+ 0.021528693,
+ -0.008337426,
+ 0.02216951,
+ 0.003173403,
+ -0.02216951,
+ -0.026218923,
+ -0.0020570878,
+ -0.02857767,
+ -0.01461606,
+ 0.025578106,
+ 0.0069773966,
+ 0.019947104,
+ -0.027418748,
+ 0.013409417,
+ 0.024732774,
+ 0.0067796977,
+ 0.027214233,
+ -0.0114528835,
+ 0.038639847,
+ -0.020492481,
+ -7.877053E-5,
+ 0.04033051,
+ 0.0148887485,
+ -0.011725571,
+ 0.01927902,
+ -0.04120311,
+ 0.0074580084,
+ 0.03056829,
+ 0.0028308393,
+ 0.015665907,
+ 0.01085297,
+ -0.010812067,
+ 0.012270946,
+ 0.010566648,
+ -0.01408432,
+ -0.0020212976,
+ -0.0059070974,
+ -0.01274815,
+ 0.00217298,
+ -0.017370205,
+ -0.00747846,
+ -0.028359521,
+ 0.031958997,
+ -0.002835952,
+ 0.0038005847,
+ 0.0066740313,
+ 0.0020144803,
+ -0.026137115,
+ 0.034849487,
+ -0.010355315,
+ 0.055900976,
+ 0.015338683,
+ 0.048047572,
+ 0.026846103,
+ 0.008487404,
+ -0.01840642,
+ 0.010689357,
+ -0.003858531,
+ -0.0022973937,
+ 0.030431947,
+ 0.010737078,
+ -0.029177584,
+ 0.0053549046,
+ 0.026900642,
+ 0.009884929,
+ -0.032013535,
+ -0.005157206,
+ 0.029450271,
+ 0.02947754,
+ 0.0015517634,
+ -0.029641153,
+ -0.03187719,
+ -0.0029109411,
+ 0.014234298,
+ -0.009319102,
+ -0.011493786,
+ -0.0055321516,
+ -0.006980805,
+ -0.0018525721,
+ 0.0051878835,
+ 0.014902382,
+ 0.034167767,
+ 0.015652273,
+ 0.013232171,
+ 0.009489532,
+ -0.006510419,
+ 0.012182323,
+ 0.003127387,
+ 0.011541507,
+ 0.034467723,
+ -0.012298215,
+ 0.021037856,
+ 0.0053003673,
+ -0.00451639,
+ 0.004247111,
+ -0.010784798,
+ 0.004455035,
+ 0.040221434,
+ -0.036621958,
+ 0.018174635,
+ -0.013866169,
+ -0.012475462,
+ 0.011391529,
+ -0.011030218,
+ 0.009257747,
+ -0.015625006,
+ -0.011936904,
+ 0.0040051006,
+ 0.016374895,
+ 0.02692791,
+ -0.01158241,
+ -0.006057075,
+ -0.004922013,
+ -0.012291398,
+ 0.009121403,
+ -0.012230043,
+ -0.0034716553,
+ -0.01408432,
+ -0.0017946259,
+ 0.021228736,
+ -0.030541021,
+ -0.0045607015,
+ 0.022101337,
+ 0.0062275054,
+ -0.018542763,
+ 0.0146978665,
+ -0.010096262,
+ -0.0038142193,
+ -0.013648019,
+ -0.016443068,
+ -0.014847845,
+ 0.02328753,
+ -0.016920272,
+ -0.0074443743,
+ 0.023832904,
+ -0.0075329975,
+ 0.0045300242,
+ -0.028877627,
+ 0.011650582,
+ 0.004533433,
+ -0.012809505,
+ 0.012870859,
+ 0.023778368,
+ -0.024419183,
+ -0.022864863,
+ 0.0072671273,
+ -0.017315669,
+ 0.023123916,
+ -0.02658705,
+ -0.019947104,
+ 0.02372383,
+ -0.01925175,
+ 0.02360112,
+ -0.017397474,
+ 0.030077454,
+ -0.0065274616,
+ -0.037030987,
+ -0.040166896,
+ -0.022155875,
+ 0.024173765,
+ 0.013368514,
+ -0.007894309,
+ -0.010062176,
+ -0.015325049,
+ -0.038258083,
+ -0.0019752814,
+ -0.018529128,
+ -0.0075739007,
+ 0.0072671273,
+ 0.0043357345,
+ 0.017915582,
+ 0.004693637,
+ 0.0011512534,
+ -0.017315669,
+ -0.024405548,
+ 7.0472725E-4,
+ -0.04673867,
+ -0.007928395,
+ -0.012250495,
+ 0.027473286,
+ 0.008896437,
+ -0.024078324,
+ -0.02326026,
+ -0.021555962,
+ -0.039103415,
+ -0.002824022,
+ 0.0101030795,
+ 0.004243702,
+ 0.023764733,
+ 0.024460087,
+ 0.008923705,
+ 0.023764733,
+ -0.006339989,
+ 0.018542763,
+ -0.031168204,
+ 0.010484842,
+ -0.034658607,
+ -0.011391529,
+ -0.002253082,
+ -0.011786926,
+ -0.04832026,
+ 0.012823139,
+ -0.012911762,
+ -0.003493811,
+ -0.026368901,
+ 0.031740848,
+ -0.016893003,
+ -0.01483421,
+ 0.004697046,
+ -0.0134026,
+ -0.013375332,
+ 0.0013745164,
+ 0.020751534,
+ -0.02471914,
+ -0.010621185,
+ 0.011091572,
+ -0.0220468,
+ 0.010273509,
+ -0.012230043,
+ -0.008269254,
+ -0.011296088,
+ 0.0211742,
+ -0.027555091,
+ -0.027814144,
+ -0.0049595074,
+ -0.011541507,
+ 0.03926703,
+ 0.002299098,
+ 0.015188704,
+ 0.022892132,
+ 9.842322E-4,
+ -0.0048129377,
+ -0.02005618,
+ -0.004700454,
+ -0.0146978665,
+ -0.010484842,
+ 0.032204416,
+ -0.032204416,
+ -0.010164434,
+ -0.014656964,
+ 0.026355267,
+ -0.025700815,
+ -0.010491659,
+ 0.0046356907,
+ -0.001417976,
+ -0.03144089,
+ 0.013143547,
+ 0.0023195497,
+ -0.023778368,
+ -0.013286708,
+ -0.017315669,
+ 0.017015712,
+ -0.0031870375,
+ -0.026355267,
+ -0.024337377,
+ -0.025264515,
+ 0.0037290042,
+ 0.009516801,
+ -0.022673981,
+ -0.015120532,
+ 0.0043084654,
+ 0.03656742,
+ -0.0061491076,
+ 0.016088573,
+ 0.21258733,
+ -0.0049935933,
+ -0.0011256889,
+ 0.010062176,
+ 0.002190023,
+ 0.0031120484,
+ 0.03435865,
+ -0.0010847858,
+ -0.01918358,
+ 0.027691435,
+ -0.012679978,
+ 0.0073966538,
+ -0.015802251,
+ 0.0119028175,
+ 0.017833775,
+ -0.011664216,
+ -3.099692E-4,
+ -0.022933036,
+ -0.011834646,
+ -0.011391529,
+ -0.005944592,
+ 0.011970989,
+ -0.010962046,
+ -0.0021917273,
+ 0.01762926,
+ 0.0012816322,
+ -0.0052901413,
+ -0.0011742614,
+ 0.011330173,
+ 0.017533818,
+ -0.013811632,
+ 0.03364966,
+ -0.00604685,
+ 0.028086832,
+ -0.018665472,
+ -0.013975244,
+ 0.011255185,
+ 0.007192138,
+ 0.014316104,
+ 9.296946E-4,
+ -6.651023E-4,
+ -0.00195483,
+ -0.0068751387,
+ -0.02105149,
+ 0.0020485662,
+ 0.018638205,
+ -0.021896822,
+ -0.013259439,
+ 0.010109897,
+ 0.010171251,
+ -0.0124481935,
+ -0.003807402,
+ 0.019428998,
+ 0.012127785,
+ 0.006796741,
+ 0.020015277,
+ -0.0019803944,
+ 0.0017034459,
+ 0.021337813,
+ 0.016347628,
+ -0.00568213,
+ 0.017929217,
+ -0.00881463,
+ -0.0055491948,
+ -0.0017656528,
+ -0.008651017,
+ -0.02612348,
+ 0.016524874,
+ 0.01032123,
+ -0.0017707658,
+ 0.0032006719,
+ -0.029204853,
+ 0.010621185,
+ -0.0059854947,
+ -0.011371077,
+ -0.03615839,
+ 0.038421698,
+ 0.009496349,
+ 4.2330503E-4,
+ 0.022019532,
+ -0.024773678,
+ -0.020465212,
+ -0.009994004,
+ -0.019551707,
+ -6.6126767E-4,
+ -0.021883188,
+ 0.012686795,
+ -0.012734516,
+ -0.021187834,
+ -0.0241874,
+ 5.5730547E-4,
+ -0.01119383,
+ 0.020342503,
+ 0.002663818,
+ 0.017683797,
+ 0.013736643,
+ 0.020328868,
+ 0.0115960445,
+ 0.008916887,
+ -0.0022309262,
+ -0.023301164,
+ 0.04676594,
+ 0.02372383,
+ 0.008950974,
+ -0.013634385,
+ 0.011814195,
+ -0.009959918,
+ -0.0011981216,
+ 0.0048265723,
+ 0.014207029,
+ -7.209181E-4,
+ -0.03564028,
+ 0.011446066,
+ -0.01576135,
+ -0.0151478015,
+ -0.011296088,
+ -0.0025717858,
+ -0.013947976,
+ 0.013211719,
+ 0.0034886983,
+ -0.023682926,
+ -0.0027592587,
+ -0.012011893,
+ 0.034876756,
+ -0.020492481,
+ -0.04548431,
+ -0.041939367,
+ 0.0021815016,
+ -0.016783928,
+ -0.0016446477,
+ 0.009516801,
+ -0.023055745,
+ 0.0038551223,
+ 0.020792438,
+ 0.00107456,
+ -0.0073966538,
+ 0.008732824,
+ 0.0060502584,
+ 0.002967183,
+ 0.023887442,
+ -0.01782014,
+ 8.108198E-4,
+ 0.01595223,
+ -0.032967944,
+ 0.007560266,
+ -0.03640381,
+ -0.0069467193,
+ 0.0057639363,
+ -0.039076146,
+ -0.025073634,
+ 0.0045470675,
+ 0.014452448,
+ -0.016429434,
+ -0.006803558,
+ 0.037003722,
+ 0.006963762,
+ -0.025305418,
+ -0.026014406,
+ 0.010709809,
+ 0.028059565,
+ -0.065335974,
+ -1.9162701E-4,
+ -0.0045913793,
+ 0.00456411,
+ -0.037385482,
+ -0.027132425,
+ -0.17266585,
+ -0.015993133,
+ 0.004168713,
+ -0.036840107,
+ 0.028359521,
+ 0.023246625,
+ 0.0012057909,
+ -0.014547888,
+ 0.009871295,
+ -0.009380457,
+ 0.018556397,
+ 0.0032466878,
+ 0.0010617777,
+ -0.023492046,
+ 0.008262437,
+ 0.006854687,
+ -0.02991384,
+ 0.0102462405,
+ 0.030186528,
+ 0.010000821,
+ -0.0013685514,
+ -0.036212925,
+ 0.01141198,
+ 0.003681284,
+ 0.029341197,
+ 0.011234733,
+ 0.009714499,
+ 0.019592611,
+ -0.005470797,
+ -0.015215973,
+ 8.6024444E-4,
+ -0.011698302,
+ 0.044666246,
+ 0.016211284,
+ 0.037876323,
+ -0.0021849102,
+ 3.2679917E-4,
+ -0.0077647823,
+ -0.012393656,
+ 0.014016148,
+ 0.015175071,
+ 0.029832033,
+ 0.02860494,
+ -0.017779239,
+ -0.001498078,
+ 0.020846974,
+ 0.0137025565,
+ -0.019906202,
+ -0.0023536356,
+ -0.023710195,
+ 0.006568365,
+ -0.027132425,
+ 0.0049424646,
+ -0.021937726,
+ 0.026437072,
+ 0.007580718,
+ 0.006152516,
+ 0.010716626,
+ 0.0035688002,
+ -0.002772893,
+ 0.0048333895,
+ -0.010348498,
+ 0.013879804,
+ 0.0058048395,
+ 0.012727698,
+ -3.65998E-4,
+ -0.020587921,
+ 0.048183914,
+ -0.027446017,
+ 0.007614804,
+ 0.002481458,
+ 0.00869192,
+ 0.0013719599,
+ 0.015611371,
+ -0.0076420726,
+ 0.024023786,
+ -0.0033182683,
+ 0.033731468,
+ 0.011050669,
+ -0.0029927474,
+ -0.008651017,
+ 0.009837208,
+ -0.0070762457,
+ -0.011623313,
+ -0.010832518,
+ -0.0086578345,
+ 0.009291833,
+ 0.004860658,
+ 0.010362132,
+ -0.016743025,
+ -2.2901506E-4,
+ -0.029123046,
+ -0.0011444362,
+ -0.014602426,
+ -0.0100076385,
+ 0.025169075,
+ 0.02039704,
+ -0.01352531,
+ 0.0055082915,
+ -0.008098825,
+ 0.015447758,
+ 0.004305057,
+ 0.021883188,
+ 0.0014486534,
+ 0.0067660636,
+ 0.002887081,
+ -0.018760914,
+ 0.023887442,
+ 0.006619494,
+ -0.0056344094,
+ -0.020628825,
+ -0.013048106,
+ 0.0048742928,
+ 0.02814137,
+ -0.01806556,
+ 0.023178454,
+ 0.0031546557,
+ -0.018992698,
+ 0.001400933,
+ 0.0037051442,
+ 0.031222742,
+ 0.011677851,
+ 0.01682483,
+ 0.034249574,
+ -0.012911762,
+ -0.028304983,
+ -0.08938703,
+ -0.03730368,
+ 0.004069864,
+ 0.01274815,
+ -0.017179325,
+ 0.027855048,
+ -0.007873857,
+ 0.015665907,
+ -0.030513754,
+ 0.0013855944,
+ -0.018338248,
+ -0.022973938,
+ -0.0259326,
+ -0.027336942,
+ -0.006745612,
+ -0.006489967,
+ 0.0011827829,
+ -0.008105642,
+ -0.008964608,
+ -0.0033250856,
+ 0.008269254,
+ 6.088605E-4,
+ 0.015379586,
+ -0.016224917,
+ -0.0025700815,
+ 0.0037460472,
+ -0.028877627,
+ 0.012148237,
+ 0.011766474,
+ 0.005031088,
+ 0.008248803,
+ -0.004455035,
+ 0.0022939853,
+ -0.022333123,
+ 0.02126964,
+ -0.00985766,
+ -0.011166561,
+ -0.0101507995,
+ 0.0010481434,
+ -0.014984189,
+ -0.0032892954,
+ -0.0020843565,
+ 0.031931728,
+ -0.021665037,
+ -0.004185756,
+ -0.012468645,
+ 0.0025428128,
+ 0.039048877,
+ -0.014643329,
+ -0.024800945,
+ -0.035940237,
+ -0.011589227,
+ -0.018638205,
+ 0.010287143,
+ 0.022960303,
+ 0.021378715,
+ 0.028768552,
+ 0.013859352,
+ -0.004209616,
+ -0.024555527,
+ 0.009257747,
+ -0.008316975,
+ -0.005150389,
+ 6.787367E-4,
+ 0.002034932,
+ 0.0024115818,
+ -0.0036335636,
+ -0.004482304,
+ 9.970143E-4,
+ -0.0068240096,
+ -0.0066808485,
+ 0.0110234,
+ -0.014343373,
+ 0.0054980656,
+ -0.036240194,
+ -0.030431947,
+ -0.011446066,
+ -0.024091957,
+ 0.025359957,
+ -0.005791205,
+ -0.04251201,
+ -0.013109461,
+ -0.010887057,
+ -0.015420489,
+ 0.015202339,
+ 0.011446066,
+ -0.0037255955,
+ 0.0032211235,
+ -0.00509926,
+ -0.0254963,
+ -0.0017571313,
+ 0.012434559,
+ 0.025864428,
+ -0.02860494,
+ -0.014506985,
+ -0.014779673,
+ -0.0041653044,
+ -0.0034392735,
+ -0.009925832,
+ 0.035013102,
+ -0.033049747,
+ -0.033731468,
+ -0.07160779,
+ 0.0054060337,
+ -0.018869989,
+ -0.018215539,
+ 0.013450321,
+ -0.004741357,
+ 0.017520184,
+ -0.016211284,
+ -0.0073557505,
+ 0.021624135,
+ -0.016252186,
+ -0.018051926,
+ -0.023860173,
+ 0.01762926,
+ 0.0037017355,
+ 0.0067558377,
+ 0.046411447,
+ 0.0035449401,
+ 0.0065615475,
+ -0.011793743,
+ 0.0029944517,
+ -0.002178093,
+ 0.04123038,
+ 0.0017221932,
+ -0.003510854,
+ -0.0051537976,
+ -0.027309673,
+ 0.008535125,
+ -2.2219786E-4,
+ 0.0022905767,
+ 0.0085623935,
+ -0.008787361,
+ -0.018897258,
+ 0.019224482,
+ -0.010471207,
+ -0.008098825,
+ 0.01925175,
+ 0.03059556,
+ -0.0013864465,
+ 0.04499347,
+ -0.034195036,
+ -0.022837594,
+ 0.020219794,
+ -0.023941979,
+ -0.023560217,
+ 0.0014972258,
+ -0.0011878958,
+ 0.004042595,
+ 0.03435865,
+ -0.011152927,
+ 0.045920607,
+ 0.008173814,
+ -0.028741283,
+ -0.04431175,
+ -0.010362132,
+ -0.02707789,
+ 0.032477103,
+ 0.0128981285,
+ 0.0011861915,
+ 0.025428127,
+ 0.037712708,
+ 0.016102208,
+ -0.0063365805,
+ -0.017002078,
+ -0.019988008,
+ -0.009496349,
+ -0.0036233377,
+ -7.9718546E-4,
+ 0.013613934,
+ -0.034985833,
+ -0.03364966,
+ -0.014711501,
+ 0.007505729,
+ 0.0027166512,
+ 0.019074505,
+ 0.027623264,
+ 0.008766909,
+ -0.01158241,
+ 0.0099121975,
+ 0.021678671,
+ -3.904973E-4,
+ -0.025469031,
+ -0.0021286684,
+ 0.014725136,
+ 0.034713145,
+ -7.3114387E-4,
+ -0.019319924,
+ 0.0046050134,
+ -0.0109075075,
+ -0.0052901413,
+ -8.845307E-4,
+ 0.008923705,
+ -0.0044584437,
+ 0.013341245,
+ 0.009387274,
+ -0.010573465,
+ -0.016361263,
+ 0.010887057,
+ 0.005579872,
+ 0.005712807,
+ 0.021964993,
+ 0.009700865,
+ 0.023451142,
+ -0.031168204,
+ -0.008282889,
+ -0.017997388,
+ -0.019565342,
+ -0.022305854,
+ 0.011139292,
+ -0.006265,
+ 0.009659962,
+ 0.0056446353,
+ -0.01473877,
+ 0.02124237,
+ -0.015120532,
+ 0.031195473,
+ -0.01585679,
+ -0.017329304,
+ -0.026109846,
+ 0.013818449,
+ 0.032122612,
+ 0.005368539,
+ 0.03564028,
+ -0.02568718,
+ 0.0113574425,
+ 0.023219358,
+ 6.075823E-4,
+ -0.0017008896,
+ -0.0028956025,
+ -0.011323357,
+ -6.8597996E-4,
+ -0.0059718606,
+ -0.02518271,
+ -0.013334428,
+ -0.02950481,
+ 0.012073248,
+ -0.013334428,
+ 0.0031069354,
+ -0.021351447,
+ 0.08475134,
+ 0.044039063,
+ 0.011227916,
+ 0.014984189,
+ -0.0027422158,
+ -0.024310108,
+ -0.0012552155,
+ 0.011909635,
+ -0.01136426,
+ -0.01153469,
+ 0.012386839,
+ -0.022564907,
+ -0.026696125,
+ -0.023860173,
+ -0.007471643,
+ 0.014138857,
+ -0.018924527,
+ 0.02306938,
+ 0.002956957,
+ -0.004400498,
+ 0.023369335,
+ 0.027977757,
+ -0.010566648,
+ -1.0071337E-4,
+ -0.0254963,
+ -0.004652734,
+ 0.004161896,
+ -7.588387E-4,
+ 0.001245842,
+ -0.03855804,
+ 0.02661432,
+ 0.017806506,
+ -0.04477532,
+ -0.020574287,
+ 0.012734516,
+ 0.013872987,
+ 0.023492046,
+ -0.011684667,
+ 0.0064013437,
+ 0.0015594327,
+ -0.0019122225,
+ 1.1120545E-4,
+ -0.0019411956,
+ -0.055328332,
+ -0.008882802,
+ 0.01313673,
+ -0.0323953,
+ -0.024051055,
+ -0.032640718
+ ],
+ "content": "The Spring AI project aims to streamline the development of applications that incorporate artificial intelligence functionality without unnecessary complexity.\nThe project draws inspiration from notable Python projects, such as LangChain and LlamaIndex, but Spring AI is not a direct port of those projects. The project was founded with the belief that the next wave of Generative AI applications will not be only for Python developers but will be ubiquitous across many programming languages.\nAt its core, Spring AI provides abstractions that serve as the foundation for developing AI applications. These abstractions have multiple implementations, enabling easy component swapping with minimal code changes. For example, Spring AI introduces the AiClient interface with implementations for OpenAI and Azure OpenAI.\nIn addition to these core abstractions, Spring AI aims to provide higher-level functionalities to address common use cases such as “Q&A over your documentation” or “Chat with your documentation.” As the complexity of the use cases increases, the Spring AI project will integrate with other projects in the Spring Ecosystem, such as Spring Integration, Spring Batch, and Spring Data.\nTo simplify setup, Spring Boot starters are available to help set up essential dependencies and classes. There is also a collection of sample applications to help you explore the project’s features. Lastly, the new Spring CLI project also enables you to get started quickly by using the spring boot new AI command for new projects or spring boot add AI for adding AI capabilities to your existing application.\n\n",
+ "id": "1",
+ "metadata": {
+ "meta1": "meta1"
+ }
+ }, {
+ "embedding": [
+ 0.012438339,
+ -4.2974597E-4,
+ -0.005043023,
+ -0.0022752243,
+ 0.006681586,
+ -0.0022199352,
+ -0.012116658,
+ -0.031873245,
+ -0.006942952,
+ -0.0039439453,
+ 0.02868324,
+ 0.016633598,
+ -8.79597E-4,
+ -0.011225333,
+ 0.005770156,
+ 0.008357009,
+ 0.033213582,
+ -0.021217555,
+ 0.010655689,
+ 0.0019284117,
+ -0.0158428,
+ 0.028200718,
+ 0.01897919,
+ -0.03066694,
+ -0.015641747,
+ 0.011459893,
+ 0.027771808,
+ -0.035063248,
+ 0.022048565,
+ -0.02345592,
+ -0.011459893,
+ -0.024434367,
+ -0.0025148096,
+ -0.027691389,
+ -0.03731502,
+ -0.03307955,
+ 0.004543747,
+ -0.027825423,
+ 0.009663839,
+ 0.003387705,
+ 0.011278947,
+ 0.021579446,
+ -0.0075528063,
+ -0.0012842116,
+ -0.012270797,
+ 0.0128739495,
+ 0.006845778,
+ -0.02096289,
+ -0.026337648,
+ 0.0028733502,
+ 0.036752075,
+ 0.011151615,
+ -0.05908211,
+ -0.030023577,
+ 0.008377114,
+ -0.026712941,
+ -0.025332393,
+ 0.015427293,
+ -0.009456087,
+ -0.009007073,
+ 0.0047280435,
+ -0.0014651573,
+ -0.008289992,
+ 0.02472924,
+ 4.0272975E-4,
+ -0.013403383,
+ -0.02420651,
+ -0.012652793,
+ 0.0033642491,
+ 0.007666735,
+ 0.028334752,
+ 0.021619657,
+ -0.0014869377,
+ -0.006661481,
+ 0.018416248,
+ -0.020815453,
+ -0.013168824,
+ -0.0029889543,
+ -0.003062673,
+ 0.022718733,
+ 0.006433624,
+ -0.04342696,
+ 0.01204294,
+ 0.0010890248,
+ -0.0018882016,
+ 0.013182227,
+ -0.0021244362,
+ 0.0039607,
+ -0.004342696,
+ -0.027275885,
+ 0.002420986,
+ 0.02056079,
+ 0.0045504486,
+ 0.018201794,
+ 0.015413891,
+ 0.015829396,
+ 0.014770527,
+ -0.005672982,
+ 0.004212013,
+ -0.021003101,
+ -0.008832829,
+ 0.0039607,
+ -0.010126255,
+ -4.6199784E-4,
+ -0.023764197,
+ 8.921627E-4,
+ 0.006731849,
+ 0.008765812,
+ 0.021137135,
+ -1.3026413E-4,
+ -0.03787796,
+ 0.03895023,
+ 0.027879037,
+ -0.04905638,
+ -0.011272245,
+ -0.005760104,
+ 0.02167327,
+ 0.0014869377,
+ 0.012706406,
+ -0.0027962807,
+ 0.03034526,
+ 0.012974475,
+ 0.012672898,
+ -0.013108509,
+ 0.015387083,
+ -0.00326875,
+ -0.009228229,
+ -0.004255574,
+ -0.007861084,
+ -0.018215198,
+ 0.012766722,
+ 0.0162449,
+ -0.0014894509,
+ 0.020265914,
+ 0.0016528047,
+ 0.007512596,
+ -0.020453563,
+ -5.2733935E-4,
+ -0.025667477,
+ -0.01081653,
+ 0.008873039,
+ 6.5676577E-4,
+ -0.023630165,
+ -0.018992594,
+ -0.013805484,
+ 0.02005146,
+ -0.004801762,
+ 0.009080792,
+ 0.0141807785,
+ -0.0065408507,
+ 0.054015633,
+ -0.016445952,
+ -0.0040947334,
+ 5.4032385E-5,
+ -0.0010463016,
+ 0.015065402,
+ 0.0017692465,
+ 0.025587058,
+ -0.030720552,
+ -7.2839006E-4,
+ 0.0034815287,
+ 4.707938E-4,
+ 0.007076986,
+ -0.0038836303,
+ 0.03522409,
+ 0.038655356,
+ -5.8304716E-4,
+ -0.014006535,
+ -0.004144996,
+ -0.0033860295,
+ -0.021700077,
+ 0.009690646,
+ -0.030827781,
+ -0.0069563556,
+ -1.23353E-4,
+ 0.015641747,
+ 0.009248334,
+ 0.024340544,
+ -0.0324898,
+ -0.0067854626,
+ -0.005260828,
+ -0.0049994616,
+ 0.025399411,
+ 0.027798615,
+ -0.012411532,
+ -0.008852934,
+ -0.012438339,
+ 0.010213378,
+ 0.008537955,
+ -0.0017843253,
+ -0.012036238,
+ 0.017799692,
+ 0.0073651588,
+ -3.0429868E-4,
+ -0.6502249,
+ -0.030425679,
+ -0.022088775,
+ -0.035090055,
+ 0.038816195,
+ -0.0086116735,
+ 0.0062258714,
+ 0.011955817,
+ -0.007747155,
+ -0.001791027,
+ 0.0034647745,
+ 0.03281148,
+ 0.013001281,
+ -0.009228229,
+ -0.023831215,
+ -0.019247258,
+ 0.0054216683,
+ -0.03015761,
+ -0.0018329126,
+ -0.01814818,
+ -0.020976294,
+ 0.032302152,
+ 0.0020406651,
+ 0.008591568,
+ 2.586434E-4,
+ -0.018402845,
+ 0.019341081,
+ -0.01168775,
+ -0.027959457,
+ 0.023804408,
+ -0.030318452,
+ 0.017799692,
+ 0.005341248,
+ 0.017343977,
+ 0.03755628,
+ -0.014690108,
+ -0.007123898,
+ 0.011989326,
+ -0.0025801512,
+ 0.030211225,
+ 0.014703511,
+ -0.016392337,
+ 0.02428693,
+ 0.013952921,
+ 0.00954991,
+ -0.0152798565,
+ 0.027798615,
+ -0.01251876,
+ 0.026726345,
+ -0.028629625,
+ 0.021056714,
+ -0.0049089887,
+ -0.009556612,
+ 0.012264095,
+ 0.024675628,
+ 0.0034580727,
+ 0.023630165,
+ -0.0135977315,
+ 0.017866708,
+ -0.003292206,
+ -0.007961609,
+ 0.036028292,
+ -0.006249327,
+ -0.004124891,
+ -0.033856943,
+ 0.0050631277,
+ 0.0036490709,
+ 0.024300333,
+ 0.0010471393,
+ -0.007907996,
+ 0.011386174,
+ 0.046054024,
+ -0.0051804073,
+ -0.0036021592,
+ 0.017357381,
+ 1.6817056E-4,
+ 0.0026203613,
+ -0.0020976295,
+ -0.031524755,
+ 0.024662225,
+ 0.009047284,
+ 0.001155204,
+ -0.03232896,
+ -0.003019112,
+ 0.02975551,
+ -0.0020791998,
+ -0.022490876,
+ 0.0050899344,
+ 0.015641747,
+ 0.009576717,
+ -0.011144913,
+ 0.00107981,
+ -0.0015598186,
+ -0.017330574,
+ 0.047287133,
+ 0.019166837,
+ -0.02682017,
+ 0.0029152357,
+ 0.0024142843,
+ -0.002476275,
+ 0.009972117,
+ -0.015614941,
+ -0.005941049,
+ 0.00772705,
+ 0.0162449,
+ 0.00824308,
+ -0.00717081,
+ 0.009201422,
+ 0.041094773,
+ -0.048761506,
+ -0.0014668327,
+ -0.025198359,
+ 0.009348859,
+ 0.0020356388,
+ 0.019046206,
+ -0.024434367,
+ 0.022678524,
+ 0.0020758489,
+ 0.0233755,
+ -0.018295618,
+ 0.016941875,
+ 0.003974103,
+ -0.005495387,
+ -0.012270797,
+ 0.028576013,
+ 0.022598103,
+ 0.006671534,
+ -0.026619118,
+ -0.02088247,
+ -0.0022433912,
+ -0.012096553,
+ 0.0035250897,
+ 0.026377857,
+ -0.0024628716,
+ 6.4084923E-4,
+ 0.00511004,
+ -2.2911407E-4,
+ -0.0065274476,
+ 0.0031280145,
+ -0.0085781645,
+ -0.009730856,
+ 0.0213918,
+ 0.014877755,
+ 0.0032101101,
+ -0.016579984,
+ -0.039566785,
+ -0.016432548,
+ -0.010977371,
+ -0.020279318,
+ -0.0036457202,
+ -0.0048319194,
+ -0.02096289,
+ -0.022839364,
+ 0.01679444,
+ 0.017585238,
+ -0.002725913,
+ -0.015561327,
+ -0.018670913,
+ -0.025131343,
+ -0.008524551,
+ 0.019662762,
+ 0.022906382,
+ -0.03388375,
+ 4.3225908E-4,
+ -0.0015321742,
+ -1.3351026E-4,
+ -0.010488147,
+ 0.0128404405,
+ -0.016579984,
+ -0.01687486,
+ 0.011238736,
+ -2.7560705E-4,
+ -0.007586315,
+ 0.023120835,
+ -0.013001281,
+ -0.0039875065,
+ 8.192818E-4,
+ -0.002853245,
+ 0.004386257,
+ -0.0069563556,
+ -0.0072914404,
+ 0.015909815,
+ 0.0015774106,
+ -0.009221528,
+ 0.014489057,
+ 0.005431721,
+ 0.005019567,
+ -0.006644727,
+ 0.014556074,
+ 0.023871426,
+ -0.011433085,
+ 0.022812558,
+ 0.0075662094,
+ -0.020373141,
+ -0.00804203,
+ 0.0123914275,
+ -0.0010530032,
+ 0.022490876,
+ 0.014140569,
+ 0.024394156,
+ 0.00938907,
+ -0.010669093,
+ 0.020399949,
+ -0.0014475654,
+ 0.0045739044,
+ -0.019743184,
+ 0.020480368,
+ -0.0034647745,
+ 0.011748065,
+ -0.005435072,
+ 0.02064121,
+ -0.045625117,
+ -0.00447673,
+ -0.030372065,
+ -0.016338723,
+ 0.031256687,
+ 0.01640574,
+ 0.019528728,
+ -3.8618495E-4,
+ 0.012619285,
+ -0.017290363,
+ 0.00851785,
+ 0.0068290234,
+ -0.01731717,
+ -0.004697886,
+ 0.015011788,
+ -0.0071574063,
+ 0.01565515,
+ -9.365614E-4,
+ -0.024809662,
+ 0.023094028,
+ 0.008129152,
+ -0.010722706,
+ 0.035921067,
+ 0.018617298,
+ 0.02718206,
+ 0.0017491415,
+ -0.019971041,
+ 0.022718733,
+ -0.0067821117,
+ -0.012498654,
+ -0.008109046,
+ 0.003126339,
+ 0.0050028125,
+ -2.5445485E-4,
+ 0.021217555,
+ 0.01818839,
+ 0.010179869,
+ 1.8932277E-4,
+ -0.00566628,
+ -0.037985187,
+ 0.0074388776,
+ -0.0049156905,
+ 0.007345054,
+ -0.012974475,
+ -0.025694285,
+ 0.010561866,
+ -0.010622181,
+ 7.405369E-4,
+ 0.022919785,
+ -0.00891325,
+ 0.021150539,
+ 0.01806776,
+ 0.0014257849,
+ 0.0065542543,
+ -0.020936083,
+ -0.0089199515,
+ -0.016191287,
+ -0.016137673,
+ 0.0031916804,
+ -0.00859827,
+ -0.0073986673,
+ 0.018014146,
+ -0.010106151,
+ 0.010702601,
+ 0.005130145,
+ -0.005213916,
+ 0.0076198233,
+ 0.013859098,
+ 7.686002E-4,
+ -0.027476935,
+ -0.02230323,
+ 0.013704959,
+ -0.010079344,
+ -0.01648616,
+ -0.011386174,
+ -0.0055657546,
+ -5.3655414E-4,
+ -0.004711289,
+ 0.017022297,
+ -0.030238032,
+ 0.0014810738,
+ -0.010213378,
+ -0.0058271205,
+ -9.952012E-4,
+ 3.3299028E-5,
+ -9.005398E-4,
+ -0.0050966362,
+ 0.017746078,
+ -0.028870886,
+ -0.01517263,
+ -0.0034681254,
+ -0.0027443427,
+ -0.006748603,
+ 0.012458445,
+ 0.024675628,
+ 0.0048520244,
+ -0.0024813013,
+ -0.007559508,
+ -0.01533347,
+ -0.006584412,
+ -0.019193644,
+ -5.855603E-4,
+ -0.0060449257,
+ 0.0057232445,
+ -0.011969221,
+ -0.030774167,
+ -0.010756215,
+ 0.03769031,
+ 0.0038601742,
+ 0.012290902,
+ -0.009080792,
+ -0.030184418,
+ 0.015829396,
+ 0.117091954,
+ 0.0062258714,
+ -0.00942928,
+ -0.0015681958,
+ 0.0048084636,
+ 0.019247258,
+ 4.2974597E-4,
+ -0.05436412,
+ 0.010488147,
+ 0.0035485455,
+ -0.016673809,
+ 0.0014391883,
+ 0.023348693,
+ -0.024943694,
+ -0.014113762,
+ 0.031471144,
+ -0.0026488435,
+ -0.005930997,
+ -0.009013775,
+ -0.007814172,
+ -0.023509534,
+ -0.011788275,
+ -0.0022936538,
+ 0.011044388,
+ -0.012572373,
+ -0.0057366476,
+ 0.025680881,
+ 0.011861994,
+ 0.00625938,
+ -0.011030984,
+ 0.006674885,
+ -0.0024276876,
+ 0.002226637,
+ 0.022169195,
+ -0.0071976166,
+ 0.014529267,
+ -0.0072110198,
+ 0.009422578,
+ 0.015936622,
+ -0.017049102,
+ 0.0015372004,
+ 0.016472757,
+ 0.009087494,
+ -0.016017042,
+ 4.8838573E-4,
+ 0.0060750833,
+ 0.021110328,
+ 0.019984445,
+ 0.0033257143,
+ -0.008296694,
+ 0.018804947,
+ -0.013611135,
+ -0.032275345,
+ -0.021257766,
+ -0.008651883,
+ 0.0099855205,
+ 0.020064864,
+ 0.016151076,
+ -0.011942414,
+ -0.0034815287,
+ -0.0032184874,
+ -0.025024116,
+ 0.0062225205,
+ -0.0019032804,
+ 0.017183136,
+ -0.03450031,
+ -0.0037428946,
+ 0.0190194,
+ -0.019327678,
+ -0.028147103,
+ -0.023388904,
+ -0.0044063623,
+ -0.020775244,
+ 0.008504447,
+ 0.007412071,
+ 0.025627268,
+ -0.009409174,
+ 0.0040947334,
+ -0.023013609,
+ 0.020024654,
+ 0.029407023,
+ 0.0015958402,
+ -0.012371322,
+ 0.010648987,
+ -0.005260828,
+ 0.009925205,
+ -3.6231018E-4,
+ -0.02623042,
+ -0.0071104947,
+ 0.015145822,
+ 0.01446225,
+ -0.008263186,
+ 0.022263018,
+ 0.004037769,
+ -0.0041785045,
+ 0.0010069291,
+ 0.03232896,
+ -0.009844785,
+ -0.019662762,
+ -8.790734E-5,
+ 0.013477101,
+ -0.02631084,
+ -0.008511148,
+ -0.022410456,
+ 0.0042019603,
+ 0.011815082,
+ 0.007660033,
+ 0.010213378,
+ 0.0018814999,
+ 0.0023003556,
+ 0.0051569515,
+ -0.02598916,
+ 0.008625077,
+ -0.0012749968,
+ -0.0066983406,
+ 0.0036323168,
+ -0.0011644189,
+ 0.017370785,
+ 0.016861456,
+ -0.031256687,
+ 0.019005997,
+ -0.019796796,
+ 0.023201255,
+ 0.0031933559,
+ 0.0038903318,
+ 0.015132419,
+ 0.018577088,
+ -0.015440697,
+ 7.4472546E-4,
+ -0.010273693,
+ -0.020239107,
+ 0.02013188,
+ 0.014757125,
+ -0.0023606708,
+ -0.046188056,
+ -0.008504447,
+ -0.0080956435,
+ -0.0048553753,
+ -0.0077404534,
+ -0.0029068587,
+ -7.011645E-4,
+ -0.013229139,
+ -0.017142927,
+ -0.031497948,
+ -0.0039171386,
+ -0.0289245,
+ 0.0023439166,
+ -0.007901294,
+ 0.011855292,
+ 0.010997475,
+ -0.03819964,
+ 0.009717452,
+ -0.012250692,
+ 2.4586832E-4,
+ 0.016941875,
+ -0.032248538,
+ -0.014676704,
+ -0.014314813,
+ 0.01604385,
+ 0.021351589,
+ 0.017960533,
+ -0.013322962,
+ -0.00855806,
+ 0.025184955,
+ -0.007036776,
+ -0.006209117,
+ 0.006929549,
+ 0.0029856034,
+ -0.040719476,
+ 0.023764197,
+ 0.0085781645,
+ 0.018040953,
+ 0.010943862,
+ -0.01311521,
+ 0.027007816,
+ 0.0324898,
+ -0.008343605,
+ -0.014984982,
+ -0.02523857,
+ -0.03935233,
+ -0.009717452,
+ -8.0252753E-4,
+ -0.012384726,
+ 0.0040813303,
+ -0.0063096425,
+ -0.013617837,
+ 0.042086624,
+ 0.009958713,
+ -0.010240184,
+ -0.0032553466,
+ 0.041952588,
+ 4.008449E-4,
+ 0.03951317,
+ -0.018242003,
+ 0.021043312,
+ -0.039137878,
+ -1.4000252E-4,
+ -0.020239107,
+ -0.006778761,
+ 0.023871426,
+ -0.010655689,
+ 0.012257393,
+ 9.2064484E-4,
+ -0.01299458,
+ -0.0067821117,
+ 0.02044016,
+ -0.018362634,
+ -0.0040511726,
+ -0.0016536424,
+ -0.017491415,
+ 0.0028113595,
+ -0.029782316,
+ -0.020748436,
+ -0.021029908,
+ 0.022919785,
+ 0.0021294625,
+ -0.010769618,
+ 0.023563147,
+ -0.020493772,
+ 3.390637E-4,
+ 0.0011443138,
+ 0.013993132,
+ 0.028736852,
+ 0.013262647,
+ 0.027825423,
+ 0.0141807785,
+ -0.031792823,
+ -0.015909815,
+ -0.00165448,
+ 0.028844079,
+ 0.022477472,
+ 0.006343151,
+ -0.0077002435,
+ 0.011144913,
+ -0.007867786,
+ 0.019528728,
+ 0.022410456,
+ -0.006996566,
+ -0.027503742,
+ 0.029567862,
+ 0.0044901334,
+ -0.01220378,
+ -0.014676704,
+ -0.008336904,
+ -0.006443676,
+ 0.04216704,
+ -0.016459353,
+ 0.02052058,
+ -0.017223347,
+ -0.030264838,
+ -0.011748065,
+ 0.011520208,
+ -0.0018848507,
+ 0.03530451,
+ 0.0020306124,
+ -0.01565515,
+ 0.009382368,
+ -0.010508252,
+ 0.023053817,
+ 0.00725123,
+ -0.010729408,
+ 0.008839531,
+ -0.013885904,
+ 0.0054987376,
+ -0.016030446,
+ 8.519525E-4,
+ -0.02254449,
+ -0.0042388197,
+ -0.0049391463,
+ 0.024809662,
+ -0.029541055,
+ -0.012686302,
+ -0.018670913,
+ -0.001858044,
+ 0.025104536,
+ 0.006691639,
+ -0.0063967644,
+ -0.00586398,
+ 0.014824142,
+ -0.025721092,
+ 0.009972117,
+ 0.012311007,
+ -0.0344735,
+ -0.0042622755,
+ 0.017303767,
+ -0.02353634,
+ -0.031900052,
+ 0.01549431,
+ -0.0029654985,
+ -0.014556074,
+ -0.024461174,
+ 0.0011300727,
+ 0.021753691,
+ 0.018161584,
+ -0.01993083,
+ 0.008323501,
+ -0.022959994,
+ 0.0017290363,
+ -0.029380215,
+ 0.01885856,
+ 0.011158316,
+ 0.022879574,
+ -0.017719273,
+ -0.0035518964,
+ -0.006607868,
+ -0.006624622,
+ 0.021297975,
+ -0.008544656,
+ -0.019823603,
+ 7.59176E-5,
+ 0.02064121,
+ 0.013048193,
+ -0.010488147,
+ -0.013135315,
+ -0.020775244,
+ 0.016647002,
+ -0.0043963096,
+ -0.0099520115,
+ -0.04010292,
+ 0.0073785624,
+ 0.017853307,
+ 0.013617837,
+ 0.013182227,
+ -0.045303434,
+ 0.0309082,
+ -0.01922045,
+ -0.014891158,
+ 0.0162449,
+ -0.023723988,
+ -0.009871592,
+ 0.019005997,
+ 0.02698101,
+ -0.032677446,
+ -0.019475115,
+ 0.011178421,
+ -0.014703511,
+ -0.018402845,
+ -0.0017457906,
+ 0.013269349,
+ 0.0043527484,
+ 0.006490588,
+ 0.020828856,
+ -0.004540396,
+ -0.00768684,
+ 3.128852E-4,
+ -0.0044365195,
+ 0.019743184,
+ -0.010561866,
+ -0.02025251,
+ -0.025372604,
+ -0.010307201,
+ 0.036725268,
+ 0.005512141,
+ -0.014596283,
+ 0.0027292639,
+ -0.013832291,
+ -0.033535264,
+ -0.009556612,
+ 0.023388904,
+ 0.02726248,
+ 0.036028292,
+ 0.010199974,
+ -0.006909444,
+ 0.0049592517,
+ 0.001791027,
+ 0.04500856,
+ 0.0087189,
+ -5.788586E-4,
+ 0.0024427664,
+ -0.014086955,
+ 0.0049123396,
+ 0.023737391,
+ -0.019005997,
+ -8.636805E-4,
+ 0.0011493401,
+ -0.009616927,
+ 1.3591867E-4,
+ -2.9340843E-4,
+ -0.011942414,
+ 0.012733214,
+ -7.7320763E-4,
+ 0.005689736,
+ 0.007144003,
+ -0.019957637,
+ 0.008665287,
+ -0.035760224,
+ 0.004235469,
+ 0.0020222354,
+ -0.0066380254,
+ 0.015092209,
+ -0.0012984527,
+ 0.020346334,
+ 0.0033944068,
+ 0.00479506,
+ 0.0072981417,
+ -0.002194804,
+ 0.0014911264,
+ -0.013704959,
+ 0.039674014,
+ 0.0072445283,
+ -0.0025617215,
+ 0.034312658,
+ 0.012297603,
+ -0.016767632,
+ 0.004275679,
+ 0.007834277,
+ -0.008645182,
+ -0.020895874,
+ 0.003823315,
+ -0.024930293,
+ 0.01972978,
+ -0.007432176,
+ 0.016526371,
+ -0.0073651588,
+ 0.010112852,
+ -0.022691928,
+ 0.012813634,
+ -0.005019567,
+ 0.019528728,
+ 0.022450667,
+ -0.026833571,
+ 0.011138211,
+ -0.018845156,
+ -0.017652255,
+ 0.0093689645,
+ -0.020574193,
+ 0.008893144,
+ -0.0017390889,
+ 0.0027292639,
+ 0.003498283,
+ -0.007901294,
+ -0.021499027,
+ 0.012009431,
+ -1.7267327E-4,
+ -0.013818888,
+ -0.0025449672,
+ 0.22217447,
+ -0.00479506,
+ -0.016633598,
+ -0.0071305996,
+ -2.4230803E-4,
+ 0.02817391,
+ 0.031444337,
+ 0.009013775,
+ -0.0040511726,
+ 0.018737929,
+ -0.035733417,
+ 0.002261821,
+ -0.0068960404,
+ 0.0030492696,
+ 0.0023757496,
+ -0.046268478,
+ -0.04385587,
+ -0.002186427,
+ -0.032141313,
+ -0.034929216,
+ 0.01204294,
+ 0.010206676,
+ 0.0038266657,
+ -0.021887723,
+ 0.0031916804,
+ -4.925743E-4,
+ -0.0062660812,
+ -0.008618375,
+ -0.0029587967,
+ 0.007827575,
+ -0.004215364,
+ -0.02900492,
+ 0.0031146111,
+ -0.0053244936,
+ -0.037422244,
+ 0.0025717742,
+ 0.018871963,
+ -0.01323584,
+ 0.020533983,
+ 0.01668721,
+ 0.004801762,
+ 0.010474743,
+ 0.03098862,
+ 1.24086E-4,
+ 0.016848052,
+ 0.02353634,
+ -0.019622553,
+ -0.016003639,
+ -0.003355872,
+ 0.011540312,
+ -0.026806766,
+ 0.013209034,
+ 0.0170357,
+ 0.016888263,
+ -0.012022834,
+ -0.002385802,
+ 0.018577088,
+ 0.0057835598,
+ -0.009717452,
+ 0.015480907,
+ -0.012384726,
+ 0.018295618,
+ -0.012297603,
+ 0.01517263,
+ -0.030532906,
+ 0.028227525,
+ 0.01922045,
+ -8.2828716E-5,
+ 0.0380388,
+ -0.010984072,
+ 0.016472757,
+ -0.018416248,
+ 0.00519046,
+ 0.005599263,
+ 0.003102883,
+ -0.012867248,
+ 0.044016708,
+ -0.008216274,
+ 0.025453024,
+ 0.019528728,
+ -0.016727421,
+ -0.022732137,
+ -0.0225847,
+ -0.009978819,
+ -0.014958175,
+ -0.032248538,
+ 0.003411161,
+ 0.009824679,
+ -0.01993083,
+ 0.0018195092,
+ 0.017491415,
+ -0.018496668,
+ -0.003054296,
+ -0.023161046,
+ -4.5236415E-4,
+ -0.009750961,
+ 0.03439308,
+ 0.0044800807,
+ 0.016834648,
+ 0.0034446693,
+ 0.002885078,
+ -0.032355767,
+ -0.005036321,
+ 0.0045068874,
+ -0.024059072,
+ 0.020399949,
+ 3.9414322E-4,
+ 0.017223347,
+ 0.0031213127,
+ -0.010360815,
+ -0.003471476,
+ -0.015856203,
+ -0.002400881,
+ -0.01255897,
+ -0.0060884864,
+ -0.013302857,
+ -0.018242003,
+ -0.010628883,
+ 0.018242003,
+ -0.016231496,
+ -0.010334008,
+ -5.9854484E-4,
+ -0.0040880316,
+ 0.015628343,
+ 0.0152128395,
+ -0.030130804,
+ -0.023362096,
+ 0.0018362635,
+ 0.013979728,
+ -0.022611506,
+ -0.0011233711,
+ -0.027195463,
+ 0.018496668,
+ -0.0088194255,
+ -0.015078805,
+ 0.003126339,
+ 0.0012657819,
+ -0.020399949,
+ -0.0126796,
+ 0.028602818,
+ -0.027128447,
+ 0.007324949,
+ 0.01077632,
+ -0.005059777,
+ 0.022611506,
+ -0.0055456497,
+ 0.006762007,
+ -0.02211558,
+ -0.03157837,
+ -0.013255945,
+ -0.015038596,
+ 2.2366895E-4,
+ -0.0043125385,
+ -0.008296694,
+ 0.015253049,
+ 0.003161523,
+ -0.038146026,
+ -0.017370785,
+ -2.2133907E-5,
+ 0.04112158,
+ -0.021780496,
+ -0.007680138,
+ 0.010836635,
+ 0.006839076,
+ -0.0058338223,
+ -0.011815082,
+ -0.1715633,
+ 0.010039134,
+ 0.012612583,
+ -0.006755305,
+ 0.030935008,
+ 6.525772E-4,
+ 0.022249615,
+ 0.0060449257,
+ -0.020091671,
+ 0.014891158,
+ -1.3340554E-4,
+ 0.021096924,
+ -0.030077191,
+ -0.011392876,
+ 0.0059745577,
+ 0.023482727,
+ -0.024635417,
+ 0.035518963,
+ 0.02171348,
+ 0.031712405,
+ 0.015119016,
+ -0.017612046,
+ 0.014877755,
+ -0.0018262109,
+ -0.0012758345,
+ 0.013624539,
+ 0.0034480202,
+ 0.00661792,
+ 0.0013302857,
+ -0.018590491,
+ -0.008893144,
+ 0.009362263,
+ 0.04254234,
+ 0.0048252176,
+ -0.0020892522,
+ 0.012887352,
+ -0.0074522807,
+ -0.0025499936,
+ -0.022959994,
+ 0.018215198,
+ 0.014408637,
+ 0.01640574,
+ 0.0054183174,
+ 0.010575269,
+ -0.015775781,
+ 0.025198359,
+ 0.009147809,
+ -0.014127165,
+ -0.016781036,
+ -0.00649729,
+ -5.3278444E-4,
+ -6.169745E-4,
+ 0.0038132623,
+ 0.0026689486,
+ 0.019528728,
+ 0.0040846807,
+ 0.028549206,
+ -0.019877216,
+ -0.0010446261,
+ -0.0348756,
+ 0.020024654,
+ -0.01038092,
+ 0.0045672026,
+ -0.010086046,
+ -0.012136763,
+ 0.024420964,
+ 0.009080792,
+ 0.015802588,
+ -0.023938442,
+ 0.0024628716,
+ -0.009147809,
+ 0.0018295618,
+ -0.0014685082,
+ -0.0099520115,
+ 0.0064403256,
+ -0.0058137174,
+ -0.022973398,
+ 0.005019567,
+ -0.0021411905,
+ -0.017585238,
+ -0.010615479,
+ -2.9047643E-4,
+ -0.033133164,
+ 0.011788275,
+ 0.010823231,
+ 0.016271707,
+ -0.0070702843,
+ 0.019662762,
+ -0.033267196,
+ -0.02876366,
+ 0.02527878,
+ -0.022088775,
+ 0.001236462,
+ -0.0070501794,
+ 0.035947874,
+ 0.020279318,
+ -0.006252678,
+ -0.0027845528,
+ 0.009181317,
+ -0.022289826,
+ 0.0031514703,
+ -0.009462788,
+ -0.02951425,
+ 0.016606791,
+ -0.011714556,
+ 0.02631084,
+ -0.0040813303,
+ 0.004687833,
+ 0.03830687,
+ -0.0108098285,
+ -0.021860918,
+ 0.010575269,
+ 0.0316856,
+ 0.0072981417,
+ -0.018295618,
+ 0.023174448,
+ 0.0069630574,
+ -0.014743721,
+ 0.013738467,
+ -0.010280395,
+ 0.05559723,
+ 0.0025667478,
+ -0.0059142425,
+ 0.003431266,
+ 0.005616017,
+ -0.025104536,
+ -0.104707226,
+ -0.021257766,
+ 0.002072498,
+ 0.0024947047,
+ 0.026846975,
+ -0.0066949897,
+ -0.018429652,
+ -0.009322053,
+ 0.0052373717,
+ 0.018201794,
+ -0.0013570925,
+ -0.053238235,
+ -4.5068873E-4,
+ -0.001889877,
+ 4.3058366E-4,
+ -0.020533983,
+ 0.0059745577,
+ -0.025841722,
+ -0.028307945,
+ 0.023214659,
+ -0.014891158,
+ -0.0048386212,
+ -0.0044800807,
+ -0.021606253,
+ -0.02639126,
+ -0.0064805355,
+ -0.0049190414,
+ 0.01125214,
+ 0.027195463,
+ 0.003930542,
+ -0.013725064,
+ 0.014770527,
+ 0.0046576755,
+ -0.018014146,
+ 0.011098001,
+ -0.010253588,
+ -0.039834853,
+ 0.018523475,
+ -0.010662391,
+ -0.023992056,
+ 0.0027828773,
+ -0.008283291,
+ -0.002472924,
+ -0.003019112,
+ 0.0023187853,
+ -0.01806776,
+ -0.031256687,
+ 5.013703E-4,
+ -0.006319695,
+ -0.024648821,
+ -0.017504819,
+ -0.017638851,
+ -0.03696653,
+ -0.015320066,
+ 0.019448308,
+ -0.0068022166,
+ -0.0225847,
+ 0.019126628,
+ -1.4618064E-4,
+ -0.023000205,
+ -0.0024377403,
+ 6.79384E-4,
+ 0.019515324,
+ 0.028656432,
+ 0.016097462,
+ 0.015011788,
+ -0.006018119,
+ 0.004148347,
+ 0.016714018,
+ -0.0038099117,
+ -0.01093716,
+ 0.013926115,
+ -0.008330203,
+ 0.026967606,
+ -0.022758944,
+ 0.011379472,
+ -0.008899846,
+ -0.013966325,
+ 0.017960533,
+ -0.028576013,
+ -0.0068022166,
+ -0.019260662,
+ 0.0044164145,
+ -0.03554577,
+ 0.012833739,
+ 0.015735572,
+ 0.03538493,
+ -0.016955279,
+ 0.005753402,
+ -0.008551358,
+ -0.0014567801,
+ 0.028736852,
+ -0.006232573,
+ -0.047206715,
+ -0.007009969,
+ 0.051281344,
+ -0.0048955856,
+ -8.804347E-4,
+ -0.008068836,
+ 0.011908906,
+ -0.015092209,
+ -0.0021696726,
+ -0.043373346,
+ 0.029192567,
+ 0.019769989,
+ -0.007887891,
+ 7.899619E-4,
+ 0.014274603,
+ 0.0064403256,
+ -0.0027192114,
+ -0.011593926,
+ 0.032302152,
+ -0.004617465,
+ -0.0044164145,
+ -0.02147222,
+ -0.020399949,
+ -0.027771808,
+ -0.010508252,
+ 0.0036122117,
+ 0.0083704125,
+ 0.016754229,
+ -0.019274065,
+ -0.006470483,
+ 0.013396681,
+ -0.0025734494,
+ 0.0019568938,
+ -0.031873245,
+ -5.713192E-4,
+ -0.01691507,
+ 0.040236954,
+ -0.01711612,
+ -0.0036792285,
+ 0.03412501,
+ -0.025747899,
+ 0.022289826,
+ 0.04983378,
+ 0.010903652,
+ -0.012076448,
+ 0.013544118,
+ 0.03986166,
+ 0.0380388,
+ 0.031015428,
+ -0.017330574,
+ -0.019247258,
+ 0.033803333,
+ -0.019207047,
+ 0.0086786905,
+ 0.012237288,
+ -0.0091612125,
+ 0.005693087,
+ 0.028790466,
+ -0.006232573,
+ 0.0026119843,
+ 0.02702122,
+ -0.021807304,
+ -0.0107093025,
+ -0.014556074,
+ -0.027610969,
+ 0.012049641,
+ 0.018416248,
+ -0.02627063,
+ -0.023764197,
+ 0.02428693,
+ 0.01533347,
+ 0.015909815,
+ 0.004949199,
+ 0.017102716,
+ 0.0037764031,
+ 3.503728E-4,
+ 0.0037831047,
+ -0.010139659,
+ -0.0072110198,
+ -0.008879741,
+ -0.007995117,
+ 0.009931907,
+ 0.022182599,
+ 0.004466677,
+ -0.028549206,
+ -0.019153435,
+ -0.019046206,
+ -0.024983905,
+ 0.012056343,
+ 0.010702601,
+ -0.008310097,
+ -0.022959994,
+ 0.01073611,
+ 0.026779959,
+ 0.02199495,
+ 7.216884E-4,
+ -0.0013596057,
+ -0.011466594,
+ -0.011151615,
+ 0.007278037,
+ 0.008986969,
+ -7.288089E-4,
+ -0.017451204,
+ -0.008745708,
+ -0.010769618,
+ -0.021780496,
+ -0.003260373,
+ 0.027825423,
+ 0.021150539,
+ -0.0098849945,
+ 0.008739006,
+ -0.0076332265,
+ 0.0020741734,
+ -0.025332393,
+ -0.005126794,
+ -0.0060248207,
+ -0.0083704125,
+ 0.0068960404,
+ 0.015641747,
+ -0.0047380957,
+ 0.012967773,
+ 0.006671534,
+ -3.0052898E-4,
+ -0.030640133,
+ 0.012538864,
+ -0.0052507753,
+ -0.028629625,
+ -0.012331112,
+ 0.0012004405,
+ 0.017705869,
+ 0.033267196,
+ 0.019448308,
+ -0.011037686,
+ 0.009261738,
+ -2.3372148E-4,
+ 0.013524014,
+ -0.024380753,
+ 0.0062828357,
+ 0.019448308,
+ 0.0070635825,
+ 0.013570925,
+ 0.006447027,
+ -0.0037898065,
+ -0.026833571,
+ -0.015266453,
+ -0.016526371,
+ 0.008450833,
+ -0.017893516,
+ 0.05213916,
+ 0.028334752,
+ -0.011593926,
+ 0.013651345,
+ -0.012625987,
+ 0.014435443,
+ 0.017545028,
+ -0.01121193,
+ 0.0053513004,
+ -0.029782316,
+ 0.0065509034,
+ 0.01054176,
+ 0.009476191,
+ -0.006942952,
+ -0.008591568,
+ 0.0065408507,
+ 0.0022735489,
+ 0.021619657,
+ -0.012974475,
+ -0.00657771,
+ 0.048949152,
+ 5.470256E-4,
+ 0.04093393,
+ -0.0031397424,
+ -0.0051502497,
+ -9.1394316E-4,
+ 0.008229677,
+ 0.006624622,
+ -0.020869067,
+ -0.020949487,
+ -0.0040813303,
+ 0.014274603,
+ -0.01529326,
+ -0.0028063334,
+ 0.009476191,
+ -0.021177344,
+ -0.006296239,
+ -0.024930293,
+ 0.009020477,
+ 0.031792823,
+ 9.3321054E-4,
+ -0.0018077813,
+ -0.010836635,
+ -0.021351589,
+ 0.01565515,
+ 0.013966325,
+ 0.00293199,
+ 0.0045001856,
+ -0.026203614
+ ],
+ "content": "Somewhere in the Andes, they believe in this very day that the future is behind you. It comes up from behind your back, surprising and unforeseeable, while the past is always before your eyes, that which has already happened. When they talk about the past, the people of the Aymara tribe point in front of them. You walk forward facing the past, and you turn back toward the future.\n― Georgi Gospodinov, Time Shelter",
+ "id": "2",
+ "metadata": {}
+}, {
+ "embedding": [
+ -0.038519744,
+ -0.03163127,
+ 0.021691099,
+ -0.031327367,
+ -0.02894679,
+ 0.004219824,
+ -0.0066162283,
+ 0.013574348,
+ -0.014979901,
+ -0.03753206,
+ -0.024223628,
+ 0.04031784,
+ 0.0023789932,
+ 0.0030548614,
+ -0.0130171925,
+ 0.020981992,
+ 0.02659154,
+ -5.919783E-4,
+ 0.009477985,
+ -0.010408688,
+ -0.0010913612,
+ 0.017651718,
+ -0.0076925526,
+ -0.0104720015,
+ 0.0011997849,
+ 0.011263417,
+ 0.019842355,
+ -0.016815983,
+ 0.01584096,
+ -0.007857167,
+ -0.031479318,
+ -0.02793378,
+ -0.022298906,
+ 0.008192727,
+ -0.005505082,
+ -0.020386847,
+ -0.010972176,
+ -0.0040457128,
+ -0.0048307963,
+ -0.004241984,
+ -0.004014056,
+ 0.018778693,
+ -0.01530913,
+ 0.0038652704,
+ -0.02879484,
+ 0.0015567131,
+ 0.0112824105,
+ -0.022678785,
+ 0.008597932,
+ 0.03727881,
+ 0.013574348,
+ 0.007831842,
+ -0.030111754,
+ 0.008059769,
+ 0.0017711865,
+ -0.005489254,
+ 0.0013936816,
+ -0.005910286,
+ 0.028338984,
+ -0.014486058,
+ -0.015638359,
+ -0.005644371,
+ -0.011541994,
+ 0.0046820105,
+ -0.008857516,
+ -0.02692077,
+ -0.013435059,
+ -0.004852956,
+ -0.005957771,
+ 0.012934885,
+ 0.027098047,
+ 0.044319235,
+ 0.018310174,
+ 0.014131504,
+ 0.006609897,
+ 0.0054987506,
+ 0.0052581606,
+ -0.026034385,
+ -0.0039475774,
+ 0.0040330505,
+ 0.0067745117,
+ -0.006546584,
+ -0.006901138,
+ -4.8790727E-4,
+ 8.396912E-4,
+ -0.007521607,
+ -0.004311628,
+ 0.02193169,
+ -0.03340404,
+ -0.01099117,
+ -0.012991867,
+ 0.012301753,
+ 0.019285198,
+ 0.0069707823,
+ -0.010585966,
+ 0.0014348351,
+ 0.026895443,
+ 0.012137138,
+ -0.010877206,
+ -0.05184084,
+ -0.014739311,
+ 0.0015052711,
+ -0.02476812,
+ -0.01415683,
+ -0.015689008,
+ 0.0038905956,
+ 0.01800627,
+ -0.0022286244,
+ -0.030365007,
+ -0.024008362,
+ 7.701456E-5,
+ 2.5008712E-4,
+ 0.018246861,
+ -0.06371839,
+ 0.02077939,
+ 0.004593372,
+ -0.006166705,
+ -0.014118842,
+ 0.016676694,
+ -0.020247558,
+ 0.008692902,
+ 0.021868376,
+ 0.02217228,
+ -0.006305994,
+ -0.02093134,
+ -0.014524046,
+ -0.05515845,
+ -0.0062173554,
+ 0.0012219446,
+ -2.9598916E-4,
+ 0.021273233,
+ 0.03239103,
+ 0.013751625,
+ 0.0072556916,
+ -0.011111465,
+ 0.056272764,
+ -0.03201115,
+ 7.8824925E-4,
+ -0.023983037,
+ -0.029503947,
+ 0.014346769,
+ 0.013802276,
+ -0.0027098046,
+ -0.018614078,
+ -4.257812E-4,
+ 0.045458872,
+ 0.013574348,
+ 0.025375927,
+ 0.0170819,
+ 0.007743203,
+ 0.015030552,
+ -0.01790497,
+ 0.0049700853,
+ -0.00264016,
+ 0.025933083,
+ 0.03315079,
+ 0.03973536,
+ -0.012561337,
+ -0.017727694,
+ -0.012580331,
+ -0.009041124,
+ 9.876858E-4,
+ 0.01171294,
+ -7.5105275E-4,
+ -0.021703761,
+ 0.014562034,
+ 0.011750928,
+ -0.014726648,
+ 0.0026164176,
+ -0.016132202,
+ -0.020209571,
+ -0.010326382,
+ -0.01929786,
+ 0.028541587,
+ -0.01396689,
+ 0.024299603,
+ 0.0110164955,
+ 0.01444807,
+ -0.02659154,
+ -0.021032643,
+ -0.017246513,
+ 5.7496293E-4,
+ 0.011105134,
+ 0.015802972,
+ -0.0118269045,
+ 0.01271962,
+ 0.025122674,
+ -0.0035265447,
+ 0.011345724,
+ -0.018310174,
+ 0.010864544,
+ 1.3790405E-4,
+ 0.009439996,
+ -6.6162285E-4,
+ -0.6390074,
+ -3.7770276E-4,
+ -0.011257085,
+ 0.00758492,
+ -0.037835963,
+ 0.011453357,
+ 0.01800627,
+ 0.019652415,
+ 0.007882493,
+ 0.00537529,
+ -0.007217704,
+ -0.0015725414,
+ -0.007445631,
+ -0.03662035,
+ 7.803351E-4,
+ -0.005884961,
+ -0.023286592,
+ 0.002359999,
+ -0.006014753,
+ 0.0012638896,
+ -0.025325276,
+ 0.023451205,
+ -0.019855017,
+ 0.016537406,
+ -0.013511035,
+ -0.0059134522,
+ 0.0044382545,
+ -0.032796234,
+ 0.022146955,
+ 0.03882365,
+ -0.024514867,
+ 0.026743492,
+ 0.0074646254,
+ 0.017107224,
+ 0.040089913,
+ -0.0056222114,
+ -0.0068124994,
+ 0.016550068,
+ 0.034442376,
+ 0.031403344,
+ -0.014600022,
+ -0.017107224,
+ -0.0073316675,
+ -0.0119345365,
+ 0.01766438,
+ 0.0067998366,
+ 0.017398465,
+ 9.512807E-4,
+ 0.007990125,
+ -0.01147235,
+ 0.025084686,
+ 0.013852926,
+ -0.010611291,
+ -0.008009119,
+ 0.017942958,
+ 0.004890944,
+ -0.0035550357,
+ -0.00635981,
+ -0.007831842,
+ -0.004713667,
+ 0.027427275,
+ 0.0031450829,
+ -0.0049036066,
+ -0.00148786,
+ -0.028237684,
+ 0.030263705,
+ -0.016524743,
+ 0.028111057,
+ 0.014296118,
+ 0.009699581,
+ 0.0035043852,
+ 0.010155436,
+ 0.006125551,
+ -0.00854095,
+ 0.016170189,
+ -0.0016651369,
+ 0.036443073,
+ 0.0011515087,
+ -0.0067111985,
+ 0.022767423,
+ -0.022666123,
+ -0.016638707,
+ -0.01680332,
+ -0.01060496,
+ 0.020956667,
+ -0.01022508,
+ -0.0028316826,
+ -0.0051726876,
+ 4.8553303E-4,
+ 0.0012314416,
+ -0.010807562,
+ -0.0063914666,
+ -0.014093516,
+ -0.007224035,
+ -0.010756911,
+ 0.036595024,
+ 0.012605656,
+ -0.0022618638,
+ 0.035404738,
+ 0.009326033,
+ 0.004137517,
+ -0.0023315083,
+ 0.0320618,
+ 0.024983386,
+ -0.0153977685,
+ 0.02586977,
+ 0.0031134263,
+ 0.015195166,
+ 0.046167977,
+ -0.007939474,
+ 0.0205388,
+ 0.0010486247,
+ -0.03565799,
+ -0.00993384,
+ -0.003021622,
+ -0.01862674,
+ 0.02107063,
+ -0.029478623,
+ -0.0052486635,
+ -0.0050618895,
+ 0.015992912,
+ -7.4590853E-4,
+ 0.00797113,
+ -0.018981295,
+ -0.01439742,
+ 0.0048307963,
+ 0.011630633,
+ -0.017778344,
+ -0.011143122,
+ -7.261232E-5,
+ 0.01511919,
+ -0.010396026,
+ 0.037709337,
+ -0.009686918,
+ 0.015068539,
+ -0.006679542,
+ 0.026388938,
+ -0.022210268,
+ 2.5345062E-4,
+ -0.03753206,
+ -0.009807213,
+ -0.00379246,
+ -8.18323E-4,
+ 0.009794551,
+ 6.169079E-4,
+ -0.028009756,
+ 0.014486058,
+ -0.008756215,
+ -0.025426578,
+ 0.008908166,
+ -0.0014063442,
+ -0.020006968,
+ -0.0029614745,
+ 0.019019283,
+ -0.0152331535,
+ -0.002678148,
+ -0.015689008,
+ -0.016360128,
+ -0.009205738,
+ -0.009294377,
+ 0.009072781,
+ -5.310394E-4,
+ -0.019601764,
+ 0.006540253,
+ -0.0017775178,
+ -0.027376624,
+ -0.03806389,
+ 0.028744189,
+ -0.0034695629,
+ -0.025401251,
+ 0.0046535195,
+ 0.0016572227,
+ 0.0062933313,
+ 0.011276079,
+ -0.004147014,
+ 0.04654786,
+ -0.009053786,
+ -0.021387195,
+ -0.025261963,
+ -0.010478334,
+ 0.037759986,
+ -0.021032643,
+ -0.027807154,
+ 6.691413E-4,
+ 0.028111057,
+ -0.01516984,
+ 0.014473395,
+ -0.012396723,
+ -0.013359084,
+ 0.002193802,
+ -0.0010320051,
+ 0.03368262,
+ 0.00472633,
+ -0.026464913,
+ -0.008889172,
+ 0.0053341365,
+ -0.017942958,
+ -0.010547978,
+ 7.063378E-4,
+ 0.022463521,
+ 0.023096653,
+ -0.009161418,
+ -0.003599355,
+ 0.019462476,
+ 0.014384757,
+ 0.0038810987,
+ 0.00863592,
+ -0.038621046,
+ -0.024616169,
+ 0.012694295,
+ 0.014751974,
+ -0.034341075,
+ 0.002359999,
+ 0.0030327018,
+ -0.017639056,
+ 0.039861985,
+ 0.0037987914,
+ 0.014334107,
+ -0.032087125,
+ 0.0034347407,
+ -0.002901327,
+ -0.020906016,
+ 0.009370352,
+ 0.0059767654,
+ -0.01761373,
+ 8.1674015E-4,
+ -0.010326382,
+ 0.0011111465,
+ -3.4090196E-4,
+ -0.022830736,
+ -0.006166705,
+ -0.008471305,
+ -0.011250754,
+ 0.01003514,
+ -0.007040427,
+ 0.015625695,
+ 0.008161071,
+ 0.003115009,
+ 0.043686103,
+ -0.0076988842,
+ -0.022210268,
+ 0.023717122,
+ 0.016347466,
+ -0.0046725133,
+ -0.0037987914,
+ -0.015714334,
+ -0.0012187789,
+ 2.176391E-4,
+ -0.027959105,
+ 0.024059013,
+ 0.0089588165,
+ 0.031479318,
+ 0.0011412202,
+ -0.01914591,
+ -0.006489602,
+ -0.02236222,
+ 0.017436452,
+ 0.0022349556,
+ 0.015461082,
+ 0.021437846,
+ 0.0031925677,
+ -0.042445164,
+ -0.017195864,
+ 0.007559595,
+ 0.027756503,
+ -0.0054702596,
+ 0.0036183489,
+ 0.01219412,
+ 0.0049384288,
+ -0.0073949806,
+ -0.011586314,
+ 0.012390392,
+ 0.011991519,
+ -0.022856062,
+ 0.02015892,
+ -0.0067935055,
+ 0.00854095,
+ -0.015714334,
+ 0.005647537,
+ 0.012415716,
+ -0.02664219,
+ -0.03125139,
+ -0.0033999183,
+ 0.011466019,
+ -0.011174778,
+ 0.009680587,
+ 0.014979901,
+ -0.01560037,
+ 0.0052138413,
+ 0.019019283,
+ -0.0074139745,
+ 0.0144227445,
+ -0.008629588,
+ -0.0017331986,
+ -0.0048846127,
+ -0.013498372,
+ 0.020981992,
+ 0.0038431108,
+ -0.005571561,
+ -0.002128906,
+ 0.012751277,
+ 0.006844156,
+ -0.014903925,
+ 0.0065592467,
+ -0.0016160692,
+ 3.4268264E-4,
+ -0.021450508,
+ 0.010288393,
+ -0.0089018345,
+ 0.0046471884,
+ 0.03249233,
+ -0.005562064,
+ -0.008749883,
+ 0.008566274,
+ 5.674445E-4,
+ -0.0064199576,
+ 0.015258479,
+ 0.00767989,
+ 0.022007665,
+ 0.04014056,
+ 0.015701672,
+ -0.019348511,
+ -0.013954228,
+ -0.028541587,
+ 0.081901945,
+ 0.03801324,
+ -0.0042356523,
+ 0.0074393,
+ 0.014764636,
+ -0.0029947138,
+ 0.024692144,
+ -0.017550416,
+ 0.0062331837,
+ 0.016676694,
+ 0.0068061682,
+ -0.0072493604,
+ 0.03710153,
+ 0.012599325,
+ 0.030390332,
+ -0.009180413,
+ 0.0074013122,
+ -0.008521955,
+ 0.01766438,
+ 0.004286303,
+ 0.003097598,
+ -0.0024106498,
+ 0.009117099,
+ 0.03978601,
+ -0.020906016,
+ -0.0042103273,
+ 0.029073417,
+ 0.0064959335,
+ 0.017461779,
+ 0.009148756,
+ 0.006423123,
+ 0.003050113,
+ -0.007907817,
+ 0.023159966,
+ -0.0044414205,
+ -0.008129414,
+ -2.6571754E-4,
+ 0.030871512,
+ 0.011269748,
+ 0.003839945,
+ 0.0041881674,
+ -0.016512081,
+ -0.0060115876,
+ -0.02342588,
+ 0.002037102,
+ -0.0053404677,
+ 0.014840612,
+ 0.0049700853,
+ -0.016486755,
+ -0.024084337,
+ 0.021969678,
+ 0.0055209105,
+ -0.015853623,
+ 0.004406598,
+ 0.016955273,
+ -0.009161418,
+ 0.004074204,
+ -0.017930295,
+ -0.021425184,
+ -0.008477637,
+ -0.0029408978,
+ -0.035987217,
+ -0.0024217295,
+ 0.0013628164,
+ -0.0031324201,
+ -0.021057967,
+ -0.007217704,
+ 0.02096933,
+ 0.0022096303,
+ -0.025021372,
+ 0.0050903806,
+ -0.0075912517,
+ -0.009762894,
+ 0.00945266,
+ 0.021437846,
+ -0.016360128,
+ 0.0036784965,
+ -0.0028285168,
+ -0.014929251,
+ -0.0022634466,
+ -0.019373836,
+ -0.029073417,
+ 0.009591948,
+ -0.011915542,
+ 0.04766217,
+ 0.0109595135,
+ 0.005530407,
+ -0.021577135,
+ -0.016132202,
+ 0.03254298,
+ 0.012561337,
+ 0.0053404677,
+ 0.006296497,
+ -0.0071164025,
+ 0.0039475774,
+ -0.0049510915,
+ 6.4698164E-4,
+ 0.019424487,
+ 0.026363613,
+ -0.01732249,
+ 0.010972176,
+ 0.006546584,
+ -0.031504642,
+ -0.020361522,
+ -0.011947199,
+ -0.0012536012,
+ 0.007224035,
+ 0.0010557475,
+ -0.0023220114,
+ 0.0053531304,
+ 0.010459339,
+ -0.03570864,
+ -0.012991867,
+ 2.0480952E-6,
+ -0.016474092,
+ 0.019855017,
+ 0.033809245,
+ 0.011155784,
+ -1.381019E-4,
+ -0.020513473,
+ 0.005941943,
+ 0.00198012,
+ -0.0042894688,
+ 0.022526834,
+ -0.01214347,
+ 0.008585269,
+ 0.011864892,
+ -0.049358964,
+ -0.022970026,
+ -0.0019294695,
+ -0.007217704,
+ 0.0027952774,
+ -0.026768817,
+ -0.010775905,
+ -0.0028237684,
+ 0.045180295,
+ -9.932257E-4,
+ 0.001436418,
+ 0.02034886,
+ -0.020171583,
+ -0.006565578,
+ -0.01732249,
+ -0.024185639,
+ -0.028490936,
+ 0.006489602,
+ -0.02937732,
+ -0.010301056,
+ -0.020222234,
+ 0.00797113,
+ 0.02707272,
+ -0.02077939,
+ -0.01530913,
+ -0.020602113,
+ 0.01790497,
+ -0.0063376506,
+ -0.035936568,
+ 0.004644023,
+ 0.0036341771,
+ 0.0062806685,
+ 0.017487103,
+ 0.030314356,
+ 0.020386847,
+ 0.024983386,
+ 0.0021241575,
+ -0.004909938,
+ 0.007141728,
+ 0.0068188305,
+ 0.0076925526,
+ -0.0076229083,
+ 0.037304133,
+ 7.245403E-4,
+ 0.009655261,
+ -0.0058089853,
+ -0.020488149,
+ 0.014080854,
+ 0.004001394,
+ 5.575518E-4,
+ -0.014334107,
+ -0.018272188,
+ -0.021133943,
+ 0.0068124994,
+ 0.015473744,
+ -0.0046408568,
+ 0.033809245,
+ -0.04166008,
+ -0.026287638,
+ 0.03882365,
+ 0.0028411795,
+ -0.0043084626,
+ -0.014106179,
+ 0.029959802,
+ -0.01656273,
+ 0.023197953,
+ -8.396912E-4,
+ -0.015005226,
+ -0.0034094153,
+ -0.027325973,
+ -0.027376624,
+ -0.011263417,
+ -0.0139922155,
+ -8.6343364E-4,
+ 0.04502834,
+ -0.023907062,
+ -0.007958468,
+ -0.0038621046,
+ -0.0025182823,
+ -0.01622084,
+ 0.0076165767,
+ -0.015258479,
+ -0.009591948,
+ 0.010617622,
+ -0.0026005893,
+ -0.011485013,
+ -0.00489411,
+ 0.027959105,
+ 0.021729087,
+ -0.007882493,
+ 0.014979901,
+ -0.009693249,
+ -0.054449346,
+ 0.0021684768,
+ -0.006312325,
+ 0.012244771,
+ -3.359556E-4,
+ 0.03375859,
+ -0.0018677391,
+ -0.0046092,
+ -0.022805411,
+ 0.019272536,
+ -0.010680935,
+ -0.0041406825,
+ 0.026718168,
+ -0.006230018,
+ -0.0068884753,
+ -0.0120421685,
+ 0.01281459,
+ 0.0048846127,
+ -0.013650324,
+ -2.5345062E-4,
+ 0.037987914,
+ 0.02659154,
+ -0.004387604,
+ -0.017005922,
+ -0.042749066,
+ -0.009034792,
+ -0.008357341,
+ -0.019817028,
+ 0.013181807,
+ 0.006685873,
+ -0.04006459,
+ -0.014549372,
+ 0.010066797,
+ -0.016334804,
+ 0.028617563,
+ -3.0983894E-4,
+ -0.011371049,
+ -0.0023726618,
+ -0.017056573,
+ -7.3047593E-4,
+ 0.024793446,
+ -0.015777647,
+ 0.019741053,
+ -0.017487103,
+ 0.0018740705,
+ -0.0024296436,
+ -0.010661941,
+ -0.011491344,
+ -0.022121629,
+ -0.025350602,
+ 0.025173325,
+ -0.028769514,
+ -0.008705564,
+ 0.0029155724,
+ -0.009737569,
+ 0.008648582,
+ -0.0013105831,
+ -0.016347466,
+ -0.017221188,
+ -0.0044509172,
+ 0.008066101,
+ 1.4208371E-5,
+ 0.02385641,
+ -0.004090032,
+ 0.0025736813,
+ -0.012725951,
+ -0.018082248,
+ -0.014460733,
+ -0.020652764,
+ 0.0274526,
+ 3.8799114E-4,
+ -0.00272405,
+ -0.012700626,
+ -0.0016588056,
+ 0.024755457,
+ -0.0022935204,
+ 0.00431796,
+ -0.004906772,
+ 0.011947199,
+ 0.0011198521,
+ 0.024438892,
+ 0.014498721,
+ 0.013422397,
+ -0.007736872,
+ -0.012687963,
+ -0.020842703,
+ -0.0046250285,
+ 0.024565518,
+ -0.010845549,
+ -0.021957016,
+ -0.03163127,
+ -0.005869133,
+ 0.012403054,
+ -0.023717122,
+ 0.022666123,
+ 0.044369884,
+ 0.0016026151,
+ -0.017056573,
+ -0.010630284,
+ -0.004818134,
+ 0.036924254,
+ -9.409923E-4,
+ 0.012187789,
+ -0.01727184,
+ 0.00935769,
+ 0.004219824,
+ -0.015271142,
+ 0.0036183489,
+ 0.007274686,
+ -0.025819119,
+ -0.011041821,
+ -0.010047804,
+ 0.027756503,
+ 0.020981992,
+ 0.009383015,
+ -0.044040658,
+ -0.014751974,
+ -0.0047294954,
+ 0.021843052,
+ -0.009686918,
+ 0.011428031,
+ -0.008515624,
+ 0.00132562,
+ -0.011345724,
+ 0.010902531,
+ 0.03033968,
+ -0.022438195,
+ -0.0067175296,
+ 0.013118493,
+ -0.021995002,
+ -0.004995411,
+ -0.013270445,
+ 0.020703413,
+ -0.0010573303,
+ 0.011276079,
+ -0.036797628,
+ 0.022615472,
+ -0.035531364,
+ 0.019044608,
+ 0.025110012,
+ 0.029022766,
+ 0.045484196,
+ 0.007755866,
+ -0.022438195,
+ 0.01367565,
+ -0.01396689,
+ 0.0067301923,
+ -0.029731875,
+ 0.026161011,
+ -0.012700626,
+ -0.007502613,
+ 0.017563079,
+ -0.029630573,
+ 0.007496282,
+ 0.0075659263,
+ -5.057141E-4,
+ -0.0013667735,
+ -0.017601067,
+ 0.0020529302,
+ 0.012118145,
+ -0.02327393,
+ 0.002595841,
+ -2.9401062E-4,
+ 0.009136094,
+ 0.01976638,
+ -0.0155623825,
+ -0.050422624,
+ -0.006068569,
+ 0.0034632315,
+ -0.006704867,
+ -0.040723044,
+ -0.008388998,
+ -6.9921504E-4,
+ -0.015651021,
+ 6.746812E-4,
+ -0.009940171,
+ -0.005198013,
+ 0.0032004819,
+ -0.022425532,
+ 0.0067301923,
+ 0.0075912517,
+ 3.9254178E-4,
+ 0.02279275,
+ 0.020272885,
+ 0.014093516,
+ 0.0027683694,
+ -0.006989776,
+ 0.0068124994,
+ 0.010782236,
+ 0.021387195,
+ -0.010263069,
+ -1.318695E-4,
+ -0.007458294,
+ 0.013080506,
+ -0.026515564,
+ 0.013637661,
+ -0.03796259,
+ -0.025375927,
+ -0.014194817,
+ 0.017639056,
+ 0.0046883416,
+ -0.0053721243,
+ 0.029731875,
+ -0.018322837,
+ -0.015929598,
+ -0.0067555173,
+ -0.0035582012,
+ -0.008749883,
+ -0.02664219,
+ -0.0040995292,
+ 0.013156481,
+ 0.0074899504,
+ 0.007287348,
+ -0.0033176113,
+ 0.0075342697,
+ -0.013637661,
+ 0.027781827,
+ 0.2027035,
+ 0.0060400786,
+ 0.019285198,
+ 0.020526137,
+ 0.0047643175,
+ -0.0033904214,
+ 0.04084967,
+ 0.006489602,
+ -0.012751277,
+ 0.0031735736,
+ -0.014169492,
+ 0.021602461,
+ -0.010142773,
+ 0.013219794,
+ -0.009579286,
+ 0.008332016,
+ -0.03580994,
+ -0.012409385,
+ -0.0108962,
+ 0.020310871,
+ -0.009800882,
+ 0.0102694,
+ -0.007515276,
+ -0.013852926,
+ 0.02922537,
+ -1.5670015E-4,
+ -0.015372443,
+ 0.02831366,
+ 0.008566274,
+ 0.009433665,
+ 0.0013746877,
+ -0.018981295,
+ -0.0071733845,
+ 0.024869421,
+ -0.010402357,
+ -0.0024233123,
+ 0.0011056066,
+ -0.032264404,
+ -0.01367565,
+ 0.023755109,
+ 0.03071956,
+ 0.021235244,
+ -0.020994654,
+ 8.1120024E-4,
+ 0.008711895,
+ 0.02788313,
+ -0.0061793677,
+ 2.740274E-4,
+ -0.004719998,
+ 0.0065909033,
+ -0.016676694,
+ -0.022032991,
+ -0.01579031,
+ 0.0274526,
+ 0.005786826,
+ 0.003839945,
+ 0.010111117,
+ 0.01468866,
+ 0.01013011,
+ -0.0057393406,
+ -0.014840612,
+ 0.04573745,
+ -0.017069235,
+ 0.025274625,
+ -0.018208874,
+ 0.005941943,
+ -0.002893413,
+ -0.017132549,
+ -0.006533921,
+ -0.030922163,
+ 0.0018297512,
+ 0.0056507024,
+ -0.033707943,
+ -0.0014933998,
+ 0.01041502,
+ -0.017841658,
+ 0.01228909,
+ 0.03791194,
+ 0.031479318,
+ 0.020614775,
+ -0.01972839,
+ 0.008756215,
+ -0.0184368,
+ 0.008623256,
+ 0.0014617433,
+ -0.0128019275,
+ 0.015093865,
+ -0.00256735,
+ -0.014600022,
+ -0.014220143,
+ 0.007793854,
+ -6.632057E-4,
+ -0.010244074,
+ 0.009610943,
+ 0.008097758,
+ 0.013511035,
+ 0.0012900062,
+ 0.01790497,
+ -0.012004181,
+ -0.01900662,
+ -0.010813893,
+ 0.049738843,
+ 0.0011760425,
+ -0.001585204,
+ -0.006850487,
+ -0.0064769397,
+ -0.016436104,
+ 0.008338347,
+ 0.010794899,
+ -0.0021700596,
+ -0.0058153165,
+ 0.008237046,
+ 0.020184245,
+ -0.013359084,
+ -0.0038652704,
+ 0.015131853,
+ 0.024084337,
+ -0.011991519,
+ 0.0029820513,
+ -0.008895503,
+ -0.0064199576,
+ -0.030213054,
+ 0.03061826,
+ 9.853116E-4,
+ -0.012675301,
+ -0.04472444,
+ -0.011111465,
+ -0.018601416,
+ -0.0010335878,
+ -0.034062497,
+ 0.019475138,
+ -0.026692841,
+ 0.00396024,
+ 0.01766438,
+ 0.004615532,
+ 0.02174175,
+ 0.028820165,
+ -0.0071797157,
+ -0.008452311,
+ 0.008325685,
+ -0.016081551,
+ -0.008895503,
+ 0.027199347,
+ -0.016626043,
+ -0.0206401,
+ -0.017715031,
+ -0.006154042,
+ -0.0054512657,
+ -0.023197953,
+ 0.012510686,
+ -0.0058912924,
+ 0.008781539,
+ -8.6264225E-4,
+ -0.0115546575,
+ -0.020196907,
+ -0.015195166,
+ -0.019259872,
+ -0.00767989,
+ 0.02702207,
+ 0.008452311,
+ -0.020728739,
+ 0.0132324565,
+ 0.013346421,
+ -0.0044952366,
+ -0.001054956,
+ -0.006302828,
+ -0.156105,
+ 0.012130807,
+ 0.010731586,
+ 0.0051948475,
+ 0.019323185,
+ 0.030972812,
+ 0.0019642918,
+ 4.4200523E-4,
+ -0.015802972,
+ 0.005736175,
+ -0.0062711714,
+ 0.0018186715,
+ -0.012649976,
+ -0.0034758942,
+ -0.003580361,
+ -0.017411128,
+ -0.033631966,
+ 0.0065149274,
+ 0.007743203,
+ 0.008971479,
+ 0.021349208,
+ 0.007262023,
+ -0.014600022,
+ -0.015878947,
+ 0.027604552,
+ 0.04915636,
+ 0.0033049486,
+ 0.03340404,
+ 0.011731935,
+ -0.019779041,
+ -0.0411789,
+ -0.004270475,
+ 0.031276718,
+ 0.004659851,
+ -0.0016999592,
+ -0.0014562034,
+ -0.0026733994,
+ -0.023641145,
+ -0.0061635394,
+ -0.01238406,
+ 0.025299951,
+ 0.0010755329,
+ 0.010016147,
+ -0.019829692,
+ 8.4127404E-4,
+ 0.03142867,
+ -8.4443967E-4,
+ -0.01007946,
+ -0.009161418,
+ -0.012523349,
+ 0.017094562,
+ 0.0012076991,
+ 0.009623605,
+ 0.010661941,
+ 0.009959165,
+ 0.022564821,
+ 0.021805063,
+ 0.007641902,
+ 0.016967935,
+ -0.026338287,
+ -0.02922537,
+ -0.010016147,
+ 0.015144516,
+ -0.004241984,
+ 0.006014753,
+ -0.03142867,
+ 6.9842365E-4,
+ 0.011529332,
+ -0.015537057,
+ -0.0014467065,
+ -0.012200452,
+ -0.017259177,
+ 0.010307387,
+ -0.010123779,
+ -0.00758492,
+ 0.01871538,
+ -0.031276718,
+ 0.012548675,
+ 0.006964451,
+ -0.014600022,
+ -0.010490996,
+ 0.040039264,
+ -8.515624E-4,
+ -0.013587011,
+ -0.014017541,
+ 0.012510686,
+ 9.030044E-4,
+ 0.026844794,
+ -0.016853971,
+ -0.0045490526,
+ 0.009636268,
+ -2.0003012E-4,
+ -0.012460036,
+ -8.9983875E-4,
+ 6.8022107E-4,
+ 0.0025784296,
+ 0.0054006153,
+ 0.018652067,
+ -0.011434362,
+ -0.008559943,
+ 0.0014047615,
+ 0.0034569001,
+ -0.018778693,
+ 0.004837128,
+ 0.02788313,
+ 0.011883886,
+ -0.022058316,
+ 0.02836431,
+ 0.030390332,
+ 0.0047738147,
+ -0.016714683,
+ -0.0069517884,
+ 0.031074114,
+ 0.0026987249,
+ -0.01819621,
+ 0.022260917,
+ 0.030972812,
+ -0.004995411,
+ 0.0129095595,
+ 0.0057266783,
+ 0.019107921,
+ -0.0038146197,
+ -0.0021779737,
+ 0.027401948,
+ -0.017449116,
+ -0.02318529,
+ -0.11112731,
+ -0.012105482,
+ 0.010668273,
+ 0.013169143,
+ 0.042546466,
+ 0.043027643,
+ 0.0068884753,
+ -0.0011894966,
+ -0.016486755,
+ 0.02270411,
+ -0.038038567,
+ -0.0044604144,
+ 0.0058374763,
+ -0.004118523,
+ 0.04991612,
+ -0.013903577,
+ 0.01881668,
+ -0.024730133,
+ -0.033176113,
+ 0.036822952,
+ -0.032644283,
+ -0.018601416,
+ -0.029174719,
+ -0.023894398,
+ 6.351104E-4,
+ 0.023780435,
+ -0.022045653,
+ 0.007857167,
+ 0.008332016,
+ -0.013409734,
+ -0.0120421685,
+ -0.017309826,
+ 0.017119886,
+ -0.022691447,
+ -0.001041502,
+ -0.01013011,
+ -0.03307481,
+ -0.01627149,
+ 0.028237684,
+ -0.052727226,
+ 0.0011863309,
+ 0.013270445,
+ 0.0021890537,
+ -0.028870815,
+ 0.022729436,
+ -0.0071860473,
+ -0.009148756,
+ 0.039558083,
+ -0.021691099,
+ 0.02217228,
+ -0.0065845717,
+ -0.0020782554,
+ -0.02414765,
+ -0.005356296,
+ 0.023121977,
+ 0.0076862215,
+ 0.012352403,
+ 8.2702853E-4,
+ -0.029174719,
+ 0.009060117,
+ 0.0064547798,
+ 0.031276718,
+ -0.022083642,
+ -0.008623256,
+ -0.023539845,
+ 0.002111495,
+ -0.008002788,
+ -0.0045712125,
+ 0.014524046,
+ -0.04771282,
+ -0.018107573,
+ 0.04036849,
+ -0.02007028,
+ 0.0022903546,
+ -0.024337592,
+ 0.014650673,
+ -0.05318308,
+ 0.009889521,
+ 0.030289032,
+ 0.007888824,
+ -0.01214347,
+ -0.010028809,
+ -0.009591948,
+ 0.0014862772,
+ 0.012219446,
+ 0.028642887,
+ 0.013764287,
+ -0.006926463,
+ -0.0116622895,
+ -0.030162403,
+ 0.019791704,
+ 0.04566147,
+ 0.049789492,
+ -0.0153977685,
+ -0.009693249,
+ 0.026946094,
+ 0.0125296805,
+ 0.006353479,
+ 0.020171583,
+ 6.9881935E-4,
+ -0.015435756,
+ -0.016296815,
+ -0.047966074,
+ 0.028718863,
+ -0.0024518033,
+ 0.022374881,
+ -0.005644371,
+ 0.021450508,
+ 0.008338347,
+ -0.006033747,
+ -0.022678785,
+ -0.0022666121,
+ -0.04391403,
+ 0.015334455,
+ -0.008053438,
+ 0.017056573,
+ -0.019563776,
+ -0.034239773,
+ 0.021222582,
+ 0.022184942,
+ 0.012099151,
+ 0.009155087,
+ 0.0070974086,
+ -0.0042546466,
+ 0.017385803,
+ 0.035354085,
+ 0.0028902472,
+ -0.018500114,
+ 0.0058533046,
+ 0.0057804943,
+ -0.014118842,
+ -0.021222582,
+ 0.010199755,
+ -0.0067111985,
+ 0.008382667,
+ 0.004241984,
+ 0.002296686,
+ -0.012789264,
+ -0.0027873632,
+ 0.02922537,
+ 0.028642887,
+ 0.03983666,
+ -0.018740704,
+ -0.010370701,
+ -0.0050333985,
+ -0.037380107,
+ -0.023907062,
+ -0.01516984,
+ 9.829373E-4,
+ -0.010028809,
+ 0.003040616,
+ -0.0118775545,
+ 0.06042611,
+ 0.006268006,
+ -0.01050999,
+ -0.024324927,
+ 0.0042388183,
+ -0.010972176,
+ -0.0058722985,
+ 0.00520751,
+ -0.015764985,
+ -0.013384408,
+ 4.681219E-4,
+ -0.0071037402,
+ 0.026287638,
+ -0.011206435,
+ 0.02007028,
+ -0.012776602,
+ -0.007224035,
+ -0.043686103,
+ 0.011244423,
+ -0.011985187,
+ 0.004789643,
+ -0.007217704,
+ 0.032517657,
+ 0.0077052154,
+ 0.0056380397,
+ 0.004454083,
+ -0.018424138,
+ -0.015435756,
+ -0.0119345365,
+ 0.013561686,
+ 0.017715031,
+ 0.022894049,
+ -0.043990005,
+ 0.03641775,
+ 0.045610823,
+ 0.008762546,
+ -0.03168192,
+ 0.0076039145,
+ -0.036746975,
+ -0.0045997035,
+ -0.0012076991,
+ 0.01425813,
+ 0.0016287318,
+ 0.004751655,
+ 0.0026923935,
+ 0.014511383,
+ -0.015866285,
+ 0.0047231643,
+ 0.02193169,
+ 0.0021827223,
+ 0.015537057,
+ 0.002779449,
+ -3.3674703E-4,
+ -0.043230247,
+ -0.015321792,
+ 0.01641078,
+ -0.022400208,
+ -0.021564472,
+ -0.0052581606,
+ 0.0058153165,
+ -6.968408E-4,
+ 0.002910824,
+ -0.029200044,
+ 0.006451614,
+ -0.012054832,
+ 0.008787871,
+ -0.010142773,
+ -0.013346421,
+ -0.019791704,
+ 0.008376335,
+ 0.0019310523,
+ 0.025844445,
+ -0.011225428,
+ -0.009098105,
+ 0.027579226,
+ -0.030137079,
+ 0.0152331535,
+ -0.008882841,
+ -6.1952946E-6,
+ 0.0014941914,
+ -0.013549023,
+ 0.0044794083,
+ 0.0042546466,
+ -0.019272536,
+ 2.8728362E-4,
+ -0.026566215,
+ 0.015081202,
+ 0.03393587,
+ 0.017968284,
+ 0.01637279,
+ 0.028845489,
+ 0.0024486377,
+ -5.785243E-4,
+ 0.004020388,
+ 0.029782524,
+ -0.010180761,
+ 0.014764636,
+ 0.0023220114,
+ 0.0056918557,
+ 0.036215145,
+ -0.0137263,
+ 0.0053246394,
+ -0.03168192,
+ -0.004137517,
+ 0.028009756,
+ 0.0043654446,
+ 0.0023552508,
+ -0.0067745117,
+ 0.031605944,
+ 0.021374533,
+ -0.010579634,
+ 0.018411476,
+ -0.0031308373,
+ -0.010440345,
+ -0.011478681,
+ 0.0070277643,
+ -0.0033714275,
+ -0.020234896,
+ -0.037759986,
+ -0.008059769,
+ -0.008287697,
+ -0.013954228,
+ -0.021615123,
+ 0.01804426,
+ 0.0017126218,
+ 0.015245817,
+ -0.01852544,
+ 0.011130459,
+ -0.028389635,
+ -0.030466307,
+ 0.020386847,
+ -0.014992564,
+ -0.039380804,
+ 0.007736872,
+ 0.0064326203,
+ 0.011548326,
+ -0.010522652,
+ -0.0045332243
+ ],
+ "content": "The Great Depression (1929–1939) was an economic shock that affected most countries across the world. It was a period of economic depression that became evident after a major fall in stock prices in the United States.[1] The economic contagion began around September 1929 and led to the Wall Street stock market crash of October 24 (Black Thursday). It was the longest, deepest, and most widespread depression of the 20th century.[2]\nBetween 1929 and 1932, worldwide gross domestic product (GDP) fell by an estimated 15%. By comparison, worldwide GDP fell by less than 1% from 2008 to 2009 during the Great Recession.[3] Some economies started to recover by the mid-1930s. However, in many countries,[specify] the negative effects of the Great Depression lasted until the beginning of World War II. Devastating effects were seen in both rich and poor countries with falling personal income, prices, tax revenues, and profits. International trade fell by more than 50%, unemployment in the U.S. rose to 23% and in some countries rose as high as 33%.[4]\nCities around the world were hit hard, especially those dependent on heavy industry. Construction was virtually halted in many countries. Farming communities and rural areas suffered as crop prices fell by about 60%.[5][6][7] Faced with plummeting demand and few job alternatives, areas dependent on primary sector industries suffered the most.[8]\nEconomic historians usually consider the catalyst of the Great Depression to be the sudden devastating collapse of U.S. stock market prices, starting on October 24, 1929. However, some dispute this conclusion, seeing the stock crash less than a cause of the Depression and more as a symptom of the rising nervousness of investors partly due to gradual price declines caused by falling sales of consumer goods (as a result of overproduction because of new production techniques, falling exports and income inequality, among other factors) that had already been underway as part of a gradual Depression",
+ "id": "3",
+ "metadata": {
+ "meta2": "meta2"
+ }
+}
+]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/greatDepressionEmbeddingValues.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/greatDepressionEmbeddingValues.json
new file mode 100644
index 00000000000..b428478c5b7
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/greatDepressionEmbeddingValues.json
@@ -0,0 +1 @@
+[-0.034526568,-0.029992511,0.025028503,-0.024650665,-0.029992511,0.014305725,-0.008162602,3.3182962E-4,-0.01123742,-0.033484254,0.0066349637,0.023074169,0.008807532,0.010279796,-0.022149118,0.013432789,0.021823395,-0.023751672,0.010566432,-0.022097003,-0.012611968,0.019582426,0.0028614707,-0.015804047,0.002859842,-0.015517412,0.0041822745,-0.030982707,0.010644605,0.001845217,-0.013081009,-0.029966453,-0.010266768,-0.037366863,-0.0040585003,-0.020377189,-0.0032230224,0.0033419111,0.0051594414,-0.008781474,-0.018774634,0.008703301,-0.0018566173,-0.008006255,-0.029914338,-6.6610216E-4,5.3744185E-5,-0.013256898,-0.007778249,0.026735289,0.03001857,0.01624703,-0.015308949,-0.002218169,-7.964929E-5,0.00829289,-0.006361357,0.0025438913,-0.0034168272,-0.0017328428,0.010266768,0.0064916457,-0.019204589,0.005833687,-0.012077784,-0.010084363,-0.005765285,-0.006846683,7.0763176E-4,7.5323286E-4,0.03708023,0.03681965,0.0144620715,0.017028764,0.009165826,0.0068271398,0.011686916,-0.021171952,-0.0131656965,0.016963618,0.019347906,-0.0065861056,-0.014761736,-0.01135468,6.3678715E-4,-0.009849843,-0.018331653,0.038226772,-0.022787534,-0.012618483,-0.008351521,0.0014844795,0.014644476,0.02247484,9.1365114E-4,-0.008488324,0.016572751,0.027595196,0.014657505,-0.05250644,-0.011745547,0.020442333,-0.0078824805,-0.008345006,-0.011100616,-0.008279862,0.010240709,-0.010631576,-7.2147493E-4,-0.027517023,0.007758706,-0.0036415756,0.008006255,-0.05508616,0.03283281,-0.008833589,-0.009165826,-0.009914988,0.011804177,-0.02908049,0.024285857,0.013576106,0.03483926,-0.022044886,-0.013615193,-0.008045342,-0.03132146,-0.011081073,1.20924415E-4,0.016650924,0.022435753,0.0451842,0.0144620715,-0.026787404,-0.024767926,0.032389827,-0.034917433,0.00841015,-0.019139444,-0.022683302,-0.0055242507,0.019530311,-0.012898604,-0.016859388,-0.008957364,0.024976388,-2.862285E-4,0.017198138,0.010318883,-0.019386992,0.019152472,-0.0039510117,0.019543339,9.535521E-4,0.017146023,0.020312045,0.022227291,-4.0817077E-4,-0.0010097392,-0.017159052,4.323964E-4,-0.0061789523,0.0011318851,-0.0043093064,-0.0010879126,0.016455492,-8.843361E-4,0.0037230062,0.0042669624,-0.012273218,-0.0074785845,8.998079E-4,-0.029054431,0.030982707,-0.005944432,0.021588875,-3.035325E-4,0.02541937,-0.02178431,-0.01964757,-0.026526826,0.0020797371,0.0061789523,0.010618548,-0.004306049,0.0115175415,0.0069704577,0.0119540095,0.016546695,-0.020846229,0.014084233,-0.0011375853,0.012820431,-9.0143655E-4,-0.68125474,-0.020624738,-0.024077395,0.010690207,-0.03001857,0.02082017,0.011302564,0.021471616,-0.010970328,-0.017119965,0.007674018,-0.001211687,-0.012084298,-0.027986063,0.01289209,-0.010201623,0.003283281,-0.0021611676,0.017589005,0.011406796,-0.019712714,0.021940656,-0.014996256,0.008807532,0.009660924,0.008110486,-0.0051854993,-0.02471581,0.0020536792,0.0055242507,-0.022305464,0.017237226,0.006905313,0.0065991343,0.060401946,0.014084233,-0.0034656855,0.025197878,0.033249736,0.044167947,-0.0085730115,-0.0041757603,0.0016294259,-0.002771897,0.019751802,-0.0012149443,0.0135370195,-0.013980002,0.029002316,0.0063548423,0.018579202,0.012872546,-0.016703041,0.011146218,0.03754927,0.0020080782,0.004130159,0.0035536306,0.01563467,0.011484969,0.013172211,0.023373833,-0.008286376,-0.014253609,-0.020481419,0.019856032,-0.019790888,0.013758511,0.01494414,0.0025943783,0.015400152,0.0013468618,0.006638221,-0.012611968,0.022696331,0.004022671,0.036142148,-0.0019608485,-0.0059314035,0.01377154,-0.021393443,-0.022500899,-0.028194524,0.010156022,0.025054561,-0.026578942,-0.009608809,-0.006990001,-0.007830365,0.008234261,-0.009771669,0.004071529,-0.0051692133,0.004788118,-0.01242305,0.025562689,0.0037230062,0.002716524,0.021106806,0.0022149119,0.005843458,-0.0022881993,-0.0060910075,0.005608938,0.00242826,0.0092114275,0.008468781,0.02694375,0.039946586,-0.013393702,0.009693496,0.007836879,-0.032858867,-0.01741963,0.0024966616,-0.033718776,0.023556238,-0.015908279,0.0035796883,-0.008625127,0.013576106,-0.008520896,0.02931501,-0.008944335,-0.015113516,-0.008546954,0.009960589,-0.016103711,-0.0053223027,-0.012918147,0.006419987,0.006957429,0.041249476,0.004302792,0.010384028,0.002289828,0.008625127,-0.018214392,0.015035342,-0.020963488,-0.007367839,0.009472005,-0.0037555783,0.019856032,0.0054037333,-0.037627444,0.015843134,-0.0132503845,-0.01695059,0.004713202,0.0022230549,-0.013667309,-0.028090293,0.008481809,-0.017849583,-0.019204589,0.0032555945,-0.02319143,0.0036448329,-0.017041791,0.0063743857,0.0025422627,-0.017002705,1.5268233E-4,-0.01529592,-0.023217486,-0.0021758252,0.036168206,-0.015282892,-0.00911371,0.008670729,0.0035178012,0.01775838,0.014032118,0.0054395627,0.044402465,-0.0055568228,-0.019764831,0.014605389,-0.002151396,0.030774245,-0.02341292,-0.0024136023,0.004038957,0.013484905,-0.025445428,0.016494578,0.008638156,-0.018670404,0.007615388,-0.014657505,0.030617898,0.008345006,-0.020650795,0.004729488,0.019751802,-0.02108075,0.0054623634,0.028064236,0.009367774,0.03025309,-0.01730237,0.017589005,0.016794244,0.04083255,-0.0074329833,-0.0057164268,-0.03731475,6.8360975E-4,0.014683562,0.010090877,-0.017432658,-0.0131656965,-0.0048109186,0.0026139216,0.02471581,-0.005283216,0.008032313,-0.018787663,0.00179473,-0.01435784,-0.00887919,0.0024608322,-0.014527216,-0.020442333,0.012286246,0.0070551457,-9.0713665E-4,0.020507477,-0.013445818,-0.008950849,0.00936126,-0.0014918082,0.010866096,-0.009680468,0.013094038,0.014019089,-0.02152373,0.03543859,-0.009673953,-0.0133676445,0.00729618,0.011862807,0.008494838,-0.0037881506,-0.0147487065,0.0070095444,0.007862937,-0.032989156,0.012735743,0.0118367495,0.02954953,-0.013185239,0.0047099446,-0.0024754896,-0.024898214,0.020207813,-9.2993723E-4,0.015035342,0.040910725,0.0042246184,-0.024351,-0.010638091,0.004478682,0.029028373,-0.008605584,0.002939644,0.027725484,-0.008123515,0.0039770696,-2.9620374E-4,-0.0031187912,0.017549919,-0.04015505,0.008911762,-0.010501288,0.0014217779,-0.0032637378,9.421518E-4,-0.010657635,0.0046936586,-0.011927951,0.020768056,4.3158207E-4,-0.010781409,-0.006905313,0.008507867,-0.01141331,0.0038109513,0.022904793,0.0052701873,0.029862223,-7.699261E-4,9.47852E-4,-0.010559917,-0.009498063,0.016976647,-0.0058564874,-0.0046480577,0.001184815,0.0072180065,-0.0054363054,0.0031888215,-0.0010740694,0.017276311,-0.005064982,-0.009374289,-0.01765415,-0.024937302,-0.0021285955,0.019738773,-0.004319078,0.006963943,0.0070290877,-0.004556855,-0.012338362,0.0014624932,0.00278004,0.021458587,0.022188205,0.0035634022,-0.013067979,-0.029731933,-0.013667309,0.090003595,0.030227032,-0.003094362,0.01636429,0.012429564,0.010970328,0.008931306,-0.04062409,0.0029021858,0.019816946,0.011543599,-0.031139053,0.026552884,0.018748578,0.010110421,0.008833589,3.4607996E-4,-0.027047982,0.023282632,-0.016064625,-0.0019673628,-0.0010911698,0.011204848,0.028898085,-0.015791018,-0.0028565847,0.015348036,0.004201818,0.022396667,0.0046773725,0.0070095444,0.011152732,-0.020702912,0.031373575,0.014227551,-0.005765285,0.002775154,0.024155568,0.038617637,-0.010931241,0.02130224,-0.013680338,7.593402E-4,-0.025862353,0.009217942,-0.009739097,-0.0031985932,0.019595455,-0.0277776,-0.0120061245,0.029731933,0.0034103128,-0.007875966,-0.009765156,0.020442333,0.008625127,0.0070290877,-0.009667438,-0.01728934,-0.022162147,-0.015686788,-0.026148988,0.0020797371,-0.009081138,-0.013745482,-0.029914338,-0.004361422,0.019217618,-0.033327907,-0.015986452,0.010208137,0.0011383995,-0.013191754,0.012885575,0.0073873824,-0.018852808,-7.9476245E-4,-0.010853068,-0.002420117,0.007517671,-0.0080518555,-0.024155568,0.019269733,-0.013315529,0.017849583,0.012084298,0.004654572,-0.029002316,-0.013628222,0.030617898,-0.0026236933,-0.0032099935,0.025367254,-0.029262893,-0.0052897306,-0.01919156,3.9066322E-4,0.022305464,-0.008403636,-1.8291344E-4,0.026683172,0.0020422789,-0.022422725,-0.010970328,-0.017628092,-0.010090877,0.0077977926,0.020338101,-0.017966844,-0.0069444,0.014331782,-0.03546465,-0.010872611,0.0037002056,0.0019771345,0.020012379,0.025458457,0.0071007465,-0.013732453,-0.017002705,-0.0010032248,-0.020768056,0.022904793,0.02247484,-0.0070551457,6.025863E-4,0.011478455,-0.054095965,-0.017250255,-0.006038892,-0.02790789,0.023491094,-0.015074429,-0.012507738,-0.011126675,0.018566173,-0.008006255,-0.0061333515,0.025562689,-0.028298756,-0.0039607836,-0.007980197,-0.0011750433,-0.026409566,0.0015854534,-0.026214132,-0.014514186,-0.001065112,-9.4866625E-4,0.026865577,-0.020924402,-0.011009415,0.0020618222,0.026735289,-0.008651185,-0.03072213,0.0054558488,-1.798598E-4,-0.006696851,-0.0027914403,0.037601385,0.012598939,0.019517282,-0.010983356,-5.960718E-4,-0.0036090033,0.02437706,0.009641381,-0.011146218,0.03168627,0.013901829,0.026761346,0.012957234,-0.03504772,0.016755156,-0.0059770048,0.010846553,-0.013035407,-0.022982966,-0.02965376,0.017680207,0.010214652,-0.013152667,0.013836685,-0.017015735,-0.026070815,0.046174396,0.013602165,-0.02059868,-0.009354745,0.023829846,-0.010195109,0.03283281,0.023139313,-0.016989676,-0.002884271,-0.028272698,0.0019054756,-0.013719425,0.0062343255,0.014957169,0.011497998,-0.0054884213,-0.0065242182,-0.0051431553,0.005240872,-0.010253739,-0.014214522,-0.009048566,-0.025875382,-0.016429434,-0.027386732,-0.013758511,-0.03048761,0.020507477,0.0035568879,-0.015491353,0.01941305,-0.0032360512,-0.033249736,-0.007198463,-0.021575846,0.008507867,-0.007406926,0.028038178,-0.002071594,-0.013341586,-0.029367125,0.030800303,0.0016106969,-0.016650924,0.024872156,-0.008286376,0.0026644086,-0.013354615,0.012338362,0.0036741479,-0.015100487,-0.014501158,0.034318104,0.00532556,-0.0065405043,0.005081268,-0.036637247,-0.007341781,-0.0073743532,-0.025588745,-0.011159247,-0.011791148,-0.044454582,-0.010918212,0.012879061,-0.012195044,0.020533536,0.0020031922,-0.0117194895,0.010957299,-0.018618288,-0.0029298724,0.026995866,-0.021588875,0.024663694,-0.012768315,0.0049086353,-0.013836685,-0.0033353965,-0.012201558,-0.0017067849,-0.024767926,0.021627963,-0.009393832,-0.021823395,0.0065144463,-0.013550049,0.013615193,0.008703301,-0.007485099,-0.014253609,-0.013393702,-0.0077456767,-0.002382659,-0.0010585976,-0.009719554,-0.0019299048,-0.014970198,-0.020637766,-0.016611839,-0.029028373,0.008559982,-0.0034331132,-0.012279731,-0.017250255,0.0073873824,0.021119835,-0.020715939,-0.015165632,0.009869386,0.025823265,-0.006393929,0.021745222,0.021367384,0.01254031,-0.00700303,0.016390348,-0.017041791,-0.008592555,0.009732583,-0.027100097,-0.02670923,-0.030070685,0.014787793,0.0111136455,-0.01741963,0.026683172,0.028298756,0.012761801,-0.005748999,-0.0034396278,-0.0013509333,0.031946845,0.012514251,-0.0052473866,0.0031513635,0.005123612,-0.012722714,-0.0040063844,0.0133350715,0.007543729,-0.02212306,-0.015230776,-0.02035113,0.026305335,0.013550049,-0.008605584,-0.031008765,-5.240058E-4,0.013445818,0.019934205,0.008494838,0.009960589,-0.0059476895,0.009967103,0.0063385563,-0.0047327452,0.025732063,-0.026409566,-0.009165826,-8.9247915E-4,0.0027328103,-0.0051008114,-0.0032279082,0.019061271,1.3507297E-4,0.012703171,-0.021640992,0.031008765,-0.027855773,0.03825283,0.004188789,0.007947625,0.022969939,3.4261917E-4,-0.01788867,0.020650795,0.010599004,0.021849453,-0.005768542,0.013263413,-0.013224326,0.0118367495,0.005459106,-0.020025408,0.0072766365,0.002985245,0.0036969483,0.0097846985,-0.009843329,-0.009745612,0.012331847,-0.01589525,0.0037751216,-0.0028956714,5.708284E-4,0.010116936,0.004716459,-0.039738122,-0.018331653,0.018448912,-0.009908473,-0.023816817,-0.009146282,0.011986582,-0.00936126,-0.0033158532,-0.011569656,-0.015256833,-0.0030259604,-0.018579202,0.0033386538,0.026266249,9.169083E-4,0.029627703,0.0046513146,0.008709815,0.0045861704,-0.010970328,-0.0064753597,0.0050128666,0.019217618,-0.012957234,0.012318818,-0.010462201,0.0058988314,-0.019035213,0.019673629,-0.033327907,-0.006446045,-0.03272858,0.010892155,0.010755351,-0.0052278433,0.025132734,-0.0063743857,-0.020781085,-0.014318753,4.6659724E-4,0.010032248,-0.015217747,-0.006159409,0.023634411,-0.013563078,9.779813E-4,0.009973617,-4.7921896E-4,-0.014774765,0.030200973,0.19491224,-0.008299405,-4.3198923E-4,0.025145764,0.008208202,0.018774634,0.026031729,-0.0023224002,-0.023999222,0.017471746,-0.0044167945,-0.013875771,-0.0037458066,0.0070942324,-0.025432399,-0.0037979223,-0.030617898,-0.0077717346,-0.020976517,0.022448782,0.011263478,0.010566432,0.0067945677,-6.913456E-4,0.03262435,-0.018110162,-0.017602034,0.016312174,0.01648155,0.016546695,-0.0104166,-0.009634866,-0.014983227,0.011426339,-0.014032118,-0.005123612,-0.003732778,-0.03650696,-0.013204783,0.0220058,0.017041791,0.0027442107,-0.019465165,-0.00532556,0.0090941675,0.026109902,-0.0030715615,0.0059639756,-0.0033272535,0.013667309,-0.017836554,-0.015400152,0.0043093064,0.031503864,0.0017377286,0.03095665,0.007928082,0.006110551,0.0066903364,-0.0038304946,-0.009055081,0.041510053,-3.986027E-4,0.017901698,-0.016624868,0.0069834865,-0.012182015,0.0033712261,0.0220058,-0.033510312,0.010892155,0.0037295206,-0.02270936,-0.007934595,-0.00538419,-0.024390088,0.04541872,0.041405823,0.021940656,0.0078108213,-0.0152698625,-0.0056121955,-0.01566073,0.0086902715,-1.806741E-4,-0.027100097,0.035230126,0.0064851316,-0.020285986,-0.0022930852,0.008586041,-0.014553273,-0.00723755,-0.0020292501,5.854859E-4,0.025236966,-0.009139769,0.008729358,-0.008514382,-0.007139833,-0.017797468,0.0451842,0.009426404,0.013589135,-0.0043516504,-0.007426469,-0.011217876,0.0027784114,0.011986582,-0.01424058,-0.013693366,0.019400021,0.0153871225,-0.0012898603,-0.0130484365,0.015243805,0.019360935,0.0012752028,-0.00841015,-0.00994756,-0.006055178,-0.033953294,0.012572882,0.006595877,-0.020481419,-0.020755026,-0.01494414,-0.011680403,0.0061984956,-0.046200454,0.020194784,-0.026839519,0.008156087,-9.250514E-4,-0.012514251,0.028220583,0.018279538,-0.0021204522,-0.025810236,0.008130029,-0.006143123,-0.020038437,0.007856422,-0.016442463,-0.013133124,-0.0076088733,0.029028373,-0.011445883,-0.019947235,0.008247289,-0.017172081,-0.0033907695,-0.003928211,-0.01942608,-0.0138888,-0.0033549399,-0.03739292,-0.01494414,-0.0133676445,0.0065567903,-0.03236377,-0.0058011147,0.017901698,-0.026435623,0.004081301,-0.0055633374,-0.16697828,0.020546565,0.018149247,-0.0147487065,0.019308819,0.014839909,0.011875836,0.006305984,-0.009634866,0.008077914,0.006084493,0.0035178012,-0.030227032,0.01777141,0.010260253,-0.016768185,-0.007954139,-0.007791278,0.014839909,0.00912674,0.0196606,-0.0048695486,-0.026435623,-0.017641122,0.017745351,0.040102933,-0.003866324,0.034187816,0.009706525,-0.013862742,-0.025471486,0.009758641,0.007582816,0.01919156,0.007517671,0.007022573,-0.0025797207,-0.009217942,5.766303E-5,-0.0049086353,0.019908149,0.001224716,0.00794111,-0.011862807,0.002553663,0.04023322,0.01586919,0.0010561546,-0.007732648,0.004934693,0.0038011796,-0.012312304,7.336895E-4,0.0024592036,0.011947495,0.028298756,-6.01772E-4,-2.4490248E-4,6.111365E-4,-0.031112997,-0.009289601,-0.017953815,-0.0014975084,-0.0034363705,0.007615388,-0.028507218,-0.007367839,-0.011993096,-0.010045276,-0.0028647278,-0.013380673,-0.016546695,0.0045698844,-0.023100227,-0.012286246,0.014996256,-0.016924532,0.029810106,-0.009439433,-0.0017556433,-0.016142799,0.04484545,-0.0028321557,-0.014149378,-0.006260383,0.010644605,8.875933E-4,0.01053386,-0.021732192,-0.01847497,0.010787923,-0.016038567,-0.02414254,0.008305919,-0.016194914,0.018318623,-0.015100487,0.018188335,-0.011869322,0.004306049,-0.011680403,-0.0013248755,-0.0127292285,0.019751802,0.034422334,0.01129605,-0.013758511,-0.0029201007,0.024337972,0.010058305,-0.017562948,-0.0034037982,0.0058174008,0.008117001,-3.0231103E-4,0.014436013,0.009914988,0.004550341,0.004550341,0.004726231,0.034761086,-0.003144849,-0.025002446,0.013823655,0.0071268044,0.0030927334,-0.093808025,-0.013081009,3.0475395E-4,0.017093908,0.031139053,0.035829455,0.0020520505,0.020559592,-0.01964757,0.008716329,-0.024038307,-0.0148659665,-0.001866389,-0.020207813,0.05026547,-0.0021481388,-0.011497998,5.871145E-4,-0.032051075,0.02319143,-0.037158404,-0.0050291526,-0.018344682,-0.022904793,-0.008455751,0.01705482,-0.018644346,0.020937432,6.4004434E-4,-0.006276669,-0.010071334,0.0017963586,0.005836944,-0.016142799,-0.019386992,-0.010156022,-0.029914338,-0.0077977926,0.021614933,-0.032103192,0.0055405367,0.014331782,-0.0023435722,-0.041822746,0.013667309,-0.011667374,0.004113873,0.013797598,0.012214587,-0.008097457,-0.008546954,-0.001438064,-0.031477805,0.009973617,0.01265757,-0.008468781,0.032337714,-0.00899645,-0.014657505,0.008117001,0.013732453,0.013523991,-0.0049965805,0.0049868086,0.0053907046,-6.2375824E-4,-0.008312434,-0.011927951,-0.0034624282,-0.04591382,-0.018331653,0.029731933,-0.031086938,0.009354745,-0.016455492,0.009641381,-0.04990066,-0.0065730764,0.036090035,-0.0042669624,-0.021810366,-0.028350871,0.00620501,0.009517606,0.0085730115,0.034630798,0.00550145,-0.014527216,-0.01942608,-0.01482688,0.024220712,0.042057265,0.03728869,-0.011550114,-0.0039444976,0.022083974,0.011934466,-0.014644476,0.008455751,0.0019071042,-0.008234261,-0.013510962,-0.060818873,0.02458552,0.009602294,-0.004713202,0.0015593956,-0.0016823558,-0.016312174,-0.021002576,-0.010618548,0.008801017,-0.036559075,0.019530311,0.012077784,0.006419987,-0.028533276,-0.034526568,0.038331002,-0.0020097068,0.016546695,0.017901698,-0.004273477,-0.0117194895,0.026266249,0.008553469,0.006012834,-0.016416404,0.00550145,0.015009285,-0.009029022,-0.01718511,-0.0070421165,-0.017940786,-0.009204913,0.031816557,0.0013533762,-0.025380284,8.204131E-4,0.016781215,0.04015505,0.026461681,-0.010436143,-0.011074559,0.008038827,-0.015204718,-0.021145893,-0.009504577,0.0073613245,0.008872676,0.012670598,-0.006605649,0.019777859,0.012090812,0.0016725841,-5.720498E-4,-0.0040910724,-0.012025668,0.009654409,0.004315821,0.0062212963,-0.010344941,0.011641316,-0.005608938,0.0065893624,-0.016533665,0.013067979,-0.00688577,0.0080844285,-0.0066838223,6.3312276E-5,-0.0277776,0.004521026,-0.0017849583,0.022995995,-5.2359863E-4,0.0012108728,0.0047457744,-0.0067359377,-9.910102E-4,-0.021132864,0.0020943945,-0.012182015,0.023438979,-0.038669754,0.021940656,0.03791408,0.02788183,-0.01941305,-0.002750725,-0.01082701,0.0034265989,-0.0060030622,0.011439368,0.0018680175,0.010579461,-0.010227681,0.013993031,-0.015113516,0.00864467,0.010657635,0.0027181527,0.020702912,-0.010716264,-0.0074916133,-0.0132178115,-0.022644216,0.026292305,-0.012253674,-0.02764731,-0.0035666595,5.199343E-4,0.008481809,-1.19702956E-4,-0.024285857,0.009771669,-0.009726069,0.012638026,-0.014983227,-0.015335007,-0.024403116,0.017914727,-0.007908538,0.036194265,0.0024510606,-0.008429694,0.02342595,-0.006814111,0.0033875122,-0.032337714,-0.009908473,-0.0043679364,0.0040845578,9.95896E-4,-0.024507347,-0.006788053,0.017602034,-0.011654344,-0.0010447544,0.010279796,-0.0047099446,0.025223937,-0.004550341,0.0068792556,0.008149573,0.017458716,0.021875512,-0.0072896658,0.004729488,0.00556008,-8.3873497E-4,0.03788802,-0.013836685,-0.010970328,-0.02459855,-0.0045470838,0.0034103128,-0.0017409858,0.011015929,-0.0033679688,0.012735743,0.023204459,-0.0011424711,0.02696981,0.008677242,-0.011673888,-0.016846359,0.0144751,-0.0052864733,-0.012866031,-0.046148337,-0.010390542,-0.009458976,-0.018305594,-0.008071399,0.031582035,-0.009354745,-2.014389E-4,-0.029836165,0.0036643762,-0.017328428,-0.039920527,0.01822742,-0.015217747,-0.036142148,0.016064625,0.016181884,0.011380738,-0.008794502,-0.0012125013]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/searchDocuments.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/searchDocuments.json
new file mode 100644
index 00000000000..469b489368c
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/searchDocuments.json
@@ -0,0 +1 @@
+[{"content":"The World is Big and Salvation Lurks Around the Corner","id":"1","metadata":{"year":2020,"activationDate":1000,"country":"BG"},"embedding":[0.02364917,-0.018419946,0.0033172895,-0.0058730734,-0.028159376,0.018681405,-0.013752862,-0.006621506,-0.008360223,-0.0034186058,0.016472058,0.03461747,-0.013543692,0.0139228115,0.01588377,-0.0021260066,0.032473486,-0.0041997214,2.696319E-4,-0.013452181,-0.0130926715,0.005948243,-7.839752E-4,-0.0093603125,-0.003984016,-0.0037879199,0.004725912,-0.03299641,0.04567728,-0.01733488,-0.0074058897,-0.019008232,-0.019478863,-0.04099712,-0.011876877,-0.0037552372,3.6543293E-4,-0.015896844,0.008124908,-0.009281875,0.020446269,0.012184094,-9.5678476E-4,-0.015125533,-0.031872127,0.013478328,-0.0034349472,-0.023792973,-0.019688033,0.020929974,0.034172986,0.0053501506,-0.0043500615,-0.007680424,-0.019910274,0.0045330846,-0.012177558,-0.006111657,0.020289393,-0.013622131,0.0069875517,-0.0025574178,-0.011046737,0.012713553,-0.024420481,0.006647652,-7.2310376E-4,0.005807708,0.013844373,0.011386638,0.015949136,0.010425767,0.014550318,0.009785187,0.017517904,-0.020367831,-0.021112995,0.012537067,0.013243012,-0.006510385,0.011661172,-0.028917614,-0.0018808868,-4.457097E-4,0.021178361,0.011504294,-0.025296375,0.02313932,0.007249013,-0.013883593,0.018302288,0.0031669494,0.0059220972,0.01754405,-0.009124997,-0.014001249,-0.008778561,0.008765488,0.011804976,-0.05059275,-0.0069744787,0.0037487007,-0.012131802,-0.0041278196,0.0077980817,-0.012327897,-0.0031702176,0.005082153,0.019570375,4.9922755E-4,-5.719465E-4,0.023832193,-0.0073013054,-0.021818941,0.027191969,-0.009732895,-0.0077719353,0.0015981819,-0.0059220972,-0.028159376,0.011085956,0.02894376,0.003608165,-0.016877323,-0.0038336755,0.013197256,-0.029780436,-0.010785276,0.001071174,0.006598628,0.011778829,0.02928366,0.022995517,0.0036604574,-0.010870251,0.022943225,-0.008595538,0.007817691,-0.00433372,-0.0063273623,0.032212026,0.02574086,7.075795E-4,-0.013739789,0.009804796,-0.009928991,-1.4982955E-4,0.016171377,0.0131057445,-0.020014858,0.043637883,0.011916096,0.02915293,-0.009242655,0.014994803,-0.0075235474,-0.011576197,0.02954512,-0.005206347,-0.015857624,-0.008804708,-0.0013963665,0.014145053,-0.009255728,0.010719911,0.018027753,0.015360848,-0.011170932,-0.023583805,-0.005761952,-5.359955E-4,0.05584812,-0.013569838,0.028159376,-0.024106726,0.0019495204,-2.084796E-5,0.017923169,-0.013622131,0.0010229672,-0.014968656,-0.006003804,-0.0027731233,0.01993642,-0.003987284,-0.0028744396,0.0118507305,-0.013700569,0.016890397,-0.027688745,0.012086046,0.020433197,-0.0017452538,0.020393977,-0.684401,-0.021675138,-0.0049514226,-0.007137892,-7.0676244E-5,-0.013948957,0.02351844,0.028969906,4.991765E-5,-3.057871E-4,0.0030966816,0.008209883,-0.010203525,-0.015347775,-0.0077980817,-0.019818762,-0.01447188,-0.033284016,-4.391732E-4,-0.0077196434,-0.010706838,0.024015216,-0.0032797046,-0.010098941,0.022577178,-0.015295483,0.014537245,-0.028891468,-0.0045232796,-0.009072705,0.015256263,0.0032453877,6.287326E-4,0.01107942,0.0620709,-0.019779542,0.0019282767,-4.3876466E-4,0.028786883,0.02638144,-0.005167128,-0.001391464,0.03425142,-0.008497491,0.0014364027,0.014707195,0.04175536,-0.007680424,-0.005056007,0.0063371668,0.014445734,0.0048925937,-0.0019004964,0.01477256,0.020577,0.0130861355,0.01528241,0.0010809789,-0.008373297,-0.0022371279,-0.01946579,0.014903291,-0.014197346,0.01856375,-0.027819477,0.01236058,-0.0085105635,-0.0013367207,0.019505009,0.017714,0.018419946,0.0028973175,-0.005307663,-0.01767478,0.008039934,0.026629828,0.007739253,-0.017596342,-0.005810976,0.008575928,0.008798171,-0.024302823,-0.01305999,0.012765845,0.024172092,0.010889861,-0.011406247,-0.0114389295,0.013726715,0.01895594,-0.0027339042,0.02049856,-5.441662E-4,-0.0015156581,0.034120694,-0.0039807474,-0.016798886,0.024355115,0.031113889,-0.0110140545,0.012497848,-0.016210597,0.009438751,0.0028156107,0.021740502,-0.021531334,0.0061966316,-0.0130861355,0.027296554,-0.030930866,-3.162047E-4,-0.002474077,-0.03461747,0.013988176,9.281874E-4,-0.023923704,0.02027632,-0.010922544,0.005121372,-0.019021306,0.023230832,0.03223817,0.006203168,-0.0054089795,-8.946877E-4,-0.010092404,0.016759666,-0.013465255,1.9119354E-4,-0.016668154,-0.015373921,0.013582911,0.004065722,0.0067587732,0.001931545,0.009249192,0.019884128,-0.014877145,0.005948243,-0.009654457,-0.027479578,-0.0013996348,0.009223046,0.013582911,0.026446804,-0.010987909,0.007902666,-0.025753932,-0.04290579,-0.035977066,0.008079153,-0.030773988,-0.04912857,-0.004134356,-0.007621595,-0.013452181,0.001440488,-0.015347775,-0.022720981,-0.041206293,0.008530173,0.017269515,-0.017897023,-0.02394985,0.018093118,0.007137892,-0.021988891,0.021256799,-0.0019854712,-0.033100992,0.016406693,-0.014798706,-0.015988356,0.02394985,-0.0023792973,0.0283424,-0.014615684,1.08261294E-4,0.005739074,0.009660993,0.0101969885,-0.0050984942,-0.014903291,-0.007249013,0.012399799,-0.0075823762,0.021962745,-0.00553971,-0.009909381,0.016994981,0.00570966,-0.0027012215,0.016890397,-0.0014813413,0.01207951,0.011818049,-0.005353419,0.010687228,0.013948957,0.019988712,0.005882878,-0.0017321807,0.018772917,-0.024773452,-0.0024413944,-0.031532228,0.0015671334,-0.038539387,0.01831536,0.0027257334,0.020563927,-0.007503938,-0.008249102,-9.028584E-5,0.015975282,0.0397944,0.017530976,-0.001748522,-0.014511099,0.011347418,-0.0034741664,5.588734E-4,-0.013569838,-0.0135044735,-0.0014560124,0.023727609,0.016668154,0.022001963,-0.002632588,-0.015870698,-0.017282588,-0.017596342,0.01336067,0.01933506,-0.0036441162,-0.03582019,0.023544585,-0.0244597,0.0050625433,-0.007974568,3.0905535E-4,-0.004922008,0.028996052,-0.0054351254,-0.014720269,0.0064286785,0.024904184,0.00260971,-0.019204328,0.0023400781,-0.002585198,-0.0022632738,-0.02296937,0.0042160624,-0.008785098,-0.034722053,0.00915768,-0.010033575,0.033310164,0.02672134,0.0019903737,0.018276142,0.0012084412,-0.0019364473,0.01222985,-0.0017877413,0.011667708,-0.008490954,0.0034937758,0.0020508366,0.01976647,-0.010412694,0.029989606,-0.01528241,0.0046670833,-0.012818137,-0.003160413,-0.0043958174,-7.451645E-4,-0.017256442,0.0053991745,-0.05020056,0.012504384,-0.001784473,-0.016968835,-0.016249817,-0.0047324486,0.005683514,-0.002869537,0.009013876,-0.009759041,0.013158037,0.005807708,-0.01631518,4.8778864E-4,-0.016916543,0.0067914557,-0.013726715,0.012805064,-0.0071313553,0.022132695,0.0051900055,-0.007595449,-0.013223402,0.026420658,-0.0065561407,8.897853E-4,-0.007667351,-0.016498204,-0.01972725,-0.026106905,-0.006389459,9.167485E-4,-0.0031783883,-0.006967942,-0.025034914,-0.03009419,0.0049873735,0.01865526,0.0052259564,-0.015086314,0.008647831,-0.017988533,-0.0015311824,0.12456014,0.009726359,-0.0034414837,0.012595896,0.023596877,-0.007765399,-0.017766291,-0.01660279,-0.009164217,-0.0033761184,-0.0023776633,0.003840212,0.0035035806,0.0041637705,0.013465255,-0.0029103905,-0.0097655775,-0.007333988,-0.0071575018,-0.0093341665,-7.8438374E-4,-4.318196E-4,-0.015007876,0.018812137,0.01835458,-0.021675138,0.02813323,0.013112281,-0.007667351,-0.025623202,0.009144607,0.005438394,0.006693408,0.011465075,0.003385923,0.001684791,0.0013179281,0.0333886,0.016655082,-0.01285082,0.041938383,0.014720269,0.006016877,-0.030643258,-0.001797546,-0.008124908,-0.011347418,0.0371275,-0.0021374456,-0.017923169,0.032865677,-0.009981283,-0.012988088,-0.009406068,-0.012184094,0.01720415,-0.0041801115,0.022551032,-0.020773096,-0.016106013,-0.009105388,-0.03393767,-0.003333631,-0.013713642,-0.011987998,-0.024002142,-0.019361205,-0.009889771,-0.017635562,0.0047782045,0.004294501,-0.03359777,-6.8347604E-4,-0.001808985,0.029440537,0.007621595,0.0130926715,-0.0038532852,0.005696587,0.0027257334,0.008654367,-0.010236207,-0.01396203,-0.0050396654,-0.007503938,0.02647295,0.01075913,-0.008327541,-0.012785455,0.015373921,0.012399799,-0.0077784723,0.013203793,-0.00499391,0.0074385726,-0.009556409,0.020825388,2.453242E-4,-0.008392906,0.0038663582,0.02364917,-0.009216509,-0.010752594,0.008353687,0.012471701,0.0038663582,0.008425589,0.0034741664,-0.011635025,-0.009660993,0.03825178,-0.027871769,0.010144697,-0.008268712,-0.028054792,0.017596342,0.030538673,0.01997564,0.010353865,-0.026198417,-0.014694122,-0.01107942,0.0038696264,0.012857357,0.012602432,-0.013726715,8.685416E-4,-0.008758952,0.0043500615,0.0059417067,-0.0037454322,0.013327987,-0.0053828335,-0.0015524261,-0.01524319,-0.0075627663,-0.0015270971,0.018537601,-0.021988891,-0.021648992,-0.0062325825,-0.0131057445,-0.005203079,-0.017060347,8.113469E-4,-0.03056482,-0.004382744,3.687012E-4,0.02313932,0.0038304073,-0.0022502008,-0.0042618182,-0.021884305,0.0010107111,-0.0139228115,-0.010549962,-0.02236801,-0.02266869,0.016589716,0.031479932,0.007935349,0.012863893,-0.012373653,0.0027273677,0.0028580981,0.0046311324,0.0043271836,-0.017622488,-0.033310164,-0.0043043057,0.017949315,0.0020214221,0.0039676744,-0.0029201952,0.020511635,0.016066793,0.00979826,-0.01891672,-0.032970265,-0.026224563,-0.017021127,-0.0019331791,-0.008216419,-0.0068372115,-0.0033009483,-0.00241198,0.028996052,0.0030705356,0.011876877,0.011641562,0.033493187,-0.01639362,0.033911522,0.009562945,-0.014236565,-0.028499275,0.004065722,-5.707209E-4,0.0071444283,0.013367206,0.0050756163,0.0050363974,0.016119085,-0.001920106,-0.009033486,0.006529995,0.0032274122,0.015674602,-0.020302465,-0.011563123,0.006817602,-0.008549782,-0.030957012,-0.036186237,0.005147518,-0.02591081,-0.005291322,0.029597413,-0.008131444,-0.03346704,-0.013988176,0.0057325377,0.0155700175,0.023923704,0.020733876,0.028839175,-0.0034676297,-0.017400246,0.035637166,0.0058501954,-3.6053054E-4,0.02425053,-0.0065365313,-0.009896308,0.001673352,-0.018772917,0.0045134746,-0.013144964,-0.03649999,0.020132516,-0.010210061,0.010739521,-0.019857982,-0.009151144,-0.0035166538,0.025544764,0.0035918239,0.0027240994,-0.0141712,-0.020250173,-0.031140035,-0.008915829,-0.02031554,0.013118818,-0.0022191524,0.002547613,0.00896812,-0.009392995,-0.008504027,-0.0209169,-0.013870519,0.028080938,0.01793624,-0.008772025,0.024773452,0.010955227,-0.0029888288,-0.0043860124,0.012628579,0.027270408,-0.019714179,-0.02915293,-0.004837033,0.00947797,0.021805868,0.0085105635,-5.84611E-4,0.0052455664,-0.020720804,-0.0059874626,0.024132874,-0.006366581,-0.012491311,-0.025518617,-0.013700569,-0.0283424,-0.037545834,0.004000357,-0.018302288,-0.016249817,-0.0118507305,-0.01733488,-0.0011749414,0.014105834,-0.0022567373,0.01660279,-0.005340346,0.02506106,-0.031140035,0.023060882,0.013595984,0.018890575,-0.01993642,0.0070333076,0.017661707,-0.011288589,0.0062456555,-0.010144697,0.01109903,0.0042160624,-0.0065920916,0.021322165,-0.006647652,-0.008752415,-0.012112192,0.01447188,0.00184657,-0.01609294,-0.0139228115,0.04110171,0.014040469,-0.0052978583,-0.003964406,-0.020393977,0.025963102,0.0076869605,-0.0135044735,0.0173741,-0.012785455,-3.8075293E-4,0.009425678,0.022211133,0.0045102066,-0.0139097385,-0.008249102,0.0031032183,-0.009510653,0.009621774,0.010406158,-0.00514425,5.743977E-4,0.019400425,-0.013373743,-0.0072816955,-0.0017991802,0.009687139,0.0030803403,-0.0058175125,-0.019871054,-0.02108685,0.004157234,0.041598484,0.009386458,-0.02753187,-0.011184005,0.010883325,-0.030355651,-0.012157948,0.022642544,0.023544585,0.029597413,0.014903291,0.02608076,0.021335237,-0.014811779,0.012497848,0.0013440743,0.008464808,0.0012092582,0.0043141106,0.0021733965,0.0037552372,-0.030172627,0.016079867,0.021400603,0.019622667,-0.0077980817,0.008732806,0.001993642,-0.010896398,4.0567346E-4,-0.020302465,0.02266869,0.007739253,-0.0118311215,-0.031479932,-0.003817334,-0.0024446626,0.019740324,0.013197256,0.0023662243,0.0066770664,0.011863804,-2.1767159E-5,-0.0089419745,-0.016994981,-0.008785098,-0.028368546,0.026146125,-0.0036114336,0.01236058,0.0076608146,0.015975282,-0.00915768,0.004415427,0.0028711713,-0.008412516,-0.0036996766,-0.021884305,-0.0101969885,-0.001058101,-0.012765845,-0.0131515,0.011641562,0.02351844,-0.0076281317,-0.018367652,-0.020472415,0.036473844,0.022799421,-0.016615862,-0.011164395,-0.0032944116,-0.012994624,0.0021881037,-0.021779722,-0.01801468,-0.0043631345,-0.008039934,0.002277981,0.006239119,-0.02651217,0.0024773453,0.0017632293,-0.014824852,0.009621774,0.21523489,-0.012210241,-0.019583447,0.022433374,-0.0029724876,0.03940221,0.02327005,-0.01222985,-0.006170485,0.002632588,-0.028446984,0.018759845,-0.005647563,-0.005229225,8.2973094E-4,-0.018812137,-0.02394985,-0.0330487,-0.0020982265,-0.045703426,5.022405E-5,0.017962387,-0.0276626,-0.025936956,0.011948779,-0.02489111,-0.026368367,-0.0029610486,0.011530441,-8.0225705E-5,0.002903854,-0.027584162,0.0060332185,0.04034347,-0.021805868,-0.0017517903,0.022995517,-0.0031930956,0.0062783384,0.007026771,0.017008053,-8.726269E-4,-0.008556319,0.00834715,-0.0049808365,0.013792081,-0.012595896,-0.017792437,-0.011301663,-0.005843659,-0.017034201,-0.0063567767,0.005660636,0.025976175,-0.004320647,0.0018204239,0.033754647,0.00883739,-0.01852453,-0.0041997214,-0.012099119,0.015334702,-0.010360402,0.014837925,-0.03817334,0.023688389,-0.025806226,0.012948868,0.012641652,-0.039977424,0.013216866,-0.007765399,-0.005111567,-0.0019397156,-0.021675138,-0.012510921,-0.0020524708,0.019269694,0.014576465,-7.619144E-4,-0.024420481,-0.018498383,0.00221425,-0.018969014,-0.0062783384,-0.014654903,0.018223848,-0.019818762,-0.0173741,0.027008947,-7.0594536E-4,-0.02104763,-0.006510385,0.009151144,0.011804976,0.021544406,0.017191077,0.02988502,-0.018249994,-0.011903023,-0.0016137061,-0.04549426,3.552196E-4,-0.002671807,-0.019674959,-0.0032388512,-0.0011120273,0.010013966,0.010615326,-0.014929437,-0.017321808,-0.014445734,-0.024982622,3.0497002E-4,0.008183737,-0.0033728501,0.012497848,-0.0013841104,0.01720415,-0.015635382,-0.01592299,-0.024485845,0.008079153,0.014498026,0.012125265,-0.011327809,-0.0068502845,0.011974925,-0.0059253653,-0.026773632,0.004935081,-0.022041183,0.00570966,0.018249994,0.0014388539,0.013001161,-0.017021127,-0.023688389,-0.0059874626,0.00819681,0.005356687,0.013033843,-0.010308109,-0.004784741,-0.019413497,0.0041866484,0.030277213,4.5959983E-4,-0.008399443,0.0048795203,-0.016445912,-0.011876877,-0.004575572,0.0044905967,0.024368187,-0.0034610932,-0.022132695,-0.030669404,-0.0042585502,0.014824852,-0.04144161,0.0143280765,0.01767478,-0.02168821,-0.013582911,-0.009451824,-0.1686948,0.0056867823,0.011131712,-0.013857446,0.039977424,0.014001249,0.02274713,0.021112995,-0.021845087,0.015373921,0.0037094813,-0.0040036254,-0.03500966,-0.0029773898,-0.0030492917,-0.02967585,-0.012497848,0.009386458,0.0038826994,0.006719554,0.0139097385,-0.0011888316,0.012112192,-0.0020573733,0.010523815,0.0043990854,-0.012876966,0.025191791,0.0089289015,0.001452744,-0.012707016,-0.013210329,0.035192683,-0.0070333076,-0.0055102957,-6.7765446E-5,-0.022145767,0.0033499722,-0.022904005,0.016158305,0.03022492,0.019387351,-0.0036767987,-0.0071836477,-0.009942064,0.023413854,-0.004493865,-0.03009419,5.1230064E-4,-0.007909203,0.0025443446,-0.0036898719,0.0059972676,-0.016027573,0.00721633,0.016955761,0.014249638,0.005412248,0.019191256,-0.022354936,-0.020773096,0.0026309537,-0.014589538,0.0027224652,-0.017269515,-0.02253796,-0.0035591412,-0.0065920916,-0.019191256,-0.0012403068,0.0126677975,-0.0028123425,-0.018459164,-0.020563927,0.009582555,-0.0031865588,-0.017269515,0.020302465,-0.014524172,-0.01060879,-0.014105834,0.016210597,-0.0030934133,-0.0027012215,0.021034557,0.00570966,-0.0045592305,-0.004124551,-0.001132454,0.0065038484,0.015805332,-0.017191077,-0.0093472395,0.0056998553,0.036813743,0.007412426,0.010739521,0.037232082,-0.01155005,-7.07171E-4,-0.008399443,-0.006422142,-0.025257157,-0.004111478,0.023936776,0.015360848,0.03534956,0.019308913,0.0134914005,-0.0041801115,-0.0064450195,-0.006994088,0.0044873287,0.016432839,0.0012999526,0.014354222,-7.1003067E-4,-0.015622309,0.008706659,4.1752093E-4,0.04630479,0.0019413497,-0.038016465,-0.008131444,0.004837033,-0.01865526,-0.08141903,-0.015687674,0.013465255,0.015857624,0.0031930956,0.021230653,-0.0064286785,0.004441573,0.0027633186,0.015949136,-0.013288768,-0.026577536,0.0044775237,0.008353687,0.02506106,-0.011942242,2.300042E-4,-0.026642902,-0.017217223,0.014158127,-0.0022567373,0.019256622,-0.025636274,-0.013988176,0.002756782,-0.0058763414,-0.033284016,0.030957012,-1.5473195E-5,0.008379833,5.2215648E-5,-0.0012983185,-0.01207951,-0.013635204,0.015896844,0.0048533743,-0.057939813,5.609161E-4,0.0045265476,-0.045572694,0.006771846,0.023165466,-0.00896812,-0.027714891,-0.009131534,-7.243294E-4,-0.0058501954,0.014079688,0.017308734,-0.0058403905,-0.004961227,-0.04110171,-0.022171913,0.0017664975,0.008647831,-0.013975103,-0.014275784,0.026355293,-0.0060593644,0.031296913,0.01075913,0.0027910988,0.011177468,0.0337285,0.004788009,0.022590252,-0.012105656,-0.018249994,0.019544229,-0.026276855,-0.014550318,0.020773096,-0.010236207,0.023204686,-0.027767185,-0.00785691,-0.01865526,-0.029309805,0.013752862,-0.021740502,-0.028446984,-0.014707195,-0.0033450697,-0.014053542,0.025335595,0.004614791,-0.0056050755,-0.019583447,-0.005121372,-0.01302077,0.018759845,0.0151778255,0.02847313,-0.03231661,-0.0050723483,0.028760737,-0.011406247,-0.021465968,0.0051900055,0.029100636,-0.012157948,-4.7553264E-4,-0.06724783,0.010484596,0.005461272,-0.008870073,-0.0046344004,-0.05046202,0.01494251,-0.012576286,-0.01571382,0.0010352231,-0.021465968,0.0048762523,0.021112995,4.2405745E-4,-0.02967585,-0.0031113888,-0.006902577,0.0050004465,-0.0057292697,0.009066169,0.0039088456,0.0012460263,0.010935617,0.0039676744,0.008137981,0.024093654,-0.025244083,0.0030525601,-0.0097786505,-0.015543871,0.032421194,-0.029022198,0.004833765,0.0394545,-0.0134914005,-0.020851534,-0.005428589,-0.009138071,0.01758327,0.043324128,-0.028656153,-0.01613216,0.014837925,0.003398996,-0.007275159,0.0052717123,0.00587961,-0.00998782,0.011223224,-0.009654457,0.029780436,0.043402568,-0.030930866,-0.005758684,-0.020054078,-0.011321272,0.014236565,0.026577536,0.0114323925,-0.0060593644,0.015334702,0.018197702,0.033780795,0.017517904,0.031558372,0.019962566,-0.013870519,-0.010576108,0.0025361741,-9.126632E-4,-0.008059543,0.003506849,0.019034378,0.010987909,0.011203614,-0.006288143,-0.010563035,0.0051638596,-0.03176754,0.006994088,0.019923346,0.010020502,-0.027505724,0.0040068934,0.021230653,0.015818406,-0.013622131,-0.006739164,-0.020001786,0.005242298,-0.012478238,-0.002449565,0.0040689907,0.011968388,-0.0049514226,0.024695015,-0.013622131,0.019622667,0.008915829,0.0044677192,-0.0049514226,-0.00815759,0.003224144,0.025204863,-0.027479578,0.011765756,-0.019857982,-0.006056096,-0.0063829226,0.019073598,0.019178182,5.2006275E-4,0.026211489,0.012994624,-0.012916186,0.02040705,0.026250709,-0.020302465,-0.024708088,0.028028645,-0.0019707642,-0.003286241,0.0147464145,-0.016419766,-0.0027208312,-0.011863804,9.404434E-4,-0.012576286,0.0030558284,-0.017112639,-0.0071052094,-0.025976175,-0.0073535973,-0.007869983,-0.0114127835,0.014798706,0.016079867,0.020485489,-0.0049089347,0.049677636,0.012759308,-0.027714891,0.019426571,-0.011693854,0.031532228,0.008700123,0.035375707,-0.0061345343,-0.03176754,0.014236565,0.0027404407,0.026172271,-0.03103545,-0.034905076,-0.017361026,0.0020639098,-0.0033924596,-0.009569482,0.0042127944,0.018080045,-0.020158662,0.015687674,0.021818941,-0.0044742557,-0.030355651,0.0035918239,0.01126898,0.006203168,-0.0033009483,-0.015125533,0.0044644508,-0.00964792,-0.0065397993,0.0028074402,-4.0015826E-4,0.00474879,-0.026459878,0.0101839155,-0.0023351756,0.0099486,0.017308734,-0.009739432,-0.009759041,0.017648634,-0.0016815226,-0.003653921,-1.6686028E-5,-0.017151857]},{"content":"The World is Big and Salvation Lurks Around the Corner","id":"2","metadata":{"activationDate":2000,"country":"NL"},"embedding":[0.02364917,-0.018419946,0.0033172895,-0.0058730734,-0.028159376,0.018681405,-0.013752862,-0.006621506,-0.008360223,-0.0034186058,0.016472058,0.03461747,-0.013543692,0.0139228115,0.01588377,-0.0021260066,0.032473486,-0.0041997214,2.696319E-4,-0.013452181,-0.0130926715,0.005948243,-7.839752E-4,-0.0093603125,-0.003984016,-0.0037879199,0.004725912,-0.03299641,0.04567728,-0.01733488,-0.0074058897,-0.019008232,-0.019478863,-0.04099712,-0.011876877,-0.0037552372,3.6543293E-4,-0.015896844,0.008124908,-0.009281875,0.020446269,0.012184094,-9.5678476E-4,-0.015125533,-0.031872127,0.013478328,-0.0034349472,-0.023792973,-0.019688033,0.020929974,0.034172986,0.0053501506,-0.0043500615,-0.007680424,-0.019910274,0.0045330846,-0.012177558,-0.006111657,0.020289393,-0.013622131,0.0069875517,-0.0025574178,-0.011046737,0.012713553,-0.024420481,0.006647652,-7.2310376E-4,0.005807708,0.013844373,0.011386638,0.015949136,0.010425767,0.014550318,0.009785187,0.017517904,-0.020367831,-0.021112995,0.012537067,0.013243012,-0.006510385,0.011661172,-0.028917614,-0.0018808868,-4.457097E-4,0.021178361,0.011504294,-0.025296375,0.02313932,0.007249013,-0.013883593,0.018302288,0.0031669494,0.0059220972,0.01754405,-0.009124997,-0.014001249,-0.008778561,0.008765488,0.011804976,-0.05059275,-0.0069744787,0.0037487007,-0.012131802,-0.0041278196,0.0077980817,-0.012327897,-0.0031702176,0.005082153,0.019570375,4.9922755E-4,-5.719465E-4,0.023832193,-0.0073013054,-0.021818941,0.027191969,-0.009732895,-0.0077719353,0.0015981819,-0.0059220972,-0.028159376,0.011085956,0.02894376,0.003608165,-0.016877323,-0.0038336755,0.013197256,-0.029780436,-0.010785276,0.001071174,0.006598628,0.011778829,0.02928366,0.022995517,0.0036604574,-0.010870251,0.022943225,-0.008595538,0.007817691,-0.00433372,-0.0063273623,0.032212026,0.02574086,7.075795E-4,-0.013739789,0.009804796,-0.009928991,-1.4982955E-4,0.016171377,0.0131057445,-0.020014858,0.043637883,0.011916096,0.02915293,-0.009242655,0.014994803,-0.0075235474,-0.011576197,0.02954512,-0.005206347,-0.015857624,-0.008804708,-0.0013963665,0.014145053,-0.009255728,0.010719911,0.018027753,0.015360848,-0.011170932,-0.023583805,-0.005761952,-5.359955E-4,0.05584812,-0.013569838,0.028159376,-0.024106726,0.0019495204,-2.084796E-5,0.017923169,-0.013622131,0.0010229672,-0.014968656,-0.006003804,-0.0027731233,0.01993642,-0.003987284,-0.0028744396,0.0118507305,-0.013700569,0.016890397,-0.027688745,0.012086046,0.020433197,-0.0017452538,0.020393977,-0.684401,-0.021675138,-0.0049514226,-0.007137892,-7.0676244E-5,-0.013948957,0.02351844,0.028969906,4.991765E-5,-3.057871E-4,0.0030966816,0.008209883,-0.010203525,-0.015347775,-0.0077980817,-0.019818762,-0.01447188,-0.033284016,-4.391732E-4,-0.0077196434,-0.010706838,0.024015216,-0.0032797046,-0.010098941,0.022577178,-0.015295483,0.014537245,-0.028891468,-0.0045232796,-0.009072705,0.015256263,0.0032453877,6.287326E-4,0.01107942,0.0620709,-0.019779542,0.0019282767,-4.3876466E-4,0.028786883,0.02638144,-0.005167128,-0.001391464,0.03425142,-0.008497491,0.0014364027,0.014707195,0.04175536,-0.007680424,-0.005056007,0.0063371668,0.014445734,0.0048925937,-0.0019004964,0.01477256,0.020577,0.0130861355,0.01528241,0.0010809789,-0.008373297,-0.0022371279,-0.01946579,0.014903291,-0.014197346,0.01856375,-0.027819477,0.01236058,-0.0085105635,-0.0013367207,0.019505009,0.017714,0.018419946,0.0028973175,-0.005307663,-0.01767478,0.008039934,0.026629828,0.007739253,-0.017596342,-0.005810976,0.008575928,0.008798171,-0.024302823,-0.01305999,0.012765845,0.024172092,0.010889861,-0.011406247,-0.0114389295,0.013726715,0.01895594,-0.0027339042,0.02049856,-5.441662E-4,-0.0015156581,0.034120694,-0.0039807474,-0.016798886,0.024355115,0.031113889,-0.0110140545,0.012497848,-0.016210597,0.009438751,0.0028156107,0.021740502,-0.021531334,0.0061966316,-0.0130861355,0.027296554,-0.030930866,-3.162047E-4,-0.002474077,-0.03461747,0.013988176,9.281874E-4,-0.023923704,0.02027632,-0.010922544,0.005121372,-0.019021306,0.023230832,0.03223817,0.006203168,-0.0054089795,-8.946877E-4,-0.010092404,0.016759666,-0.013465255,1.9119354E-4,-0.016668154,-0.015373921,0.013582911,0.004065722,0.0067587732,0.001931545,0.009249192,0.019884128,-0.014877145,0.005948243,-0.009654457,-0.027479578,-0.0013996348,0.009223046,0.013582911,0.026446804,-0.010987909,0.007902666,-0.025753932,-0.04290579,-0.035977066,0.008079153,-0.030773988,-0.04912857,-0.004134356,-0.007621595,-0.013452181,0.001440488,-0.015347775,-0.022720981,-0.041206293,0.008530173,0.017269515,-0.017897023,-0.02394985,0.018093118,0.007137892,-0.021988891,0.021256799,-0.0019854712,-0.033100992,0.016406693,-0.014798706,-0.015988356,0.02394985,-0.0023792973,0.0283424,-0.014615684,1.08261294E-4,0.005739074,0.009660993,0.0101969885,-0.0050984942,-0.014903291,-0.007249013,0.012399799,-0.0075823762,0.021962745,-0.00553971,-0.009909381,0.016994981,0.00570966,-0.0027012215,0.016890397,-0.0014813413,0.01207951,0.011818049,-0.005353419,0.010687228,0.013948957,0.019988712,0.005882878,-0.0017321807,0.018772917,-0.024773452,-0.0024413944,-0.031532228,0.0015671334,-0.038539387,0.01831536,0.0027257334,0.020563927,-0.007503938,-0.008249102,-9.028584E-5,0.015975282,0.0397944,0.017530976,-0.001748522,-0.014511099,0.011347418,-0.0034741664,5.588734E-4,-0.013569838,-0.0135044735,-0.0014560124,0.023727609,0.016668154,0.022001963,-0.002632588,-0.015870698,-0.017282588,-0.017596342,0.01336067,0.01933506,-0.0036441162,-0.03582019,0.023544585,-0.0244597,0.0050625433,-0.007974568,3.0905535E-4,-0.004922008,0.028996052,-0.0054351254,-0.014720269,0.0064286785,0.024904184,0.00260971,-0.019204328,0.0023400781,-0.002585198,-0.0022632738,-0.02296937,0.0042160624,-0.008785098,-0.034722053,0.00915768,-0.010033575,0.033310164,0.02672134,0.0019903737,0.018276142,0.0012084412,-0.0019364473,0.01222985,-0.0017877413,0.011667708,-0.008490954,0.0034937758,0.0020508366,0.01976647,-0.010412694,0.029989606,-0.01528241,0.0046670833,-0.012818137,-0.003160413,-0.0043958174,-7.451645E-4,-0.017256442,0.0053991745,-0.05020056,0.012504384,-0.001784473,-0.016968835,-0.016249817,-0.0047324486,0.005683514,-0.002869537,0.009013876,-0.009759041,0.013158037,0.005807708,-0.01631518,4.8778864E-4,-0.016916543,0.0067914557,-0.013726715,0.012805064,-0.0071313553,0.022132695,0.0051900055,-0.007595449,-0.013223402,0.026420658,-0.0065561407,8.897853E-4,-0.007667351,-0.016498204,-0.01972725,-0.026106905,-0.006389459,9.167485E-4,-0.0031783883,-0.006967942,-0.025034914,-0.03009419,0.0049873735,0.01865526,0.0052259564,-0.015086314,0.008647831,-0.017988533,-0.0015311824,0.12456014,0.009726359,-0.0034414837,0.012595896,0.023596877,-0.007765399,-0.017766291,-0.01660279,-0.009164217,-0.0033761184,-0.0023776633,0.003840212,0.0035035806,0.0041637705,0.013465255,-0.0029103905,-0.0097655775,-0.007333988,-0.0071575018,-0.0093341665,-7.8438374E-4,-4.318196E-4,-0.015007876,0.018812137,0.01835458,-0.021675138,0.02813323,0.013112281,-0.007667351,-0.025623202,0.009144607,0.005438394,0.006693408,0.011465075,0.003385923,0.001684791,0.0013179281,0.0333886,0.016655082,-0.01285082,0.041938383,0.014720269,0.006016877,-0.030643258,-0.001797546,-0.008124908,-0.011347418,0.0371275,-0.0021374456,-0.017923169,0.032865677,-0.009981283,-0.012988088,-0.009406068,-0.012184094,0.01720415,-0.0041801115,0.022551032,-0.020773096,-0.016106013,-0.009105388,-0.03393767,-0.003333631,-0.013713642,-0.011987998,-0.024002142,-0.019361205,-0.009889771,-0.017635562,0.0047782045,0.004294501,-0.03359777,-6.8347604E-4,-0.001808985,0.029440537,0.007621595,0.0130926715,-0.0038532852,0.005696587,0.0027257334,0.008654367,-0.010236207,-0.01396203,-0.0050396654,-0.007503938,0.02647295,0.01075913,-0.008327541,-0.012785455,0.015373921,0.012399799,-0.0077784723,0.013203793,-0.00499391,0.0074385726,-0.009556409,0.020825388,2.453242E-4,-0.008392906,0.0038663582,0.02364917,-0.009216509,-0.010752594,0.008353687,0.012471701,0.0038663582,0.008425589,0.0034741664,-0.011635025,-0.009660993,0.03825178,-0.027871769,0.010144697,-0.008268712,-0.028054792,0.017596342,0.030538673,0.01997564,0.010353865,-0.026198417,-0.014694122,-0.01107942,0.0038696264,0.012857357,0.012602432,-0.013726715,8.685416E-4,-0.008758952,0.0043500615,0.0059417067,-0.0037454322,0.013327987,-0.0053828335,-0.0015524261,-0.01524319,-0.0075627663,-0.0015270971,0.018537601,-0.021988891,-0.021648992,-0.0062325825,-0.0131057445,-0.005203079,-0.017060347,8.113469E-4,-0.03056482,-0.004382744,3.687012E-4,0.02313932,0.0038304073,-0.0022502008,-0.0042618182,-0.021884305,0.0010107111,-0.0139228115,-0.010549962,-0.02236801,-0.02266869,0.016589716,0.031479932,0.007935349,0.012863893,-0.012373653,0.0027273677,0.0028580981,0.0046311324,0.0043271836,-0.017622488,-0.033310164,-0.0043043057,0.017949315,0.0020214221,0.0039676744,-0.0029201952,0.020511635,0.016066793,0.00979826,-0.01891672,-0.032970265,-0.026224563,-0.017021127,-0.0019331791,-0.008216419,-0.0068372115,-0.0033009483,-0.00241198,0.028996052,0.0030705356,0.011876877,0.011641562,0.033493187,-0.01639362,0.033911522,0.009562945,-0.014236565,-0.028499275,0.004065722,-5.707209E-4,0.0071444283,0.013367206,0.0050756163,0.0050363974,0.016119085,-0.001920106,-0.009033486,0.006529995,0.0032274122,0.015674602,-0.020302465,-0.011563123,0.006817602,-0.008549782,-0.030957012,-0.036186237,0.005147518,-0.02591081,-0.005291322,0.029597413,-0.008131444,-0.03346704,-0.013988176,0.0057325377,0.0155700175,0.023923704,0.020733876,0.028839175,-0.0034676297,-0.017400246,0.035637166,0.0058501954,-3.6053054E-4,0.02425053,-0.0065365313,-0.009896308,0.001673352,-0.018772917,0.0045134746,-0.013144964,-0.03649999,0.020132516,-0.010210061,0.010739521,-0.019857982,-0.009151144,-0.0035166538,0.025544764,0.0035918239,0.0027240994,-0.0141712,-0.020250173,-0.031140035,-0.008915829,-0.02031554,0.013118818,-0.0022191524,0.002547613,0.00896812,-0.009392995,-0.008504027,-0.0209169,-0.013870519,0.028080938,0.01793624,-0.008772025,0.024773452,0.010955227,-0.0029888288,-0.0043860124,0.012628579,0.027270408,-0.019714179,-0.02915293,-0.004837033,0.00947797,0.021805868,0.0085105635,-5.84611E-4,0.0052455664,-0.020720804,-0.0059874626,0.024132874,-0.006366581,-0.012491311,-0.025518617,-0.013700569,-0.0283424,-0.037545834,0.004000357,-0.018302288,-0.016249817,-0.0118507305,-0.01733488,-0.0011749414,0.014105834,-0.0022567373,0.01660279,-0.005340346,0.02506106,-0.031140035,0.023060882,0.013595984,0.018890575,-0.01993642,0.0070333076,0.017661707,-0.011288589,0.0062456555,-0.010144697,0.01109903,0.0042160624,-0.0065920916,0.021322165,-0.006647652,-0.008752415,-0.012112192,0.01447188,0.00184657,-0.01609294,-0.0139228115,0.04110171,0.014040469,-0.0052978583,-0.003964406,-0.020393977,0.025963102,0.0076869605,-0.0135044735,0.0173741,-0.012785455,-3.8075293E-4,0.009425678,0.022211133,0.0045102066,-0.0139097385,-0.008249102,0.0031032183,-0.009510653,0.009621774,0.010406158,-0.00514425,5.743977E-4,0.019400425,-0.013373743,-0.0072816955,-0.0017991802,0.009687139,0.0030803403,-0.0058175125,-0.019871054,-0.02108685,0.004157234,0.041598484,0.009386458,-0.02753187,-0.011184005,0.010883325,-0.030355651,-0.012157948,0.022642544,0.023544585,0.029597413,0.014903291,0.02608076,0.021335237,-0.014811779,0.012497848,0.0013440743,0.008464808,0.0012092582,0.0043141106,0.0021733965,0.0037552372,-0.030172627,0.016079867,0.021400603,0.019622667,-0.0077980817,0.008732806,0.001993642,-0.010896398,4.0567346E-4,-0.020302465,0.02266869,0.007739253,-0.0118311215,-0.031479932,-0.003817334,-0.0024446626,0.019740324,0.013197256,0.0023662243,0.0066770664,0.011863804,-2.1767159E-5,-0.0089419745,-0.016994981,-0.008785098,-0.028368546,0.026146125,-0.0036114336,0.01236058,0.0076608146,0.015975282,-0.00915768,0.004415427,0.0028711713,-0.008412516,-0.0036996766,-0.021884305,-0.0101969885,-0.001058101,-0.012765845,-0.0131515,0.011641562,0.02351844,-0.0076281317,-0.018367652,-0.020472415,0.036473844,0.022799421,-0.016615862,-0.011164395,-0.0032944116,-0.012994624,0.0021881037,-0.021779722,-0.01801468,-0.0043631345,-0.008039934,0.002277981,0.006239119,-0.02651217,0.0024773453,0.0017632293,-0.014824852,0.009621774,0.21523489,-0.012210241,-0.019583447,0.022433374,-0.0029724876,0.03940221,0.02327005,-0.01222985,-0.006170485,0.002632588,-0.028446984,0.018759845,-0.005647563,-0.005229225,8.2973094E-4,-0.018812137,-0.02394985,-0.0330487,-0.0020982265,-0.045703426,5.022405E-5,0.017962387,-0.0276626,-0.025936956,0.011948779,-0.02489111,-0.026368367,-0.0029610486,0.011530441,-8.0225705E-5,0.002903854,-0.027584162,0.0060332185,0.04034347,-0.021805868,-0.0017517903,0.022995517,-0.0031930956,0.0062783384,0.007026771,0.017008053,-8.726269E-4,-0.008556319,0.00834715,-0.0049808365,0.013792081,-0.012595896,-0.017792437,-0.011301663,-0.005843659,-0.017034201,-0.0063567767,0.005660636,0.025976175,-0.004320647,0.0018204239,0.033754647,0.00883739,-0.01852453,-0.0041997214,-0.012099119,0.015334702,-0.010360402,0.014837925,-0.03817334,0.023688389,-0.025806226,0.012948868,0.012641652,-0.039977424,0.013216866,-0.007765399,-0.005111567,-0.0019397156,-0.021675138,-0.012510921,-0.0020524708,0.019269694,0.014576465,-7.619144E-4,-0.024420481,-0.018498383,0.00221425,-0.018969014,-0.0062783384,-0.014654903,0.018223848,-0.019818762,-0.0173741,0.027008947,-7.0594536E-4,-0.02104763,-0.006510385,0.009151144,0.011804976,0.021544406,0.017191077,0.02988502,-0.018249994,-0.011903023,-0.0016137061,-0.04549426,3.552196E-4,-0.002671807,-0.019674959,-0.0032388512,-0.0011120273,0.010013966,0.010615326,-0.014929437,-0.017321808,-0.014445734,-0.024982622,3.0497002E-4,0.008183737,-0.0033728501,0.012497848,-0.0013841104,0.01720415,-0.015635382,-0.01592299,-0.024485845,0.008079153,0.014498026,0.012125265,-0.011327809,-0.0068502845,0.011974925,-0.0059253653,-0.026773632,0.004935081,-0.022041183,0.00570966,0.018249994,0.0014388539,0.013001161,-0.017021127,-0.023688389,-0.0059874626,0.00819681,0.005356687,0.013033843,-0.010308109,-0.004784741,-0.019413497,0.0041866484,0.030277213,4.5959983E-4,-0.008399443,0.0048795203,-0.016445912,-0.011876877,-0.004575572,0.0044905967,0.024368187,-0.0034610932,-0.022132695,-0.030669404,-0.0042585502,0.014824852,-0.04144161,0.0143280765,0.01767478,-0.02168821,-0.013582911,-0.009451824,-0.1686948,0.0056867823,0.011131712,-0.013857446,0.039977424,0.014001249,0.02274713,0.021112995,-0.021845087,0.015373921,0.0037094813,-0.0040036254,-0.03500966,-0.0029773898,-0.0030492917,-0.02967585,-0.012497848,0.009386458,0.0038826994,0.006719554,0.0139097385,-0.0011888316,0.012112192,-0.0020573733,0.010523815,0.0043990854,-0.012876966,0.025191791,0.0089289015,0.001452744,-0.012707016,-0.013210329,0.035192683,-0.0070333076,-0.0055102957,-6.7765446E-5,-0.022145767,0.0033499722,-0.022904005,0.016158305,0.03022492,0.019387351,-0.0036767987,-0.0071836477,-0.009942064,0.023413854,-0.004493865,-0.03009419,5.1230064E-4,-0.007909203,0.0025443446,-0.0036898719,0.0059972676,-0.016027573,0.00721633,0.016955761,0.014249638,0.005412248,0.019191256,-0.022354936,-0.020773096,0.0026309537,-0.014589538,0.0027224652,-0.017269515,-0.02253796,-0.0035591412,-0.0065920916,-0.019191256,-0.0012403068,0.0126677975,-0.0028123425,-0.018459164,-0.020563927,0.009582555,-0.0031865588,-0.017269515,0.020302465,-0.014524172,-0.01060879,-0.014105834,0.016210597,-0.0030934133,-0.0027012215,0.021034557,0.00570966,-0.0045592305,-0.004124551,-0.001132454,0.0065038484,0.015805332,-0.017191077,-0.0093472395,0.0056998553,0.036813743,0.007412426,0.010739521,0.037232082,-0.01155005,-7.07171E-4,-0.008399443,-0.006422142,-0.025257157,-0.004111478,0.023936776,0.015360848,0.03534956,0.019308913,0.0134914005,-0.0041801115,-0.0064450195,-0.006994088,0.0044873287,0.016432839,0.0012999526,0.014354222,-7.1003067E-4,-0.015622309,0.008706659,4.1752093E-4,0.04630479,0.0019413497,-0.038016465,-0.008131444,0.004837033,-0.01865526,-0.08141903,-0.015687674,0.013465255,0.015857624,0.0031930956,0.021230653,-0.0064286785,0.004441573,0.0027633186,0.015949136,-0.013288768,-0.026577536,0.0044775237,0.008353687,0.02506106,-0.011942242,2.300042E-4,-0.026642902,-0.017217223,0.014158127,-0.0022567373,0.019256622,-0.025636274,-0.013988176,0.002756782,-0.0058763414,-0.033284016,0.030957012,-1.5473195E-5,0.008379833,5.2215648E-5,-0.0012983185,-0.01207951,-0.013635204,0.015896844,0.0048533743,-0.057939813,5.609161E-4,0.0045265476,-0.045572694,0.006771846,0.023165466,-0.00896812,-0.027714891,-0.009131534,-7.243294E-4,-0.0058501954,0.014079688,0.017308734,-0.0058403905,-0.004961227,-0.04110171,-0.022171913,0.0017664975,0.008647831,-0.013975103,-0.014275784,0.026355293,-0.0060593644,0.031296913,0.01075913,0.0027910988,0.011177468,0.0337285,0.004788009,0.022590252,-0.012105656,-0.018249994,0.019544229,-0.026276855,-0.014550318,0.020773096,-0.010236207,0.023204686,-0.027767185,-0.00785691,-0.01865526,-0.029309805,0.013752862,-0.021740502,-0.028446984,-0.014707195,-0.0033450697,-0.014053542,0.025335595,0.004614791,-0.0056050755,-0.019583447,-0.005121372,-0.01302077,0.018759845,0.0151778255,0.02847313,-0.03231661,-0.0050723483,0.028760737,-0.011406247,-0.021465968,0.0051900055,0.029100636,-0.012157948,-4.7553264E-4,-0.06724783,0.010484596,0.005461272,-0.008870073,-0.0046344004,-0.05046202,0.01494251,-0.012576286,-0.01571382,0.0010352231,-0.021465968,0.0048762523,0.021112995,4.2405745E-4,-0.02967585,-0.0031113888,-0.006902577,0.0050004465,-0.0057292697,0.009066169,0.0039088456,0.0012460263,0.010935617,0.0039676744,0.008137981,0.024093654,-0.025244083,0.0030525601,-0.0097786505,-0.015543871,0.032421194,-0.029022198,0.004833765,0.0394545,-0.0134914005,-0.020851534,-0.005428589,-0.009138071,0.01758327,0.043324128,-0.028656153,-0.01613216,0.014837925,0.003398996,-0.007275159,0.0052717123,0.00587961,-0.00998782,0.011223224,-0.009654457,0.029780436,0.043402568,-0.030930866,-0.005758684,-0.020054078,-0.011321272,0.014236565,0.026577536,0.0114323925,-0.0060593644,0.015334702,0.018197702,0.033780795,0.017517904,0.031558372,0.019962566,-0.013870519,-0.010576108,0.0025361741,-9.126632E-4,-0.008059543,0.003506849,0.019034378,0.010987909,0.011203614,-0.006288143,-0.010563035,0.0051638596,-0.03176754,0.006994088,0.019923346,0.010020502,-0.027505724,0.0040068934,0.021230653,0.015818406,-0.013622131,-0.006739164,-0.020001786,0.005242298,-0.012478238,-0.002449565,0.0040689907,0.011968388,-0.0049514226,0.024695015,-0.013622131,0.019622667,0.008915829,0.0044677192,-0.0049514226,-0.00815759,0.003224144,0.025204863,-0.027479578,0.011765756,-0.019857982,-0.006056096,-0.0063829226,0.019073598,0.019178182,5.2006275E-4,0.026211489,0.012994624,-0.012916186,0.02040705,0.026250709,-0.020302465,-0.024708088,0.028028645,-0.0019707642,-0.003286241,0.0147464145,-0.016419766,-0.0027208312,-0.011863804,9.404434E-4,-0.012576286,0.0030558284,-0.017112639,-0.0071052094,-0.025976175,-0.0073535973,-0.007869983,-0.0114127835,0.014798706,0.016079867,0.020485489,-0.0049089347,0.049677636,0.012759308,-0.027714891,0.019426571,-0.011693854,0.031532228,0.008700123,0.035375707,-0.0061345343,-0.03176754,0.014236565,0.0027404407,0.026172271,-0.03103545,-0.034905076,-0.017361026,0.0020639098,-0.0033924596,-0.009569482,0.0042127944,0.018080045,-0.020158662,0.015687674,0.021818941,-0.0044742557,-0.030355651,0.0035918239,0.01126898,0.006203168,-0.0033009483,-0.015125533,0.0044644508,-0.00964792,-0.0065397993,0.0028074402,-4.0015826E-4,0.00474879,-0.026459878,0.0101839155,-0.0023351756,0.0099486,0.017308734,-0.009739432,-0.009759041,0.017648634,-0.0016815226,-0.003653921,-1.6686028E-5,-0.017151857]},{"content":"The World is Big and Salvation Lurks Around the Corner","id":"3","metadata":{"year":2023,"activationDate":3000,"country":"BG"},"embedding":[0.02364917,-0.018419946,0.0033172895,-0.0058730734,-0.028159376,0.018681405,-0.013752862,-0.006621506,-0.008360223,-0.0034186058,0.016472058,0.03461747,-0.013543692,0.0139228115,0.01588377,-0.0021260066,0.032473486,-0.0041997214,2.696319E-4,-0.013452181,-0.0130926715,0.005948243,-7.839752E-4,-0.0093603125,-0.003984016,-0.0037879199,0.004725912,-0.03299641,0.04567728,-0.01733488,-0.0074058897,-0.019008232,-0.019478863,-0.04099712,-0.011876877,-0.0037552372,3.6543293E-4,-0.015896844,0.008124908,-0.009281875,0.020446269,0.012184094,-9.5678476E-4,-0.015125533,-0.031872127,0.013478328,-0.0034349472,-0.023792973,-0.019688033,0.020929974,0.034172986,0.0053501506,-0.0043500615,-0.007680424,-0.019910274,0.0045330846,-0.012177558,-0.006111657,0.020289393,-0.013622131,0.0069875517,-0.0025574178,-0.011046737,0.012713553,-0.024420481,0.006647652,-7.2310376E-4,0.005807708,0.013844373,0.011386638,0.015949136,0.010425767,0.014550318,0.009785187,0.017517904,-0.020367831,-0.021112995,0.012537067,0.013243012,-0.006510385,0.011661172,-0.028917614,-0.0018808868,-4.457097E-4,0.021178361,0.011504294,-0.025296375,0.02313932,0.007249013,-0.013883593,0.018302288,0.0031669494,0.0059220972,0.01754405,-0.009124997,-0.014001249,-0.008778561,0.008765488,0.011804976,-0.05059275,-0.0069744787,0.0037487007,-0.012131802,-0.0041278196,0.0077980817,-0.012327897,-0.0031702176,0.005082153,0.019570375,4.9922755E-4,-5.719465E-4,0.023832193,-0.0073013054,-0.021818941,0.027191969,-0.009732895,-0.0077719353,0.0015981819,-0.0059220972,-0.028159376,0.011085956,0.02894376,0.003608165,-0.016877323,-0.0038336755,0.013197256,-0.029780436,-0.010785276,0.001071174,0.006598628,0.011778829,0.02928366,0.022995517,0.0036604574,-0.010870251,0.022943225,-0.008595538,0.007817691,-0.00433372,-0.0063273623,0.032212026,0.02574086,7.075795E-4,-0.013739789,0.009804796,-0.009928991,-1.4982955E-4,0.016171377,0.0131057445,-0.020014858,0.043637883,0.011916096,0.02915293,-0.009242655,0.014994803,-0.0075235474,-0.011576197,0.02954512,-0.005206347,-0.015857624,-0.008804708,-0.0013963665,0.014145053,-0.009255728,0.010719911,0.018027753,0.015360848,-0.011170932,-0.023583805,-0.005761952,-5.359955E-4,0.05584812,-0.013569838,0.028159376,-0.024106726,0.0019495204,-2.084796E-5,0.017923169,-0.013622131,0.0010229672,-0.014968656,-0.006003804,-0.0027731233,0.01993642,-0.003987284,-0.0028744396,0.0118507305,-0.013700569,0.016890397,-0.027688745,0.012086046,0.020433197,-0.0017452538,0.020393977,-0.684401,-0.021675138,-0.0049514226,-0.007137892,-7.0676244E-5,-0.013948957,0.02351844,0.028969906,4.991765E-5,-3.057871E-4,0.0030966816,0.008209883,-0.010203525,-0.015347775,-0.0077980817,-0.019818762,-0.01447188,-0.033284016,-4.391732E-4,-0.0077196434,-0.010706838,0.024015216,-0.0032797046,-0.010098941,0.022577178,-0.015295483,0.014537245,-0.028891468,-0.0045232796,-0.009072705,0.015256263,0.0032453877,6.287326E-4,0.01107942,0.0620709,-0.019779542,0.0019282767,-4.3876466E-4,0.028786883,0.02638144,-0.005167128,-0.001391464,0.03425142,-0.008497491,0.0014364027,0.014707195,0.04175536,-0.007680424,-0.005056007,0.0063371668,0.014445734,0.0048925937,-0.0019004964,0.01477256,0.020577,0.0130861355,0.01528241,0.0010809789,-0.008373297,-0.0022371279,-0.01946579,0.014903291,-0.014197346,0.01856375,-0.027819477,0.01236058,-0.0085105635,-0.0013367207,0.019505009,0.017714,0.018419946,0.0028973175,-0.005307663,-0.01767478,0.008039934,0.026629828,0.007739253,-0.017596342,-0.005810976,0.008575928,0.008798171,-0.024302823,-0.01305999,0.012765845,0.024172092,0.010889861,-0.011406247,-0.0114389295,0.013726715,0.01895594,-0.0027339042,0.02049856,-5.441662E-4,-0.0015156581,0.034120694,-0.0039807474,-0.016798886,0.024355115,0.031113889,-0.0110140545,0.012497848,-0.016210597,0.009438751,0.0028156107,0.021740502,-0.021531334,0.0061966316,-0.0130861355,0.027296554,-0.030930866,-3.162047E-4,-0.002474077,-0.03461747,0.013988176,9.281874E-4,-0.023923704,0.02027632,-0.010922544,0.005121372,-0.019021306,0.023230832,0.03223817,0.006203168,-0.0054089795,-8.946877E-4,-0.010092404,0.016759666,-0.013465255,1.9119354E-4,-0.016668154,-0.015373921,0.013582911,0.004065722,0.0067587732,0.001931545,0.009249192,0.019884128,-0.014877145,0.005948243,-0.009654457,-0.027479578,-0.0013996348,0.009223046,0.013582911,0.026446804,-0.010987909,0.007902666,-0.025753932,-0.04290579,-0.035977066,0.008079153,-0.030773988,-0.04912857,-0.004134356,-0.007621595,-0.013452181,0.001440488,-0.015347775,-0.022720981,-0.041206293,0.008530173,0.017269515,-0.017897023,-0.02394985,0.018093118,0.007137892,-0.021988891,0.021256799,-0.0019854712,-0.033100992,0.016406693,-0.014798706,-0.015988356,0.02394985,-0.0023792973,0.0283424,-0.014615684,1.08261294E-4,0.005739074,0.009660993,0.0101969885,-0.0050984942,-0.014903291,-0.007249013,0.012399799,-0.0075823762,0.021962745,-0.00553971,-0.009909381,0.016994981,0.00570966,-0.0027012215,0.016890397,-0.0014813413,0.01207951,0.011818049,-0.005353419,0.010687228,0.013948957,0.019988712,0.005882878,-0.0017321807,0.018772917,-0.024773452,-0.0024413944,-0.031532228,0.0015671334,-0.038539387,0.01831536,0.0027257334,0.020563927,-0.007503938,-0.008249102,-9.028584E-5,0.015975282,0.0397944,0.017530976,-0.001748522,-0.014511099,0.011347418,-0.0034741664,5.588734E-4,-0.013569838,-0.0135044735,-0.0014560124,0.023727609,0.016668154,0.022001963,-0.002632588,-0.015870698,-0.017282588,-0.017596342,0.01336067,0.01933506,-0.0036441162,-0.03582019,0.023544585,-0.0244597,0.0050625433,-0.007974568,3.0905535E-4,-0.004922008,0.028996052,-0.0054351254,-0.014720269,0.0064286785,0.024904184,0.00260971,-0.019204328,0.0023400781,-0.002585198,-0.0022632738,-0.02296937,0.0042160624,-0.008785098,-0.034722053,0.00915768,-0.010033575,0.033310164,0.02672134,0.0019903737,0.018276142,0.0012084412,-0.0019364473,0.01222985,-0.0017877413,0.011667708,-0.008490954,0.0034937758,0.0020508366,0.01976647,-0.010412694,0.029989606,-0.01528241,0.0046670833,-0.012818137,-0.003160413,-0.0043958174,-7.451645E-4,-0.017256442,0.0053991745,-0.05020056,0.012504384,-0.001784473,-0.016968835,-0.016249817,-0.0047324486,0.005683514,-0.002869537,0.009013876,-0.009759041,0.013158037,0.005807708,-0.01631518,4.8778864E-4,-0.016916543,0.0067914557,-0.013726715,0.012805064,-0.0071313553,0.022132695,0.0051900055,-0.007595449,-0.013223402,0.026420658,-0.0065561407,8.897853E-4,-0.007667351,-0.016498204,-0.01972725,-0.026106905,-0.006389459,9.167485E-4,-0.0031783883,-0.006967942,-0.025034914,-0.03009419,0.0049873735,0.01865526,0.0052259564,-0.015086314,0.008647831,-0.017988533,-0.0015311824,0.12456014,0.009726359,-0.0034414837,0.012595896,0.023596877,-0.007765399,-0.017766291,-0.01660279,-0.009164217,-0.0033761184,-0.0023776633,0.003840212,0.0035035806,0.0041637705,0.013465255,-0.0029103905,-0.0097655775,-0.007333988,-0.0071575018,-0.0093341665,-7.8438374E-4,-4.318196E-4,-0.015007876,0.018812137,0.01835458,-0.021675138,0.02813323,0.013112281,-0.007667351,-0.025623202,0.009144607,0.005438394,0.006693408,0.011465075,0.003385923,0.001684791,0.0013179281,0.0333886,0.016655082,-0.01285082,0.041938383,0.014720269,0.006016877,-0.030643258,-0.001797546,-0.008124908,-0.011347418,0.0371275,-0.0021374456,-0.017923169,0.032865677,-0.009981283,-0.012988088,-0.009406068,-0.012184094,0.01720415,-0.0041801115,0.022551032,-0.020773096,-0.016106013,-0.009105388,-0.03393767,-0.003333631,-0.013713642,-0.011987998,-0.024002142,-0.019361205,-0.009889771,-0.017635562,0.0047782045,0.004294501,-0.03359777,-6.8347604E-4,-0.001808985,0.029440537,0.007621595,0.0130926715,-0.0038532852,0.005696587,0.0027257334,0.008654367,-0.010236207,-0.01396203,-0.0050396654,-0.007503938,0.02647295,0.01075913,-0.008327541,-0.012785455,0.015373921,0.012399799,-0.0077784723,0.013203793,-0.00499391,0.0074385726,-0.009556409,0.020825388,2.453242E-4,-0.008392906,0.0038663582,0.02364917,-0.009216509,-0.010752594,0.008353687,0.012471701,0.0038663582,0.008425589,0.0034741664,-0.011635025,-0.009660993,0.03825178,-0.027871769,0.010144697,-0.008268712,-0.028054792,0.017596342,0.030538673,0.01997564,0.010353865,-0.026198417,-0.014694122,-0.01107942,0.0038696264,0.012857357,0.012602432,-0.013726715,8.685416E-4,-0.008758952,0.0043500615,0.0059417067,-0.0037454322,0.013327987,-0.0053828335,-0.0015524261,-0.01524319,-0.0075627663,-0.0015270971,0.018537601,-0.021988891,-0.021648992,-0.0062325825,-0.0131057445,-0.005203079,-0.017060347,8.113469E-4,-0.03056482,-0.004382744,3.687012E-4,0.02313932,0.0038304073,-0.0022502008,-0.0042618182,-0.021884305,0.0010107111,-0.0139228115,-0.010549962,-0.02236801,-0.02266869,0.016589716,0.031479932,0.007935349,0.012863893,-0.012373653,0.0027273677,0.0028580981,0.0046311324,0.0043271836,-0.017622488,-0.033310164,-0.0043043057,0.017949315,0.0020214221,0.0039676744,-0.0029201952,0.020511635,0.016066793,0.00979826,-0.01891672,-0.032970265,-0.026224563,-0.017021127,-0.0019331791,-0.008216419,-0.0068372115,-0.0033009483,-0.00241198,0.028996052,0.0030705356,0.011876877,0.011641562,0.033493187,-0.01639362,0.033911522,0.009562945,-0.014236565,-0.028499275,0.004065722,-5.707209E-4,0.0071444283,0.013367206,0.0050756163,0.0050363974,0.016119085,-0.001920106,-0.009033486,0.006529995,0.0032274122,0.015674602,-0.020302465,-0.011563123,0.006817602,-0.008549782,-0.030957012,-0.036186237,0.005147518,-0.02591081,-0.005291322,0.029597413,-0.008131444,-0.03346704,-0.013988176,0.0057325377,0.0155700175,0.023923704,0.020733876,0.028839175,-0.0034676297,-0.017400246,0.035637166,0.0058501954,-3.6053054E-4,0.02425053,-0.0065365313,-0.009896308,0.001673352,-0.018772917,0.0045134746,-0.013144964,-0.03649999,0.020132516,-0.010210061,0.010739521,-0.019857982,-0.009151144,-0.0035166538,0.025544764,0.0035918239,0.0027240994,-0.0141712,-0.020250173,-0.031140035,-0.008915829,-0.02031554,0.013118818,-0.0022191524,0.002547613,0.00896812,-0.009392995,-0.008504027,-0.0209169,-0.013870519,0.028080938,0.01793624,-0.008772025,0.024773452,0.010955227,-0.0029888288,-0.0043860124,0.012628579,0.027270408,-0.019714179,-0.02915293,-0.004837033,0.00947797,0.021805868,0.0085105635,-5.84611E-4,0.0052455664,-0.020720804,-0.0059874626,0.024132874,-0.006366581,-0.012491311,-0.025518617,-0.013700569,-0.0283424,-0.037545834,0.004000357,-0.018302288,-0.016249817,-0.0118507305,-0.01733488,-0.0011749414,0.014105834,-0.0022567373,0.01660279,-0.005340346,0.02506106,-0.031140035,0.023060882,0.013595984,0.018890575,-0.01993642,0.0070333076,0.017661707,-0.011288589,0.0062456555,-0.010144697,0.01109903,0.0042160624,-0.0065920916,0.021322165,-0.006647652,-0.008752415,-0.012112192,0.01447188,0.00184657,-0.01609294,-0.0139228115,0.04110171,0.014040469,-0.0052978583,-0.003964406,-0.020393977,0.025963102,0.0076869605,-0.0135044735,0.0173741,-0.012785455,-3.8075293E-4,0.009425678,0.022211133,0.0045102066,-0.0139097385,-0.008249102,0.0031032183,-0.009510653,0.009621774,0.010406158,-0.00514425,5.743977E-4,0.019400425,-0.013373743,-0.0072816955,-0.0017991802,0.009687139,0.0030803403,-0.0058175125,-0.019871054,-0.02108685,0.004157234,0.041598484,0.009386458,-0.02753187,-0.011184005,0.010883325,-0.030355651,-0.012157948,0.022642544,0.023544585,0.029597413,0.014903291,0.02608076,0.021335237,-0.014811779,0.012497848,0.0013440743,0.008464808,0.0012092582,0.0043141106,0.0021733965,0.0037552372,-0.030172627,0.016079867,0.021400603,0.019622667,-0.0077980817,0.008732806,0.001993642,-0.010896398,4.0567346E-4,-0.020302465,0.02266869,0.007739253,-0.0118311215,-0.031479932,-0.003817334,-0.0024446626,0.019740324,0.013197256,0.0023662243,0.0066770664,0.011863804,-2.1767159E-5,-0.0089419745,-0.016994981,-0.008785098,-0.028368546,0.026146125,-0.0036114336,0.01236058,0.0076608146,0.015975282,-0.00915768,0.004415427,0.0028711713,-0.008412516,-0.0036996766,-0.021884305,-0.0101969885,-0.001058101,-0.012765845,-0.0131515,0.011641562,0.02351844,-0.0076281317,-0.018367652,-0.020472415,0.036473844,0.022799421,-0.016615862,-0.011164395,-0.0032944116,-0.012994624,0.0021881037,-0.021779722,-0.01801468,-0.0043631345,-0.008039934,0.002277981,0.006239119,-0.02651217,0.0024773453,0.0017632293,-0.014824852,0.009621774,0.21523489,-0.012210241,-0.019583447,0.022433374,-0.0029724876,0.03940221,0.02327005,-0.01222985,-0.006170485,0.002632588,-0.028446984,0.018759845,-0.005647563,-0.005229225,8.2973094E-4,-0.018812137,-0.02394985,-0.0330487,-0.0020982265,-0.045703426,5.022405E-5,0.017962387,-0.0276626,-0.025936956,0.011948779,-0.02489111,-0.026368367,-0.0029610486,0.011530441,-8.0225705E-5,0.002903854,-0.027584162,0.0060332185,0.04034347,-0.021805868,-0.0017517903,0.022995517,-0.0031930956,0.0062783384,0.007026771,0.017008053,-8.726269E-4,-0.008556319,0.00834715,-0.0049808365,0.013792081,-0.012595896,-0.017792437,-0.011301663,-0.005843659,-0.017034201,-0.0063567767,0.005660636,0.025976175,-0.004320647,0.0018204239,0.033754647,0.00883739,-0.01852453,-0.0041997214,-0.012099119,0.015334702,-0.010360402,0.014837925,-0.03817334,0.023688389,-0.025806226,0.012948868,0.012641652,-0.039977424,0.013216866,-0.007765399,-0.005111567,-0.0019397156,-0.021675138,-0.012510921,-0.0020524708,0.019269694,0.014576465,-7.619144E-4,-0.024420481,-0.018498383,0.00221425,-0.018969014,-0.0062783384,-0.014654903,0.018223848,-0.019818762,-0.0173741,0.027008947,-7.0594536E-4,-0.02104763,-0.006510385,0.009151144,0.011804976,0.021544406,0.017191077,0.02988502,-0.018249994,-0.011903023,-0.0016137061,-0.04549426,3.552196E-4,-0.002671807,-0.019674959,-0.0032388512,-0.0011120273,0.010013966,0.010615326,-0.014929437,-0.017321808,-0.014445734,-0.024982622,3.0497002E-4,0.008183737,-0.0033728501,0.012497848,-0.0013841104,0.01720415,-0.015635382,-0.01592299,-0.024485845,0.008079153,0.014498026,0.012125265,-0.011327809,-0.0068502845,0.011974925,-0.0059253653,-0.026773632,0.004935081,-0.022041183,0.00570966,0.018249994,0.0014388539,0.013001161,-0.017021127,-0.023688389,-0.0059874626,0.00819681,0.005356687,0.013033843,-0.010308109,-0.004784741,-0.019413497,0.0041866484,0.030277213,4.5959983E-4,-0.008399443,0.0048795203,-0.016445912,-0.011876877,-0.004575572,0.0044905967,0.024368187,-0.0034610932,-0.022132695,-0.030669404,-0.0042585502,0.014824852,-0.04144161,0.0143280765,0.01767478,-0.02168821,-0.013582911,-0.009451824,-0.1686948,0.0056867823,0.011131712,-0.013857446,0.039977424,0.014001249,0.02274713,0.021112995,-0.021845087,0.015373921,0.0037094813,-0.0040036254,-0.03500966,-0.0029773898,-0.0030492917,-0.02967585,-0.012497848,0.009386458,0.0038826994,0.006719554,0.0139097385,-0.0011888316,0.012112192,-0.0020573733,0.010523815,0.0043990854,-0.012876966,0.025191791,0.0089289015,0.001452744,-0.012707016,-0.013210329,0.035192683,-0.0070333076,-0.0055102957,-6.7765446E-5,-0.022145767,0.0033499722,-0.022904005,0.016158305,0.03022492,0.019387351,-0.0036767987,-0.0071836477,-0.009942064,0.023413854,-0.004493865,-0.03009419,5.1230064E-4,-0.007909203,0.0025443446,-0.0036898719,0.0059972676,-0.016027573,0.00721633,0.016955761,0.014249638,0.005412248,0.019191256,-0.022354936,-0.020773096,0.0026309537,-0.014589538,0.0027224652,-0.017269515,-0.02253796,-0.0035591412,-0.0065920916,-0.019191256,-0.0012403068,0.0126677975,-0.0028123425,-0.018459164,-0.020563927,0.009582555,-0.0031865588,-0.017269515,0.020302465,-0.014524172,-0.01060879,-0.014105834,0.016210597,-0.0030934133,-0.0027012215,0.021034557,0.00570966,-0.0045592305,-0.004124551,-0.001132454,0.0065038484,0.015805332,-0.017191077,-0.0093472395,0.0056998553,0.036813743,0.007412426,0.010739521,0.037232082,-0.01155005,-7.07171E-4,-0.008399443,-0.006422142,-0.025257157,-0.004111478,0.023936776,0.015360848,0.03534956,0.019308913,0.0134914005,-0.0041801115,-0.0064450195,-0.006994088,0.0044873287,0.016432839,0.0012999526,0.014354222,-7.1003067E-4,-0.015622309,0.008706659,4.1752093E-4,0.04630479,0.0019413497,-0.038016465,-0.008131444,0.004837033,-0.01865526,-0.08141903,-0.015687674,0.013465255,0.015857624,0.0031930956,0.021230653,-0.0064286785,0.004441573,0.0027633186,0.015949136,-0.013288768,-0.026577536,0.0044775237,0.008353687,0.02506106,-0.011942242,2.300042E-4,-0.026642902,-0.017217223,0.014158127,-0.0022567373,0.019256622,-0.025636274,-0.013988176,0.002756782,-0.0058763414,-0.033284016,0.030957012,-1.5473195E-5,0.008379833,5.2215648E-5,-0.0012983185,-0.01207951,-0.013635204,0.015896844,0.0048533743,-0.057939813,5.609161E-4,0.0045265476,-0.045572694,0.006771846,0.023165466,-0.00896812,-0.027714891,-0.009131534,-7.243294E-4,-0.0058501954,0.014079688,0.017308734,-0.0058403905,-0.004961227,-0.04110171,-0.022171913,0.0017664975,0.008647831,-0.013975103,-0.014275784,0.026355293,-0.0060593644,0.031296913,0.01075913,0.0027910988,0.011177468,0.0337285,0.004788009,0.022590252,-0.012105656,-0.018249994,0.019544229,-0.026276855,-0.014550318,0.020773096,-0.010236207,0.023204686,-0.027767185,-0.00785691,-0.01865526,-0.029309805,0.013752862,-0.021740502,-0.028446984,-0.014707195,-0.0033450697,-0.014053542,0.025335595,0.004614791,-0.0056050755,-0.019583447,-0.005121372,-0.01302077,0.018759845,0.0151778255,0.02847313,-0.03231661,-0.0050723483,0.028760737,-0.011406247,-0.021465968,0.0051900055,0.029100636,-0.012157948,-4.7553264E-4,-0.06724783,0.010484596,0.005461272,-0.008870073,-0.0046344004,-0.05046202,0.01494251,-0.012576286,-0.01571382,0.0010352231,-0.021465968,0.0048762523,0.021112995,4.2405745E-4,-0.02967585,-0.0031113888,-0.006902577,0.0050004465,-0.0057292697,0.009066169,0.0039088456,0.0012460263,0.010935617,0.0039676744,0.008137981,0.024093654,-0.025244083,0.0030525601,-0.0097786505,-0.015543871,0.032421194,-0.029022198,0.004833765,0.0394545,-0.0134914005,-0.020851534,-0.005428589,-0.009138071,0.01758327,0.043324128,-0.028656153,-0.01613216,0.014837925,0.003398996,-0.007275159,0.0052717123,0.00587961,-0.00998782,0.011223224,-0.009654457,0.029780436,0.043402568,-0.030930866,-0.005758684,-0.020054078,-0.011321272,0.014236565,0.026577536,0.0114323925,-0.0060593644,0.015334702,0.018197702,0.033780795,0.017517904,0.031558372,0.019962566,-0.013870519,-0.010576108,0.0025361741,-9.126632E-4,-0.008059543,0.003506849,0.019034378,0.010987909,0.011203614,-0.006288143,-0.010563035,0.0051638596,-0.03176754,0.006994088,0.019923346,0.010020502,-0.027505724,0.0040068934,0.021230653,0.015818406,-0.013622131,-0.006739164,-0.020001786,0.005242298,-0.012478238,-0.002449565,0.0040689907,0.011968388,-0.0049514226,0.024695015,-0.013622131,0.019622667,0.008915829,0.0044677192,-0.0049514226,-0.00815759,0.003224144,0.025204863,-0.027479578,0.011765756,-0.019857982,-0.006056096,-0.0063829226,0.019073598,0.019178182,5.2006275E-4,0.026211489,0.012994624,-0.012916186,0.02040705,0.026250709,-0.020302465,-0.024708088,0.028028645,-0.0019707642,-0.003286241,0.0147464145,-0.016419766,-0.0027208312,-0.011863804,9.404434E-4,-0.012576286,0.0030558284,-0.017112639,-0.0071052094,-0.025976175,-0.0073535973,-0.007869983,-0.0114127835,0.014798706,0.016079867,0.020485489,-0.0049089347,0.049677636,0.012759308,-0.027714891,0.019426571,-0.011693854,0.031532228,0.008700123,0.035375707,-0.0061345343,-0.03176754,0.014236565,0.0027404407,0.026172271,-0.03103545,-0.034905076,-0.017361026,0.0020639098,-0.0033924596,-0.009569482,0.0042127944,0.018080045,-0.020158662,0.015687674,0.021818941,-0.0044742557,-0.030355651,0.0035918239,0.01126898,0.006203168,-0.0033009483,-0.015125533,0.0044644508,-0.00964792,-0.0065397993,0.0028074402,-4.0015826E-4,0.00474879,-0.026459878,0.0101839155,-0.0023351756,0.0099486,0.017308734,-0.009739432,-0.009759041,0.017648634,-0.0016815226,-0.003653921,-1.6686028E-5,-0.017151857]}]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springAIRocksDocuments.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springAIRocksDocuments.json
new file mode 100644
index 00000000000..dd597019021
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springAIRocksDocuments.json
@@ -0,0 +1 @@
+{"content":"Spring AI rocks!!","id":"f0849acf-58fb-4bfc-822f-1e75d7cb4b12","metadata":{"meta1":"meta1"},"embedding":[-6.9538393E-4,-0.018435681,-3.152407E-4,-0.021416139,-0.005411351,0.017262379,-0.014093114,0.0021948845,0.003106891,-0.029103292,0.022548983,3.253554E-4,0.0077545843,-0.012043207,8.298248E-4,-0.002795022,0.013074904,-5.588358E-4,0.013041188,-0.003627797,-0.0038536913,0.006574539,6.709401E-4,-0.014376325,-0.009393162,-0.0046156636,0.019743847,-0.029885493,0.009588712,-0.021712836,0.037761454,9.651086E-4,-0.018543571,-0.004231306,-0.018745864,0.013142334,-0.010148391,0.0071949055,0.015414765,-0.010418115,0.0063014426,0.016156508,-0.0061969245,-0.022602927,-0.023911092,0.019973112,-0.010573207,-0.0058260527,-0.012865867,0.005856397,0.012144353,0.021996047,-0.013688527,-0.011375638,-0.0056237592,-0.0070195845,-0.019757332,0.015913755,0.044909157,0.002061708,-4.184947E-4,-0.0046325214,-0.014821371,0.024814669,-0.0058901124,-0.004450457,0.012144353,0.008543529,-0.003143978,0.0036783703,0.0074039423,-0.011321693,-0.0067734607,-0.019460635,0.0010342256,0.006362131,-0.017626507,9.761715E-5,0.017950177,0.008253575,0.005731649,-0.008745822,0.0055428417,0.029480906,0.02094412,0.020188892,-0.008880685,-0.002083623,-0.0025219256,-0.008165915,-0.001115143,0.0067060296,0.011989262,0.0037356867,-0.022333203,0.023263752,-3.9194367E-4,-0.010694583,-0.010337198,-0.046608422,0.01153073,-0.001405097,-0.00882674,-0.013904307,-0.01869192,2.541312E-4,0.005549585,0.042184938,0.018975131,0.006412704,-0.008273805,-0.007970364,0.024517972,-0.031665675,-0.014484215,-0.019757332,0.010087702,-0.005893484,-0.025502468,-0.022117423,0.013863848,0.015522655,0.021389166,-0.0035097923,0.0054315804,0.0032956982,-0.021969074,-0.008145685,-0.004902246,-0.014915775,0.018017609,-0.011692564,0.023358157,-1.0620409E-4,-0.026203752,6.1741666E-5,-0.023897605,-0.0058429106,-0.018085038,-0.014241463,0.013762701,0.021038525,-0.006062062,-0.017707424,-0.009595456,0.024018982,0.009339217,-0.013654811,0.013675041,0.015994674,-0.01732981,-0.022225313,-0.0032046663,0.012724262,0.010748528,-0.008037795,7.236207E-4,0.009750547,-0.013344628,-0.013412059,0.0035367648,0.016129535,0.007815273,-0.019892195,0.007565777,0.009575225,0.022144396,0.018085038,-0.0041267877,-0.032987326,0.018165957,-0.001748153,-0.014511188,0.0065441946,-4.5221025E-4,0.00607892,0.005482154,5.672647E-4,-0.014942747,0.0067060296,0.023479532,0.010532748,0.02985852,0.022171367,-0.0015610316,0.005532727,0.016021645,-0.011564446,-0.008179401,7.0128415E-4,0.00493259,0.019069534,0.0033429002,-0.014956233,-0.660286,-0.035468794,0.007147704,-0.01754559,0.05116677,0.024787698,0.023047972,-0.015536141,0.0060957777,0.011368895,-0.0018847011,0.0137020135,-0.00995284,0.0049966495,-3.5612084E-4,-0.027026411,0.023263752,-0.01947412,0.007451144,0.028267145,-0.025596872,0.020027056,-0.0041402737,-0.008766051,0.0039413515,-0.016776875,-0.0029501135,0.008685134,-0.005657475,-0.0036446545,-0.023978524,0.02055302,-0.0028135655,-0.0038874068,0.05518567,-0.019029075,-0.022103937,0.035037234,7.823069E-5,0.04207705,-0.032636683,-0.0028523384,-5.1795563E-4,-0.009339217,-0.0065307086,0.008321006,0.0060890345,-0.0062980712,-0.01432238,-0.031449895,0.007147704,-0.01215784,0.0015290017,0.026082376,-0.018786324,-0.011274491,0.025987972,0.007505089,-0.0044167414,0.0032805263,-0.008745822,0.0070870155,-0.039649528,-0.017518617,-0.010971051,0.013256968,0.007309539,0.0061362362,0.0018071553,-0.041969158,0.02624421,0.0053405487,-0.013850362,-6.3385296E-4,0.017855773,0.008449125,0.018664947,2.4148787E-4,-0.025367605,0.004534746,0.0037289436,9.153781E-4,-0.0025944142,-0.03039797,0.022063479,0.001663864,-0.024895588,-0.031315032,-0.00653408,-0.011679078,0.021065496,0.046662368,7.442715E-4,-0.030910447,0.021362195,0.0014413412,-0.001625934,0.010620409,0.014093114,-0.04461246,-0.015279902,0.009157153,-0.004285251,0.010984537,-0.0018813296,0.00545181,-0.013364857,1.7626928E-4,0.02581265,-0.02477421,0.010856418,0.01912348,-0.020606965,0.010735041,-0.004463943,-0.022023018,-0.011389124,0.0028068223,0.02886054,-0.027916504,0.03050586,-0.007727612,0.012346647,9.3897904E-4,-0.007430915,0.016561095,0.009784263,-0.012312931,-0.03244788,-8.656476E-4,0.009265043,-0.0026618454,0.013155821,-1.4729495E-4,0.018219901,-0.027916504,-7.809372E-4,-0.004015526,0.016668985,-0.0023466046,-0.028321091,0.0117599955,-4.6822516E-4,-0.0041369023,-0.02048559,-0.023250267,-0.025556412,0.009197611,5.803295E-4,0.0022943455,-0.0041335304,0.012852381,-0.0046527507,0.006031718,-0.010937335,-0.0010586693,-0.030263107,-0.016722929,-0.0047876127,-0.033176135,-0.011429583,0.01940669,-0.0019453892,-0.023466047,-0.010809216,-0.011018253,-0.031530812,0.039946225,-0.02749843,-0.032313015,0.028348062,-0.018637974,0.0019555038,0.016884765,-0.022252286,0.008941373,-0.025286688,-0.0013907679,0.009123437,-0.0014674708,-0.015050637,0.015198985,0.003100148,7.7672274E-4,0.02602843,0.030640723,0.021996047,0.029480906,-0.033311,0.0034238175,-0.0074916026,0.039973196,0.011665592,-0.0020094488,-0.012414078,0.0038267188,-0.02592054,0.0036311683,0.020687882,0.017410727,0.02044513,0.03104531,0.025165312,0.0059069702,0.002397178,-0.024544945,-0.019676415,-0.02453146,0.03225907,0.013877334,0.008927886,-1.3286047E-4,0.0010291681,-0.0114902705,0.011213803,0.011132886,0.012589399,-0.0070128413,-0.00832775,-0.0020364213,0.00363454,0.006655456,0.0013199651,-0.022886138,-0.007936648,0.024248248,-8.1591716E-4,0.027066872,0.01776137,-0.018894212,-0.0055799293,0.006220525,0.023371642,0.0053506633,0.030451916,-0.011159859,0.017599534,-0.0069656395,0.03519907,-6.706241E-5,0.014241463,-0.006308186,0.021078983,-0.010896876,0.026325127,0.008557015,0.047498513,0.015441737,-0.024180816,0.00956174,-0.024248248,-0.022670358,-0.030748613,0.015104582,0.022481551,-0.001107557,0.005077567,-0.004993278,-0.008752566,0.024517972,0.011996005,0.0378154,0.0059508006,0.0044403425,-0.011402611,0.012151096,-0.009858437,-0.0015214157,0.011186831,-0.00716119,9.836522E-4,-5.314419E-4,0.00821986,-0.0049123606,0.029211182,-0.002204999,0.015671004,6.1825954E-4,-0.005809195,0.009689859,0.0070195845,-0.05202989,0.015010178,0.037275948,9.044205E-4,-0.006395846,-0.011786968,0.0014480844,-0.010566464,0.012670317,0.016992655,0.0189077,-0.008368208,0.0013730671,-0.018179443,-0.0065273372,0.017774856,0.005674333,0.018058067,-0.024248248,0.006786947,0.028779622,-0.011611647,-0.03803118,0.01700614,-0.014983205,-4.336667E-4,-0.026837604,-0.021726321,-0.032501824,-0.0034170744,-0.010020272,-7.4216427E-4,0.0012811922,0.0055833007,0.0069116945,0.0029180837,-0.035360903,0.041996133,-0.0011176716,-0.013445775,-0.028240172,-0.008880685,-0.014632563,0.07751887,-0.002098795,0.017410727,0.008058025,-0.0128928395,-0.021335222,-0.017356783,-0.009393162,-0.005670961,-0.016695958,-0.022373661,0.0189077,0.001748153,-0.028590815,0.0067161443,0.026379073,0.022373661,-0.029319072,0.0025320402,-0.0054383236,-0.0040188977,0.023857147,0.0064531625,0.031180171,0.019649442,0.0022286,-2.9290412E-4,0.017923204,-0.018570544,-0.024747238,0.013020959,7.206706E-4,-0.010910363,0.002388749,0.014308894,-0.002230286,0.0038975214,0.016143022,-0.007693896,-0.023493018,0.01786926,0.010950821,0.015778894,-0.013782931,0.015279902,-0.013971738,0.018786324,0.022535495,-0.016237425,-0.034848426,0.0018644718,0.021712836,-0.014780912,-0.002634873,-0.017680451,0.053648237,-0.01514504,-0.013836876,0.019608984,-0.0385976,-0.024679808,-0.0123533895,-0.014484215,-0.006803805,-0.012865867,-0.026365586,-0.008118712,0.016668985,-0.007956877,0.009986556,0.0030293453,-0.011234033,-0.03061375,-0.013540179,0.025826138,0.013344628,0.012508482,-0.0071949055,-0.016722929,0.024679808,-6.1362365E-4,-0.0029754003,-0.0032366961,-0.0025252972,-0.010721556,-0.010883391,-5.8117235E-4,-0.0051213973,0.01622394,0.020296782,0.03309522,0.014983205,0.024477514,-0.00945385,-0.011348666,-0.021942101,0.028887512,0.02689155,-0.015050637,0.015954215,0.01668247,-0.030883474,-0.010000042,0.0012972071,0.0066824285,-0.0030630608,0.033068243,0.0122455,0.0012575913,-0.009447106,-0.010512519,-9.7606616E-4,0.0046628653,-0.047741268,0.018853754,-0.019083021,-3.2029804E-4,-0.017262379,-0.023425588,0.015023665,0.0123264175,-0.019716874,0.026122835,0.013263711,-0.0045988057,0.0036783703,0.020431643,-0.011011509,-0.011092427,0.0155766,-0.00861096,0.003405274,0.0048449296,-0.0061598374,0.0060856626,-0.017734397,-0.009575225,0.011045225,0.0053000897,-0.027012926,-0.015819352,0.008590731,0.0038739205,-0.0040795854,-0.03476751,-0.024504486,-0.0078085293,0.025758706,-0.010195592,0.017518617,-0.029561823,0.028267145,-0.012825408,0.009332473,-0.0053000897,-0.012508482,1.7426742E-4,0.0072960523,0.033715583,0.015522655,0.035576683,0.009514538,0.03762659,0.002810194,-0.0050573377,-0.019770818,0.014767426,-0.011449812,-0.0022167997,0.0062812134,0.012724262,0.0032923268,0.028887512,-0.015711462,0.0013275511,0.006628484,-0.02198256,-0.020755313,-0.01568449,-0.030532833,4.395669E-4,0.00986518,0.018624488,0.013344628,4.4335992E-4,-0.0030057442,0.008361464,0.0028658246,0.013540179,-0.004238049,0.01912348,-0.0016048618,-0.01654761,0.015940728,0.00945385,-0.019770818,0.014915775,-0.022009533,0.012319675,0.019029075,-0.0050876816,0.032339986,0.017316325,0.023870634,-0.0031338634,0.0077748136,-0.028671732,-0.007673667,-0.0030967763,-0.023735771,0.01546871,-0.014295408,1.9217882E-4,-0.03784237,-0.0034760768,-0.01503715,-0.00861096,0.0054079797,-0.0016040188,-0.015172013,0.033445857,0.020903662,0.024976505,0.014619078,0.031773567,0.014699995,0.0126500875,-0.011874628,-0.01958201,0.011065454,0.0011867885,0.008644676,0.010532748,-0.0122994445,-0.012771463,0.0010375971,0.033068243,-0.022495037,-0.023506505,0.015940728,0.008105227,0.003258611,-0.027619807,-0.023128891,0.0012112324,0.023371642,-0.006992612,-0.015172013,-0.0036783703,0.004221191,-0.007842245,0.004180732,-0.00571142,0.021847699,0.009716831,0.01676339,-0.0014877002,-0.0023179464,0.013985224,-0.010074217,-0.011287977,0.029130265,-0.010600179,0.0054686675,0.007390456,-0.014848343,0.013358114,-0.025691275,0.010930592,0.029103292,-0.03447081,-0.010175363,-0.013654811,-0.0012011176,0.0123264175,-0.012879353,-0.015131554,0.02219834,-0.014025683,3.0639037E-4,0.0014716852,0.0066217408,-0.014403298,0.0044706864,-0.026594853,-0.01492926,0.027700724,8.740765E-4,-0.018611003,-0.023681827,-0.0016065476,0.009413391,-2.971186E-4,-0.0024898958,0.04299411,-0.027646778,-7.704011E-4,0.010593437,-0.0060553188,0.007498346,-0.0054922686,0.01564403,2.4180395E-5,0.008799767,-0.00419759,-0.0066385986,0.01646669,-0.006985869,0.007498346,-0.011213803,0.0034996776,0.009595456,0.0037828884,0.007997337,0.04121393,0.014767426,-0.005060709,-0.007518575,-0.0010139962,-0.0020414786,8.31932E-4,0.011132886,0.018867241,-0.005391122,0.015333847,-0.0056170165,0.020000083,-0.005778851,-0.028348062,-0.01068784,0.0016697643,0.004443714,-0.006352016,-0.036143105,-0.019217882,-0.0013983538,-0.018071553,0.001282878,-0.00674986,-0.021308249,-0.003617682,0.029912466,0.03314916,-0.0127310045,6.785261E-4,-0.01265683,0.009035776,0.0030445172,-0.024234762,0.010532748,0.009993299,0.033877417,0.015482196,-0.024261734,-0.018934673,-0.012387105,-0.024194302,-0.013229995,-0.0075388043,0.011699308,0.015306875,0.0025539554,0.0035907098,0.029373016,0.01858403,-0.0059440574,-0.015495682,-0.007869218,-0.008988575,-8.100169E-4,-0.007848988,-0.0073634833,-0.020000083,-0.0069116945,0.013452518,0.015131554,-0.0052933465,0.006038461,0.00486853,-0.009413391,-0.0021257675,-0.014335866,-0.002169598,0.030101273,-0.0013427231,-0.03244788,-0.007923163,-0.009608941,-0.011969033,0.0037222004,0.021739809,0.018813295,0.0055428417,0.009764033,-0.0045010303,-0.012130867,-0.013735729,-0.0076669236,0.01879981,-0.014106601,-0.010998024,0.010708069,0.017963663,-2.5971536E-5,6.1278074E-4,0.0125152245,-0.004288622,-0.019136965,-0.0029450562,-0.01958201,0.022211827,-0.013634582,0.008240089,-0.018031094,-0.012076922,0.0046156636,0.022683844,-0.041294847,0.01912348,-0.022063479,0.0023246894,-0.0025859852,-0.04118696,0.008678392,-0.022265771,-0.01607559,7.687153E-4,-0.025043936,-0.005323691,0.015104582,-0.02327724,-0.019352745,0.020647423,0.026797146,-0.013823389,0.01797715,0.2373577,-0.018192928,-0.017774856,0.00493259,0.0011404296,0.0013637954,0.017923204,0.0040424983,-0.014619078,0.002611272,0.02477421,0.026945494,-0.026958982,-0.0036851133,0.006938667,0.0027528773,-0.021537514,-0.015091095,-0.017410727,-0.009056006,0.030640723,0.009049263,-0.0045920624,-0.016453205,0.010640638,-0.007215135,-0.015819352,0.001518887,-0.007977108,0.016884765,-0.011294721,0.002907969,0.009858437,4.6822516E-4,-0.011341922,-0.0248821,-0.007026328,0.01654761,0.014659536,0.0075860065,-0.010101189,-0.008213116,-0.007619722,-0.00997307,-0.0029416848,0.010627152,-0.011645363,-0.0067599746,-0.01639926,0.02972366,-0.016844306,-0.01194206,0.02148357,0.024140358,-0.0030630608,-0.010033757,-0.0010173677,0.017532103,0.011186831,0.025259715,-0.015212472,0.031530812,0.014996692,-0.0035435078,-0.023398615,-0.00486853,-0.02356045,0.025772192,0.021996047,-0.0016427918,-0.008415409,-0.029480906,0.010923849,-0.01925834,-0.026851092,-0.027525403,0.018772837,0.012016234,0.015225958,-0.008927886,7.7292975E-4,-0.009292015,0.018098526,-0.020876689,-0.0203777,-0.022913111,0.021119442,-0.0019976483,0.00374243,0.014605591,-0.0074713733,-0.013863848,0.007990593,-0.022994028,0.018233387,-0.0019453892,0.025111366,0.031449895,-6.309029E-4,0.009892153,-5.322848E-4,-0.023708798,3.3357355E-4,0.027080357,0.0020178778,0.0063924748,0.001984162,0.008577244,-0.005182085,-0.006008117,-0.034605674,-0.039406773,0.0028422237,-0.011045225,0.006287956,-0.015819352,-0.02875265,-0.02399201,0.021025037,-0.044639435,-4.758112E-4,-0.004234677,0.002864139,0.014821371,4.9756825E-5,-0.024855128,-0.03215118,-0.0012002748,-0.010674354,-0.0078085293,0.013445775,-0.011733023,-0.003442361,0.009683115,-0.011901601,0.0076669236,0.015940728,0.0025960999,-0.0025455265,0.004342567,-0.009608941,0.019676415,0.0046291496,0.0030681181,-0.0017970406,-0.019878708,0.014376325,0.010890134,-0.036466774,-0.01879981,-0.009777519,0.010027015,-0.007815273,0.0068375203,0.046743285,-0.012097151,-0.029669713,-0.005077567,-0.008685134,0.040431727,-0.04256255,0.017815314,-0.005313576,-0.0125961425,-0.037302922,-0.023857147,-0.17413425,0.013769444,0.027457971,-0.03716806,0.028725678,0.011476785,0.0064329333,0.0138099035,-0.006618369,-6.321672E-4,0.027700724,0.038112096,-0.009959583,-7.282566E-4,0.020741828,4.977263E-4,-0.010735041,0.03309522,0.018449167,0.0026854463,-0.0011387438,-0.01915045,0.0016756646,0.0025505838,0.0038334618,-0.0030293453,0.004514517,0.01068784,0.004285251,-0.018651461,-0.021335222,-0.045340717,0.017397242,0.009541511,0.014659536,5.231842E-6,3.434775E-4,-0.018570544,-0.023897605,0.01979779,0.0063655023,0.026001459,0.010748528,-0.0039649527,0.0074174283,0.021025037,0.0072421073,-0.0048415577,0.013850362,-0.0203777,6.612469E-4,-0.027862558,-0.0018358135,-0.0012432622,0.030020356,0.019096507,-0.011449812,0.011591418,0.013149078,-0.012501738,-0.00956174,-0.0012002748,0.028186228,-0.019770818,-0.005219172,-0.0014750567,-0.0068948367,0.015886784,-0.022117423,0.022346688,-0.00616658,-0.009838208,0.0028742536,-0.024909073,0.0030242878,-0.0038874068,-0.02442357,0.017599534,-0.0021830841,-0.022818707,0.0077073826,0.02463935,-0.010526005,0.0023499762,-0.015738435,-0.005670961,0.015738435,0.011955546,-0.025178798,-0.0075455476,0.034066226,-0.024625862,-0.026500449,-0.008469354,0.0034406753,0.03420109,-0.004093072,0.00181727,0.00456509,-0.0056777042,-0.0063722455,0.003275469,-0.011004766,0.007201649,0.013796417,-3.7382153E-4,6.86955E-4,0.0043021087,0.031422924,-0.023385128,-0.0059339427,0.02051256,0.01079573,0.031746592,0.004093072,0.023803202,-0.018246874,-0.029426962,0.0063351584,-0.016453205,0.028482925,0.004834815,-0.006112635,0.032717604,-1.68894E-4,-0.0076534376,-0.09564437,-0.049818147,0.009480822,0.02983155,-0.008948116,0.007046557,-0.0042414204,0.021551002,-0.025165312,0.00945385,0.023681827,-0.039541636,-0.009764033,-0.0014868572,0.03757265,-0.0036918565,-0.011685821,-0.019959625,-0.022049991,0.010654124,7.75037E-4,0.006405961,0.02026981,-0.016938709,0.0071881623,-0.010411372,-0.036439802,0.017100545,0.01568449,0.022575954,0.015428252,-0.011719537,0.013445775,-0.027781641,0.008260318,-0.008388437,-0.021928616,-0.01265683,0.0021493684,-0.028132282,0.0076871533,-0.004534746,0.02366834,-0.012387105,-0.014983205,-0.0031507213,0.006797062,0.016480178,0.010654124,-0.023196321,-0.03946072,-0.03312219,-0.014147059,-0.009318987,0.020984579,-0.012737747,0.04121393,0.00319118,-0.011429583,0.009703345,-0.0042110765,0.006830777,4.1512314E-5,0.020081002,0.0028742536,0.013128849,-0.018314306,-0.0076332083,0.0046089203,-0.007848988,0.004147017,0.030020356,-0.012090408,0.030155217,-0.011213803,-0.008698621,-0.028590815,-0.031611733,0.01153073,-0.0035232785,-0.036385857,-0.021604946,-8.7070494E-4,-0.026365586,0.023128891,0.0052495166,-0.016736416,-0.007518575,0.00497642,-0.02875265,-0.009487566,0.006220525,0.013776188,-0.019285314,-0.026756687,-0.003985182,-0.0051348833,-0.0047201817,0.013863848,2.945899E-4,-0.038570628,-0.009703345,-0.07029025,0.017397242,0.0013570522,0.008799767,0.014511188,-0.02585311,0.020822745,-0.033877417,0.006308186,-0.009426877,-0.022117423,-0.015428252,-0.0022640014,0.019716874,-0.0056777042,-0.006985869,0.035603657,0.008563758,0.008698621,-0.0131895365,0.006918438,0.00726908,0.015225958,-0.010600179,0.0032164666,-0.0011741453,-0.0071342173,0.019190911,-0.0119757755,-0.004281879,-0.005795709,-0.019932654,-0.015293389,0.022670358,-0.032205127,-0.028375035,0.0047201817,0.008887428,0.01486183,0.0020515933,-0.023519991,-0.037788425,0.022764763,-0.02180724,-0.024234762,0.0018965016,-0.010782244,-0.011557702,0.0166555,0.012070179,0.0031692649,0.026446505,-0.025354119,-0.026257697,-0.03684439,-0.023857147,0.010842931,0.017141003,-0.014740453,0.004352682,0.022778248,0.014915775,0.037464757,8.2476746E-4,0.011281234,0.0065677958,-0.005778851,0.004642636,0.009642657,-0.005397865,-0.01983825,-0.008321006,0.01486183,0.00986518,0.0059103416,0.017801829,0.006352016,-0.006405961,-0.02399201,0.013594124,0.0053641493,-0.013486234,-0.023209808,0.021470083,0.020714855,0.01923137,-0.013128849,0.010593437,-9.221212E-4,-0.007842245,-0.037491728,-0.008246832,0.007215135,0.0027225334,0.010445088,0.021645404,-9.08635E-4,0.005394493,0.016021645,0.024437055,-0.0027697352,-0.0018543571,0.0043695397,-0.013317656,-0.005043851,0.0012643344,-0.008597474,-0.008705364,0.0027697352,-0.0012584341,0.027066872,0.028617788,0.007639951,0.022103937,-0.001625934,0.01464605,-0.008819996,0.0021510543,-0.03004733,0.006931924,0.03463265,0.013823389,0.008388437,-0.0011395867,0.01815247,0.012704032,0.007929905,-0.0123803625,-0.0063553876,-0.009548253,0.005940686,-0.00809174,-0.022656873,0.0017312953,-0.02388412,-0.00523603,-0.013492976,0.00861096,-0.047903102,0.083560705,0.0074713733,0.008786282,0.006068805,-8.1591716E-4,0.010155134,-0.011254262,0.017275864,-0.037788425,-0.01711403,-0.013681784,-0.0126770595,-0.014551646,0.0018425566,0.0014379696,-0.009082979,0.0017093801,0.013641325,-0.0037828884,-0.015617059,0.009851693,0.02377623,0.026095862,0.014416784,-0.019932654,-0.020256322,0.013304169,-0.0028725676,0.003985182,-0.026689256,0.006200296,-0.027417513,-0.037653565,0.00337493,-0.0089144,0.01711403,0.007869218,-0.0048887595,-0.006483507,0.021105956,-0.016480178,0.021942101,-0.026797146,-0.03490237,0.024410082,0.014888802,-0.02169935,-0.00893463,-0.0012887781]}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springEmbeddingValues.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springEmbeddingValues.json
new file mode 100644
index 00000000000..457ca3c805c
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/springEmbeddingValues.json
@@ -0,0 +1 @@
+[0.0071215807,-0.010692772,-0.0036266665,-0.014797909,-0.008404436,0.021094302,-0.008099324,-0.02078919,-0.009167215,-0.02808413,0.02252278,0.0140628675,-0.021038827,0.0016191714,0.0061854427,-0.015144627,0.035087828,-0.012835487,0.018473117,-0.017127851,0.002340344,-0.0026281197,-0.0059878137,-0.0046702866,-0.007544576,0.006899681,0.003692543,-0.028389242,0.0045107966,-0.012363952,0.021510363,-0.016004486,-0.023479719,-0.021524232,-0.011108833,-0.015602294,-0.0063969404,-0.006462817,0.0076693944,-0.007482167,0.015269445,0.017405225,0.0045246654,-0.008314289,-6.7393243E-4,0.008466844,-0.0027841427,-0.0018011981,-0.0025015678,0.0043305033,0.010040943,0.018278955,-0.028042523,0.004698024,-0.011961759,-0.011441682,0.0069066156,0.0075584445,0.030954951,-0.027889967,-0.012114314,0.00943072,-0.009950796,0.022134455,0.010727444,-0.0032834162,-0.013154468,0.020303786,-0.0038416316,0.02282789,0.024977539,0.009132543,-0.0015827661,-5.6168257E-4,0.009354442,-0.015602294,-0.00836283,-0.02239796,-0.01833443,0.017946105,0.010692772,-0.015380395,-0.01704464,9.9247925E-5,0.027612593,0.016781135,-0.009104805,0.016448285,-0.008390567,-0.003751485,0.0010089483,0.02431184,0.00931977,0.010491676,-0.010713575,-0.015019808,0.010970146,0.02058116,-0.022592122,-0.03428344,0.014548273,0.010741313,-0.012398623,-0.01237782,-0.018237349,-0.010027074,0.025130095,0.016531497,0.0053914594,-0.012571982,-0.009825978,0.02099722,-0.0020092288,-0.058692362,0.0024391587,-1.2839388E-4,0.017613256,-0.009569407,0.0073781516,-0.019208157,0.023313295,0.0011805736,0.036308274,-0.02551842,0.015574557,-0.002782409,-0.014312505,-0.005249305,0.0026263862,0.010061746,0.023216214,0.010165761,0.017599387,0.0091949515,-0.023479719,0.017086245,-0.021940293,-0.0043478394,-0.0077664754,-0.02775128,-0.006726322,0.012703734,-0.023119133,-0.024187023,0.011809203,0.008244946,0.013542791,0.012606653,0.009645685,-0.010838394,0.021080432,-0.012884027,0.0056064245,-0.011961759,-0.01640668,0.0024148885,-3.5820267E-4,0.017308146,-0.016989164,0.0038000254,0.007149318,-0.009354442,0.020026412,-0.013189139,-0.003924844,0.015865799,0.006806067,0.011975627,0.015394264,-0.017169457,4.3014658E-4,0.006674315,-0.018903047,0.015200102,2.8864245E-4,0.03181481,0.006268655,-0.009132543,-0.02067824,-0.0215381,-0.03012283,0.006674315,0.018070923,0.017530045,-0.020026412,0.0025813128,-0.012128184,-0.0026697258,0.0029939068,0.0018237348,0.016351204,0.0053741233,0.0063900063,0.0057659145,-0.6856688,-0.0197213,-0.006313728,-0.005661899,0.011892416,0.012953371,0.032092184,0.0027095985,-0.020719847,0.0014718164,0.009437654,0.011192045,0.0044899937,6.1412365E-4,-0.0030840535,-0.011691319,-0.0028569533,0.0056064245,-0.0059947483,0.008300421,-0.010061746,0.023313295,-0.001208311,0.014936596,0.012960305,7.285405E-4,0.0018688081,-0.006896214,-0.0036197323,0.010685838,-0.021690655,0.038416315,0.020664372,0.02174613,0.04629374,-0.014534404,-0.029928667,0.037334558,0.00281188,0.074669115,-0.022203797,0.013501185,0.022703072,-0.014659222,-0.0055232123,0.01992933,0.015713243,-0.0013660676,-0.010047877,-0.0037965581,0.024048336,0.009409917,0.013189139,0.013861772,0.023923518,0.0031776673,0.020608896,0.009895322,-0.010214302,0.01013109,-0.0019762905,0.008425239,-0.017987711,-0.020622766,-0.014153014,6.9690245E-4,-0.004857514,-0.00916028,0.0151862325,-0.028763697,0.011004818,0.030455679,-0.0068476736,-0.01088,0.021551969,0.028236685,0.0012776545,-0.0072949394,-0.013917246,0.005245838,0.001574965,-0.014520535,-0.015144627,-0.004437986,0.019124946,-0.014451192,-0.024561478,-8.1608666E-4,0.02047021,-0.0075723133,0.021302331,0.037889306,5.2847354E-5,-0.009971599,-0.0016330401,0.0074058888,-4.7413638E-4,-0.003292084,0.0018202676,-0.02432571,0.004732696,0.005481606,0.023798699,0.0016573103,0.019277502,0.023937386,-0.031703863,0.02174613,0.023382638,-0.022675334,-0.0059427405,0.0138062965,-0.010470873,0.0069412873,-0.01049861,-0.03555936,0.0072047925,0.015477476,0.025227176,0.009402983,-0.010852262,0.0017786615,-0.009409917,-0.020276047,-0.0021063096,0.0087026125,0.0042507583,0.0040357932,-0.004205685,-0.015907405,0.019749038,0.010831459,0.010852262,-0.016878216,0.027154926,-0.0026489228,0.002837884,0.004358241,0.030705314,-0.011081096,-0.010013206,-0.008161733,-0.007974505,0.008217208,-0.012461032,-0.033257157,-0.025449075,-0.021260725,4.6633524E-4,0.020539554,-0.020068018,0.013362498,-0.028125735,-0.009715028,0.016656315,-0.013307023,-0.02164905,-0.017502306,-0.01981838,-0.0051210197,0.027460037,0.03653017,-0.014340241,3.2721477E-4,0.0016850478,-0.011219783,0.013882575,-2.4573613E-4,3.837731E-4,-0.031232325,0.021246858,-0.016586972,-0.009812109,0.011857743,0.0026402548,0.003869369,-0.012017233,-0.01371615,0.022481171,0.0074752322,0.00559949,-0.010394595,-0.026170248,-0.009638751,0.006175041,0.02851406,0.015200102,0.015075283,-0.019222027,-0.0039352453,-0.00353652,0.0126829315,0.013771625,0.008286552,-0.006702052,-0.0018497386,-0.0029748373,0.019790644,0.025019145,0.0031221923,0.048290834,0.0087026125,0.005384525,0.0030927213,0.012710669,-0.031870287,-0.0048471126,-0.013736953,0.016573103,0.017100114,0.019319108,-0.027654199,-0.01938845,-0.02101109,0.0046494836,0.007849688,-0.009298967,-0.016004486,-0.013168336,0.001317527,-0.0031481963,0.012738407,0.017308146,-0.013293155,0.0016824474,0.021732261,0.011698253,0.032203134,-0.00666738,-0.01940232,-0.017724207,0.014326373,0.010984015,0.016365074,-0.008834366,2.8631293E-5,-0.0011970426,-0.003127393,0.029928667,0.0037376161,0.002071638,0.013445711,0.0041502104,0.0013565328,0.0054053282,-0.0088413,0.01863954,0.0032470108,-0.02238409,9.266029E-4,-0.0045974758,-0.013112862,-0.011809203,0.018473117,3.8875715E-4,-0.014534404,0.0073226765,-0.006171574,0.031981237,0.03633601,0.0063692033,0.018736621,0.013903378,0.008473779,0.029457131,0.0012993243,7.047036E-4,-0.010547151,-0.0036994773,-0.022675334,0.02142715,-0.0013400638,0.009728897,-0.0016122371,0.0039005736,-0.023507457,-0.0135497255,0.005526679,-0.0041328743,-0.013854837,-0.013882575,-0.01811253,0.012509572,0.010748247,-0.012336214,0.006917017,-0.017765813,0.009049331,0.0038034925,0.0060432884,-0.012405558,0.0043097003,-0.002829216,0.003056316,0.0041363416,-0.018278955,0.020345392,-8.576928E-4,0.01280775,0.0067713954,0.001128566,0.005173027,-0.0043929126,-0.012793881,0.035947684,0.012065774,-0.012024168,-0.04210539,-0.012322345,-0.023438113,0.007801147,-0.0037826896,-0.008716482,0.022120586,-0.0029835054,0.0031637985,0.0012369152,-0.005873397,0.016573103,-0.013362498,-0.026863683,-0.0070591713,-0.011566501,-0.017973842,0.092421055,0.01703077,0.021274595,0.022855626,0.012863224,0.015491344,0.0064108092,-0.001894812,0.00469109,-0.014173818,0.01259972,0.009333639,-0.0070036966,-0.0046460163,-0.0047465647,-0.008023046,5.2050984E-4,-0.023230081,0.017627126,-0.019360714,-0.010977081,7.7491393E-4,0.0011511026,0.027362956,0.008127062,0.0016599108,-0.0041155387,0.011004818,0.015519082,-0.018584065,-0.016947558,0.014714696,-0.0058317906,-0.0023004715,-0.00532905,0.0035677245,0.00605369,0.00750297,0.0087026125,4.0089228E-4,0.017627126,0.0029072275,-0.004659885,-5.5214786E-4,0.011011752,-0.0046425494,0.006601504,0.026447622,-8.570427E-5,-0.016476022,0.023493588,0.029124282,-0.012322345,-0.0030407137,-0.015935143,0.023868043,0.0056272275,0.0025414403,-0.009125608,-0.031703863,-0.028375372,-0.042299554,-0.0020300318,-0.012960305,0.0017361887,-0.013723085,-0.020608896,0.0017439898,-0.004770835,-0.00820334,-0.012724537,-0.024408922,-0.01875049,0.0026090504,0.02926297,6.7664114E-5,0.012301542,-0.03664112,0.004500395,-0.00986065,0.023105264,-0.011219783,3.5581898E-4,-0.011587304,-0.024963671,0.013882575,0.0049372595,-0.013792428,0.019610351,0.03206445,0.008910644,-0.009285099,0.0111851115,-0.028846908,-0.017391358,0.012703734,0.024977539,0.013528923,-0.009832912,-0.0013643339,0.023410376,-0.013355563,-0.017363619,4.8453792E-4,0.018057056,0.0069620903,0.020331522,0.025338126,-0.008224143,-0.008903709,0.0027668069,-0.023826437,7.1467174E-4,-0.0058907326,-0.0011823071,-0.016462155,0.0011519694,-0.0019190821,-0.008529254,-0.011830006,8.689611E-4,-0.022217667,0.019124946,0.010311383,-0.0012767877,0.013071255,0.008085456,-0.005166093,-0.013133665,7.8618224E-4,-0.0131752705,0.020872403,-0.014243161,-0.009465392,-0.0518967,-0.021787737,-0.027168795,0.015338789,-0.007246399,-0.013653741,-0.0065113576,0.013653741,-0.0023646143,-0.033839643,0.0149504645,-0.04798572,-0.008432173,-0.0016971829,-0.009742766,0.015893538,-0.018195743,0.015879668,-0.004854047,0.012273804,-0.0088204965,-0.031010427,-0.011670516,-8.316889E-4,-0.0062825237,0.01843151,0.018251216,0.011823072,0.0319535,4.0793497E-5,2.485532E-4,0.0043131677,-0.0062721223,0.0022207266,0.0029748373,0.036474697,0.02292497,0.021232989,-0.008633269,0.0058629955,-0.0046564178,0.019263633,0.007086909,-0.012495704,-0.0105540855,-0.023479719,0.013910312,-0.007967572,-0.017738074,-0.014673091,0.021260725,-0.010581822,0.031703863,0.0065529635,0.010276711,-0.016170911,0.02550455,-0.0053394516,0.027709674,0.009486195,-0.0063900063,-7.809815E-4,-0.011642778,-0.005006603,-0.010561019,0.03985866,-0.012509572,0.016614709,-0.0038450987,0.012259936,-0.017973842,0.02776515,-0.019749038,-0.009049331,0.0016833142,-0.026170248,-0.023230081,-0.012461032,-0.019624218,-0.032286346,-9.396048E-4,0.0010626896,-0.001877476,0.019915462,0.0031984702,-0.0050447416,-0.009042396,-0.0056861695,0.016365074,0.016170911,0.04499008,0.03139875,-0.016157042,-0.028957859,-0.0011563033,-0.008432173,-0.020220574,0.013910312,0.0155606875,-0.01628186,-0.012655194,-0.0021271128,-0.0068546077,0.004462256,0.004129407,0.031676125,0.02399286,0.010678903,-0.02004028,-0.01275921,-0.01334863,0.02786223,-0.015519082,-0.002690529,-0.02474177,-0.02626733,-0.0056272275,0.018278955,-0.007544576,0.025116226,0.010325251,-0.018819833,-0.012246068,0.0031412619,-0.0039213765,-0.007586182,-0.020442473,0.03633601,-0.0029418992,0.010463938,0.009971599,0.0145760095,-0.01409754,-0.0052076993,-0.012592785,0.030649839,-0.039581288,3.081453E-4,0.004971931,0.014173818,0.0063934736,0.007627788,-0.018722752,-0.013723085,-0.005013537,-7.840153E-4,0.025462944,0.023701617,-0.010547151,-0.004912989,-0.025046883,-0.03131554,0.0021877883,-0.025476813,-0.019416189,-0.016989164,-0.023965124,-0.0020386998,-0.0027147993,0.031648386,-0.009791306,-0.022536647,0.00106529,0.008674876,-0.016434416,0.008508451,-0.003789624,-0.009125608,-0.030233778,0.0105540855,0.0084460415,-0.010034009,-0.0036440024,-0.011615041,-0.021662919,0.010366858,-0.013369433,0.011386207,-0.003477578,-0.0048263096,0.023299426,-0.015491344,-0.014014327,-0.011580369,-0.018792097,0.03001188,-0.009208821,-0.016878216,0.0040947353,-0.026322804,0.011552632,0.010665035,0.031870287,0.018265085,-0.014104473,-0.010935474,-0.013085124,0.013764691,-0.011504091,-0.022578252,-0.018792097,-0.011212849,-0.011032555,0.010893868,-0.010144958,-0.01777968,4.8540471E-4,-0.0012707202,0.034338914,0.006917017,0.019998673,-0.02881917,-0.023618406,-0.01259972,-0.016753396,-0.025254913,-0.012606653,0.03192576,0.02238409,-0.004278496,-0.026059298,-0.001002014,-0.01875049,-0.034033805,0.011531829,0.009548604,0.01983225,-0.00607796,0.0029488336,0.027182663,0.0054295985,0.008335092,-0.01811253,0.0135705285,-0.006358802,0.0015862333,0.022883365,-0.012988043,-0.022300879,-0.0074128234,-0.0068546077,8.169534E-4,-0.024880458,-0.0023143403,-0.007225596,0.016032225,-0.008265749,0.0057867174,0.001444079,-0.0070973104,0.020054149,-0.03761193,-0.015033677,0.023812568,-0.012322345,-0.028208947,-0.018916914,0.019430056,0.005828324,0.01629573,-0.015089152,7.757807E-4,0.0033683619,-0.036391485,0.017807418,-0.016323466,-7.237731E-5,0.0067367237,-0.0020161632,-5.855194E-4,-0.0055336137,-0.002387151,-0.028597271,0.0086818095,0.0025397066,-0.0025067686,0.0036231994,-0.014423454,0.013043518,-0.0032730147,-0.012884027,-0.014340241,2.1951561E-4,-0.012086577,0.020068018,0.005453869,-0.025033014,-0.012357017,-0.019735169,-0.016656315,0.008959184,-0.010352989,-0.010997884,-0.024519872,-0.014548273,0.012211395,-0.011531829,-0.012793881,-0.014409585,0.022231536,-0.002829216,0.00750297,0.25629368,-0.029484868,6.0892286E-4,0.011850809,0.02271694,0.010352989,0.015727112,-0.012662129,-0.020622766,0.0014380114,-0.014881121,-0.010089483,-0.0031135245,5.1444233E-4,0.016448285,0.012065774,-0.007246399,-0.013216876,-0.024297973,-0.010873065,0.021205252,-0.002829216,-0.029762242,-0.0036682726,0.040052824,0.004573206,-0.008896775,-0.0014120076,0.017668732,0.005228502,-0.0030597833,0.0319535,-0.020983351,0.009035462,-0.023091394,0.0028517526,0.012176724,0.0070244996,0.01951327,0.0070002293,-0.011323798,0.0116774505,0.008771957,-0.01683661,-0.004573206,0.017488439,-0.0068476736,-0.008799694,0.015616163,0.009846781,-0.031093638,0.014194621,0.021843212,0.02324395,0.014673091,0.01832056,0.017502306,0.010727444,0.0010098151,0.0049788654,-0.0080715865,0.039165225,-0.021954162,0.003557323,0.002487699,1.3990599E-5,-0.044629496,0.0016391077,0.0028344167,-0.0036301338,-0.002572645,-0.0060432884,0.009694225,-0.011296061,-0.013244614,-0.025976086,0.015935143,-0.011254455,0.005498942,0.025629368,0.001158037,-0.0021531165,-0.0018982791,-0.022966577,-0.00573471,-0.018237349,0.02399286,0.018903047,-0.005585621,-8.936647E-4,0.0037410834,-0.0136884125,-0.0015506947,-0.025712581,0.011719056,0.025865136,0.012363952,0.029568082,-0.002310873,-0.008279617,0.001516023,1.12899936E-4,0.036391485,0.0010479541,0.004146743,0.01875049,0.008688744,0.00782195,0.0072394647,-0.016157042,-0.015630031,-0.025601631,0.009326705,0.014839515,-0.0050586103,-0.0030077756,-0.0047604335,-0.011857743,0.018168004,0.0018688081,-0.0074544293,-7.3114084E-4,3.53652E-4,0.0029904398,0.005873397,-0.028250555,-0.017016903,0.016337335,0.003924844,-0.023368768,0.011517961,-0.0032799488,0.018486984,-0.016212517,-0.020525685,-0.013674544,1.104079E-4,-0.0068476736,-0.012627456,0.013827099,-9.950796E-4,-0.011233652,0.006601504,0.008050784,0.008508451,-0.015019808,0.023881912,-0.01146942,-0.020289917,-0.0018514722,-0.0029332312,0.017862894,-0.027779019,-0.02164905,0.029900929,-0.005346386,-0.042077653,-0.021510363,-0.011413945,0.028236685,-0.04188349,-0.005027406,0.017807418,-0.014992071,-0.028375372,0.002740803,-0.18317787,-0.0057901847,0.019970937,-0.035198774,0.014589879,0.016892083,0.017197195,-1.5071382E-4,-0.009680357,0.0018618738,0.011268323,0.0071701207,-0.02271694,-0.0114208795,-0.011476354,0.0045974758,-0.01800158,-0.0019589546,0.0079328995,0.012974175,0.0079537025,-0.02356293,0.008945315,-0.010110287,0.0026593243,0.012273804,0.006327597,0.0011250988,0.018168004,-0.011289126,-0.013390236,-5.001402E-4,3.0186106E-4,0.011830006,-0.014603747,0.011393142,-0.018722752,-0.0050378074,-0.026406016,0.016892083,0.016795002,0.011850809,-0.0058248565,0.0030788528,-0.0160877,0.02593448,0.008335092,0.008744219,0.011802268,-0.03888785,0.0012559847,-0.02881917,0.014853384,0.011427813,0.012717604,0.0028864243,-0.010373792,0.0076763285,-0.012627456,-0.0053706565,-0.006833805,-0.008584728,0.0077110003,0.0075515104,-0.0047222944,-0.012877094,-0.004205685,0.01521397,-0.02421476,0.023230081,0.005946208,-0.011656648,0.013085124,-0.033284895,0.0015792989,0.015630031,0.005637629,0.0043547736,0.00959021,-0.027917705,-0.007329611,0.045600306,0.005616826,-0.013882575,-0.011413945,0.013279286,0.0011276992,0.007620854,0.0049372595,-0.008272683,0.003952581,-0.01640668,0.014825647,-0.020068018,0.005110618,0.027695805,-0.015921274,-0.004320102,0.013258482,0.009326705,0.0065321606,0.0052354364,-0.012662129,0.040136036,0.0024426258,-0.0056514977,-0.0048228423,0.018389903,0.0141807515,-9.38738E-4,-0.013216876,0.00629986,0.016919822,0.0049788654,0.0040947353,0.015505213,-0.0062721223,-4.8540471E-4,0.016878216,-0.026933027,0.043547735,-0.0035399871,-0.0014813511,0.010963212,-0.0062755896,0.0065321606,-0.101130605,-0.019762905,0.008293486,0.03858274,-0.006147304,0.023022052,-0.009077068,0.011615041,-0.006719388,0.017391358,-0.0063692033,-0.013216876,-0.01777968,-0.018417642,0.022633728,0.0039733844,0.013064321,-0.022786284,-0.01875049,0.017363619,-0.0037653537,-0.0041987505,-0.013015781,-0.011074161,-0.0056272275,0.0069274185,-0.032008972,0.0389988,0.008827431,-0.009999337,0.0020317654,-0.01758552,0.024894327,-0.030206041,-0.0053186486,-0.017363619,-0.030927215,-0.007835818,0.014340241,-0.00916028,-0.0071839895,-0.0027945442,0.019443925,-0.023424244,0.009978534,-0.025837399,-0.016919822,0.011490223,0.012870159,-0.02464469,-0.019887725,-0.010089483,-0.012890962,-0.006518292,0.022578252,0.010027074,6.214914E-4,0.029179757,-0.01221833,-0.006358802,0.006230516,-0.0067956657,-0.014520535,-0.012495704,0.013279286,-0.0038208284,-0.004500395,-0.023285557,0.0053914594,-0.010859197,-0.009222689,0.011968693,-0.011108833,0.027709674,-0.011448617,0.002201657,-0.021607444,-0.016129306,0.018251216,-0.019859986,0.002693996,-0.029346181,0.015740981,-0.014562141,0.04565578,0.010117221,0.01033912,0.010387661,0.018251216,-0.00879276,0.0032175398,0.009631816,0.014631485,-0.011531829,-0.018916914,-0.004815908,-0.021205252,-0.014187686,0.0039560483,0.020068018,-0.02368775,-0.0105540855,-0.09280938,0.024686296,0.0027581388,-0.010893868,0.011608107,-0.017918369,0.014340241,1.6241554E-4,-0.019346844,0.010782919,-0.008501517,0.01897239,-0.005290911,-5.2874442E-5,-0.012911765,-0.009992403,0.033257157,-0.0017084512,0.011233652,0.006365736,-0.007364283,-0.007606985,0.034727238,0.0060987636,-0.012641326,0.011906284,-0.012440229,0.01747457,-0.009846781,-0.014478929,-0.009486195,-0.03761193,-0.018348297,0.049317118,-0.0043929126,-0.021288464,0.0067852642,0.022134455,0.015449738,-0.003156864,-0.03334037,-0.01339717,-0.008161733,-0.009513932,-0.016101567,0.0060606245,-0.0046876227,8.4555766E-4,0.015713243,-0.010505545,0.015283314,-0.008619401,0.0070799743,-0.014742434,-0.023049789,-0.013993524,0.022994313,0.0028777565,0.014631485,-0.022120586,0.03334037,0.0149504645,0.0079537025,-0.0014882855,0.005231969,-0.011136571,-0.02411768,-0.001288056,0.0050551435,-0.025657106,-0.009201886,-0.0050239386,0.008106259,0.025837399,0.013466514,0.009534735,-0.00820334,0.005360255,6.453282E-4,0.017349752,-0.012911765,0.010796787,-0.019235894,0.02088627,0.02174613,0.025046883,-0.008161733,-0.020359261,-9.786106E-4,0.009028528,-0.018348297,0.011642778,0.01714172,-0.01258585,0.013951918,0.018140268,-0.007482167,-0.0020092288,0.016600842,0.01832056,0.007717935,-0.004503862,0.0040184576,-0.023174608,-0.0048436457,0.0017214532,-0.0043478394,-0.010228171,-0.008633269,0.0014960866,-0.004292364,0.006431612,-5.409337E-5,0.020622766,-0.017821288,0.020289917,-0.009687291,-0.041217793,-0.016670184,0.006910083,0.032730147,0.013064321,0.002487699,-0.005901134,0.0058248565,0.014478929,0.0031551307,-0.027792886,-0.004025392,9.768769E-4,0.011823072,-0.0067956657,-0.024395054,-0.02851406,-0.0133139575,0.008737285,0.0074336263,0.015740981,-0.04468497,0.041855752,0.014978202,-0.01597675,0.02292497,-0.0130573865,0.0011389675,-0.024908196,-0.0039803186,-0.010921606,-0.0108106565,0.008612466,-0.02937392,-0.005859528,-0.018292824,-0.0064697512,-0.003872836,-0.007697132,0.017086245,8.516252E-4,0.014423454,0.012259936,0.0017318546,0.03289657,0.0024114212,-0.014423454,-0.010741313,0.010387661,7.250733E-4,-0.007912097,-0.0174607,-7.6104526E-4,0.016157042,-0.025726449,-0.015838062,0.025449075,0.013008846,-0.0069482215,-0.016157042,0.009881453,0.0032660803,-0.005991281,0.02732135,-0.0074058888,-0.039886396,0.011843875,0.019749038,-0.010685838,0.0012048439,-0.025976086]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/theWorldEmbeddingValues.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/theWorldEmbeddingValues.json
new file mode 100644
index 00000000000..b8a78b64121
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/theWorldEmbeddingValues.json
@@ -0,0 +1 @@
+[0.009861075,2.3483406E-4,0.01675632,-0.020835903,-0.01096857,-0.0024245982,-0.009179059,0.0051432764,-0.004401819,-0.015054408,-0.001820795,0.011807011,-0.004445618,-0.01907142,0.0066574775,0.0071580396,0.02820668,0.0059973607,0.0010926335,-0.012476513,-0.022800608,0.0019099576,0.016268272,0.0019866063,0.0028469476,0.012082321,0.011919637,-0.02833182,0.0271555,-0.025078166,0.0075960313,-0.016668722,-0.023426311,-0.037942614,-0.006870216,0.008615927,-0.007708658,-0.022224963,-1.9983381E-4,-0.009435598,0.015229605,0.029683338,-0.0031097427,-0.009373027,-0.0348141,0.022149878,-0.0064197103,0.009454369,-0.018170409,0.008960064,0.0055374694,0.037917588,-7.3050795E-4,-0.013202328,-0.009454369,-0.019371757,-0.026454713,0.004824168,0.033312414,-0.014278537,0.014053284,0.012607911,-0.014991838,0.006407196,-0.032811854,0.0014258202,-0.005024393,0.013777975,0.008046538,0.030659435,0.030659435,0.01120008,0.010023758,-0.005518698,0.011875838,0.0104304645,-0.01820795,0.001698783,0.013415067,0.012977075,0.02292575,-0.018595885,-0.0332123,-0.0045332164,0.012232489,0.0012193383,0.005900377,0.02178697,0.0076085455,-0.011550473,0.015379773,0.012395171,0.014804128,0.019008849,-0.020435452,-0.017169284,-0.011099967,0.03691646,0.009129004,-0.05008125,-0.008421959,0.02111121,-0.0082655335,-0.008953806,0.010643204,0.0028266122,-0.007089212,-8.6503406E-4,0.024552576,-0.0013937529,-0.020510536,0.0065323366,0.0035289635,-0.038092785,0.010762087,-0.035114437,0.0084657585,-0.013840545,-0.01404077,-0.02061065,0.01601799,0.04492546,0.025929121,-0.023826761,0.019083934,7.074352E-4,-0.04342377,-0.03166056,0.0085283285,-0.004245393,0.022387644,0.016218215,-8.5017364E-4,0.0023901844,-0.028982552,0.008578385,-0.008478273,0.018958794,4.227404E-4,-0.022212448,0.0108622,0.0030565578,-0.017269395,-0.008472015,-0.01096857,0.020172657,-0.009698393,0.018383147,0.0047709835,-0.015992962,0.031935867,0.016831404,0.018345606,-0.0061475295,0.024064528,0.0059629474,-0.015367259,0.008872465,0.0011293935,-0.0026451584,1.7412135E-4,-0.003647847,0.007057927,-0.025678841,0.0085033,0.013214842,0.020235227,-0.016906489,-0.009523196,-0.01746962,-0.016168159,0.025416046,-0.018120352,0.027505893,-0.016668722,0.015730167,0.0012576625,0.006203843,-0.023313684,0.002972088,-0.023251114,0.003963827,0.005096349,0.009698393,0.005900377,0.018833652,0.02067322,-0.014253508,0.024001958,-0.018057782,0.010417951,0.009373027,0.03085966,0.024089556,-0.7091965,-0.014729043,0.0061412724,-0.0022181163,0.014766585,-0.010561863,0.032636657,0.01675632,0.003763602,0.010286553,-0.017594762,0.013652834,-0.01740705,-0.013690377,-0.014328593,-0.0076523446,-0.013440095,-0.03005876,-0.037041605,-0.001820795,0.0064885374,0.02153669,-0.005011879,-0.013027132,0.0106932605,0.0022134236,-0.004261036,-0.024339838,-7.3402753E-4,0.013765461,-0.009754706,0.020422937,-0.01728191,-0.0033349956,0.030634407,-0.0026748793,-0.010286553,0.0047365697,0.008584642,0.023901844,-0.006222614,0.003001809,0.007821284,-0.015642568,-0.0038793571,0.010073815,0.037266858,-0.004195337,0.004548859,-0.0018254878,0.021486633,-0.036591098,0.023276143,0.021161268,-0.0046521,0.007483405,0.009272914,0.013527693,-0.005991104,0.0016784476,0.008134136,0.011982208,-0.002685829,-0.0051964615,-0.023601508,0.021361493,-0.02740578,0.026930247,0.009798505,-0.0060004895,0.0062007145,0.00574708,-0.02610432,-0.024064528,0.007545975,0.034088288,0.011794497,-0.019371757,0.012119862,0.008165421,0.016405927,-0.01972215,0.0017331967,0.008665984,0.022725524,-0.009498168,-0.02098607,-0.002143032,0.017769959,0.025566215,0.017882586,0.013477637,-0.013590264,-0.011124995,0.014641444,-0.0022525298,-0.014516304,-9.268222E-4,0.031159997,0.011588015,0.013777975,-0.004836682,0.009448112,0.009191574,0.0066762483,-0.0070016137,-0.014541332,0.023476368,0.039744638,-0.023701621,0.0042234934,-0.01654358,-0.03854329,0.013527693,0.006438481,-0.022049764,0.019947404,-0.006632449,0.023075918,-0.027931372,0.009210344,0.006594907,0.015542457,-0.010824658,-0.005249646,-2.2153788E-4,0.0013171043,6.8788195E-4,0.009604537,-0.006807646,0.010148899,0.026604882,0.0090539185,-0.01149416,0.020698247,0.010017501,0.018508287,-0.0125328265,0.018107837,-0.0012592268,-0.018620914,-0.02258787,-0.0029642668,-4.219583E-4,0.015116978,-0.02351391,0.0030237085,-0.017857557,-0.015329718,-0.005449871,0.024540061,-0.014178424,-0.03413834,0.010280296,0.010217726,-0.022537813,0.005187076,-0.013002103,-0.032361347,-0.024352351,0.0070766984,0.013302441,-0.007752457,-0.016856432,0.012457741,-0.0117757255,-0.034739017,0.020510536,-0.009491911,-0.019509412,0.015279661,-0.002016327,-0.017382022,0.013077187,-0.0051182485,0.014954296,-0.009717164,-0.02132395,0.002527839,-9.839176E-4,-0.0055437265,-0.014428706,-0.011268906,-0.0035101925,0.020573106,-0.011963436,0.0014391163,0.016631179,-0.023163516,-0.005681381,0.0020554336,0.0029220318,-0.007258152,0.005230875,0.0033287387,-0.0056845094,-0.001583028,-0.013327469,0.023689106,0.021962166,0.02262541,-0.026379628,0.019772207,0.001997556,0.021824513,-0.03191084,-0.0026733151,-0.03216112,0.032236207,0.006322726,0.022838151,0.0022869436,-0.002064819,0.020410424,0.017331967,0.031985924,0.017119227,-0.008972578,-0.01984729,0.010730802,-0.0026076161,-0.00560004,-0.0057877507,-0.009735934,0.016255757,0.03493924,-0.0155799985,0.032611627,-0.009748449,-0.047628492,-0.0096107945,-0.017331967,0.002814098,0.022700496,-0.008640955,5.6606546E-5,-0.0027233711,-0.014879212,0.014015742,0.014616417,-0.0049712085,-0.0023151003,0.0046927705,-0.017019115,0.020860929,-0.0060317745,0.018971307,-0.022412673,-0.031285137,0.0052402606,0.004026397,-0.0053497585,-0.031159997,0.013752947,-0.005559369,-0.024927998,-0.0034132085,-0.0014054849,0.018483259,0.023276143,0.01623073,-0.0019005721,0.0016925259,-0.0016127488,-0.0077587143,-0.013865573,-0.006181943,-0.015842794,0.004486289,-0.0034069514,0.0043986905,-0.0061663007,0.01721934,-0.029608255,0.01271428,-0.0067263045,-0.0025059395,2.7980644E-4,-0.0056500956,-0.0082655335,-0.00844073,-0.017820014,-0.017382022,0.018345606,-0.010017501,-0.022487758,-0.024014471,-0.0017942026,-0.011006111,0.010223983,-0.010405437,0.026905218,-0.008515814,-0.0035039354,0.011625557,-0.005293445,0.0016893974,-0.0014508483,-0.0071955817,0.008184192,0.01799521,0.0021414678,0.014378649,0.004092096,0.038743515,-0.0063133407,-0.0096420795,-0.007320722,-0.019083934,-0.018783597,-0.010649461,-0.007908883,-7.629663E-4,0.009454369,0.0026701866,-0.005947305,-0.01456636,0.0015853744,0.0085283285,0.008878722,1.5486144E-4,-0.0035383492,-0.0186084,-0.012119862,0.08234248,-6.3352403E-4,-0.013189814,0.019922376,-0.006551108,-0.0154924,-0.019171532,-0.01555497,-0.010311581,0.028907467,-0.010236497,0.005287188,0.020698247,0.031460334,-2.5125875E-4,0.015292175,-0.014741557,-0.031810727,-0.007445863,-0.019346729,0.0049180235,-0.02107367,0.007095469,0.014378649,-0.0125328265,-0.014178424,0.015717654,0.035615,-0.0010081636,-0.023151003,0.003604048,-0.0044612605,-0.004286064,0.0060130036,0.0064322245,0.004329863,0.015992962,0.03999492,0.0032411402,-0.004786626,0.007558489,0.00513702,2.784377E-4,-0.029558199,-0.02144909,0.002355771,-0.010743316,0.021874567,-0.012739308,-0.01109371,0.01218869,-0.0044299755,-0.020961042,-0.021036126,-0.019797236,0.015630055,-0.011131252,-0.0043486343,-0.009548224,-0.021837026,-0.012607911,-0.026654938,0.0066825054,0.002216552,-0.011412818,-0.027055386,-0.017306939,-0.016731292,-0.0050400356,-0.018057782,0.01012387,-0.016531067,-0.010768345,0.0029673954,0.02203725,-8.861515E-4,-3.7346632E-4,-0.010843429,-0.0054154573,0.022575356,0.011738184,-0.023138488,-0.008090337,-7.2346884E-5,-0.02024774,0.020635678,0.017619789,-0.0019474998,-0.010367895,0.024865428,0.009373027,-0.012864449,0.030784575,-5.5609335E-4,-0.0066762483,-0.008978834,0.02271301,0.022700496,-0.011832039,-0.0033381241,0.010837172,-0.004523831,0.008403188,0.02410207,0.012632939,0.018232979,0.0026389014,0.00791514,-0.022312561,-0.0093167145,0.020135114,-0.022537813,-8.994477E-4,-0.006782618,-0.016093075,0.018620914,0.013828031,0.010599405,0.015567484,-0.019008849,-0.010943541,-0.025929121,-9.0022985E-4,0.011212593,0.001924036,-0.006745076,0.011982208,-0.013014617,-0.0022932007,-9.478419E-5,0.004561373,0.020047516,8.267098E-4,0.025678841,-0.021424063,-0.007470891,-0.015755195,0.0069640717,-0.007996481,0.0041077384,-0.0035571202,-0.016831404,-0.007483405,0.003428851,-0.022537813,-0.030934744,-0.012345116,0.0053184736,-0.004749084,0.027956398,-0.011043654,-0.007470891,-0.011462875,-0.004980594,-0.03166056,-0.036440928,-0.02006003,-0.031835757,0.013978199,0.019359244,0.016268272,0.004749084,0.0069327867,0.018095324,-0.016243244,0.0053841723,0.008540843,-0.0032380119,-0.0050400356,0.012570368,0.021987194,0.014003227,-0.005815907,5.0525495E-4,0.0069703287,0.010674489,-0.003982598,-0.010993597,-0.0042485218,-0.016205702,-0.007996481,-0.008184192,0.0027327568,-0.004830425,0.007014128,0.0024683974,0.025015596,-0.01681889,-0.002563817,0.0031582348,0.011387791,-0.017081685,0.022350103,-0.004902381,-0.007833798,-0.023801733,-8.7285537E-4,-0.0049055098,0.02808154,0.0034006946,-0.0043580197,0.004304835,-0.015692625,-0.007589774,0.008384417,0.03388806,0.0069578146,0.0099048745,0.005359144,0.0020319696,-0.0038199152,0.006332112,-0.011024882,-0.009623309,0.014190938,-0.0025247107,-0.017269395,0.035389747,-0.008522072,-0.028456962,-0.0022619155,-0.0064760237,0.031685587,0.0043548914,0.020760817,0.014403678,-0.013953172,-0.010211469,0.03493924,-0.014691501,-0.01079963,0.02675505,-0.008127878,0.0035790198,-0.02298832,-0.0075710034,0.0051995898,5.3693115E-4,-0.026554825,0.023926873,0.012801878,0.0186084,-0.010117614,-0.012582882,0.0040482967,0.019121476,-0.009648336,-0.014954296,-0.039744638,-0.009698393,-0.012770593,-0.004939923,-0.03536472,0.022412673,0.014553846,-0.013490152,-0.0045801443,-0.014441219,0.0040952247,0.011425332,-0.011731926,0.017507164,0.011594272,-0.015192063,0.006826417,1.981718E-4,-0.013502666,0.0054217144,-0.0033662808,0.01576771,-0.011606786,-0.018683484,-0.014516304,0.010436722,0.010905999,0.0028062768,0.007952682,-0.006056803,-0.0013726354,-0.0045582447,0.024164641,-0.009773477,-0.013264898,-0.008565871,-0.023351226,-0.018620914,-0.03268671,-0.0076022884,0.011944666,-0.019346729,-0.013415067,-1.8565774E-4,-0.005055678,0.023926873,-0.0030675076,-0.0047834977,-0.0014453734,0.034864157,-0.026329571,0.019221589,0.01833309,0.017094199,-0.027205557,0.013815517,0.0059285336,-0.02126138,0.016868947,-0.017907612,0.01073706,-0.004902381,0.0139406575,0.015817765,-0.016593637,0.0014649265,0.011606786,0.0020663834,0.0016659336,-0.026780078,-0.016781349,0.037166744,-0.0028047126,4.986069E-4,5.9050697E-5,-0.011150023,0.016180674,0.013540207,-0.018433204,0.024089556,-0.010205212,0.0115129305,0.0018129738,0.024953026,0.0034476223,-0.0082342485,-0.026254488,-5.5804866E-4,-0.011562987,0.02107367,0.008090337,-0.002380799,-0.008259276,0.02218742,0.016793862,-0.004980594,-0.0027656062,-0.0099048745,0.0068889875,-0.007470891,-0.04572636,-0.018495774,-0.010180184,0.04755341,-0.0064134533,-0.0035884052,-0.018433204,0.014453733,-0.02900758,-0.0026467226,-5.8855163E-4,0.02477783,0.005287188,0.023263628,0.0162933,0.02107367,-0.010417951,-4.164834E-4,4.2577118E-5,-0.011988465,0.015392288,-0.027380753,0.021374006,0.0059598186,-0.012069806,0.009454369,0.016994087,0.0040170117,0.009817276,-0.008159164,-0.002246273,-0.014053284,-0.0033475098,-0.0038887425,0.0014047027,0.019271646,0.0090539185,-0.026254488,0.011312705,-0.014666473,-0.010180184,-0.009028891,0.006801389,0.0019287288,-0.007358264,-0.0033756664,-0.006551108,-0.0020757688,-0.0029736524,-0.038743515,0.009210344,-0.012013493,0.02006003,0.020485507,-0.005096349,0.0066574775,0.009229115,-0.012964561,-0.024852913,-0.013189814,-0.008634698,-0.011650586,0.006519823,-0.006826417,0.0062632845,-0.033412527,0.012501541,-0.0018035882,-0.012451485,-0.013189814,0.018308062,0.032111064,-0.01892125,0.005869092,-0.015442344,0.0037291883,-0.0019709638,-0.014253508,0.005797136,-0.013765461,-0.014954296,0.01509195,-0.02647974,-0.0037354454,0.014078312,0.025378503,-0.010480521,0.022375131,0.22405164,-0.0128269065,-0.008115365,0.034338567,-0.007170554,0.02993362,0.010030015,-0.006047417,0.0071580396,-9.846997E-4,-0.031059885,0.016506039,-0.0027890701,0.009341742,-0.0065010516,-0.0063008266,-0.026604882,-0.031335194,-0.017707389,-0.025541186,-0.0010480521,-0.012270031,-0.035114437,-0.0063477545,0.01050555,0.0034663933,-0.0022321946,-0.01555497,0.020422937,0.013402553,0.0075960313,-0.0093167145,-0.0011004547,0.0027452707,-0.019409299,-0.0050838348,-0.004983722,0.014616417,0.007014128,0.034488738,-0.008935035,0.016643694,0.014929268,0.003629076,0.013064673,0.019709637,-0.015667597,0.008741068,0.0096107945,0.02132395,1.0783596E-4,5.995015E-4,0.0138780875,0.044950485,0.004298578,0.0035508631,0.0031097427,0.015755195,-0.00837816,-0.010004987,-0.009585766,0.0155799985,-0.012977075,0.00884118,-0.020009974,0.02292575,-0.051157456,0.010561863,0.010324095,-0.013815517,0.0014273844,-0.023826761,-0.013715404,0.0032442687,-0.031185025,-0.012545341,0.0024152126,0.018232979,0.020360367,0.027530922,-0.006563622,0.006551108,-0.01456636,0.00143677,-0.021686858,-0.014541332,0.010011244,-0.015992962,-0.028682215,0.006235128,0.0064635095,-0.01972215,-0.007082955,0.007082955,0.008403188,0.010280296,-0.0015001224,-0.0025075038,-0.0073019513,-0.005487413,-0.010493035,0.005628196,0.004013883,-0.0040013692,6.8436237E-4,-0.009154031,0.0025794597,0.009836047,-0.011193822,-0.025153251,-0.025653813,-5.8933377E-4,-0.009398055,-0.0048617106,0.004373662,0.007039156,-0.018132865,0.006582393,0.016443469,3.2653863E-4,-0.014065798,-0.02925786,-0.0067388187,-0.0068889875,-0.006582393,-0.011337734,0.01063069,0.013552722,0.0031910841,-0.028682215,0.001698783,-0.009222859,-0.0030768933,0.0015971062,-0.013565236,0.0023698492,0.011850811,-0.014804128,-0.016268272,2.9989738E-5,-0.004329863,-0.0025403532,0.017544705,-0.005512441,-0.012582882,-0.0062570274,0.03311219,-0.005293445,-0.014353621,-0.0021883955,-0.029107692,-0.007908883,-0.012789364,-0.0064885374,0.022700496,-0.01225126,-0.029207805,-0.0032599114,-0.0060192603,0.019421814,-0.034663934,-0.0029736524,0.033938117,-0.002344821,-0.023488881,0.00682016,-0.16088068,0.0144662475,0.016518552,1.7329034E-5,0.024702745,0.009491911,0.0041077384,0.018057782,-0.0011450361,0.014866698,0.015642568,8.227991E-4,-0.034914214,-0.0077712284,0.0112814205,-0.013077187,-5.025175E-4,0.011825782,0.022012223,0.012395171,0.01728191,0.007527204,-0.015792737,-0.010023758,0.0043204776,0.022913234,-0.0061412724,0.028832383,-0.010543091,-0.0024996826,-0.02298832,-0.011875838,0.040545538,0.014979324,0.010299067,0.0014242559,-0.00860967,-0.031560447,-0.011037396,0.01814538,0.019734666,0.031460334,0.0054967985,-0.0058503207,6.257027E-4,0.00867224,0.013752947,-0.01035538,0.013828031,-0.00814665,0.0106932605,0.012977075,-0.0108622,0.0090539185,0.016656207,0.017544705,0.027505893,0.0075835176,0.0142660225,-0.013352497,-0.035840254,-0.0030424797,-0.005862835,-0.01583028,-0.004060811,-0.0027374495,0.0018739797,0.015842794,-0.004792883,0.008415702,-0.0018958794,-0.019634552,-0.008008995,-0.016093075,-8.134136E-4,-0.009698393,-0.032261234,0.019509412,-0.0073019513,-0.013202328,-0.01694403,0.022024738,-0.0032849396,-0.029207805,0.006519823,-0.007908883,-6.034121E-4,0.0080027385,-0.0111875655,-0.011932151,0.014090826,-0.02178697,-0.011638071,-0.004179694,0.01648101,0.011882096,-0.0040076263,0.03391309,-0.023864303,-0.016931517,-0.0087911235,0.010011244,-0.022500271,0.0240395,0.025566215,0.001759789,0.033412527,0.0016893974,0.012270031,0.003622819,-0.012639196,0.008978834,0.024527548,0.033712864,-0.014941782,0.014128368,0.011907123,-0.0067575895,0.014416192,0.01456636,0.05851572,0.005287188,-0.016343355,0.021862054,0.0026764434,-5.025175E-4,-0.07328231,-0.02740578,-8.8380516E-4,0.015229605,0.016981572,0.031710617,-0.013602778,-0.016493525,0.018358119,0.020936014,-0.008340618,-0.030434182,-0.01456636,-0.022763066,0.03151039,-0.01681889,-0.0058534495,-0.0098735895,-0.028907467,0.0076398305,0.010036272,0.00456763,0.01305216,-0.011819525,0.0014915189,-0.003701032,-0.03298705,0.03361275,0.0020429194,-0.0041202526,-0.028456962,-0.009986216,-0.008221734,-0.022550328,-0.0025231463,0.018258007,-0.020535564,0.02391436,0.020160142,-0.026579853,0.012270031,0.030484239,-0.011099967,-0.031860784,1.21034376E-4,0.0061850715,-0.007877598,0.019609524,0.0085908985,-0.0071392683,-0.011306449,-0.02530342,-0.009379284,0.018007725,0.015667597,-0.0027656062,0.0047365697,0.015980449,0.0024527549,0.032886937,0.015655084,-0.002027277,-0.030083789,0.027255611,9.444201E-5,0.027480865,-0.019234102,-0.0016455982,0.03574014,-0.022612898,-0.019271646,0.0070766984,-0.014866698,0.0017707387,-0.035840254,-0.020135114,-0.016656207,-0.0043392484,0.024189668,-0.008346875,-0.021611772,-0.02517828,-0.0049524372,-0.012839421,0.0085033,0.013490152,0.001875544,-0.009216602,-0.006669991,-0.020135114,0.008534585,0.015079437,0.035239577,-0.027505893,0.0054154573,0.022600383,0.0049305377,-0.005631325,0.008346875,0.012213718,-0.0047365697,-0.0060067466,-0.06672494,0.018583372,-0.013352497,-0.014353621,0.0145288175,-0.0043017063,0.0046521,-0.005991104,-0.010392923,-0.0026701866,-0.022237476,-0.003532092,-5.5922184E-4,-6.558147E-4,-0.027430808,-0.00942934,0.015980449,0.010849685,-0.0042485218,0.0017738673,-0.004304835,0.0019099576,-0.0015963241,0.011900866,-0.005180819,-0.008353132,-0.019446842,0.0031582348,-0.0044988026,-0.016681235,0.019021364,-0.0248404,-0.013727918,0.040595595,0.0047834977,-0.013690377,-0.013365011,0.005018136,0.021424063,0.046276975,-0.022362616,-0.019697122,0.021862054,-0.0051526623,-0.001960014,0.015204577,-0.0014125239,-0.0054967985,0.019096447,0.015192063,0.0035727627,0.03376292,-0.013540207,-0.0017066043,-0.0029564456,-0.01984729,5.122941E-4,-0.0033162246,0.0069140154,-0.020936014,0.030384125,0.0033349956,0.0271555,-0.001120008,0.017319452,0.009279172,-0.02351391,-0.0014969938,-0.0049055098,-0.008096593,0.003916899,-0.0031504133,0.01694403,0.017519677,0.027180528,-0.012182432,-0.005628196,0.0255537,-0.0263546,0.021899596,-0.002917339,0.012182432,-0.039269105,0.013803002,0.024690231,-0.01965958,-0.024727773,-0.015142007,0.0015720782,0.014491276,-0.0090539185,-0.0062976982,0.009554481,0.011656842,-0.005906634,0.013452609,-0.0023119717,-0.012245003,0.0071768104,0.01012387,-0.02073579,-0.0054967985,-0.0099048745,-0.0013632498,-0.025979178,0.015529943,-0.025278391,-0.02524085,-0.014428706,0.013928143,0.0071017263,0.019521926,0.008941293,0.011306449,-0.018220464,0.012495284,8.439166E-4,-0.003544606,-0.020860929,0.022888206,8.0402807E-4,-0.017294424,0.01462893,-0.013815517,-9.7453204E-4,0.011813268,0.002728064,-0.016005477,-0.0070016137,-0.018433204,-9.86264E-4,0.004827297,-0.0069140154,-0.0087598385,-0.00820922,-0.0061412724,0.0024371122,0.037266858,-0.027580978,0.039369218,0.0013874959,-0.0065010516,0.026079291,-0.008102851,0.02940803,0.0073832925,0.019459356,-0.0098735895,-0.009235373,0.013602778,-0.0016847047,0.02662991,-0.009423084,-0.0050838348,0.0013233613,-0.021499146,0.0060849595,-0.017557219,0.0034601362,0.027631033,-0.014115854,0.022562841,0.0049055098,-0.009391799,-0.0138780875,0.016868947,0.004439361,-0.007908883,-0.0073019513,0.024702745,-0.003910642,-0.027906343,-0.0043861764,0.024702745,-0.0018599015,8.9475495E-4,-0.009986216,0.0155174285,0.009473139,-0.0077899992,0.013164786,-0.0017926384,-0.03679132,0.01978472,0.0011982208,-0.01715677,-0.014603903,-0.02144909]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateDocument.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateDocument.json
new file mode 100644
index 00000000000..080d0c74abf
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateDocument.json
@@ -0,0 +1 @@
+{"content":"The World is Big and Salvation Lurks Around the Corner","id":"1","metadata":{"meta2":"meta2"},"embedding":[0.02364917,-0.018419946,0.0033172895,-0.0058730734,-0.028159376,0.018681405,-0.013752862,-0.006621506,-0.008360223,-0.0034186058,0.016472058,0.03461747,-0.013543692,0.0139228115,0.01588377,-0.0021260066,0.032473486,-0.0041997214,2.696319E-4,-0.013452181,-0.0130926715,0.005948243,-7.839752E-4,-0.0093603125,-0.003984016,-0.0037879199,0.004725912,-0.03299641,0.04567728,-0.01733488,-0.0074058897,-0.019008232,-0.019478863,-0.04099712,-0.011876877,-0.0037552372,3.6543293E-4,-0.015896844,0.008124908,-0.009281875,0.020446269,0.012184094,-9.5678476E-4,-0.015125533,-0.031872127,0.013478328,-0.0034349472,-0.023792973,-0.019688033,0.020929974,0.034172986,0.0053501506,-0.0043500615,-0.007680424,-0.019910274,0.0045330846,-0.012177558,-0.006111657,0.020289393,-0.013622131,0.0069875517,-0.0025574178,-0.011046737,0.012713553,-0.024420481,0.006647652,-7.2310376E-4,0.005807708,0.013844373,0.011386638,0.015949136,0.010425767,0.014550318,0.009785187,0.017517904,-0.020367831,-0.021112995,0.012537067,0.013243012,-0.006510385,0.011661172,-0.028917614,-0.0018808868,-4.457097E-4,0.021178361,0.011504294,-0.025296375,0.02313932,0.007249013,-0.013883593,0.018302288,0.0031669494,0.0059220972,0.01754405,-0.009124997,-0.014001249,-0.008778561,0.008765488,0.011804976,-0.05059275,-0.0069744787,0.0037487007,-0.012131802,-0.0041278196,0.0077980817,-0.012327897,-0.0031702176,0.005082153,0.019570375,4.9922755E-4,-5.719465E-4,0.023832193,-0.0073013054,-0.021818941,0.027191969,-0.009732895,-0.0077719353,0.0015981819,-0.0059220972,-0.028159376,0.011085956,0.02894376,0.003608165,-0.016877323,-0.0038336755,0.013197256,-0.029780436,-0.010785276,0.001071174,0.006598628,0.011778829,0.02928366,0.022995517,0.0036604574,-0.010870251,0.022943225,-0.008595538,0.007817691,-0.00433372,-0.0063273623,0.032212026,0.02574086,7.075795E-4,-0.013739789,0.009804796,-0.009928991,-1.4982955E-4,0.016171377,0.0131057445,-0.020014858,0.043637883,0.011916096,0.02915293,-0.009242655,0.014994803,-0.0075235474,-0.011576197,0.02954512,-0.005206347,-0.015857624,-0.008804708,-0.0013963665,0.014145053,-0.009255728,0.010719911,0.018027753,0.015360848,-0.011170932,-0.023583805,-0.005761952,-5.359955E-4,0.05584812,-0.013569838,0.028159376,-0.024106726,0.0019495204,-2.084796E-5,0.017923169,-0.013622131,0.0010229672,-0.014968656,-0.006003804,-0.0027731233,0.01993642,-0.003987284,-0.0028744396,0.0118507305,-0.013700569,0.016890397,-0.027688745,0.012086046,0.020433197,-0.0017452538,0.020393977,-0.684401,-0.021675138,-0.0049514226,-0.007137892,-7.0676244E-5,-0.013948957,0.02351844,0.028969906,4.991765E-5,-3.057871E-4,0.0030966816,0.008209883,-0.010203525,-0.015347775,-0.0077980817,-0.019818762,-0.01447188,-0.033284016,-4.391732E-4,-0.0077196434,-0.010706838,0.024015216,-0.0032797046,-0.010098941,0.022577178,-0.015295483,0.014537245,-0.028891468,-0.0045232796,-0.009072705,0.015256263,0.0032453877,6.287326E-4,0.01107942,0.0620709,-0.019779542,0.0019282767,-4.3876466E-4,0.028786883,0.02638144,-0.005167128,-0.001391464,0.03425142,-0.008497491,0.0014364027,0.014707195,0.04175536,-0.007680424,-0.005056007,0.0063371668,0.014445734,0.0048925937,-0.0019004964,0.01477256,0.020577,0.0130861355,0.01528241,0.0010809789,-0.008373297,-0.0022371279,-0.01946579,0.014903291,-0.014197346,0.01856375,-0.027819477,0.01236058,-0.0085105635,-0.0013367207,0.019505009,0.017714,0.018419946,0.0028973175,-0.005307663,-0.01767478,0.008039934,0.026629828,0.007739253,-0.017596342,-0.005810976,0.008575928,0.008798171,-0.024302823,-0.01305999,0.012765845,0.024172092,0.010889861,-0.011406247,-0.0114389295,0.013726715,0.01895594,-0.0027339042,0.02049856,-5.441662E-4,-0.0015156581,0.034120694,-0.0039807474,-0.016798886,0.024355115,0.031113889,-0.0110140545,0.012497848,-0.016210597,0.009438751,0.0028156107,0.021740502,-0.021531334,0.0061966316,-0.0130861355,0.027296554,-0.030930866,-3.162047E-4,-0.002474077,-0.03461747,0.013988176,9.281874E-4,-0.023923704,0.02027632,-0.010922544,0.005121372,-0.019021306,0.023230832,0.03223817,0.006203168,-0.0054089795,-8.946877E-4,-0.010092404,0.016759666,-0.013465255,1.9119354E-4,-0.016668154,-0.015373921,0.013582911,0.004065722,0.0067587732,0.001931545,0.009249192,0.019884128,-0.014877145,0.005948243,-0.009654457,-0.027479578,-0.0013996348,0.009223046,0.013582911,0.026446804,-0.010987909,0.007902666,-0.025753932,-0.04290579,-0.035977066,0.008079153,-0.030773988,-0.04912857,-0.004134356,-0.007621595,-0.013452181,0.001440488,-0.015347775,-0.022720981,-0.041206293,0.008530173,0.017269515,-0.017897023,-0.02394985,0.018093118,0.007137892,-0.021988891,0.021256799,-0.0019854712,-0.033100992,0.016406693,-0.014798706,-0.015988356,0.02394985,-0.0023792973,0.0283424,-0.014615684,1.08261294E-4,0.005739074,0.009660993,0.0101969885,-0.0050984942,-0.014903291,-0.007249013,0.012399799,-0.0075823762,0.021962745,-0.00553971,-0.009909381,0.016994981,0.00570966,-0.0027012215,0.016890397,-0.0014813413,0.01207951,0.011818049,-0.005353419,0.010687228,0.013948957,0.019988712,0.005882878,-0.0017321807,0.018772917,-0.024773452,-0.0024413944,-0.031532228,0.0015671334,-0.038539387,0.01831536,0.0027257334,0.020563927,-0.007503938,-0.008249102,-9.028584E-5,0.015975282,0.0397944,0.017530976,-0.001748522,-0.014511099,0.011347418,-0.0034741664,5.588734E-4,-0.013569838,-0.0135044735,-0.0014560124,0.023727609,0.016668154,0.022001963,-0.002632588,-0.015870698,-0.017282588,-0.017596342,0.01336067,0.01933506,-0.0036441162,-0.03582019,0.023544585,-0.0244597,0.0050625433,-0.007974568,3.0905535E-4,-0.004922008,0.028996052,-0.0054351254,-0.014720269,0.0064286785,0.024904184,0.00260971,-0.019204328,0.0023400781,-0.002585198,-0.0022632738,-0.02296937,0.0042160624,-0.008785098,-0.034722053,0.00915768,-0.010033575,0.033310164,0.02672134,0.0019903737,0.018276142,0.0012084412,-0.0019364473,0.01222985,-0.0017877413,0.011667708,-0.008490954,0.0034937758,0.0020508366,0.01976647,-0.010412694,0.029989606,-0.01528241,0.0046670833,-0.012818137,-0.003160413,-0.0043958174,-7.451645E-4,-0.017256442,0.0053991745,-0.05020056,0.012504384,-0.001784473,-0.016968835,-0.016249817,-0.0047324486,0.005683514,-0.002869537,0.009013876,-0.009759041,0.013158037,0.005807708,-0.01631518,4.8778864E-4,-0.016916543,0.0067914557,-0.013726715,0.012805064,-0.0071313553,0.022132695,0.0051900055,-0.007595449,-0.013223402,0.026420658,-0.0065561407,8.897853E-4,-0.007667351,-0.016498204,-0.01972725,-0.026106905,-0.006389459,9.167485E-4,-0.0031783883,-0.006967942,-0.025034914,-0.03009419,0.0049873735,0.01865526,0.0052259564,-0.015086314,0.008647831,-0.017988533,-0.0015311824,0.12456014,0.009726359,-0.0034414837,0.012595896,0.023596877,-0.007765399,-0.017766291,-0.01660279,-0.009164217,-0.0033761184,-0.0023776633,0.003840212,0.0035035806,0.0041637705,0.013465255,-0.0029103905,-0.0097655775,-0.007333988,-0.0071575018,-0.0093341665,-7.8438374E-4,-4.318196E-4,-0.015007876,0.018812137,0.01835458,-0.021675138,0.02813323,0.013112281,-0.007667351,-0.025623202,0.009144607,0.005438394,0.006693408,0.011465075,0.003385923,0.001684791,0.0013179281,0.0333886,0.016655082,-0.01285082,0.041938383,0.014720269,0.006016877,-0.030643258,-0.001797546,-0.008124908,-0.011347418,0.0371275,-0.0021374456,-0.017923169,0.032865677,-0.009981283,-0.012988088,-0.009406068,-0.012184094,0.01720415,-0.0041801115,0.022551032,-0.020773096,-0.016106013,-0.009105388,-0.03393767,-0.003333631,-0.013713642,-0.011987998,-0.024002142,-0.019361205,-0.009889771,-0.017635562,0.0047782045,0.004294501,-0.03359777,-6.8347604E-4,-0.001808985,0.029440537,0.007621595,0.0130926715,-0.0038532852,0.005696587,0.0027257334,0.008654367,-0.010236207,-0.01396203,-0.0050396654,-0.007503938,0.02647295,0.01075913,-0.008327541,-0.012785455,0.015373921,0.012399799,-0.0077784723,0.013203793,-0.00499391,0.0074385726,-0.009556409,0.020825388,2.453242E-4,-0.008392906,0.0038663582,0.02364917,-0.009216509,-0.010752594,0.008353687,0.012471701,0.0038663582,0.008425589,0.0034741664,-0.011635025,-0.009660993,0.03825178,-0.027871769,0.010144697,-0.008268712,-0.028054792,0.017596342,0.030538673,0.01997564,0.010353865,-0.026198417,-0.014694122,-0.01107942,0.0038696264,0.012857357,0.012602432,-0.013726715,8.685416E-4,-0.008758952,0.0043500615,0.0059417067,-0.0037454322,0.013327987,-0.0053828335,-0.0015524261,-0.01524319,-0.0075627663,-0.0015270971,0.018537601,-0.021988891,-0.021648992,-0.0062325825,-0.0131057445,-0.005203079,-0.017060347,8.113469E-4,-0.03056482,-0.004382744,3.687012E-4,0.02313932,0.0038304073,-0.0022502008,-0.0042618182,-0.021884305,0.0010107111,-0.0139228115,-0.010549962,-0.02236801,-0.02266869,0.016589716,0.031479932,0.007935349,0.012863893,-0.012373653,0.0027273677,0.0028580981,0.0046311324,0.0043271836,-0.017622488,-0.033310164,-0.0043043057,0.017949315,0.0020214221,0.0039676744,-0.0029201952,0.020511635,0.016066793,0.00979826,-0.01891672,-0.032970265,-0.026224563,-0.017021127,-0.0019331791,-0.008216419,-0.0068372115,-0.0033009483,-0.00241198,0.028996052,0.0030705356,0.011876877,0.011641562,0.033493187,-0.01639362,0.033911522,0.009562945,-0.014236565,-0.028499275,0.004065722,-5.707209E-4,0.0071444283,0.013367206,0.0050756163,0.0050363974,0.016119085,-0.001920106,-0.009033486,0.006529995,0.0032274122,0.015674602,-0.020302465,-0.011563123,0.006817602,-0.008549782,-0.030957012,-0.036186237,0.005147518,-0.02591081,-0.005291322,0.029597413,-0.008131444,-0.03346704,-0.013988176,0.0057325377,0.0155700175,0.023923704,0.020733876,0.028839175,-0.0034676297,-0.017400246,0.035637166,0.0058501954,-3.6053054E-4,0.02425053,-0.0065365313,-0.009896308,0.001673352,-0.018772917,0.0045134746,-0.013144964,-0.03649999,0.020132516,-0.010210061,0.010739521,-0.019857982,-0.009151144,-0.0035166538,0.025544764,0.0035918239,0.0027240994,-0.0141712,-0.020250173,-0.031140035,-0.008915829,-0.02031554,0.013118818,-0.0022191524,0.002547613,0.00896812,-0.009392995,-0.008504027,-0.0209169,-0.013870519,0.028080938,0.01793624,-0.008772025,0.024773452,0.010955227,-0.0029888288,-0.0043860124,0.012628579,0.027270408,-0.019714179,-0.02915293,-0.004837033,0.00947797,0.021805868,0.0085105635,-5.84611E-4,0.0052455664,-0.020720804,-0.0059874626,0.024132874,-0.006366581,-0.012491311,-0.025518617,-0.013700569,-0.0283424,-0.037545834,0.004000357,-0.018302288,-0.016249817,-0.0118507305,-0.01733488,-0.0011749414,0.014105834,-0.0022567373,0.01660279,-0.005340346,0.02506106,-0.031140035,0.023060882,0.013595984,0.018890575,-0.01993642,0.0070333076,0.017661707,-0.011288589,0.0062456555,-0.010144697,0.01109903,0.0042160624,-0.0065920916,0.021322165,-0.006647652,-0.008752415,-0.012112192,0.01447188,0.00184657,-0.01609294,-0.0139228115,0.04110171,0.014040469,-0.0052978583,-0.003964406,-0.020393977,0.025963102,0.0076869605,-0.0135044735,0.0173741,-0.012785455,-3.8075293E-4,0.009425678,0.022211133,0.0045102066,-0.0139097385,-0.008249102,0.0031032183,-0.009510653,0.009621774,0.010406158,-0.00514425,5.743977E-4,0.019400425,-0.013373743,-0.0072816955,-0.0017991802,0.009687139,0.0030803403,-0.0058175125,-0.019871054,-0.02108685,0.004157234,0.041598484,0.009386458,-0.02753187,-0.011184005,0.010883325,-0.030355651,-0.012157948,0.022642544,0.023544585,0.029597413,0.014903291,0.02608076,0.021335237,-0.014811779,0.012497848,0.0013440743,0.008464808,0.0012092582,0.0043141106,0.0021733965,0.0037552372,-0.030172627,0.016079867,0.021400603,0.019622667,-0.0077980817,0.008732806,0.001993642,-0.010896398,4.0567346E-4,-0.020302465,0.02266869,0.007739253,-0.0118311215,-0.031479932,-0.003817334,-0.0024446626,0.019740324,0.013197256,0.0023662243,0.0066770664,0.011863804,-2.1767159E-5,-0.0089419745,-0.016994981,-0.008785098,-0.028368546,0.026146125,-0.0036114336,0.01236058,0.0076608146,0.015975282,-0.00915768,0.004415427,0.0028711713,-0.008412516,-0.0036996766,-0.021884305,-0.0101969885,-0.001058101,-0.012765845,-0.0131515,0.011641562,0.02351844,-0.0076281317,-0.018367652,-0.020472415,0.036473844,0.022799421,-0.016615862,-0.011164395,-0.0032944116,-0.012994624,0.0021881037,-0.021779722,-0.01801468,-0.0043631345,-0.008039934,0.002277981,0.006239119,-0.02651217,0.0024773453,0.0017632293,-0.014824852,0.009621774,0.21523489,-0.012210241,-0.019583447,0.022433374,-0.0029724876,0.03940221,0.02327005,-0.01222985,-0.006170485,0.002632588,-0.028446984,0.018759845,-0.005647563,-0.005229225,8.2973094E-4,-0.018812137,-0.02394985,-0.0330487,-0.0020982265,-0.045703426,5.022405E-5,0.017962387,-0.0276626,-0.025936956,0.011948779,-0.02489111,-0.026368367,-0.0029610486,0.011530441,-8.0225705E-5,0.002903854,-0.027584162,0.0060332185,0.04034347,-0.021805868,-0.0017517903,0.022995517,-0.0031930956,0.0062783384,0.007026771,0.017008053,-8.726269E-4,-0.008556319,0.00834715,-0.0049808365,0.013792081,-0.012595896,-0.017792437,-0.011301663,-0.005843659,-0.017034201,-0.0063567767,0.005660636,0.025976175,-0.004320647,0.0018204239,0.033754647,0.00883739,-0.01852453,-0.0041997214,-0.012099119,0.015334702,-0.010360402,0.014837925,-0.03817334,0.023688389,-0.025806226,0.012948868,0.012641652,-0.039977424,0.013216866,-0.007765399,-0.005111567,-0.0019397156,-0.021675138,-0.012510921,-0.0020524708,0.019269694,0.014576465,-7.619144E-4,-0.024420481,-0.018498383,0.00221425,-0.018969014,-0.0062783384,-0.014654903,0.018223848,-0.019818762,-0.0173741,0.027008947,-7.0594536E-4,-0.02104763,-0.006510385,0.009151144,0.011804976,0.021544406,0.017191077,0.02988502,-0.018249994,-0.011903023,-0.0016137061,-0.04549426,3.552196E-4,-0.002671807,-0.019674959,-0.0032388512,-0.0011120273,0.010013966,0.010615326,-0.014929437,-0.017321808,-0.014445734,-0.024982622,3.0497002E-4,0.008183737,-0.0033728501,0.012497848,-0.0013841104,0.01720415,-0.015635382,-0.01592299,-0.024485845,0.008079153,0.014498026,0.012125265,-0.011327809,-0.0068502845,0.011974925,-0.0059253653,-0.026773632,0.004935081,-0.022041183,0.00570966,0.018249994,0.0014388539,0.013001161,-0.017021127,-0.023688389,-0.0059874626,0.00819681,0.005356687,0.013033843,-0.010308109,-0.004784741,-0.019413497,0.0041866484,0.030277213,4.5959983E-4,-0.008399443,0.0048795203,-0.016445912,-0.011876877,-0.004575572,0.0044905967,0.024368187,-0.0034610932,-0.022132695,-0.030669404,-0.0042585502,0.014824852,-0.04144161,0.0143280765,0.01767478,-0.02168821,-0.013582911,-0.009451824,-0.1686948,0.0056867823,0.011131712,-0.013857446,0.039977424,0.014001249,0.02274713,0.021112995,-0.021845087,0.015373921,0.0037094813,-0.0040036254,-0.03500966,-0.0029773898,-0.0030492917,-0.02967585,-0.012497848,0.009386458,0.0038826994,0.006719554,0.0139097385,-0.0011888316,0.012112192,-0.0020573733,0.010523815,0.0043990854,-0.012876966,0.025191791,0.0089289015,0.001452744,-0.012707016,-0.013210329,0.035192683,-0.0070333076,-0.0055102957,-6.7765446E-5,-0.022145767,0.0033499722,-0.022904005,0.016158305,0.03022492,0.019387351,-0.0036767987,-0.0071836477,-0.009942064,0.023413854,-0.004493865,-0.03009419,5.1230064E-4,-0.007909203,0.0025443446,-0.0036898719,0.0059972676,-0.016027573,0.00721633,0.016955761,0.014249638,0.005412248,0.019191256,-0.022354936,-0.020773096,0.0026309537,-0.014589538,0.0027224652,-0.017269515,-0.02253796,-0.0035591412,-0.0065920916,-0.019191256,-0.0012403068,0.0126677975,-0.0028123425,-0.018459164,-0.020563927,0.009582555,-0.0031865588,-0.017269515,0.020302465,-0.014524172,-0.01060879,-0.014105834,0.016210597,-0.0030934133,-0.0027012215,0.021034557,0.00570966,-0.0045592305,-0.004124551,-0.001132454,0.0065038484,0.015805332,-0.017191077,-0.0093472395,0.0056998553,0.036813743,0.007412426,0.010739521,0.037232082,-0.01155005,-7.07171E-4,-0.008399443,-0.006422142,-0.025257157,-0.004111478,0.023936776,0.015360848,0.03534956,0.019308913,0.0134914005,-0.0041801115,-0.0064450195,-0.006994088,0.0044873287,0.016432839,0.0012999526,0.014354222,-7.1003067E-4,-0.015622309,0.008706659,4.1752093E-4,0.04630479,0.0019413497,-0.038016465,-0.008131444,0.004837033,-0.01865526,-0.08141903,-0.015687674,0.013465255,0.015857624,0.0031930956,0.021230653,-0.0064286785,0.004441573,0.0027633186,0.015949136,-0.013288768,-0.026577536,0.0044775237,0.008353687,0.02506106,-0.011942242,2.300042E-4,-0.026642902,-0.017217223,0.014158127,-0.0022567373,0.019256622,-0.025636274,-0.013988176,0.002756782,-0.0058763414,-0.033284016,0.030957012,-1.5473195E-5,0.008379833,5.2215648E-5,-0.0012983185,-0.01207951,-0.013635204,0.015896844,0.0048533743,-0.057939813,5.609161E-4,0.0045265476,-0.045572694,0.006771846,0.023165466,-0.00896812,-0.027714891,-0.009131534,-7.243294E-4,-0.0058501954,0.014079688,0.017308734,-0.0058403905,-0.004961227,-0.04110171,-0.022171913,0.0017664975,0.008647831,-0.013975103,-0.014275784,0.026355293,-0.0060593644,0.031296913,0.01075913,0.0027910988,0.011177468,0.0337285,0.004788009,0.022590252,-0.012105656,-0.018249994,0.019544229,-0.026276855,-0.014550318,0.020773096,-0.010236207,0.023204686,-0.027767185,-0.00785691,-0.01865526,-0.029309805,0.013752862,-0.021740502,-0.028446984,-0.014707195,-0.0033450697,-0.014053542,0.025335595,0.004614791,-0.0056050755,-0.019583447,-0.005121372,-0.01302077,0.018759845,0.0151778255,0.02847313,-0.03231661,-0.0050723483,0.028760737,-0.011406247,-0.021465968,0.0051900055,0.029100636,-0.012157948,-4.7553264E-4,-0.06724783,0.010484596,0.005461272,-0.008870073,-0.0046344004,-0.05046202,0.01494251,-0.012576286,-0.01571382,0.0010352231,-0.021465968,0.0048762523,0.021112995,4.2405745E-4,-0.02967585,-0.0031113888,-0.006902577,0.0050004465,-0.0057292697,0.009066169,0.0039088456,0.0012460263,0.010935617,0.0039676744,0.008137981,0.024093654,-0.025244083,0.0030525601,-0.0097786505,-0.015543871,0.032421194,-0.029022198,0.004833765,0.0394545,-0.0134914005,-0.020851534,-0.005428589,-0.009138071,0.01758327,0.043324128,-0.028656153,-0.01613216,0.014837925,0.003398996,-0.007275159,0.0052717123,0.00587961,-0.00998782,0.011223224,-0.009654457,0.029780436,0.043402568,-0.030930866,-0.005758684,-0.020054078,-0.011321272,0.014236565,0.026577536,0.0114323925,-0.0060593644,0.015334702,0.018197702,0.033780795,0.017517904,0.031558372,0.019962566,-0.013870519,-0.010576108,0.0025361741,-9.126632E-4,-0.008059543,0.003506849,0.019034378,0.010987909,0.011203614,-0.006288143,-0.010563035,0.0051638596,-0.03176754,0.006994088,0.019923346,0.010020502,-0.027505724,0.0040068934,0.021230653,0.015818406,-0.013622131,-0.006739164,-0.020001786,0.005242298,-0.012478238,-0.002449565,0.0040689907,0.011968388,-0.0049514226,0.024695015,-0.013622131,0.019622667,0.008915829,0.0044677192,-0.0049514226,-0.00815759,0.003224144,0.025204863,-0.027479578,0.011765756,-0.019857982,-0.006056096,-0.0063829226,0.019073598,0.019178182,5.2006275E-4,0.026211489,0.012994624,-0.012916186,0.02040705,0.026250709,-0.020302465,-0.024708088,0.028028645,-0.0019707642,-0.003286241,0.0147464145,-0.016419766,-0.0027208312,-0.011863804,9.404434E-4,-0.012576286,0.0030558284,-0.017112639,-0.0071052094,-0.025976175,-0.0073535973,-0.007869983,-0.0114127835,0.014798706,0.016079867,0.020485489,-0.0049089347,0.049677636,0.012759308,-0.027714891,0.019426571,-0.011693854,0.031532228,0.008700123,0.035375707,-0.0061345343,-0.03176754,0.014236565,0.0027404407,0.026172271,-0.03103545,-0.034905076,-0.017361026,0.0020639098,-0.0033924596,-0.009569482,0.0042127944,0.018080045,-0.020158662,0.015687674,0.021818941,-0.0044742557,-0.030355651,0.0035918239,0.01126898,0.006203168,-0.0033009483,-0.015125533,0.0044644508,-0.00964792,-0.0065397993,0.0028074402,-4.0015826E-4,0.00474879,-0.026459878,0.0101839155,-0.0023351756,0.0099486,0.017308734,-0.009739432,-0.009759041,0.017648634,-0.0016815226,-0.003653921,-1.6686028E-5,-0.017151857]}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateEmbeddingValues.json b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateEmbeddingValues.json
new file mode 100644
index 00000000000..3c56eec1176
--- /dev/null
+++ b/vector-stores/spring-ai-elasticsearch-store/src/test/resources/updateEmbeddingValues.json
@@ -0,0 +1 @@
+[-0.013368895,-0.021889955,-0.031667106,-0.028245103,-0.011589997,0.00740076,-0.028245103,-0.018848173,4.9522286E-4,9.4970764E-4,0.010415382,-0.015915029,0.029983262,-0.001174616,-0.023886122,-0.012370812,0.023587376,0.010639441,0.018304998,-0.0017067578,-0.017137172,0.010340695,0.010829552,0.014027496,-0.015480489,0.010109846,0.004810494,-0.02198501,-0.006596182,0.003186061,0.042965148,-0.021699842,-0.027362444,6.2295387E-4,-0.024008337,-0.02480952,-0.0033693826,-0.005927398,0.017042117,-0.011861585,0.011202985,-0.008215522,0.0051296093,-0.0066708685,-0.008622903,0.0035611913,0.016702633,-0.0022236228,-0.031667106,0.0049225236,0.01891607,0.007862459,-0.023465162,-0.0070205373,0.0030078318,-0.019608619,-0.010245639,0.014380559,0.021034453,0.0059443717,-0.00826984,0.023763908,-0.027457498,-6.5265875E-4,-3.280268E-4,-0.015073108,-0.025067529,0.0058730803,0.004847837,-0.003982152,0.007271756,0.01607798,-0.012574502,-0.014842258,0.032128803,0.0019011126,-0.009444456,-0.011298041,0.020939399,0.002816023,0.020654231,-0.024728043,-0.015154583,0.018427214,0.019771572,0.0066131563,0.010422171,0.026506942,-0.006198985,0.002114988,0.013531848,0.01154926,0.010686969,0.004199422,-0.010904239,0.017327284,0.0010218481,0.021957852,0.016892744,-0.014122551,-0.0103882225,0.010625862,-0.0017008169,-0.011922692,0.00826984,0.0043114517,0.0114202555,0.0045796447,0.009240765,-0.009030285,-0.006480757,0.03174858,0.019432086,-0.030798025,-0.0287068,-0.009288293,0.010931398,-0.01894323,-0.022935566,-0.015779234,0.009437666,0.013592956,0.026819268,-0.0096141985,0.016349569,-0.010069108,-0.034274343,-0.0045864345,0.0045830393,-0.005027764,0.05048812,0.012947935,0.02024685,-0.01524964,-0.022881249,0.018223522,-0.025162583,0.0022049511,-0.024103392,-0.008086518,0.004206212,0.03416571,-0.0011440624,-0.001136424,-0.01913334,0.02829942,0.017327284,0.012771403,0.011637526,-0.009946893,0.0053468794,-0.020070318,0.0032794194,-0.0030010422,2.622517E-4,0.01653968,0.0061752214,0.044458877,-0.011786899,-0.0037513026,0.0023679037,0.007360022,0.01501879,-0.014720044,0.015765656,0.037126016,0.009899365,0.010157374,-0.018169206,-0.00803899,0.016797688,0.024958894,-0.011780108,0.012044907,0.007516185,0.011922692,8.274932E-4,-0.004236765,-0.005414776,-0.02588229,-0.026466204,-0.0023645088,0.021618366,0.014407718,-0.0045355116,0.013355317,0.020287588,-0.0064400192,8.792646E-4,-0.012676348,3.1211347E-4,0.011651104,0.011678264,0.014380559,-0.68526965,-0.0064060707,-0.00936298,-0.024429297,0.008507479,0.021007296,0.008459952,7.952422E-4,-0.011800478,0.0022049511,-0.02069497,-5.9568905E-5,0.017693928,0.014910155,-0.013484321,-0.0031028874,0.005136399,-0.0134979,-0.022881249,0.016200196,-0.011277672,0.04527364,0.019255556,0.005723707,0.01197022,-0.006874559,0.0058493163,-0.028245103,-0.018535849,-0.017965514,-0.03006474,0.0256786,0.022881249,-0.0025970556,0.055838395,0.006029243,-0.031395517,0.020341905,0.0136540625,0.03503479,-0.008860542,-0.008106887,0.01719149,-0.01087708,0.0011822544,0.012038117,0.030091897,0.0030265034,5.9568905E-5,-0.013192364,-0.00446422,-0.02984747,-0.015616283,0.020274008,-0.00391765,0.003503479,0.0230442,0.0121060135,0.0021404491,0.013070149,0.006640315,0.01762603,-0.016010085,-0.009919735,0.0028007464,-0.003893886,-0.013633694,0.013036201,0.008419213,0.00468149,0.008555007,0.016471783,-0.018332157,-0.0075569227,0.027919197,0.027864879,0.019214816,-0.023383686,-0.02217512,-0.0030400828,0.011257303,-0.0073532322,-0.019853048,0.0069322716,0.02178132,0.0053842226,-0.039733253,0.008480321,0.025990926,-0.0045117475,0.014000337,0.011943061,-0.0056727845,0.0056863637,-0.0051975064,0.017748244,-0.016023664,0.031096771,0.030444961,-0.03136836,-0.017110014,0.009003126,0.01501879,0.010422171,-0.007869248,0.00848711,-8.334342E-4,0.012886828,0.031232566,-0.040032,-0.0070205373,-0.0057983934,-0.029765991,-0.014027496,-1.0152705E-4,-0.034084234,0.005503042,-0.01173937,-7.880282E-4,-0.006874559,0.009396928,-0.024768783,0.020708548,0.010293167,0.018834595,0.0026327015,0.0041892375,-0.008113678,-6.6241896E-4,-0.018956808,-0.006032638,0.0043454003,0.023220733,-0.0069933785,0.012900407,0.016770529,0.022921987,0.0073192837,0.0036494574,-0.012139962,-0.039923366,-0.012893617,9.7007665E-4,-2.9280529E-4,-0.034980472,-0.02069497,-0.027430339,-0.004762966,0.0074618673,0.013355317,-0.0025376459,-0.0024510773,-0.025407013,0.017150752,0.015955767,-0.02394044,-9.395231E-4,-0.024035495,-0.025637861,-0.015711337,0.009118551,0.011372727,-0.024266345,0.0025800813,0.031857215,0.014652147,0.012330074,0.004895365,-0.0036392729,-0.02134678,0.0037513026,-0.0056014927,-0.0054283557,-5.2789826E-4,0.0024969077,0.0011975312,-0.012031327,0.013755908,-0.010911029,-0.0067217913,0.008480321,0.00848711,-0.01611872,-0.005112635,0.028408054,-0.0011618853,-0.014978052,0.016091561,-0.0020250245,0.0102795875,-0.0014529933,0.0050447383,-0.005676179,0.011454204,-0.011854796,-0.0048851804,-0.0015395618,0.0024578671,-0.003656247,0.013667642,0.016661894,0.010551175,0.03047212,-0.018685222,0.024239186,-0.024130551,-0.0015573847,-0.03047212,0.025569966,0.028245103,0.019337032,-0.0029348426,-0.013518269,0.006830426,0.009030285,0.02155047,0.0037173543,0.015154583,0.024470035,-8.29615E-5,-6.000387E-4,0.006114114,-0.0071088034,0.014910155,0.0027158752,-0.013884912,9.845048E-4,0.042286176,0.009315452,-0.0045830393,-0.009505563,0.01959504,-0.0048614168,0.013423213,-0.007516185,-0.01610514,-0.005747471,-0.003350711,0.029765991,-0.0059885047,0.008072939,8.3852647E-4,0.028435213,0.0013121072,0.0052552186,-0.0050888713,0.0026768346,-0.014991631,-0.003768277,-0.0064094653,-0.028380897,0.00489197,-0.029222818,0.0070205373,0.014855837,-0.006507916,0.020355485,0.0018841384,7.052788E-4,0.023166416,0.013294209,-0.0029620014,0.010048739,-0.0030723338,-0.019499984,0.0021370542,0.010157374,-0.023872543,-0.008392055,-0.020436961,0.012391181,0.008229102,0.008018621,0.003077426,0.01023885,-0.0064739673,0.010788814,0.004718833,-0.006005479,0.0043623745,-0.00555057,-0.024415718,0.0071767,0.007414339,-0.0030434777,0.0027277572,-0.028462373,-0.006480757,0.010252429,0.0022609662,0.005020974,0.015738497,-0.007855669,-0.009104972,0.004243555,0.008215522,0.01153568,-0.023207154,-0.025108267,0.0068575847,0.007767403,2.1939179E-4,-0.0015836947,-0.0064773625,0.03913576,-3.763503E-5,-0.008439582,-0.016363148,-0.0048885755,-0.012296125,0.012818931,0.012445498,-0.010354274,-0.0069017177,0.0071223825,4.311452E-4,-0.010524017,0.0066946326,0.020396223,0.007013748,-0.023519479,-0.010103056,-0.011644315,0.01219428,0.0670278,-0.002296612,0.0037479077,0.028571008,-0.0050379485,0.022623241,-0.03242755,-0.039488826,0.008222313,-0.0066946326,-0.0071699107,-0.01458425,5.1347015E-4,-0.012486236,0.032970726,-0.0056456258,-0.002164213,-0.03131404,0.042313337,-0.021930693,-0.0056727845,0.0059375823,-4.6000138E-4,0.011155457,0.022120804,-0.0050243693,-0.0094648255,0.020206112,7.982127E-4,-0.03880986,0.017272966,0.018793857,-0.01478794,0.008738329,0.0027888643,0.016431045,-0.010116635,0.005007395,0.024470035,0.010972136,0.022039328,0.01176653,0.0023271656,7.2098E-4,0.022514606,0.0011966826,-0.006704817,0.018875333,-8.365108E-5,0.006358543,-0.004504958,0.022989884,0.010123425,-0.016064402,-0.0033201575,3.8382955E-4,0.0025597124,-0.0064332294,-0.0019282714,-0.0047935196,-0.015181743,-0.025542807,0.028842594,-0.0033880544,0.0047561764,-0.035550807,-0.0064298348,-0.01808773,-8.2537146E-5,-0.012173911,9.1342525E-5,0.010490068,-0.002581779,0.005788209,0.022731876,-0.009410508,0.004532117,-0.005054923,0.011922692,0.01849511,-0.0013587864,-0.023030622,-0.016743371,-0.004566065,-0.0056354413,0.033052202,0.03658284,0.0030519648,-0.016892744,0.0020097475,0.008242682,-0.005632046,0.02241955,-0.00848711,0.006460388,-0.03804941,0.0063008303,0.010109846,-0.019554302,9.666818E-4,0.0015412592,-0.019513564,-0.0011304831,0.01175295,0.018875333,0.0059104236,0.0028567612,-0.002434103,-0.020532016,-0.0066199456,0.03003758,-0.0086908005,0.016933482,0.0027447315,-0.005961346,0.020111056,-0.004661121,0.035849553,-0.023234313,-0.02309852,-0.0144484565,-0.025325537,0.020613493,0.024320662,0.005048133,-0.020952977,0.0020216296,-0.02695506,0.0022270177,-0.015195322,-0.0114406245,0.008276629,-0.012540554,-0.019432086,-0.031042453,-0.025407013,-0.0128596695,0.017205069,-0.008276629,-0.009804309,-0.033160836,0.0018230312,0.007821721,-0.0072242282,-0.017368022,-0.03136836,-0.0033150653,7.646886E-4,-0.0024918155,0.028027833,-0.0036494574,0.03028201,0.0017958725,0.019880207,-0.008398844,-0.0047290176,-0.007271756,-0.021238144,0.019241976,0.033812646,0.00784209,0.021265304,0.010639441,-0.011155457,0.0014181961,-0.00685419,-0.008622903,-0.0068202415,-0.008636483,0.022324495,0.0115696285,0.03001042,0.008846964,0.008378475,-9.878996E-4,0.0136540625,-0.018983968,-0.008324157,-0.015317536,-0.007998252,0.024442878,-0.01044933,-0.019703675,0.021862796,0.0031351384,-0.004063628,0.011834426,-0.010625862,-0.0047561764,-0.003720749,0.03068939,-0.0062091695,0.020654231,0.0010540991,0.005903634,0.0036664316,-0.027864879,-0.007516185,-0.01523606,0.009220396,0.023179995,0.0023458372,-0.01219428,-0.009519143,0.013246682,0.035116266,0.0156706,-0.0062397234,0.0076995064,-0.02239239,-0.019065443,-0.01848153,-0.0024425902,-0.02914134,0.0045490908,0.011359148,-0.018983968,0.021835636,-0.0040534437,-0.023329368,0.009926524,-0.012099224,0.023791067,-0.01588787,0.023818227,0.019771572,0.0051941113,-0.005788209,0.027294546,0.007502605,0.0030791236,0.015697759,0.021170247,0.0050175795,-0.009654936,0.0045830393,0.022310914,-0.010741287,-0.03508911,0.039515983,0.013742329,0.013124467,-0.0075772917,0.008948809,-0.019119762,0.02328863,-0.0033167626,-0.01088387,-0.004769756,-8.699288E-4,-0.04353548,0.0020912238,-0.029005548,0.009654936,0.014869417,-0.024171289,-0.02175416,-0.011820847,-0.003921045,0.0056286515,-0.011447414,0.020165373,0.023112098,0.010245639,0.0034491615,-0.008643273,-0.015141005,-0.00674895,0.006311015,0.022718295,-0.021360358,-0.01827784,-0.0044065076,7.9566654E-8,0.009437666,-0.019635778,-0.005316326,-0.016702633,-0.024456456,-0.0059104236,-0.0071699107,0.010041948,-0.035387855,8.9793623E-4,0.002103106,-0.005119425,-0.011786899,-0.018848173,0.022867668,-0.020803604,-0.026181037,-0.0014750598,0.022256598,0.0029246581,0.008568586,-0.017177911,0.015969345,0.019825889,-0.028380897,0.01565702,0.0011304831,0.007923566,-0.011814057,-0.007794562,3.2951206E-4,-0.004294478,0.00892844,-0.022324495,0.0019893786,-0.029657356,-0.0055132266,0.0135454275,0.0026004505,-0.003567981,0.0057712346,-0.015195322,-0.002114988,-0.03826668,-0.007665558,0.0051024505,-0.017911198,-0.011216565,0.0049870256,-0.020056738,0.021645525,0.015168163,-0.0027464288,0.0028380896,-0.02178132,-0.0040534437,-0.009274714,0.029277135,-0.02024685,-0.021889955,-0.046604417,0.0019605225,-0.022012169,0.012431919,-0.019337032,-3.7491808E-4,0.0034695305,0.026751371,0.00913892,0.01937777,-0.0027651004,-0.026669895,-0.017340863,0.0015370157,-0.019079024,-0.0113116205,-0.011488152,0.01023885,0.01651252,-0.0023797858,-0.002485026,0.0031911533,-0.011460993,0.011528891,-0.012309704,0.017082855,0.014760782,-0.034980472,-0.008534638,0.031694263,0.0020810394,0.021930693,-0.019092603,-0.014136131,0.014624988,0.012689927,0.010653021,-0.025067529,-0.014027496,-0.025732918,0.024021916,0.014190448,0.006243118,0.023981178,-0.011501731,-0.0063924915,-0.0052586133,-0.012248597,0.008296999,-0.004545696,0.0090981815,-0.017530974,-0.009227186,0.017463077,-0.0024103392,-0.012010958,0.0090981815,-0.007502605,-0.0035611913,-5.2328338E-5,0.016363148,-0.010843132,0.007380391,-0.018644484,0.025719339,-0.0090981815,-5.0031516E-4,0.013755908,0.0028007464,-0.03394844,-0.00468149,0.0047493866,-0.009444456,-0.0035170584,-0.00913892,-0.028245103,-0.01808773,-0.022039328,0.016797688,-0.008643273,-0.0022422944,-0.016892744,-0.040738128,4.4530807E-5,0.024076235,0.010361064,-0.017938355,-0.014597829,-5.6396844E-4,-0.0072106486,-0.004661121,-0.0018926256,-0.0043827435,-0.0127306655,-0.011352358,0.034736045,-0.0221887,-0.026303252,0.017205069,0.037044536,-9.878996E-4,0.029249975,0.24073517,-0.008521059,-0.020817183,0.031015296,0.012655978,0.01587429,0.018318579,0.0010354274,-0.010211691,0.0078081414,-0.023030622,0.014543512,-0.002863551,0.006205775,-0.0054521193,-0.0128800385,-0.04160721,-0.018576587,-0.032509025,-0.040330745,0.021034453,-0.010632652,-0.0055980976,-0.0012229925,0.022283755,-0.009179658,-0.014434877,4.8885756E-4,0.031857215,0.041308463,0.004399718,-0.012764613,6.467178E-4,0.008588956,-0.017639609,0.010829552,-0.0021743977,-0.029901786,0.019513564,-0.00914571,-0.006222749,-0.010177743,-0.011854796,-0.007536554,0.0012145054,-0.0017653189,-0.0023271656,0.012506605,0.02282693,0.01807415,-0.022446709,-0.009159289,0.00489876,0.019662937,0.005927398,-0.0015794511,0.002276243,0.013443583,-0.0070205373,-1.2232047E-4,0.010544386,0.04416013,-0.013986757,0.029087024,-0.02895123,-0.026439045,0.0037343283,0.023587376,0.017286547,-0.0013256866,-0.013823804,-0.005570939,0.004236765,0.0043691644,-0.013701591,-0.033187997,0.014855837,0.019825889,0.016879164,0.03967894,5.0965097E-4,0.008208733,-0.002951817,0.017123593,-0.009926524,-0.031911533,0.022093644,0.023587376,0.009607408,-0.03003758,-8.24841E-6,0.00740755,-0.013511479,-0.008140836,-9.707132E-5,0.02829942,-0.021591209,0.019540722,-6.56478E-4,0.010686969,-0.023709591,0.01414971,0.012017747,-0.0049870256,-0.039271556,-0.016824847,0.010028369,0.015752077,-0.0014988236,0.008622903,-0.0066335252,0.0031589023,-0.0036766161,-0.0049361032,0.030200532,-0.018155625,-0.020341905,-0.0015047647,0.0036868006,-0.009688885,0.007760613,0.0042265807,0.012309704,6.1361806E-4,-0.013036201,-0.0028703406,-0.013321368,-0.023600956,0.008032201,-0.03674579,0.0071020136,-0.011196195,0.0011533983,-0.021020874,-0.013165205,0.004589829,0.0025121847,-0.019866627,-0.017897617,0.0040398645,6.114963E-4,0.022514606,-0.002196464,0.008120467,-0.0032149174,-0.009553091,0.02524406,-0.0031487178,-0.0014529933,-0.004742597,-0.02634399,-0.0060597965,-0.03028201,-0.02547491,0.008385264,-0.010469699,-0.009016706,-0.0453008,0.017924776,-0.0144484565,-0.023383686,-0.010035159,0.018332157,-0.008263051,-0.034708884,-0.019988842,-0.17816141,0.025407013,0.019486405,0.004365769,0.021577628,-0.009118551,0.023709591,0.0098722065,-0.01740876,0.028571008,2.2405971E-4,-0.013871333,-0.034736045,-0.011943061,-0.008351317,0.0012382694,0.012968305,-0.0059919,0.014611409,-4.718833E-4,0.029032705,-0.016254513,0.01804699,0.0010456119,0.011875165,0.026058823,-0.006263487,0.03745192,0.010965346,-0.010815973,-0.017177911,-0.015045948,0.011943061,-0.019296294,-0.006165037,0.003382962,0.011257303,-0.00805257,0.0070205373,0.012133173,0.0067930827,0.025814394,0.008493899,0.0033608957,0.017069276,0.0022168332,0.03068939,0.021292461,0.015779234,0.0067930827,0.0068440055,-0.029249975,0.017150752,-0.008106887,-0.0077809826,0.008643273,-0.0012501513,0.009057444,-0.0026564654,-0.0035815604,-0.008351317,-0.02593661,3.7491808E-4,-0.02243313,-0.016933482,-0.03001042,-0.021862796,0.018155625,-0.0028262076,-0.004179053,-0.017069276,-7.4134907E-4,0.02631683,-0.018019833,0.006263487,0.0052993516,-0.02744392,0.001914692,0.004589829,-0.010965346,-0.0051703476,0.04024927,-0.027729087,5.4699427E-4,-0.003462741,0.02873396,-0.011725791,0.0132670505,-0.0019282714,-0.012248597,0.008188364,-0.009200027,-0.009111761,-0.017707506,0.0072310176,0.016607577,-0.009749992,0.017368022,0.00402968,-0.010707338,-0.0027990488,0.0066301306,-0.037098855,0.014896575,0.027864879,0.02375033,0.0018858359,0.008100098,0.018861754,0.0010277891,-0.028380897,-0.009974051,0.040575176,0.0044947737,-0.0012280848,0.0014640265,0.013205944,-0.009050654,0.004372559,0.018400054,0.049944945,-0.002035209,-0.01694706,0.008134047,-0.014991631,-0.0058934493,-0.060672652,-0.020518437,0.004725623,0.010578334,-0.009308662,-0.0011584905,1.8363984E-4,0.029277135,-0.019418508,0.01894323,-0.011780108,-0.02895123,0.00609035,-0.015779234,0.046821687,0.017055696,-0.0029348426,-9.233976E-4,-0.019853048,0.020151794,-0.00913892,0.002099711,-0.0059511615,0.009648147,-0.0153718535,0.0151138455,-0.024904575,0.0186988,0.019079024,-0.003060452,0.0014996723,-0.0096141985,0.035333537,-0.017245807,-0.004528722,0.008799436,-0.00740076,-0.025515648,0.018875333,-0.024755202,-0.007156331,0.01721865,-0.0027701927,-0.024171289,-0.005489463,0.004460825,-0.010490068,0.01653968,0.03202017,-0.012051696,-0.038864173,-0.025298377,-0.02066781,-0.01936419,0.03916292,-0.017110014,0.0040161004,0.010775235,-0.011488152,0.0049496824,-0.01110114,-0.015344695,-0.011814057,0.021441834,0.018196363,0.0061039296,0.0017220346,7.176912E-5,0.01672979,-0.008663642,-0.011298041,0.01042896,-0.021659104,0.037940778,-0.009892575,-0.014027496,-0.019825889,0.002763403,9.344308E-4,-0.031449836,7.3837856E-4,-0.025284799,-0.017422339,-0.007095224,0.012160331,0.029684516,0.02199859,0.018237103,3.0850645E-4,-0.0296302,0.0041111563,0.023383686,0.010395013,-0.024646567,-0.007943935,-1.7059091E-4,0.020925818,-0.009688885,-8.1306515E-4,0.028408054,-0.016607577,-0.024239186,-0.082616925,0.030336326,0.009736412,-0.0020606704,5.3680973E-4,-0.026588418,0.0123640215,-0.0033897518,0.006874559,0.02089866,-0.031911533,0.003982152,-0.008813015,-0.018875333,-0.02914134,-0.009206817,0.012384391,-0.005180532,0.025868712,-3.8987662E-5,-2.546133E-4,0.002517277,0.022799773,-0.025990926,-0.017802563,0.004056839,-0.014910155,0.021591209,-0.016240934,-0.025203321,0.02741676,-0.031042453,-0.014068234,0.013898492,-0.0064298348,-0.008731538,-0.010578334,0.014312662,0.024918156,0.016431045,-0.020817183,-0.038375318,0.019255556,-0.024904575,-0.020002421,3.3439213E-4,-0.0071223825,-0.008982757,0.033866964,-0.008799436,0.009885786,0.016607577,-0.005652415,-0.015982926,0.0065622334,-0.017300125,0.013789857,-0.0062974356,-0.01610514,-0.017788982,0.009308662,0.02914134,7.2904275E-4,1.7854758E-4,-0.0041383146,1.9371828E-4,-0.013728749,-0.0018281235,0.012852879,-0.028217943,-0.022718295,0.030119056,-0.010714128,0.016050823,0.0065418645,-0.016526101,-0.019445667,-0.008724749,-0.010320325,0.03267198,0.0037716718,5.007395E-4,-0.022012169,0.019011127,0.026805688,0.021251723,-0.0036053243,-0.034084234,-0.003961783,0.010198112,-0.017490236,-0.0020131425,-0.015303957,0.034029916,0.011888743,0.0051397937,-0.00891486,-0.009688885,0.01284609,0.005964741,0.0010184532,-0.012717086,0.008813015,-0.013918861,-0.019309873,-0.010836342,-0.020382643,-0.037316125,0.0049598673,-0.006796478,0.019757992,-0.002372996,-0.003958388,0.020436961,0.0145570915,0.0071495413,7.880282E-4,-2.1727002E-4,-0.01545333,0.013973178,0.009940104,0.021808477,0.016132299,-0.007930356,0.0029620014,0.0039108605,-8.4828667E-4,0.0018247287,-0.008989547,-0.018413633,-0.007292125,-0.016213775,-0.008426003,-0.020382643,-0.0063857017,-0.0033422238,0.004026285,0.0060801655,-0.0106665995,0.033541057,0.007516185,-0.012010958,-0.00217949,-0.012764613,0.012791772,0.018821016,0.010775235,-0.013368895,-0.026248934,0.036474206,-2.011445E-4,-0.014652147,-0.01284609,-0.0052348496,-0.016390307,-0.004830863,0.0020725522,-0.009444456,0.001785688,0.0022456893,0.013484321,0.02045054,0.0020453935,-0.005329905,-4.292356E-4,2.7519456E-4,0.002710783,-0.005245034,-0.045952607,0.002147239,-0.005632046,-0.037153173,-0.012676348,0.0269958,-0.01590145,-0.012343653,0.005285772,8.6865574E-4,0.027131593,-0.023247892,0.025502069,-0.012221439,-0.026221775,0.010299956,-0.0041654734,-0.021930693,-5.2280596E-4,-0.030716548]
\ No newline at end of file
diff --git a/vector-stores/spring-ai-milvus-store/pom.xml b/vector-stores/spring-ai-milvus-store/pom.xml
index cbf58bc40d4..b0336ef9b69 100644
--- a/vector-stores/spring-ai-milvus-store/pom.xml
+++ b/vector-stores/spring-ai-milvus-store/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-milvus-store
diff --git a/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/MilvusVectorStore.java b/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/MilvusVectorStore.java
index c19ad16f195..0a6004a1c0d 100644
--- a/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/MilvusVectorStore.java
+++ b/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/MilvusVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.util.ArrayList;
diff --git a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusEmbeddingDimensionsTests.java b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusEmbeddingDimensionsTests.java
index 1f4bd158af0..2e1e94d5bca 100644
--- a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusEmbeddingDimensionsTests.java
+++ b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusEmbeddingDimensionsTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import io.milvus.client.MilvusServiceClient;
diff --git a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusVectorStoreIT.java b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusVectorStoreIT.java
index 2a4242ec458..b5965388880 100644
--- a/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusVectorStoreIT.java
+++ b/vector-stores/spring-ai-milvus-store/src/test/java/org/springframework/ai/vectorstore/MilvusVectorStoreIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.io.IOException;
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/pom.xml b/vector-stores/spring-ai-mongodb-atlas-store/pom.xml
new file mode 100644
index 00000000000..691bebece9f
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/pom.xml
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+ org.springframework.ai
+ spring-ai
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+ spring-ai-mongodb-atlas-store
+ jar
+ Spring AI MongoDB Atlas Vector Store
+ Spring AI MongoDB Atlas Vector Store
+ https://github.com/spring-projects-experimental/spring-ai
+
+
+ https://github.com/spring-projects/spring-ai
+ git://github.com/spring-projects/spring-ai.git
+ git@github.com:spring-projects/spring-ai.git
+
+
+
+
+ org.springframework.ai
+ spring-ai-core
+ ${parent.version}
+
+
+
+ org.springframework.data
+ spring-data-mongodb
+
+
+ org.mongodb
+ mongodb-driver-sync
+
+
+
+
+ org.springframework.ai
+ spring-ai-openai-spring-boot-starter
+ ${parent.version}
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
+ test
+
+
+
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java
new file mode 100644
index 00000000000..f541b000224
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterExpressionConverter.java
@@ -0,0 +1,97 @@
+/*
+ * 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.vectorstore;
+
+import org.springframework.ai.vectorstore.filter.Filter;
+import org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter;
+
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.OR;
+
+/**
+ * Converts {@link Filter.Expression} into MongDB Atlas metadata filter expression format.
+ * (https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#std-label-vectorSearch-agg-pipeline-filter)
+ *
+ * @author Chris Smith
+ * @since 1.0.0
+ */
+public class MongoDBAtlasFilterExpressionConverter extends AbstractFilterExpressionConverter {
+
+ @Override
+ protected void doExpression(Filter.Expression expression, StringBuilder context) {
+ // Handling AND/OR
+ if (AND.equals(expression.type()) || OR.equals(expression.type())) {
+ doCompoundExpressionType(expression, context);
+ }
+ else {
+ doSingleExpressionType(expression, context);
+ }
+ }
+
+ private void doCompoundExpressionType(Filter.Expression expression, StringBuilder context) {
+ context.append("{");
+ context.append(getOperationSymbol(expression));
+ context.append(":[");
+ this.convertOperand(expression.left(), context);
+ context.append(",");
+ this.convertOperand(expression.right(), context);
+ context.append("]}");
+ }
+
+ private void doSingleExpressionType(Filter.Expression expression, StringBuilder context) {
+ context.append("{");
+ this.convertOperand(expression.left(), context);
+ context.append(":{");
+ context.append(getOperationSymbol(expression));
+ context.append(":");
+ this.convertOperand(expression.right(), context);
+ context.append("}}");
+ }
+
+ private String getOperationSymbol(Filter.Expression exp) {
+ switch (exp.type()) {
+ case AND:
+ return "$and";
+ case OR:
+ return "$or";
+ case EQ:
+ return "$eq";
+ case NE:
+ return "$ne";
+ case LT:
+ return "$lt";
+ case LTE:
+ return "$lte";
+ case GT:
+ return "$gt";
+ case GTE:
+ return "$gte";
+ case IN:
+ return "$in";
+ case NIN:
+ return "$nin";
+ default:
+ throw new RuntimeException("Not supported expression type:" + exp.type());
+ }
+ }
+
+ @Override
+ protected void doKey(Filter.Key filterKey, StringBuilder context) {
+ var identifier = (hasOuterQuotes(filterKey.key())) ? removeOuterQuotes(filterKey.key()) : filterKey.key();
+ context.append("\"metadata." + identifier + "\"");
+ }
+
+}
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java
new file mode 100644
index 00000000000..928cbb14048
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStore.java
@@ -0,0 +1,271 @@
+/*
+ * 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.vectorstore;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import com.mongodb.BasicDBObject;
+
+import org.springframework.ai.document.Document;
+import org.springframework.ai.embedding.EmbeddingClient;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.aggregation.Aggregation;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.util.Assert;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+
+/**
+ * @author Chris Smith
+ * @since 1.0.0
+ */
+public class MongoDBAtlasVectorStore implements VectorStore, InitializingBean {
+
+ public static final String ID_FIELD_NAME = "_id";
+
+ public static final String METADATA_FIELD_NAME = "metadata";
+
+ public static final String CONTENT_FIELD_NAME = "content";
+
+ public static final String SCORE_FIELD_NAME = "score";
+
+ private static final String DEFAULT_VECTOR_COLLECTION_NAME = "vector_store";
+
+ private static final String DEFAULT_VECTOR_INDEX_NAME = "vector_index";
+
+ private static final String DEFAULT_PATH_NAME = "embedding";
+
+ private static final int DEFAULT_NUM_CANDIDATES = 200;
+
+ private final MongoTemplate mongoTemplate;
+
+ private final EmbeddingClient embeddingClient;
+
+ private final MongoDBVectorStoreConfig config;
+
+ private final MongoDBAtlasFilterExpressionConverter filterExpressionConverter = new MongoDBAtlasFilterExpressionConverter();
+
+ public MongoDBAtlasVectorStore(MongoTemplate mongoTemplate, EmbeddingClient embeddingClient) {
+ this(mongoTemplate, embeddingClient, MongoDBVectorStoreConfig.defaultConfig());
+ }
+
+ public MongoDBAtlasVectorStore(MongoTemplate mongoTemplate, EmbeddingClient embeddingClient,
+ MongoDBVectorStoreConfig config) {
+ this.mongoTemplate = mongoTemplate;
+ this.embeddingClient = embeddingClient;
+ this.config = config;
+
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ // Create the collection if it does not exist
+ if (!mongoTemplate.collectionExists(this.config.collectionName)) {
+ mongoTemplate.createCollection(this.config.collectionName);
+ }
+ // Create search index, command doesn't do anything if already existing
+ mongoTemplate.executeCommand(createSearchIndex());
+ }
+
+ /**
+ * Provides the Definition for the search index
+ */
+ private org.bson.Document createSearchIndex() {
+ List vectorFields = new ArrayList<>();
+ vectorFields.add(new org.bson.Document().append("type", "vector")
+ .append("path", this.config.pathName)
+ .append("numDimensions", 1536)
+ .append("similarity", "cosine"));
+ vectorFields.addAll(this.config.metadataFieldsToFilter.stream()
+ .map(fieldName -> new org.bson.Document().append("type", "filter").append("path", "metadata." + fieldName))
+ .toList());
+
+ return new org.bson.Document().append("createSearchIndexes", this.config.collectionName)
+ .append("indexes",
+ List.of(new org.bson.Document().append("name", this.config.vectorIndexName)
+ .append("type", "vectorSearch")
+ .append("definition", new org.bson.Document("fields", vectorFields))));
+ }
+
+ /**
+ * Maps a BasicDBObject to a Spring AI Document
+ * @param basicDBObject the basicDBObject to map to a spring ai document
+ * @return the spring ai document
+ */
+ @SuppressWarnings("unchecked")
+ private Document mapBasicDbObject(BasicDBObject basicDBObject) {
+ String id = basicDBObject.getString(ID_FIELD_NAME);
+ String content = basicDBObject.getString(CONTENT_FIELD_NAME);
+ Map metadata = (Map) basicDBObject.get(METADATA_FIELD_NAME);
+ List embedding = (List) basicDBObject.get(this.config.pathName);
+
+ Document document = new Document(id, content, metadata);
+ document.setEmbedding(embedding);
+
+ return document;
+ }
+
+ @Override
+ public void add(List documents) {
+ for (Document document : documents) {
+ List embedding = this.embeddingClient.embed(document);
+ document.setEmbedding(embedding);
+ this.mongoTemplate.save(document, this.config.collectionName);
+ }
+ }
+
+ @Override
+ public Optional delete(List idList) {
+ Query query = new Query(where(ID_FIELD_NAME).in(idList));
+
+ var deleteRes = this.mongoTemplate.remove(query, this.config.collectionName);
+ long deleteCount = deleteRes.getDeletedCount();
+
+ return Optional.of(deleteCount == idList.size());
+ }
+
+ @Override
+ public List similaritySearch(String query) {
+ return similaritySearch(SearchRequest.query(query));
+ }
+
+ @Override
+ public List similaritySearch(SearchRequest request) {
+
+ String nativeFilterExpressions = (request.getFilterExpression() != null)
+ ? this.filterExpressionConverter.convertExpression(request.getFilterExpression()) : "";
+
+ List queryEmbedding = this.embeddingClient.embed(request.getQuery());
+ var vectorSearch = new VectorSearchAggregation(queryEmbedding, this.config.pathName, this.config.numCandidates,
+ this.config.vectorIndexName, request.getTopK(), nativeFilterExpressions);
+
+ Aggregation aggregation = Aggregation.newAggregation(vectorSearch,
+ Aggregation.addFields()
+ .addField(SCORE_FIELD_NAME)
+ .withValueOfExpression("{\"$meta\":\"vectorSearchScore\"}")
+ .build(),
+ Aggregation.match(new Criteria(SCORE_FIELD_NAME).gte(request.getSimilarityThreshold())));
+
+ return this.mongoTemplate.aggregate(aggregation, this.config.collectionName, BasicDBObject.class)
+ .getMappedResults()
+ .stream()
+ .map(this::mapBasicDbObject)
+ .toList();
+ }
+
+ public static class MongoDBVectorStoreConfig {
+
+ private final String collectionName;
+
+ private final String vectorIndexName;
+
+ private final String pathName;
+
+ private final List metadataFieldsToFilter;
+
+ private final int numCandidates;
+
+ private MongoDBVectorStoreConfig(Builder builder) {
+ this.collectionName = builder.collectionName;
+ this.vectorIndexName = builder.vectorIndexName;
+ this.pathName = builder.pathName;
+ this.numCandidates = builder.numCandidates;
+ this.metadataFieldsToFilter = builder.metadataFieldsToFilter;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static MongoDBVectorStoreConfig defaultConfig() {
+ return builder().build();
+ }
+
+ public static class Builder {
+
+ private String collectionName = DEFAULT_VECTOR_COLLECTION_NAME;
+
+ private String vectorIndexName = DEFAULT_VECTOR_INDEX_NAME;
+
+ private String pathName = DEFAULT_PATH_NAME;
+
+ private int numCandidates = DEFAULT_NUM_CANDIDATES;
+
+ private List metadataFieldsToFilter = Collections.emptyList();
+
+ private Builder() {
+ }
+
+ /**
+ * Configures the collection to use This must match the name of the collection
+ * for the Vector Search Index in Atlas
+ * @param collectionName
+ * @return this builder
+ */
+ public Builder withCollectionName(String collectionName) {
+ Assert.notNull(collectionName, "Collection Name must not be null");
+ Assert.notNull(collectionName, "Collection Name must not be empty");
+ this.collectionName = collectionName;
+ return this;
+ }
+
+ /**
+ * Configures the vector index name. This must match the name of the Vector
+ * Search Index Name in Atlas
+ * @param vectorIndexName
+ * @return this builder
+ */
+ public Builder withVectorIndexName(String vectorIndexName) {
+ Assert.notNull(vectorIndexName, "Vector Index Name must not be null");
+ Assert.notNull(vectorIndexName, "Vector Index Name must not be empty");
+ this.vectorIndexName = vectorIndexName;
+ return this;
+ }
+
+ /**
+ * Configures the path name. This must match the name of the field indexed for
+ * the Vector Search Index in Atlas
+ * @param pathName
+ * @return this builder
+ */
+ public Builder withPathName(String pathName) {
+ Assert.notNull(pathName, "Path Name must not be null");
+ Assert.notNull(pathName, "Path Name must not be empty");
+ this.pathName = pathName;
+ return this;
+ }
+
+ public Builder withMetadataFieldsToFilter(List metadataFieldsToFilter) {
+ Assert.notEmpty(metadataFieldsToFilter, "Fields list must not be empty");
+ this.metadataFieldsToFilter = metadataFieldsToFilter;
+ return this;
+ }
+
+ public MongoDBVectorStoreConfig build() {
+ return new MongoDBVectorStoreConfig(this);
+ }
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java
new file mode 100644
index 00000000000..572749af48d
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/main/java/org/springframework/ai/vectorstore/VectorSearchAggregation.java
@@ -0,0 +1,42 @@
+/*
+ * 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.vectorstore;
+
+import org.bson.Document;
+import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
+import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
+import org.springframework.lang.NonNull;
+
+import java.util.List;
+
+record VectorSearchAggregation(List embeddings, String path, int numCandidates, String index, int count,
+ String filter) implements AggregationOperation {
+
+ @SuppressWarnings("null")
+ @Override
+ public org.bson.Document toDocument(@NonNull AggregationOperationContext context) {
+ var vectorSearch = new Document("queryVector", embeddings).append("path", path)
+ .append("numCandidates", numCandidates)
+ .append("index", index)
+ .append("limit", count);
+ if (!filter.isEmpty()) {
+ vectorSearch.append("filter", Document.parse(filter));
+ }
+ var doc = new Document("$vectorSearch", vectorSearch);
+
+ return context.getMappedObject(doc);
+ }
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasContainer.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasContainer.java
new file mode 100644
index 00000000000..60dfec22f29
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasContainer.java
@@ -0,0 +1,39 @@
+/*
+ * 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.vectorstore;
+
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+import java.time.Duration;
+
+public class MongoDBAtlasContainer extends GenericContainer {
+
+ public MongoDBAtlasContainer() {
+ super("mongodb/atlas:v1.15.1");
+ withPrivilegedMode(true);
+ withCommand("/bin/bash", "-c",
+ "atlas deployments setup local-test --type local --port 27778 --bindIpAll --username root --password root --force && tail -f /dev/null");
+ withExposedPorts(27778);
+ waitingFor(Wait.forLogMessage(".*Deployment created!.*\\n", 1));
+ withStartupTimeout(Duration.ofMinutes(5));
+ }
+
+ public String getConnectionString() {
+ return String.format("mongodb://root:root@%s:%s/?directConnection=true", getHost(), getMappedPort(27778));
+ }
+
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java
new file mode 100644
index 00000000000..6ab38c55ca1
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasFilterConverterTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.vectorstore;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.ai.vectorstore.filter.Filter.Expression;
+import org.springframework.ai.vectorstore.filter.Filter.Group;
+import org.springframework.ai.vectorstore.filter.Filter.Key;
+import org.springframework.ai.vectorstore.filter.Filter.Value;
+import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.EQ;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.GTE;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.IN;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.LTE;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NE;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NIN;
+import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.OR;
+
+/**
+ * @author Christopher Smith
+ */
+public class MongoDBAtlasFilterConverterTest {
+
+ FilterExpressionConverter converter = new MongoDBAtlasFilterExpressionConverter();
+
+ @Test
+ public void testEQ() {
+ // country == "BG"
+ String vectorExpr = converter.convertExpression(new Expression(EQ, new Key("country"), new Value("BG")));
+ assertThat(vectorExpr).isEqualTo("{\"metadata.country\":{$eq:\"BG\"}}");
+ }
+
+ @Test
+ public void tesEqAndGte() {
+ // genre == "drama" AND year >= 2020
+ String vectorExpr = converter
+ .convertExpression(new Expression(AND, new Expression(EQ, new Key("genre"), new Value("drama")),
+ new Expression(GTE, new Key("year"), new Value(2020))));
+ assertThat(vectorExpr)
+ .isEqualTo("{$and:[{\"metadata.genre\":{$eq:\"drama\"}},{\"metadata.year\":{$gte:2020}}]}");
+ }
+
+ @Test
+ public void tesIn() {
+ // genre in ["comedy", "documentary", "drama"]
+ String vectorExpr = converter.convertExpression(
+ new Expression(IN, new Key("genre"), new Value(List.of("comedy", "documentary", "drama"))));
+ assertThat(vectorExpr).isEqualTo("{\"metadata.genre\":{$in:[\"comedy\",\"documentary\",\"drama\"]}}");
+ }
+
+ @Test
+ public void testNe() {
+ // year >= 2020 OR country == "BG" AND city != "Sofia"
+ String vectorExpr = converter
+ .convertExpression(new Expression(OR, new Expression(GTE, new Key("year"), new Value(2020)),
+ new Expression(AND, new Expression(EQ, new Key("country"), new Value("BG")),
+ new Expression(NE, new Key("city"), new Value("Sofia")))));
+ assertThat(vectorExpr).isEqualTo(
+ "{$or:[{\"metadata.year\":{$gte:2020}},{$and:[{\"metadata.country\":{$eq:\"BG\"}},{\"metadata.city\":{$ne:\"Sofia\"}}]}]}");
+ }
+
+ @Test
+ public void testGroup() {
+ // (year >= 2020 OR country == "BG") AND city NIN ["Sofia", "Plovdiv"]
+ String vectorExpr = converter.convertExpression(new Expression(AND,
+ new Group(new Expression(OR, new Expression(GTE, new Key("year"), new Value(2020)),
+ new Expression(EQ, new Key("country"), new Value("BG")))),
+ new Expression(NIN, new Key("city"), new Value(List.of("Sofia", "Plovdiv")))));
+ assertThat(vectorExpr).isEqualTo(
+ "{$and:[{$or:[{\"metadata.year\":{$gte:2020}},{\"metadata.country\":{$eq:\"BG\"}}]},{\"metadata.city\":{$nin:[\"Sofia\",\"Plovdiv\"]}}]}");
+ }
+
+ @Test
+ public void testBoolean() {
+ // isOpen == true AND year >= 2020 AND country IN ["BG", "NL", "US"]
+ String vectorExpr = converter.convertExpression(new Expression(AND,
+ new Expression(AND, new Expression(EQ, new Key("isOpen"), new Value(true)),
+ new Expression(GTE, new Key("year"), new Value(2020))),
+ new Expression(IN, new Key("country"), new Value(List.of("BG", "NL", "US")))));
+
+ assertThat(vectorExpr).isEqualTo(
+ "{$and:[{$and:[{\"metadata.isOpen\":{$eq:true}},{\"metadata.year\":{$gte:2020}}]},{\"metadata.country\":{$in:[\"BG\",\"NL\",\"US\"]}}]}");
+ }
+
+ @Test
+ public void testDecimal() {
+ // temperature >= -15.6 && temperature <= +20.13
+ String vectorExpr = converter
+ .convertExpression(new Expression(AND, new Expression(GTE, new Key("temperature"), new Value(-15.6)),
+ new Expression(LTE, new Key("temperature"), new Value(20.13))));
+
+ assertThat(vectorExpr)
+ .isEqualTo("{$and:[{\"metadata.temperature\":{$gte:-15.6}},{\"metadata.temperature\":{$lte:20.13}}]}");
+ }
+
+ @Test
+ public void testComplexIdentifiers() {
+ String vectorExpr = converter
+ .convertExpression(new Expression(EQ, new Key("\"country 1 2 3\""), new Value("BG")));
+ assertThat(vectorExpr).isEqualTo("{\"metadata.country 1 2 3\":{$eq:\"BG\"}}");
+
+ vectorExpr = converter.convertExpression(new Expression(EQ, new Key("'country 1 2 3'"), new Value("BG")));
+ assertThat(vectorExpr).isEqualTo("{\"metadata.country 1 2 3\":{$eq:\"BG\"}}");
+ }
+
+}
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java
new file mode 100644
index 00000000000..afc2dcbd743
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/MongoDBAtlasVectorStoreIT.java
@@ -0,0 +1,216 @@
+/*
+ * 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.vectorstore;
+
+import com.mongodb.client.MongoClient;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.embedding.EmbeddingClient;
+import org.springframework.ai.openai.OpenAiEmbeddingClient;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Chris Smith
+ */
+
+@Testcontainers
+class MongoDBAtlasVectorStoreIT {
+
+ @Container
+ private static MongoDBAtlasContainer container = new MongoDBAtlasContainer();
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withUserConfiguration(TestApplication.class)
+ .withPropertyValues("spring.ai.openai.apiKey=" + System.getenv("OPENAI_API_KEY"),
+ String.format("spring.data.mongodb.database=" + "springaisample"),
+ String.format("spring.data.mongodb.uri=" + container.getConnectionString()));
+
+ @BeforeEach
+ public void beforeEach() {
+ contextRunner.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class)).run(context -> {
+ MongoTemplate mongoTemplate = context.getBean(MongoTemplate.class);
+ mongoTemplate.getCollection("vector_store").deleteMany(new org.bson.Document());
+ });
+ }
+
+ @Test
+ void vectorStoreTest() {
+ contextRunner.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class)).run(context -> {
+ VectorStore vectorStore = context.getBean(VectorStore.class);
+
+ List documents = List.of(
+ new Document(
+ "Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!",
+ Collections.singletonMap("meta1", "meta1")),
+ new Document("Hello World Hello World Hello World Hello World Hello World Hello World Hello World"),
+ new Document(
+ "Great Depression Great Depression Great Depression Great Depression Great Depression Great Depression",
+ Collections.singletonMap("meta2", "meta2")));
+
+ vectorStore.add(documents);
+ Thread.sleep(5000); // Await a second for the document to be indexed
+
+ List results = vectorStore.similaritySearch(SearchRequest.query("Great").withTopK(1));
+
+ assertThat(results).hasSize(1);
+ Document resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(documents.get(2).getId());
+ assertThat(resultDoc.getContent()).isEqualTo(
+ "Great Depression Great Depression Great Depression Great Depression Great Depression Great Depression");
+ assertThat(resultDoc.getMetadata()).containsEntry("meta2", "meta2");
+
+ // Remove all documents from the store
+ vectorStore.delete(documents.stream().map(Document::getId).collect(Collectors.toList()));
+
+ List results2 = vectorStore.similaritySearch(SearchRequest.query("Great").withTopK(1));
+ assertThat(results2).isEmpty();
+
+ });
+ }
+
+ @Test
+ void documentUpdateTest() {
+ contextRunner.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class)).run(context -> {
+ VectorStore vectorStore = context.getBean(VectorStore.class);
+
+ Document document = new Document(UUID.randomUUID().toString(), "Spring AI rocks!!",
+ Collections.singletonMap("meta1", "meta1"));
+
+ vectorStore.add(List.of(document));
+ Thread.sleep(5000); // Await a second for the document to be indexed
+
+ List results = vectorStore.similaritySearch(SearchRequest.query("Spring").withTopK(5));
+
+ assertThat(results).hasSize(1);
+ Document resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(document.getId());
+ assertThat(resultDoc.getContent()).isEqualTo("Spring AI rocks!!");
+ assertThat(resultDoc.getMetadata()).containsEntry("meta1", "meta1");
+
+ Document sameIdDocument = new Document(document.getId(),
+ "The World is Big and Salvation Lurks Around the Corner",
+ Collections.singletonMap("meta2", "meta2"));
+
+ vectorStore.add(List.of(sameIdDocument));
+
+ results = vectorStore.similaritySearch(SearchRequest.query("FooBar").withTopK(5));
+
+ assertThat(results).hasSize(1);
+ resultDoc = results.get(0);
+ assertThat(resultDoc.getId()).isEqualTo(document.getId());
+ assertThat(resultDoc.getContent()).isEqualTo("The World is Big and Salvation Lurks Around the Corner");
+ assertThat(resultDoc.getMetadata()).containsEntry("meta2", "meta2");
+ });
+ }
+
+ @Test
+ void searchWithFilters() {
+ contextRunner.withConfiguration(AutoConfigurations.of(OpenAiAutoConfiguration.class)).run(context -> {
+ VectorStore vectorStore = context.getBean(VectorStore.class);
+
+ var bgDocument = new Document("The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "BG", "year", 2020));
+ var nlDocument = new Document("The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "NL"));
+ var bgDocument2 = new Document("The World is Big and Salvation Lurks Around the Corner",
+ Map.of("country", "BG", "year", 2023));
+
+ vectorStore.add(List.of(bgDocument, nlDocument, bgDocument2));
+ Thread.sleep(5000); // Await a second for the document to be indexed
+
+ List results = vectorStore.similaritySearch(SearchRequest.query("The World").withTopK(5));
+ assertThat(results).hasSize(3);
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'NL'"));
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(nlDocument.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'BG'"));
+
+ assertThat(results).hasSize(2);
+ assertThat(results.get(0).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+ assertThat(results.get(1).getId()).isIn(bgDocument.getId(), bgDocument2.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("country == 'BG' && year == 2020"));
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).getId()).isEqualTo(bgDocument.getId());
+
+ results = vectorStore.similaritySearch(SearchRequest.query("The World")
+ .withTopK(5)
+ .withSimilarityThresholdAll()
+ .withFilterExpression("NOT(country == 'BG' && year == 2020)"));
+
+ assertThat(results).hasSize(2);
+ assertThat(results.get(0).getId()).isIn(nlDocument.getId(), bgDocument2.getId());
+ assertThat(results.get(1).getId()).isIn(nlDocument.getId(), bgDocument2.getId());
+
+ });
+ }
+
+ @SpringBootConfiguration
+ @EnableAutoConfiguration
+ public static class TestApplication {
+
+ @Bean
+ public VectorStore vectorStore(MongoTemplate mongoTemplate, EmbeddingClient embeddingClient) {
+ return new MongoDBAtlasVectorStore(mongoTemplate, embeddingClient,
+ MongoDBAtlasVectorStore.MongoDBVectorStoreConfig.builder()
+ .withMetadataFieldsToFilter(List.of("country", "year"))
+ .build());
+ }
+
+ @Bean
+ public MongoTemplate mongoTemplate(MongoClient mongoClient) {
+ return new MongoTemplate(mongoClient, "springaisample");
+ }
+
+ @Bean
+ public EmbeddingClient embeddingClient() {
+ return new OpenAiEmbeddingClient(new OpenAiApi(System.getenv("OPENAI_API_KEY")));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java
new file mode 100644
index 00000000000..f489df3da1c
--- /dev/null
+++ b/vector-stores/spring-ai-mongodb-atlas-store/src/test/java/org/springframework/ai/vectorstore/VectorSearchAggregationTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.vectorstore;
+
+import org.bson.Document;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.mongodb.core.aggregation.Aggregation;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class VectorSearchAggregationTest {
+
+ @Test
+ void toDocumentNoFilter() {
+ var vectorSearchAggregation = new VectorSearchAggregation(List.of(1.0, 2.0, 3.0), "embedding", 10,
+ "vector_store", 10, "");
+ var aggregation = Aggregation.newAggregation(vectorSearchAggregation);
+ var document = aggregation.toDocument("vector_store", Aggregation.DEFAULT_CONTEXT);
+
+ var vectorSearchDocument = new Document("$vectorSearch",
+ new Document("queryVector", List.of(1.0, 2.0, 3.0)).append("path", "embedding")
+ .append("numCandidates", 10)
+ .append("index", "vector_store")
+ .append("limit", 10));
+ var expected = new Document().append("aggregate", "vector_store")
+ .append("pipeline", List.of(vectorSearchDocument));
+ assertEquals(expected, document);
+ }
+
+ @Test
+ void toDocumentWithFilter() {
+ var vectorSearchAggregation = new VectorSearchAggregation(List.of(1.0, 2.0, 3.0), "embedding", 10,
+ "vector_store", 10, "{\"metadata.country\":{$eq:\"BG\"}}");
+ var aggregation = Aggregation.newAggregation(vectorSearchAggregation);
+ var document = aggregation.toDocument("vector_store", Aggregation.DEFAULT_CONTEXT);
+
+ var vectorSearchDocument = new Document("$vectorSearch",
+ new Document("queryVector", List.of(1.0, 2.0, 3.0)).append("path", "embedding")
+ .append("numCandidates", 10)
+ .append("index", "vector_store")
+ .append("filter", new Document("metadata.country", new Document().append("$eq", "BG")))
+ .append("limit", 10));
+ var expected = new Document().append("aggregate", "vector_store")
+ .append("pipeline", List.of(vectorSearchDocument));
+ assertEquals(expected, document);
+ }
+
+}
\ No newline at end of file
diff --git a/vector-stores/spring-ai-neo4j-store/pom.xml b/vector-stores/spring-ai-neo4j-store/pom.xml
index b4f028449fe..89d7b9db340 100644
--- a/vector-stores/spring-ai-neo4j-store/pom.xml
+++ b/vector-stores/spring-ai-neo4j-store/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-neo4j-store
diff --git a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java
index 6515c551b6e..7837ecda358 100644
--- a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java
+++ b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import org.neo4j.cypherdsl.support.schema_name.SchemaNames;
@@ -64,14 +63,19 @@ public static final class Neo4jVectorStoreConfig {
private final Neo4jDistanceType distanceType;
- private final String label;
-
private final String embeddingProperty;
- private final String quotedLabel;
+ private final String label;
private final String indexName;
+ // needed for similarity search call
+ private final String indexNameNotSanitized;
+
+ private final String idProperty;
+
+ private final String constraintName;
+
/**
* Start building a new configuration.
* @return The entry point for creating a new configuration.
@@ -97,10 +101,12 @@ private Neo4jVectorStoreConfig(Builder builder) {
.orElseGet(SessionConfig::defaultConfig);
this.embeddingDimension = builder.embeddingDimension;
this.distanceType = builder.distanceType;
- this.label = builder.label;
- this.embeddingProperty = builder.embeddingProperty;
- this.quotedLabel = SchemaNames.sanitize(this.label).orElseThrow();
- this.indexName = builder.indexName;
+ this.embeddingProperty = SchemaNames.sanitize(builder.embeddingProperty).orElseThrow();
+ this.label = SchemaNames.sanitize(builder.label).orElseThrow();
+ this.indexNameNotSanitized = builder.indexName;
+ this.indexName = SchemaNames.sanitize(builder.indexName, true).orElseThrow();
+ this.constraintName = SchemaNames.sanitize(builder.constraintName).orElseThrow();
+ this.idProperty = SchemaNames.sanitize(builder.idProperty).orElseThrow();
}
public static class Builder {
@@ -117,6 +123,10 @@ public static class Builder {
private String indexName = DEFAULT_INDEX_NAME;
+ private String idProperty = DEFAULT_ID_PROPERTY;
+
+ private String constraintName = DEFAULT_CONSTRAINT_NAME;
+
private Builder() {
}
@@ -203,6 +213,35 @@ public Builder withIndexName(String newIndexName) {
return this;
}
+ /**
+ * Configures the id property to be used. Defaults to {@literal id}.
+ * @param newIdProperty The name of the id property of the {@link Document}
+ * entity
+ * @return this builder
+ */
+ public Builder withIdProperty(String newIdProperty) {
+
+ Assert.hasText(newIdProperty, "Id property may not be null or blank");
+
+ this.idProperty = newIdProperty;
+ return this;
+ }
+
+ /**
+ * Configures the constraint name to be used. Defaults to
+ * {@literal Document_unique_idx}.
+ * @param newConstraintName The name of the unique constraint for the id
+ * property.
+ * @return this builder
+ */
+ public Builder withConstraintName(String newConstraintName) {
+
+ Assert.hasText(newConstraintName, "Constraint name may not be null or blank");
+
+ this.constraintName = newConstraintName;
+ return this;
+ }
+
/**
* {@return the immutable configuration}
*/
@@ -223,6 +262,10 @@ public Neo4jVectorStoreConfig build() {
public static final String DEFAULT_EMBEDDING_PROPERTY = "embedding";
+ public static final String DEFAULT_ID_PROPERTY = "id";
+
+ public static final String DEFAULT_CONSTRAINT_NAME = DEFAULT_LABEL + "_unique_idx";
+
private final Neo4jVectorFilterExpressionConverter filterExpressionConverter = new Neo4jVectorFilterExpressionConverter();
private final Driver driver;
@@ -250,16 +293,16 @@ public void add(List documents) {
try (var session = this.driver.session()) {
var statement = """
UNWIND $rows AS row
- MERGE (u:%s {id: row.id})
+ MERGE (u:%s {%2$s: row.id})
ON CREATE
SET u += row.properties
ON MATCH
SET u = {}
- SET u.id = row.id,
+ SET u.%2$s = row.id,
u += row.properties
WITH row, u
CALL db.create.setNodeVectorProperty(u, $embeddingProperty, row.embedding)
- """.formatted(this.config.quotedLabel);
+ """.formatted(this.config.label, this.config.idProperty);
session.run(statement, Map.of("rows", rows, "embeddingProperty", this.config.embeddingProperty)).consume();
}
}
@@ -269,10 +312,12 @@ public Optional delete(List idList) {
try (var session = this.driver.session(this.config.sessionConfig)) {
- var summary = session.run("""
- MATCH (n:%s) WHERE n.id IN $ids
- CALL { WITH n DETACH DELETE n } IN TRANSACTIONS OF $transactionSize ROWS
- """.formatted(this.config.quotedLabel), Map.of("ids", idList, "transactionSize", 10_000))
+ var summary = session
+ .run("""
+ MATCH (n:%s) WHERE n.%s IN $ids
+ CALL { WITH n DETACH DELETE n } IN TRANSACTIONS OF $transactionSize ROWS
+ """.formatted(this.config.label, this.config.idProperty),
+ Map.of("ids", idList, "transactionSize", 10_000))
.consume();
return Optional.of(idList.size() == summary.counters().nodesDeleted());
}
@@ -298,10 +343,9 @@ public List similaritySearch(SearchRequest request) {
RETURN node, score""".formatted(condition);
return session
- .run(query,
- Map.of("indexName", this.config.indexName, "numberOfNearestNeighbours", request.getTopK(),
- "embeddingValue", embedding, "threshold", request.getSimilarityThreshold()))
- .list(Neo4jVectorStore::recordToDocument);
+ .run(query, Map.of("indexName", this.config.indexNameNotSanitized, "numberOfNearestNeighbours",
+ request.getTopK(), "embeddingValue", embedding, "threshold", request.getSimilarityThreshold()))
+ .list(this::recordToDocument);
}
}
@@ -311,8 +355,8 @@ public void afterPropertiesSet() {
try (var session = this.driver.session(this.config.sessionConfig)) {
session
- .run("CREATE CONSTRAINT %s IF NOT EXISTS FOR (n:%s) REQUIRE n.id IS UNIQUE".formatted(
- SchemaNames.sanitize(this.config.label + "_unique_idx").orElseThrow(), this.config.quotedLabel))
+ .run("CREATE CONSTRAINT %s IF NOT EXISTS FOR (n:%s) REQUIRE n.%s IS UNIQUE"
+ .formatted(this.config.constraintName, this.config.label, this.config.idProperty))
.consume();
var statement = """
@@ -321,9 +365,8 @@ public void afterPropertiesSet() {
`vector.dimensions`: %d,
`vector.similarity_function`: '%s'
}}
- """.formatted(SchemaNames.sanitize(this.config.indexName, true).orElseThrow(),
- this.config.quotedLabel, this.config.embeddingProperty, this.config.embeddingDimension,
- this.config.distanceType.name);
+ """.formatted(this.config.indexName, this.config.label, this.config.embeddingProperty,
+ this.config.embeddingDimension, this.config.distanceType.name);
session.run(statement).consume();
session.run("CALL db.awaitIndexes()").consume();
}
@@ -356,7 +399,7 @@ private static float[] toFloatArray(List embeddingDouble) {
return embeddingFloat;
}
- private static Document recordToDocument(org.neo4j.driver.Record neoRecord) {
+ private Document recordToDocument(org.neo4j.driver.Record neoRecord) {
var node = neoRecord.get("node").asNode();
var score = neoRecord.get("score").asFloat();
var metaData = new HashMap();
@@ -367,7 +410,8 @@ private static Document recordToDocument(org.neo4j.driver.Record neoRecord) {
}
});
- return new Document(node.get("id").asString(), node.get("text").asString(), Map.copyOf(metaData));
+ return new Document(node.get(this.config.idProperty).asString(), node.get("text").asString(),
+ Map.copyOf(metaData));
}
}
diff --git a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverter.java b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverter.java
index ceb83eb6ffd..5d03333be91 100644
--- a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverter.java
+++ b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
diff --git a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java
index 940db8579f6..a258d815366 100644
--- a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java
+++ b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java
@@ -1,3 +1,18 @@
+/*
+ * 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.vectorstore;
import java.util.Collections;
@@ -43,7 +58,7 @@ class Neo4jVectorStoreIT {
// creation
// function.
@Container
- static Neo4jContainer> neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.15"))
+ static Neo4jContainer> neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.18"))
.withRandomPassword();
List documents = List.of(
diff --git a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverterTests.java b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverterTests.java
index 2b6d19f8500..37bb4637956 100644
--- a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverterTests.java
+++ b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/filter/Neo4jVectorFilterExpressionConverterTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.filter;
import java.util.List;
diff --git a/vector-stores/spring-ai-pgvector-store/pom.xml b/vector-stores/spring-ai-pgvector-store/pom.xml
index 5158886e293..c9077fd6ded 100644
--- a/vector-stores/spring-ai-pgvector-store/pom.xml
+++ b/vector-stores/spring-ai-pgvector-store/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-pgvector-store
diff --git a/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/PgVectorStore.java b/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/PgVectorStore.java
index 37941a15a00..1d85ee361df 100644
--- a/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/PgVectorStore.java
+++ b/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/PgVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.sql.PreparedStatement;
diff --git a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorEmbeddingDimensionsTests.java b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorEmbeddingDimensionsTests.java
index dc18a6997ac..cff66185be3 100644
--- a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorEmbeddingDimensionsTests.java
+++ b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorEmbeddingDimensionsTests.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import org.junit.jupiter.api.Test;
diff --git a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorStoreIT.java b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorStoreIT.java
index 3505ef4c352..9bfb63e567c 100644
--- a/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorStoreIT.java
+++ b/vector-stores/spring-ai-pgvector-store/src/test/java/org/springframework/ai/vectorstore/PgVectorStoreIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.io.IOException;
diff --git a/vector-stores/spring-ai-pinecone/pom.xml b/vector-stores/spring-ai-pinecone/pom.xml
index a978d582c4a..f9a40f83bf8 100644
--- a/vector-stores/spring-ai-pinecone/pom.xml
+++ b/vector-stores/spring-ai-pinecone/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-pinecone
diff --git a/vector-stores/spring-ai-pinecone/src/main/java/org/springframework/ai/vectorstore/PineconeVectorStore.java b/vector-stores/spring-ai-pinecone/src/main/java/org/springframework/ai/vectorstore/PineconeVectorStore.java
index d350032f089..a2e083f8a45 100644
--- a/vector-stores/spring-ai-pinecone/src/main/java/org/springframework/ai/vectorstore/PineconeVectorStore.java
+++ b/vector-stores/spring-ai-pinecone/src/main/java/org/springframework/ai/vectorstore/PineconeVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,
diff --git a/vector-stores/spring-ai-pinecone/src/test/java/org/springframework/ai/vectorstore/PineconeVectorStoreIT.java b/vector-stores/spring-ai-pinecone/src/test/java/org/springframework/ai/vectorstore/PineconeVectorStoreIT.java
index 1ab2add0826..d2ee47be2c1 100644
--- a/vector-stores/spring-ai-pinecone/src/test/java/org/springframework/ai/vectorstore/PineconeVectorStoreIT.java
+++ b/vector-stores/spring-ai-pinecone/src/test/java/org/springframework/ai/vectorstore/PineconeVectorStoreIT.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-2023 the original author or authors.
+ * Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.io.IOException;
diff --git a/vector-stores/spring-ai-qdrant/pom.xml b/vector-stores/spring-ai-qdrant/pom.xml
index d990790f64a..8b635c4c172 100644
--- a/vector-stores/spring-ai-qdrant/pom.xml
+++ b/vector-stores/spring-ai-qdrant/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-qdrant
diff --git a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantFilterExpressionConverter.java b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantFilterExpressionConverter.java
index ec1ecfae80d..ec1d1fbdd97 100644
--- a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantFilterExpressionConverter.java
+++ b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantFilterExpressionConverter.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.qdrant;
import static io.qdrant.client.ConditionFactory.filter;
diff --git a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantObjectFactory.java b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantObjectFactory.java
index d87dbddba1b..8f86cb87206 100644
--- a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantObjectFactory.java
+++ b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantObjectFactory.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.qdrant;
import java.util.Map;
diff --git a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantValueFactory.java b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantValueFactory.java
index 72c2552c10b..87c1067dd61 100644
--- a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantValueFactory.java
+++ b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantValueFactory.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,
diff --git a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java
index 9ddcca6be8d..afe5f638982 100644
--- a/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.java
+++ b/vector-stores/spring-ai-qdrant/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStore.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,
diff --git a/vector-stores/spring-ai-qdrant/src/test/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStoreIT.java b/vector-stores/spring-ai-qdrant/src/test/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStoreIT.java
index d5506afcfe6..bc0bfc3c7e7 100644
--- a/vector-stores/spring-ai-qdrant/src/test/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStoreIT.java
+++ b/vector-stores/spring-ai-qdrant/src/test/java/org/springframework/ai/vectorstore/qdrant/QdrantVectorStoreIT.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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore.qdrant;
import java.util.Collections;
diff --git a/vector-stores/spring-ai-redis/pom.xml b/vector-stores/spring-ai-redis/pom.xml
index 1732e370d07..8bf9b348e8a 100644
--- a/vector-stores/spring-ai-redis/pom.xml
+++ b/vector-stores/spring-ai-redis/pom.xml
@@ -5,7 +5,7 @@
org.springframework.aispring-ai
- 0.8.1-SNAPSHOT
+ 1.0.0-SNAPSHOT../../pom.xmlspring-ai-redis
diff --git a/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisFilterExpressionConverter.java b/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisFilterExpressionConverter.java
index 40e3f5129d4..95198ff3b94 100644
--- a/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisFilterExpressionConverter.java
+++ b/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisFilterExpressionConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.text.MessageFormat;
diff --git a/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisVectorStore.java b/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisVectorStore.java
index 44882e5bd09..ce267ebeb69 100644
--- a/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisVectorStore.java
+++ b/vector-stores/spring-ai-redis/src/main/java/org/springframework/ai/vectorstore/RedisVectorStore.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2023-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,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.ai.vectorstore;
import java.text.MessageFormat;
@@ -304,25 +303,26 @@ public JedisPooled getJedis() {
@Override
public void add(List documents) {
- Pipeline pipeline = this.jedis.pipelined();
- for (Document document : documents) {
- var embedding = this.embeddingClient.embed(document);
- document.setEmbedding(embedding);
-
- var fields = new HashMap();
- fields.put(this.config.embeddingFieldName, embedding);
- fields.put(this.config.contentFieldName, document.getContent());
- fields.putAll(document.getMetadata());
- pipeline.jsonSetWithEscape(key(document.getId()), JSON_SET_PATH, fields);
- }
- List