diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingConnectionDetails.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingConnectionDetails.java index b78c42d4eeb..c8dae1bba74 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingConnectionDetails.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingConnectionDetails.java @@ -30,6 +30,7 @@ * * @author Christian Tzolov * @author Mark Pollack + * @author Ilayaperumal Gopinathan * @since 1.0.0 */ public class VertexAiEmbeddingConnectionDetails { @@ -125,26 +126,72 @@ public static class Builder { */ private PredictionServiceSettings predictionServiceSettings; + public Builder apiEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public Builder projectId(String projectId) { + this.projectId = projectId; + return this; + } + + public Builder location(String location) { + this.location = location; + return this; + } + + public Builder publisher(String publisher) { + this.publisher = publisher; + return this; + } + + public Builder predictionServiceSettings(PredictionServiceSettings predictionServiceSettings) { + this.predictionServiceSettings = predictionServiceSettings; + return this; + } + + /** + * @deprecated use {@link #apiEndpoint(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withApiEndpoint(String endpoint) { this.endpoint = endpoint; return this; } + /** + * @deprecated use {@link #projectId(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withProjectId(String projectId) { this.projectId = projectId; return this; } + /** + * @deprecated use {@link #location(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withLocation(String location) { this.location = location; return this; } + /** + * @deprecated use {@link #publisher(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withPublisher(String publisher) { this.publisher = publisher; return this; } + /** + * @deprecated use {@link #predictionServiceSettings(PredictionServiceSettings)} + * instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withPredictionServiceSettings(PredictionServiceSettings predictionServiceSettings) { this.predictionServiceSettings = predictionServiceSettings; return this; diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingUtils.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingUtils.java index caac760df72..ac99abb33e1 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingUtils.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/VertexAiEmbeddingUtils.java @@ -32,6 +32,7 @@ * Utility class for constructing parameter objects for Vertex AI embedding requests. * * @author Christian Tzolov + * @author Ilayaperumal Gopinathan * @since 1.0.0 */ public abstract class VertexAiEmbeddingUtils { @@ -82,12 +83,32 @@ public static TextParametersBuilder of() { return new TextParametersBuilder(); } + public TextParametersBuilder outputDimensionality(Integer outputDimensionality) { + Assert.notNull(outputDimensionality, "Output dimensionality must not be null"); + this.outputDimensionality = outputDimensionality; + return this; + } + + public TextParametersBuilder autoTruncate(Boolean autoTruncate) { + Assert.notNull(autoTruncate, "Auto truncate must not be null"); + this.autoTruncate = autoTruncate; + return this; + } + + /** + * @deprecated use {@link #outputDimensionality(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public TextParametersBuilder withOutputDimensionality(Integer outputDimensionality) { Assert.notNull(outputDimensionality, "Output dimensionality must not be null"); this.outputDimensionality = outputDimensionality; return this; } + /** + * @deprecated use {@link #autoTruncate(Boolean)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public TextParametersBuilder withAutoTruncate(Boolean autoTruncate) { Assert.notNull(autoTruncate, "Auto truncate must not be null"); this.autoTruncate = autoTruncate; @@ -123,12 +144,32 @@ public static TextInstanceBuilder of(String content) { return builder; } + public TextInstanceBuilder taskType(String taskType) { + Assert.hasText(taskType, "Task type must not be empty"); + this.taskType = taskType; + return this; + } + + public TextInstanceBuilder title(String title) { + Assert.hasText(title, "Title must not be empty"); + this.title = title; + return this; + } + + /** + * @deprecated use {@link #taskType(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public TextInstanceBuilder withTaskType(String taskType) { Assert.hasText(taskType, "Task type must not be empty"); this.taskType = taskType; return this; } + /** + * @deprecated use {@link #title(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public TextInstanceBuilder withTitle(String title) { Assert.hasText(title, "Title must not be empty"); this.title = title; @@ -179,12 +220,45 @@ public static MultimodalInstanceBuilder of() { return new MultimodalInstanceBuilder(); } + public MultimodalInstanceBuilder text(String text) { + Assert.hasText(text, "Text must not be empty"); + this.text = text; + return this; + } + + public MultimodalInstanceBuilder dimension(Integer dimension) { + Assert.isTrue(dimension == 128 || dimension == 256 || dimension == 512 || dimension == 1408, + "Invalid dimension value: " + dimension + ". Accepted values: 128, 256, 512, or 1408."); + this.dimension = dimension; + return this; + } + + public MultimodalInstanceBuilder image(Struct image) { + Assert.notNull(image, "Image must not be null"); + this.image = image; + return this; + } + + public MultimodalInstanceBuilder video(Struct video) { + Assert.notNull(video, "Video must not be null"); + this.video = video; + return this; + } + + /** + * @deprecated use {@link #text(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public MultimodalInstanceBuilder withText(String text) { Assert.hasText(text, "Text must not be empty"); this.text = text; return this; } + /** + * @deprecated use {@link #dimension(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public MultimodalInstanceBuilder withDimension(Integer dimension) { Assert.isTrue(dimension == 128 || dimension == 256 || dimension == 512 || dimension == 1408, "Invalid dimension value: " + dimension + ". Accepted values: 128, 256, 512, or 1408."); @@ -192,12 +266,20 @@ public MultimodalInstanceBuilder withDimension(Integer dimension) { return this; } + /** + * @deprecated use {@link #image(Struct)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public MultimodalInstanceBuilder withImage(Struct image) { Assert.notNull(image, "Image must not be null"); this.image = image; return this; } + /** + * @deprecated use {@link #video(Struct)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public MultimodalInstanceBuilder withVideo(Struct video) { Assert.notNull(video, "Video must not be null"); this.video = video; @@ -255,6 +337,35 @@ public static ImageBuilder of(MimeType mimeType) { return builder; } + public ImageBuilder imageData(Object imageData) { + Assert.notNull(imageData, "Image data must not be null"); + if (imageData instanceof byte[] bytes) { + return imageBytes(bytes); + } + else if (imageData instanceof String uri) { + return gcsUri(uri); + } + else { + throw new IllegalArgumentException("Unsupported image data type: " + imageData.getClass()); + } + } + + public ImageBuilder imageBytes(byte[] imageBytes) { + Assert.notNull(imageBytes, "Image bytes must not be null"); + this.imageBytes = imageBytes; + return this; + } + + public ImageBuilder gcsUri(String gcsUri) { + Assert.hasText(gcsUri, "GCS URI must not be empty"); + this.gcsUri = gcsUri; + return this; + } + + /** + * @deprecated use {@link #imageData(Object)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public ImageBuilder withImageData(Object imageData) { Assert.notNull(imageData, "Image data must not be null"); if (imageData instanceof byte[] bytes) { @@ -268,12 +379,20 @@ else if (imageData instanceof String uri) { } } + /** + * @deprecated use {@link #imageBytes(byte[])} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public ImageBuilder withImageBytes(byte[] imageBytes) { Assert.notNull(imageBytes, "Image bytes must not be null"); this.imageBytes = imageBytes; return this; } + /** + * @deprecated use {@link #gcsUri(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public ImageBuilder withGcsUri(String gcsUri) { Assert.hasText(gcsUri, "GCS URI must not be empty"); this.gcsUri = gcsUri; @@ -351,31 +470,94 @@ public static VideoBuilder of(MimeType mimeType) { return builder; } + public VideoBuilder videoData(Object imageData) { + Assert.notNull(imageData, "Video data must not be null"); + if (imageData instanceof byte[] imageBytes) { + return videoBytes(imageBytes); + } + else if (imageData instanceof String uri) { + return gcsUri(uri); + } + else { + throw new IllegalArgumentException("Unsupported image data type: " + imageData.getClass()); + } + } + + public VideoBuilder videoBytes(byte[] imageBytes) { + Assert.notNull(imageBytes, "Video bytes must not be null"); + this.videoBytes = imageBytes; + return this; + } + + public VideoBuilder gcsUri(String gcsUri) { + Assert.hasText(gcsUri, "GCS URI must not be empty"); + this.gcsUri = gcsUri; + return this; + } + + public VideoBuilder startOffsetSec(Integer startOffsetSec) { + if (startOffsetSec != null) { + this.startOffsetSec = startOffsetSec; + } + return this; + } + + public VideoBuilder endOffsetSec(Integer endOffsetSec) { + if (endOffsetSec != null) { + this.endOffsetSec = endOffsetSec; + } + return this; + + } + + public VideoBuilder intervalSec(Integer intervalSec) { + if (intervalSec != null) { + this.intervalSec = intervalSec; + } + return this; + } + + /** + * @deprecated use {@link #videoData(Object)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withVideoData(Object imageData) { Assert.notNull(imageData, "Video data must not be null"); if (imageData instanceof byte[] imageBytes) { - return withVideoBytes(imageBytes); + return videoBytes(imageBytes); } else if (imageData instanceof String uri) { - return withGcsUri(uri); + return gcsUri(uri); } else { throw new IllegalArgumentException("Unsupported image data type: " + imageData.getClass()); } } + /** + * @deprecated use {@link #videoBytes(byte[])} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withVideoBytes(byte[] imageBytes) { Assert.notNull(imageBytes, "Video bytes must not be null"); this.videoBytes = imageBytes; return this; } + /** + * @deprecated use {@link #gcsUri(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withGcsUri(String gcsUri) { Assert.hasText(gcsUri, "GCS URI must not be empty"); this.gcsUri = gcsUri; return this; } + /** + * @deprecated use {@link #startOffsetSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withStartOffsetSec(Integer startOffsetSec) { if (startOffsetSec != null) { this.startOffsetSec = startOffsetSec; @@ -383,6 +565,10 @@ public VideoBuilder withStartOffsetSec(Integer startOffsetSec) { return this; } + /** + * @deprecated use {@link #endOffsetSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withEndOffsetSec(Integer endOffsetSec) { if (endOffsetSec != null) { this.endOffsetSec = endOffsetSec; @@ -391,6 +577,10 @@ public VideoBuilder withEndOffsetSec(Integer endOffsetSec) { } + /** + * @deprecated use {@link #intervalSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public VideoBuilder withIntervalSec(Integer intervalSec) { if (intervalSec != null) { this.intervalSec = intervalSec; diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java index bb77ed4390d..f623794ce82 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModel.java @@ -138,12 +138,12 @@ private EmbeddingResponse doSingleDocumentPrediction(PredictionServiceClient cli // optional dimensions parameter if (mergedOptions.getDimensions() != null) { - instanceBuilder.withDimension(mergedOptions.getDimensions()); + instanceBuilder.dimension(mergedOptions.getDimensions()); } // optional text parameter if (StringUtils.hasText(document.getContent())) { - instanceBuilder.withText(document.getContent()); + instanceBuilder.text(document.getContent()); documentMetadata.put(ModalityType.TEXT, new DocumentMetadata(document.getId(), MimeTypeUtils.TEXT_PLAIN, document.getContent())); } @@ -151,7 +151,7 @@ private EmbeddingResponse doSingleDocumentPrediction(PredictionServiceClient cli Media media = document.getMedia(); if (media != null) { if (media.getMimeType().isCompatibleWith(TEXT_MIME_TYPE)) { - instanceBuilder.withText(media.getData().toString()); + instanceBuilder.text(media.getData().toString()); documentMetadata.put(ModalityType.TEXT, new DocumentMetadata(document.getId(), MimeTypeUtils.TEXT_PLAIN, media.getData())); if (StringUtils.hasText(document.getContent())) { @@ -160,8 +160,7 @@ private EmbeddingResponse doSingleDocumentPrediction(PredictionServiceClient cli } else if (media.getMimeType().isCompatibleWith(IMAGE_MIME_TYPE)) { if (SUPPORTED_IMAGE_MIME_SUB_TYPES.contains(media.getMimeType())) { - instanceBuilder - .withImage(ImageBuilder.of(media.getMimeType()).withImageData(media.getData()).build()); + instanceBuilder.image(ImageBuilder.of(media.getMimeType()).imageData(media.getData()).build()); documentMetadata.put(ModalityType.IMAGE, new DocumentMetadata(document.getId(), media.getMimeType(), media.getData())); } @@ -171,11 +170,11 @@ else if (media.getMimeType().isCompatibleWith(IMAGE_MIME_TYPE)) { } } else if (media.getMimeType().isCompatibleWith(VIDEO_MIME_TYPE)) { - instanceBuilder.withVideo(VideoBuilder.of(media.getMimeType()) - .withVideoData(media.getData()) - .withStartOffsetSec(mergedOptions.getVideoStartOffsetSec()) - .withEndOffsetSec(mergedOptions.getVideoEndOffsetSec()) - .withIntervalSec(mergedOptions.getVideoIntervalSec()) + instanceBuilder.video(VideoBuilder.of(media.getMimeType()) + .videoData(media.getData()) + .startOffsetSec(mergedOptions.getVideoStartOffsetSec()) + .endOffsetSec(mergedOptions.getVideoEndOffsetSec()) + .intervalSec(mergedOptions.getVideoIntervalSec()) .build()); documentMetadata.put(ModalityType.VIDEO, new DocumentMetadata(document.getId(), media.getMimeType(), media.getData())); diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingOptions.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingOptions.java index 98bc4a73548..986fe29bb44 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingOptions.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingOptions.java @@ -58,6 +58,7 @@ *

* * @author Christian Tzolov + * @author Ilayaperumal Gopinathan * @since 1.0.0 */ @JsonInclude(Include.NON_NULL) @@ -174,31 +175,85 @@ public Builder from(VertexAiMultimodalEmbeddingOptions fromOptions) { return this; } + public Builder model(String model) { + this.options.setModel(model); + return this; + } + + public Builder model(VertexAiMultimodalEmbeddingModelName model) { + this.options.setModel(model.getName()); + return this; + } + + public Builder dimensions(Integer dimensions) { + this.options.setDimensions(dimensions); + return this; + } + + public Builder videoStartOffsetSec(Integer videoStartOffsetSec) { + this.options.setVideoStartOffsetSec(videoStartOffsetSec); + return this; + } + + public Builder videoEndOffsetSec(Integer videoEndOffsetSec) { + this.options.setVideoEndOffsetSec(videoEndOffsetSec); + return this; + } + + public Builder videoIntervalSec(Integer videoIntervalSec) { + this.options.setVideoIntervalSec(videoIntervalSec); + return this; + } + + /** + * @deprecated use {@link #model(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(String model) { this.options.setModel(model); return this; } + /** + * @deprecated use {@link #model(VertexAiMultimodalEmbeddingModelName)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(VertexAiMultimodalEmbeddingModelName model) { this.options.setModel(model.getName()); return this; } + /** + * @deprecated use {@link #dimensions(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withDimensions(Integer dimensions) { this.options.setDimensions(dimensions); return this; } + /** + * @deprecated use {@link #videoStartOffsetSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withVideoStartOffsetSec(Integer videoStartOffsetSec) { this.options.setVideoStartOffsetSec(videoStartOffsetSec); return this; } + /** + * @deprecated use {@link #videoEndOffsetSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withVideoEndOffsetSec(Integer videoEndOffsetSec) { this.options.setVideoEndOffsetSec(videoEndOffsetSec); return this; } + /** + * @deprecated use {@link #videoIntervalSec(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withVideoIntervalSec(Integer videoIntervalSec) { this.options.setVideoIntervalSec(videoIntervalSec); return this; diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModel.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModel.java index 31d2846e9c5..cf92d66ff57 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModel.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModel.java @@ -183,11 +183,11 @@ protected PredictRequest.Builder getPredictRequestBuilder(EmbeddingRequest reque TextParametersBuilder parametersBuilder = TextParametersBuilder.of(); if (finalOptions.getAutoTruncate() != null) { - parametersBuilder.withAutoTruncate(finalOptions.getAutoTruncate()); + parametersBuilder.autoTruncate(finalOptions.getAutoTruncate()); } if (finalOptions.getDimensions() != null) { - parametersBuilder.withOutputDimensionality(finalOptions.getDimensions()); + parametersBuilder.outputDimensionality(finalOptions.getDimensions()); } predictRequestBuilder.setParameters(VertexAiEmbeddingUtils.valueOf(parametersBuilder.build())); @@ -195,9 +195,9 @@ protected PredictRequest.Builder getPredictRequestBuilder(EmbeddingRequest reque for (int i = 0; i < request.getInstructions().size(); i++) { TextInstanceBuilder instanceBuilder = TextInstanceBuilder.of(request.getInstructions().get(i)) - .withTaskType(finalOptions.getTaskType().name()); + .taskType(finalOptions.getTaskType().name()); if (StringUtils.hasText(finalOptions.getTitle())) { - instanceBuilder.withTitle(finalOptions.getTitle()); + instanceBuilder.title(finalOptions.getTitle()); } predictRequestBuilder.addInstances(VertexAiEmbeddingUtils.valueOf(instanceBuilder.build())); } diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java index c2cfe0bc4b3..403d5b9f649 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java @@ -27,6 +27,7 @@ * Options for the Vertex AI Text Embedding service. * * @author Christian Tzolov + * @author Ilayaperumal Gopinathan * @since 1.0.0 */ @JsonInclude(Include.NON_NULL) @@ -192,31 +193,85 @@ public Builder from(VertexAiTextEmbeddingOptions fromOptions) { return this; } + public Builder model(String model) { + this.options.setModel(model); + return this; + } + + public Builder model(VertexAiTextEmbeddingModelName model) { + this.options.setModel(model.getName()); + return this; + } + + public Builder taskType(TaskType taskType) { + this.options.setTaskType(taskType); + return this; + } + + public Builder dimensions(Integer dimensions) { + this.options.dimensions = dimensions; + return this; + } + + public Builder title(String user) { + this.options.setTitle(user); + return this; + } + + public Builder autoTruncate(Boolean autoTruncate) { + this.options.setAutoTruncate(autoTruncate); + return this; + } + + /** + * @deprecated use {@link #model(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(String model) { this.options.setModel(model); return this; } + /** + * @deprecated use {@link #model(VertexAiTextEmbeddingModelName)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(VertexAiTextEmbeddingModelName model) { this.options.setModel(model.getName()); return this; } + /** + * @deprecated use {@link #taskType(TaskType)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withTaskType(TaskType taskType) { this.options.setTaskType(taskType); return this; } + /** + * @deprecated use {@link #dimensions(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withDimensions(Integer dimensions) { this.options.dimensions = dimensions; return this; } + /** + * @deprecated use {@link #title(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withTitle(String user) { this.options.setTitle(user); return this; } + /** + * @deprecated use {@link #autoTruncate(Boolean)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withAutoTruncate(Boolean autoTruncate) { this.options.setAutoTruncate(autoTruncate); return this; diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java index d1bd8f4c76e..e6e37b78fef 100644 --- a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/multimodal/VertexAiMultimodalEmbeddingModelIT.java @@ -225,8 +225,8 @@ static class Config { @Bean public VertexAiEmbeddingConnectionDetails connectionDetails() { return VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) - .withLocation(System.getenv("VERTEX_AI_GEMINI_LOCATION")) + .projectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) + .location(System.getenv("VERTEX_AI_GEMINI_LOCATION")) .build(); } @@ -235,7 +235,7 @@ public VertexAiMultimodalEmbeddingModel vertexAiEmbeddingModel( VertexAiEmbeddingConnectionDetails connectionDetails) { VertexAiMultimodalEmbeddingOptions options = VertexAiMultimodalEmbeddingOptions.builder() - .withModel(VertexAiMultimodalEmbeddingModelName.MULTIMODAL_EMBEDDING_001) + .model(VertexAiMultimodalEmbeddingModelName.MULTIMODAL_EMBEDDING_001) .build(); return new VertexAiMultimodalEmbeddingModel(connectionDetails, options); diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelIT.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelIT.java index d1701b7a8d3..ddfb9bfa106 100644 --- a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelIT.java +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelIT.java @@ -47,7 +47,7 @@ class VertexAiTextEmbeddingModelIT { void defaultEmbedding(String modelName) { assertThat(this.embeddingModel).isNotNull(); - var options = VertexAiTextEmbeddingOptions.builder().withModel(modelName).build(); + var options = VertexAiTextEmbeddingOptions.builder().model(modelName).build(); EmbeddingResponse embeddingResponse = this.embeddingModel .call(new EmbeddingRequest(List.of("Hello World", "World is Big"), options)); @@ -71,8 +71,8 @@ static class Config { @Bean public VertexAiEmbeddingConnectionDetails connectionDetails() { return VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) - .withLocation(System.getenv("VERTEX_AI_GEMINI_LOCATION")) + .projectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) + .location(System.getenv("VERTEX_AI_GEMINI_LOCATION")) .build(); } @@ -80,7 +80,7 @@ public VertexAiEmbeddingConnectionDetails connectionDetails() { public VertexAiTextEmbeddingModel vertexAiEmbeddingModel(VertexAiEmbeddingConnectionDetails connectionDetails) { VertexAiTextEmbeddingOptions options = VertexAiTextEmbeddingOptions.builder() - .withModel(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) + .model(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); return new VertexAiTextEmbeddingModel(connectionDetails, options); diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelObservationIT.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelObservationIT.java index 9a277d40348..f6e6bbbbe70 100644 --- a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelObservationIT.java +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingModelObservationIT.java @@ -61,8 +61,8 @@ public class VertexAiTextEmbeddingModelObservationIT { void observationForEmbeddingOperation() { var options = VertexAiTextEmbeddingOptions.builder() - .withModel(VertexAiTextEmbeddingModelName.TEXT_EMBEDDING_004.getName()) - .withDimensions(768) + .model(VertexAiTextEmbeddingModelName.TEXT_EMBEDDING_004.getName()) + .dimensions(768) .build(); EmbeddingRequest embeddingRequest = new EmbeddingRequest(List.of("Here comes the sun"), options); @@ -104,8 +104,8 @@ public TestObservationRegistry observationRegistry() { @Bean public VertexAiEmbeddingConnectionDetails connectionDetails() { return VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) - .withLocation(System.getenv("VERTEX_AI_GEMINI_LOCATION")) + .projectId(System.getenv("VERTEX_AI_GEMINI_PROJECT_ID")) + .location(System.getenv("VERTEX_AI_GEMINI_LOCATION")) .build(); } @@ -114,7 +114,7 @@ public VertexAiTextEmbeddingModel vertexAiEmbeddingModel(VertexAiEmbeddingConnec ObservationRegistry observationRegistry) { VertexAiTextEmbeddingOptions options = VertexAiTextEmbeddingOptions.builder() - .withModel(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) + .model(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); return new VertexAiTextEmbeddingModel(connectionDetails, options, RetryUtils.DEFAULT_RETRY_TEMPLATE, diff --git a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java index 7601ca35ad8..098dd1c12d7 100644 --- a/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java +++ b/models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModel.java @@ -121,8 +121,7 @@ public class VertexAiGeminiChatModel extends AbstractToolCallSupport implements private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION; public VertexAiGeminiChatModel(VertexAI vertexAI) { - this(vertexAI, - VertexAiGeminiChatOptions.builder().withModel(ChatModel.GEMINI_1_5_PRO).withTemperature(0.8).build()); + this(vertexAI, VertexAiGeminiChatOptions.builder().model(ChatModel.GEMINI_1_5_PRO).temperature(0.8).build()); } public VertexAiGeminiChatModel(VertexAI vertexAI, VertexAiGeminiChatOptions options) { 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 bdd81c3e45d..0802250fd42 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 @@ -39,6 +39,7 @@ * @author Christian Tzolov * @author Thomas Vitale * @author Grogdunn + * @author Ilayaperumal Gopinathan * @since 1.0.0 */ @JsonInclude(Include.NON_NULL) @@ -340,79 +341,222 @@ public static class Builder { private VertexAiGeminiChatOptions options = new VertexAiGeminiChatOptions(); + public Builder stopSequences(List stopSequences) { + this.options.setStopSequences(stopSequences); + return this; + } + + public Builder temperature(Double temperature) { + this.options.setTemperature(temperature); + return this; + } + + public Builder topP(Double topP) { + this.options.setTopP(topP); + return this; + } + + public Builder topK(Float topK) { + this.options.setTopK(topK); + return this; + } + + public Builder candidateCount(Integer candidateCount) { + this.options.setCandidateCount(candidateCount); + return this; + } + + public Builder maxOutputTokens(Integer maxOutputTokens) { + this.options.setMaxOutputTokens(maxOutputTokens); + return this; + } + + public Builder model(String modelName) { + this.options.setModel(modelName); + return this; + } + + public Builder model(ChatModel model) { + this.options.setModel(model.getValue()); + return this; + } + + public Builder responseMimeType(String mimeType) { + Assert.notNull(mimeType, "mimeType must not be null"); + this.options.setResponseMimeType(mimeType); + return this; + } + + public Builder functionCallbacks(List functionCallbacks) { + this.options.functionCallbacks = functionCallbacks; + return this; + } + + public Builder functions(Set functionNames) { + Assert.notNull(functionNames, "Function names must not be null"); + this.options.functions = functionNames; + return this; + } + + public Builder function(String functionName) { + Assert.hasText(functionName, "Function name must not be empty"); + this.options.functions.add(functionName); + return this; + } + + public Builder googleSearchRetrieval(boolean googleSearch) { + this.options.googleSearchRetrieval = googleSearch; + return this; + } + + public Builder proxyToolCalls(boolean proxyToolCalls) { + this.options.proxyToolCalls = proxyToolCalls; + return this; + } + + public Builder toolContext(Map toolContext) { + if (this.options.toolContext == null) { + this.options.toolContext = toolContext; + } + else { + this.options.toolContext.putAll(toolContext); + } + return this; + } + + /** + * @deprecated use {@link #stopSequences(List)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withStopSequences(List stopSequences) { this.options.setStopSequences(stopSequences); return this; } + /** + * @deprecated use {@link #temperature(Double)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withTemperature(Double temperature) { this.options.setTemperature(temperature); return this; } + /** + * @deprecated use {@link #topP(Double)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withTopP(Double topP) { this.options.setTopP(topP); return this; } + /** + * @deprecated use {@link #topK(Float)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withTopK(Float topK) { this.options.setTopK(topK); return this; } + /** + * @deprecated use {@link #candidateCount(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withCandidateCount(Integer candidateCount) { this.options.setCandidateCount(candidateCount); return this; } + /** + * @deprecated use {@link #maxOutputTokens(Integer)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withMaxOutputTokens(Integer maxOutputTokens) { this.options.setMaxOutputTokens(maxOutputTokens); return this; } + /** + * @deprecated use {@link #model(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(String modelName) { this.options.setModel(modelName); return this; } + /** + * @deprecated use {@link #model(ChatModel)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withModel(ChatModel model) { this.options.setModel(model.getValue()); return this; } + /** + * @deprecated use {@link #responseMimeType(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withResponseMimeType(String mimeType) { Assert.notNull(mimeType, "mimeType must not be null"); this.options.setResponseMimeType(mimeType); return this; } + /** + * @deprecated use {@link #functionCallbacks(List)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withFunctionCallbacks(List functionCallbacks) { this.options.functionCallbacks = functionCallbacks; return this; } + /** + * @deprecated use {@link #functions(Set)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withFunctions(Set functionNames) { Assert.notNull(functionNames, "Function names must not be null"); this.options.functions = functionNames; return this; } + /** + * @deprecated use {@link #function(String)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withFunction(String functionName) { Assert.hasText(functionName, "Function name must not be empty"); this.options.functions.add(functionName); return this; } + /** + * @deprecated use {@link #googleSearchRetrieval(boolean)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withGoogleSearchRetrieval(boolean googleSearch) { this.options.googleSearchRetrieval = googleSearch; return this; } + /** + * @deprecated use {@link #proxyToolCalls(boolean)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withProxyToolCalls(boolean proxyToolCalls) { this.options.proxyToolCalls = proxyToolCalls; return this; } + /** + * @deprecated use {@link #toolContext(Map)} instead. + */ + @Deprecated(forRemoval = true, since = "1.0.0-M5") public Builder withToolContext(Map toolContext) { if (this.options.toolContext == null) { this.options.toolContext = toolContext; diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java index 9f86e523ebc..bc3eea8a30e 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/CreateGeminiRequestTests.java @@ -52,7 +52,7 @@ public class CreateGeminiRequestTests { public void createRequestWithChatOptions() { var client = new VertexAiGeminiChatModel(this.vertexAI, - VertexAiGeminiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6).build()); + VertexAiGeminiChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build()); GeminiRequest request = client.createGeminiRequest(new Prompt("Test message content"), null); @@ -62,10 +62,8 @@ public void createRequestWithChatOptions() { assertThat(request.model().getModelName()).isEqualTo("DEFAULT_MODEL"); assertThat(request.model().getGenerationConfig().getTemperature()).isEqualTo(66.6f); - request = client.createGeminiRequest( - new Prompt("Test message content", - VertexAiGeminiChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9).build()), - null); + request = client.createGeminiRequest(new Prompt("Test message content", + VertexAiGeminiChatOptions.builder().model("PROMPT_MODEL").temperature(99.9).build()), null); assertThat(request.contents()).hasSize(1); @@ -83,7 +81,7 @@ public void createRequestWithSystemMessage() throws MalformedURLException { List.of(Media.builder().mimeType(MimeTypeUtils.IMAGE_PNG).data(new URL("http://example.com")).build())); var client = new VertexAiGeminiChatModel(this.vertexAI, - VertexAiGeminiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6).build()); + VertexAiGeminiChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build()); GeminiRequest request = client.createGeminiRequest(new Prompt(List.of(systemMessage, userMessage)), null); @@ -112,12 +110,12 @@ public void promptOptionsTools() { final String TOOL_FUNCTION_NAME = "CurrentWeather"; var client = new VertexAiGeminiChatModel(this.vertexAI, - VertexAiGeminiChatOptions.builder().withModel("DEFAULT_MODEL").build()); + VertexAiGeminiChatOptions.builder().model("DEFAULT_MODEL").build()); var request = client.createGeminiRequest(new Prompt("Test message content", VertexAiGeminiChatOptions.builder() - .withModel("PROMPT_MODEL") - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .model("PROMPT_MODEL") + .functionCallbacks(List.of(FunctionCallback.builder() .function(TOOL_FUNCTION_NAME, new MockWeatherService()) .description("Get the weather in location") .inputType(MockWeatherService.Request.class) @@ -144,8 +142,8 @@ public void defaultOptionsTools() { var client = new VertexAiGeminiChatModel(this.vertexAI, VertexAiGeminiChatOptions.builder() - .withModel("DEFAULT_MODEL") - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .model("DEFAULT_MODEL") + .functionCallbacks(List.of(FunctionCallback.builder() .function(TOOL_FUNCTION_NAME, new MockWeatherService()) .description("Get the weather in location") .inputType(MockWeatherService.Request.class) @@ -168,7 +166,7 @@ public void defaultOptionsTools() { // Explicitly enable the function request = client.createGeminiRequest(new Prompt("Test message content", - VertexAiGeminiChatOptions.builder().withFunction(TOOL_FUNCTION_NAME).build()), null); + VertexAiGeminiChatOptions.builder().function(TOOL_FUNCTION_NAME).build()), null); assertThat(request.model().getTools()).hasSize(1); assertThat(request.model().getTools().get(0).getFunctionDeclarations(0).getName()) @@ -178,7 +176,7 @@ public void defaultOptionsTools() { // Override the default options function with one from the prompt request = client.createGeminiRequest(new Prompt("Test message content", VertexAiGeminiChatOptions.builder() - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .functionCallbacks(List.of(FunctionCallback.builder() .function(TOOL_FUNCTION_NAME, new MockWeatherService()) .description("Overridden function description") .inputType(MockWeatherService.Request.class) @@ -202,14 +200,14 @@ public void createRequestWithGenerationConfigOptions() { var client = new VertexAiGeminiChatModel(this.vertexAI, VertexAiGeminiChatOptions.builder() - .withModel("DEFAULT_MODEL") - .withTemperature(66.6) - .withMaxOutputTokens(100) - .withTopK(10.0f) - .withTopP(5.0) - .withStopSequences(List.of("stop1", "stop2")) - .withCandidateCount(1) - .withResponseMimeType("application/json") + .model("DEFAULT_MODEL") + .temperature(66.6) + .maxOutputTokens(100) + .topK(10.0f) + .topP(5.0) + .stopSequences(List.of("stop1", "stop2")) + .candidateCount(1) + .responseMimeType("application/json") .build()); GeminiRequest request = client.createGeminiRequest(new Prompt("Test message content"), null); diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiChatModelObservationIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiChatModelObservationIT.java index 3905212a652..c6f68cfc5c4 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiChatModelObservationIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiChatModelObservationIT.java @@ -66,11 +66,11 @@ void beforeEach() { void observationForChatOperation() { var options = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO.getValue()) - .withTemperature(0.7) - .withStopSequences(List.of("this-is-the-end")) - .withMaxOutputTokens(2048) - .withTopP(1.0) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO.getValue()) + .temperature(0.7) + .stopSequences(List.of("this-is-the-end")) + .maxOutputTokens(2048) + .topP(1.0) .build(); Prompt prompt = new Prompt("Why does a raven look like a desk?", options); @@ -88,11 +88,11 @@ void observationForChatOperation() { void observationForStreamingOperation() { var options = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO.getValue()) - .withTemperature(0.7) - .withStopSequences(List.of("this-is-the-end")) - .withMaxOutputTokens(2048) - .withTopP(1.0) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO.getValue()) + .temperature(0.7) + .stopSequences(List.of("this-is-the-end")) + .maxOutputTokens(2048) + .topP(1.0) .build(); Prompt prompt = new Prompt("Why does a raven look like a desk?", options); @@ -178,9 +178,7 @@ public VertexAI vertexAiApi() { public VertexAiGeminiChatModel vertexAiEmbedding(VertexAI vertexAi, TestObservationRegistry observationRegistry) { return new VertexAiGeminiChatModel(vertexAi, - VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO) - .build(), + VertexAiGeminiChatOptions.builder().model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO).build(), null, List.of(), RetryTemplate.defaultInstance(), observationRegistry); } diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java index bfae7cccbd8..882886df6b2 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatModelIT.java @@ -87,7 +87,7 @@ void testMessageHistory() { @Test void googleSearchTool() { - Prompt prompt = createPrompt(VertexAiGeminiChatOptions.builder().withGoogleSearchRetrieval(true).build()); + Prompt prompt = createPrompt(VertexAiGeminiChatOptions.builder().googleSearchRetrieval(true).build()); ChatResponse response = this.chatModel.call(prompt); assertThat(response.getResult().getOutput().getText()).containsAnyOf("Blackbeard", "Bartholomew"); } @@ -282,7 +282,7 @@ public VertexAI vertexAiApi() { public VertexAiGeminiChatModel vertexAiEmbedding(VertexAI vertexAi) { return new VertexAiGeminiChatModel(vertexAi, VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO) .build()); } diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiRetryTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiRetryTests.java index a69f7ed96af..f42ae4f7bb0 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiRetryTests.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiRetryTests.java @@ -73,9 +73,9 @@ public void setUp() { this.chatModel = new TestVertexAiGeminiChatModel(this.vertexAI, VertexAiGeminiChatOptions.builder() - .withTemperature(0.7) - .withTopP(1.0) - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_PRO.getValue()) + .temperature(0.7) + .topP(1.0) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_PRO.getValue()) .build(), null, Collections.emptyList(), this.retryTemplate); diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatModelFunctionCallingIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatModelFunctionCallingIT.java index c4328726270..cf05a5a5257 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatModelFunctionCallingIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiChatModelFunctionCallingIT.java @@ -83,7 +83,7 @@ public void functionCallExplicitOpenApiSchema() { """; var promptOptions = VertexAiGeminiChatOptions.builder() - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .functionCallbacks(List.of(FunctionCallback.builder() .function("get_current_weather", new MockWeatherService()) .description("Get the current weather in a given location") .inputTypeSchema(openApiSchema) @@ -106,8 +106,8 @@ public void functionCallTestInferredOpenApiSchema() { List messages = new ArrayList<>(List.of(userMessage)); var promptOptions = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) - .withFunctionCallbacks(List.of( + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) + .functionCallbacks(List.of( FunctionCallback.builder() .function("get_current_weather", new MockWeatherService()) .schemaType(SchemaType.OPEN_API_SCHEMA) @@ -147,8 +147,8 @@ public void functionCallTestInferredOpenApiSchema2() { List messages = new ArrayList<>(List.of(userMessage)); var promptOptions = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) - .withFunctionCallbacks(List.of( + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) + .functionCallbacks(List.of( FunctionCallback.builder() .function("get_current_weather", new MockWeatherService()) .schemaType(SchemaType.OPEN_API_SCHEMA) @@ -188,8 +188,8 @@ public void functionCallTestInferredOpenApiSchemaStream() { List messages = new ArrayList<>(List.of(userMessage)); var promptOptions = VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) + .functionCallbacks(List.of(FunctionCallback.builder() .function("getCurrentWeather", new MockWeatherService()) .schemaType(SchemaType.OPEN_API_SCHEMA) .description("Get the current weather in a given location") @@ -248,8 +248,8 @@ public VertexAI vertexAiApi() { public VertexAiGeminiChatModel vertexAiEmbedding(VertexAI vertexAi) { return new VertexAiGeminiChatModel(vertexAi, VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO) - .withTemperature(0.9) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_PRO) + .temperature(0.9) .build()); } diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiPaymentTransactionIT.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiPaymentTransactionIT.java index b9dfc8c7808..36386890405 100644 --- a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiPaymentTransactionIT.java +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/function/VertexAiGeminiPaymentTransactionIT.java @@ -212,8 +212,8 @@ public VertexAiGeminiChatModel vertexAiChatModel(VertexAI vertexAi, ApplicationC return new VertexAiGeminiChatModel(vertexAi, VertexAiGeminiChatOptions.builder() - .withModel(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) - .withTemperature(0.1) + .model(VertexAiGeminiChatModel.ChatModel.GEMINI_1_5_FLASH) + .temperature(0.1) .build(), functionCallbackResolver); } diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc index d40a1442473..9568bcd1b76 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat/vertexai-gemini-chat.adoc @@ -104,7 +104,7 @@ ChatResponse response = chatModel.call( new Prompt( "Generate the names of 5 famous pirates.", VertexAiGeminiChatOptions.builder() - .withTemperature(0.4) + .temperature(0.4) .build() )); ---- @@ -240,8 +240,8 @@ VertexAI vertexApi = new VertexAI(projectId, location); var chatModel = new VertexAiGeminiChatModel(this.vertexApi, VertexAiGeminiChatOptions.builder() - .withModel(ChatModel.GEMINI_PRO_1_5_PRO) - .withTemperature(0.4) + .model(ChatModel.GEMINI_PRO_1_5_PRO) + .temperature(0.4) .build()); ChatResponse response = this.chatModel.call( diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-multimodal.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-multimodal.adoc index 1f9db4495b7..61cbb7955e0 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-multimodal.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-multimodal.adoc @@ -119,12 +119,12 @@ Next, create a `VertexAiMultimodalEmbeddingModel` and use it for embeddings gene ---- VertexAiEmbeddingConnectionDetails connectionDetails = VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv()) - .withLocation(System.getenv()) + .projectId(System.getenv()) + .location(System.getenv()) .build(); VertexAiMultimodalEmbeddingOptions options = VertexAiMultimodalEmbeddingOptions.builder() - .withModel(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME) + .model(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); var embeddingModel = new VertexAiMultimodalEmbeddingModel(this.connectionDetails, this.options); diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-text.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-text.adoc index 2e1596f55ed..81f9db4a903 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-text.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/vertexai-embeddings-text.adoc @@ -146,12 +146,12 @@ Next, create a `VertexAiTextEmbeddingModel` and use it for text generations: ---- VertexAiEmbeddingConnectionDetails connectionDetails = VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv()) - .withLocation(System.getenv()) + .projectId(System.getenv()) + .location(System.getenv()) .build(); VertexAiTextEmbeddingOptions options = VertexAiTextEmbeddingOptions.builder() - .withModel(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) + .model(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); var embeddingModel = new VertexAiTextEmbeddingModel(this.connectionDetails, this.options); @@ -172,10 +172,10 @@ credentials.refreshIfExpired(); VertexAiEmbeddingConnectionDetails connectionDetails = VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(System.getenv()) - .withLocation(System.getenv()) - .withApiEndpoint(endpoint) - .withPredictionServiceSettings( + .projectId(System.getenv()) + .location(System.getenv()) + .apiEndpoint(endpoint) + .predictionServiceSettings( PredictionServiceSettings.newBuilder() .setEndpoint(endpoint) .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiEmbeddingAutoConfiguration.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiEmbeddingAutoConfiguration.java index 7549cb727e2..c6f32025e9d 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiEmbeddingAutoConfiguration.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiEmbeddingAutoConfiguration.java @@ -61,11 +61,11 @@ public VertexAiEmbeddingConnectionDetails connectionDetails( Assert.hasText(connectionProperties.getLocation(), "Vertex AI location must be set!"); var connectionBuilder = VertexAiEmbeddingConnectionDetails.builder() - .withProjectId(connectionProperties.getProjectId()) - .withLocation(connectionProperties.getLocation()); + .projectId(connectionProperties.getProjectId()) + .location(connectionProperties.getLocation()); if (StringUtils.hasText(connectionProperties.getApiEndpoint())) { - connectionBuilder.withApiEndpoint(connectionProperties.getApiEndpoint()); + connectionBuilder.apiEndpoint(connectionProperties.getApiEndpoint()); } return connectionBuilder.build(); diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiMultimodalEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiMultimodalEmbeddingProperties.java index a47488b92fe..912084bd5b1 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiMultimodalEmbeddingProperties.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiMultimodalEmbeddingProperties.java @@ -36,7 +36,7 @@ public class VertexAiMultimodalEmbeddingProperties { * Vertex AI Text Embedding API options. */ private VertexAiMultimodalEmbeddingOptions options = VertexAiMultimodalEmbeddingOptions.builder() - .withModel(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME) + .model(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); public VertexAiMultimodalEmbeddingOptions getOptions() { diff --git a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiTextEmbeddingProperties.java b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiTextEmbeddingProperties.java index 26073283f07..7addfab95cb 100644 --- a/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiTextEmbeddingProperties.java +++ b/spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vertexai/embedding/VertexAiTextEmbeddingProperties.java @@ -36,8 +36,8 @@ public class VertexAiTextEmbeddingProperties { * Vertex AI Text Embedding API options. */ private VertexAiTextEmbeddingOptions options = VertexAiTextEmbeddingOptions.builder() - .withTaskType(VertexAiTextEmbeddingOptions.TaskType.RETRIEVAL_DOCUMENT) - .withModel(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) + .taskType(VertexAiTextEmbeddingOptions.TaskType.RETRIEVAL_DOCUMENT) + .model(VertexAiTextEmbeddingOptions.DEFAULT_MODEL_NAME) .build(); public VertexAiTextEmbeddingOptions getOptions() { 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 22d25ab2488..f024067bc1f 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 @@ -37,9 +37,9 @@ public class VertexAiGeminiChatProperties { * Vertex AI Gemini API generative options. */ private VertexAiGeminiChatOptions options = VertexAiGeminiChatOptions.builder() - .withTemperature(0.7) - .withCandidateCount(1) - .withModel(DEFAULT_MODEL) + .temperature(0.7) + .candidateCount(1) + .model(DEFAULT_MODEL) .build(); public VertexAiGeminiChatOptions getOptions() { 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 530e564eb22..d9260aa8399 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 @@ -69,14 +69,14 @@ void functionCallTest() { """); ChatResponse response = chatModel.call(new Prompt(List.of(userMessage), - VertexAiGeminiChatOptions.builder().withFunction("weatherFunction").build())); + VertexAiGeminiChatOptions.builder().function("weatherFunction").build())); logger.info("Response: {}", response); assertThat(response.getResult().getOutput().getText()).contains("30", "10", "15"); response = chatModel.call(new Prompt(List.of(userMessage), - VertexAiGeminiChatOptions.builder().withFunction("weatherFunction3").build())); + VertexAiGeminiChatOptions.builder().function("weatherFunction3").build())); logger.info("Response: {}", response); @@ -116,7 +116,7 @@ void functionCallWithPortableFunctionCallingOptions() { assertThat(response.getResult().getOutput().getText()).contains("30", "10", "15"); response = chatModel.call(new Prompt(List.of(userMessage), - VertexAiGeminiChatOptions.builder().withFunction("weatherFunction3").build())); + VertexAiGeminiChatOptions.builder().function("weatherFunction3").build())); logger.info("Response: {}", response); 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 111cc1db693..4747e6af870 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 @@ -65,7 +65,7 @@ void functionCallTest() { """); ChatResponse response = chatModel.call(new Prompt(List.of(userMessage), - VertexAiGeminiChatOptions.builder().withFunction("WeatherInfo").build())); + VertexAiGeminiChatOptions.builder().function("WeatherInfo").build())); logger.info("Response: {}", response); 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 388622f09d4..99e524f5219 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 @@ -68,7 +68,7 @@ void functionCallTest() { """); var promptOptions = VertexAiGeminiChatOptions.builder() - .withFunctionCallbacks(List.of(FunctionCallback.builder() + .functionCallbacks(List.of(FunctionCallback.builder() .function("CurrentWeatherService", new MockWeatherService()) .schemaType(SchemaType.OPEN_API_SCHEMA) // IMPORTANT!! .description("Get the weather in location")