Refactor Vertex AI embedding/Gemini options builder methods
- Deprecate the builder methods with the prefix `with` - Update references and docs
This commit is contained in:
committed by
Mark Pollack
parent
9748820727
commit
3e82e3117f
@@ -30,6 +30,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Mark Pollack
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class VertexAiEmbeddingConnectionDetails {
|
||||
@@ -125,26 +126,72 @@ public class VertexAiEmbeddingConnectionDetails {
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.util.StringUtils;
|
||||
* 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 abstract class VertexAiEmbeddingUtils {
|
||||
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 abstract class VertexAiEmbeddingUtils {
|
||||
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 abstract class VertexAiEmbeddingUtils {
|
||||
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 abstract class VertexAiEmbeddingUtils {
|
||||
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 abstract class VertexAiEmbeddingUtils {
|
||||
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 @@ public abstract class VertexAiEmbeddingUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 abstract class VertexAiEmbeddingUtils {
|
||||
return builder;
|
||||
}
|
||||
|
||||
public VideoBuilder withVideoData(Object imageData) {
|
||||
public VideoBuilder videoData(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());
|
||||
}
|
||||
}
|
||||
|
||||
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 videoBytes(imageBytes);
|
||||
}
|
||||
else if (imageData instanceof String 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 abstract class VertexAiEmbeddingUtils {
|
||||
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 abstract class VertexAiEmbeddingUtils {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
@@ -138,12 +138,12 @@ public class VertexAiMultimodalEmbeddingModel implements DocumentEmbeddingModel
|
||||
|
||||
// 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 @@ public class VertexAiMultimodalEmbeddingModel implements DocumentEmbeddingModel
|
||||
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 @@ public class VertexAiMultimodalEmbeddingModel implements DocumentEmbeddingModel
|
||||
}
|
||||
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 @@ public class VertexAiMultimodalEmbeddingModel implements DocumentEmbeddingModel
|
||||
}
|
||||
}
|
||||
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()));
|
||||
|
||||
@@ -58,6 +58,7 @@ import org.springframework.util.StringUtils;
|
||||
* </p>
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
@@ -174,31 +175,85 @@ public class VertexAiMultimodalEmbeddingOptions implements EmbeddingOptions {
|
||||
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;
|
||||
|
||||
@@ -183,11 +183,11 @@ public class VertexAiTextEmbeddingModel extends AbstractEmbeddingModel {
|
||||
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 @@ public class VertexAiTextEmbeddingModel extends AbstractEmbeddingModel {
|
||||
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()));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
* 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 class VertexAiTextEmbeddingOptions implements EmbeddingOptions {
|
||||
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;
|
||||
|
||||
@@ -225,8 +225,8 @@ class VertexAiMultimodalEmbeddingModelIT {
|
||||
@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 @@ class VertexAiMultimodalEmbeddingModelIT {
|
||||
VertexAiEmbeddingConnectionDetails connectionDetails) {
|
||||
|
||||
VertexAiMultimodalEmbeddingOptions options = VertexAiMultimodalEmbeddingOptions.builder()
|
||||
.withModel(VertexAiMultimodalEmbeddingModelName.MULTIMODAL_EMBEDDING_001)
|
||||
.model(VertexAiMultimodalEmbeddingModelName.MULTIMODAL_EMBEDDING_001)
|
||||
.build();
|
||||
|
||||
return new VertexAiMultimodalEmbeddingModel(connectionDetails, options);
|
||||
|
||||
@@ -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 @@ class VertexAiTextEmbeddingModelIT {
|
||||
@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 @@ class VertexAiTextEmbeddingModelIT {
|
||||
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);
|
||||
|
||||
@@ -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 class VertexAiTextEmbeddingModelObservationIT {
|
||||
@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 class VertexAiTextEmbeddingModelObservationIT {
|
||||
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,
|
||||
|
||||
@@ -123,8 +123,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) {
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.util.Assert;
|
||||
* @author Christian Tzolov
|
||||
* @author Thomas Vitale
|
||||
* @author Grogdunn
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
@@ -355,85 +356,235 @@ public class VertexAiGeminiChatOptions implements FunctionCallingOptions {
|
||||
|
||||
private VertexAiGeminiChatOptions options = new VertexAiGeminiChatOptions();
|
||||
|
||||
public Builder stopSequences(List<String> 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<FunctionCallback> functionCallbacks) {
|
||||
this.options.functionCallbacks = functionCallbacks;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder functions(Set<String> 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 safetySettings(List<VertexAiGeminiSafetySetting> safetySettings) {
|
||||
Assert.notNull(safetySettings, "safetySettings must not be null");
|
||||
this.options.safetySettings = safetySettings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder proxyToolCalls(boolean proxyToolCalls) {
|
||||
this.options.proxyToolCalls = proxyToolCalls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder toolContext(Map<String, Object> 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<String> 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<FunctionCallback> 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<String> 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(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withSafetySettings(List<VertexAiGeminiSafetySetting> safetySettings) {
|
||||
Assert.notNull(safetySettings, "safetySettings must not be null");
|
||||
this.options.safetySettings = safetySettings;
|
||||
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<String, Object> toolContext) {
|
||||
if (this.options.toolContext == null) {
|
||||
this.options.toolContext = toolContext;
|
||||
|
||||
@@ -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 class CreateGeminiRequestTests {
|
||||
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 class CreateGeminiRequestTests {
|
||||
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 class CreateGeminiRequestTests {
|
||||
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 class CreateGeminiRequestTests {
|
||||
|
||||
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 class CreateGeminiRequestTests {
|
||||
|
||||
// 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 class CreateGeminiRequestTests {
|
||||
// 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 class CreateGeminiRequestTests {
|
||||
|
||||
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);
|
||||
|
||||
@@ -66,11 +66,11 @@ public class VertexAiChatModelObservationIT {
|
||||
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 @@ public class VertexAiChatModelObservationIT {
|
||||
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 class VertexAiChatModelObservationIT {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class VertexAiGeminiChatModelIT {
|
||||
|
||||
@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");
|
||||
}
|
||||
@@ -295,7 +295,7 @@ class VertexAiGeminiChatModelIT {
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +73,9 @@ public class VertexAiGeminiRetryTests {
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class VertexAiGeminiChatModelFunctionCallingIT {
|
||||
""";
|
||||
|
||||
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 class VertexAiGeminiChatModelFunctionCallingIT {
|
||||
List<Message> 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 class VertexAiGeminiChatModelFunctionCallingIT {
|
||||
List<Message> 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 class VertexAiGeminiChatModelFunctionCallingIT {
|
||||
List<Message> 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 class VertexAiGeminiChatModelFunctionCallingIT {
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -212,8 +212,8 @@ public class VertexAiGeminiPaymentTransactionIT {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ ChatResponse response = chatModel.call(
|
||||
new Prompt(
|
||||
"Generate the names of 5 famous pirates.",
|
||||
VertexAiGeminiChatOptions.builder()
|
||||
.withTemperature(0.4)
|
||||
.temperature(0.4)
|
||||
.build()
|
||||
));
|
||||
----
|
||||
@@ -241,8 +241,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(
|
||||
|
||||
@@ -119,12 +119,12 @@ Next, create a `VertexAiMultimodalEmbeddingModel` and use it for embeddings gene
|
||||
----
|
||||
VertexAiEmbeddingConnectionDetails connectionDetails =
|
||||
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();
|
||||
|
||||
VertexAiMultimodalEmbeddingOptions options = VertexAiMultimodalEmbeddingOptions.builder()
|
||||
.withModel(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME)
|
||||
.model(VertexAiMultimodalEmbeddingOptions.DEFAULT_MODEL_NAME)
|
||||
.build();
|
||||
|
||||
var embeddingModel = new VertexAiMultimodalEmbeddingModel(this.connectionDetails, this.options);
|
||||
|
||||
@@ -146,12 +146,12 @@ Next, create a `VertexAiTextEmbeddingModel` and use it for text generations:
|
||||
----
|
||||
VertexAiEmbeddingConnectionDetails connectionDetails =
|
||||
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();
|
||||
|
||||
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(<VERTEX_AI_GEMINI_PROJECT_ID>))
|
||||
.withLocation(System.getenv(<VERTEX_AI_GEMINI_LOCATION>))
|
||||
.withApiEndpoint(endpoint)
|
||||
.withPredictionServiceSettings(
|
||||
.projectId(System.getenv(<VERTEX_AI_GEMINI_PROJECT_ID>))
|
||||
.location(System.getenv(<VERTEX_AI_GEMINI_LOCATION>))
|
||||
.apiEndpoint(endpoint)
|
||||
.predictionServiceSettings(
|
||||
PredictionServiceSettings.newBuilder()
|
||||
.setEndpoint(endpoint)
|
||||
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
|
||||
|
||||
@@ -61,11 +61,11 @@ public class VertexAiEmbeddingAutoConfiguration {
|
||||
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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -69,14 +69,14 @@ class FunctionCallWithFunctionBeanIT {
|
||||
""");
|
||||
|
||||
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 @@ class FunctionCallWithFunctionBeanIT {
|
||||
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);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public class FunctionCallWithFunctionWrapperIT {
|
||||
""");
|
||||
|
||||
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
|
||||
VertexAiGeminiChatOptions.builder().withFunction("WeatherInfo").build()));
|
||||
VertexAiGeminiChatOptions.builder().function("WeatherInfo").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
""");
|
||||
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user