diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java b/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java index b615ac7c1..7d1624ad8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/VectorConfig.java @@ -17,6 +17,7 @@ import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecJinaAiVectorizer; +import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecWeaviateVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecAwsVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecBindVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecClipVectorizer; @@ -78,7 +79,8 @@ public enum Kind implements JsonEnum { MULTI2VEC_NVIDIA("multi2vec-nvidia"), MULTI2VEC_VOYAGEAI("multi2vec-voyageai"), TEXT2MULTIVEC_JINAAI("text2multivec-jinaai"), - MULTI2MULTIVEC_JINAAI("multi2multivec-jinaai"); + MULTI2MULTIVEC_JINAAI("multi2multivec-jinaai"), + MULTI2MULTIVEC_WEAVIATE("multi2multivec-weaviate"); private static final Map jsonValueMap = JsonEnum.collectNames(Kind.values()); private final String jsonValue; @@ -208,6 +210,43 @@ public static Map.Entry multi2multivecJinaai(String vector return Map.entry(vectorName, Multi2MultiVecJinaAiVectorizer.of(fn)); } + /** Create a vector index with an {@code multi2multivec-weaviate} vectorizer. */ + public static Map.Entry multi2multivecWeaviate() { + return multi2multivecWeaviate(VectorIndex.DEFAULT_VECTOR_NAME); + } + + /** + * Create a vector index with an {@code multi2multivec-weaviate} vectorizer. + * + * @param fn Lambda expression for optional parameters. + */ + public static Map.Entry multi2multivecWeaviate( + Function> fn) { + return multi2multivecWeaviate(VectorIndex.DEFAULT_VECTOR_NAME, fn); + } + + /** + * Create a named vector index with an {@code multi2multivec-weaviate} + * vectorizer. + * + * @param vectorName Vector name. + */ + public static Map.Entry multi2multivecWeaviate(String vectorName) { + return Map.entry(vectorName, Multi2MultiVecWeaviateVectorizer.of()); + } + + /** + * Create a named vector index with an {@code multi2multivec-weaviate} + * vectorizer. + * + * @param vectorName Vector name. + * @param fn Lambda expression for optional parameters. + */ + public static Map.Entry multi2multivecWeaviate(String vectorName, + Function> fn) { + return Map.entry(vectorName, Multi2MultiVecWeaviateVectorizer.of(fn)); + } + /** Create a vector index with an {@code multi2vec-aws} vectorizer. */ public static Map.Entry multi2vecAws() { return multi2vecAws(VectorIndex.DEFAULT_VECTOR_NAME); @@ -1650,6 +1689,7 @@ private final void init(Gson gson) { addAdapter(gson, VectorConfig.Kind.MULTI2VEC_VOYAGEAI, Multi2VecVoyageAiVectorizer.class); addAdapter(gson, VectorConfig.Kind.TEXT2MULTIVEC_JINAAI, Text2MultiVecJinaAiVectorizer.class); addAdapter(gson, VectorConfig.Kind.MULTI2MULTIVEC_JINAAI, Multi2MultiVecJinaAiVectorizer.class); + addAdapter(gson, VectorConfig.Kind.MULTI2MULTIVEC_WEAVIATE, Multi2MultiVecWeaviateVectorizer.class); } @SuppressWarnings("unchecked") diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java new file mode 100644 index 000000000..5cb07c921 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/vectorizers/Multi2MultiVecWeaviateVectorizer.java @@ -0,0 +1,109 @@ +package io.weaviate.client6.v1.api.collections.vectorizers; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import com.google.gson.annotations.SerializedName; + +import io.weaviate.client6.v1.api.collections.Quantization; +import io.weaviate.client6.v1.api.collections.VectorConfig; +import io.weaviate.client6.v1.api.collections.VectorIndex; +import io.weaviate.client6.v1.internal.ObjectBuilder; + +public record Multi2MultiVecWeaviateVectorizer( + /** Base URL of the embedding service. */ + @SerializedName("baseURL") String baseUrl, + /** Inference model to use. */ + @SerializedName("model") String model, + /** BLOB properties included in the embedding. */ + @SerializedName("imageFields") List imageFields, + /** Vector index configuration. */ + VectorIndex vectorIndex, + /** Vector quantization method. */ + Quantization quantization) implements VectorConfig { + + @Override + public VectorConfig.Kind _kind() { + return VectorConfig.Kind.MULTI2MULTIVEC_WEAVIATE; + } + + @Override + public Object _self() { + return this; + } + + /** ColBERT-family model available in the Weaviate Embedding Service. */ + public static String MODERNVBERT_COLMODERNVBERT = "ModernVBERT/colmodernvbert"; + + public static Multi2MultiVecWeaviateVectorizer of() { + return of(ObjectBuilder.identity()); + } + + public static Multi2MultiVecWeaviateVectorizer of( + Function> fn) { + return fn.apply(new Builder()).build(); + } + + public Multi2MultiVecWeaviateVectorizer(Builder builder) { + this( + builder.baseUrl, + builder.model, + builder.imageFields, + builder.vectorIndex, + builder.quantization); + } + + public static class Builder implements ObjectBuilder { + private VectorIndex vectorIndex = VectorIndex.DEFAULT_VECTOR_INDEX; + private Quantization quantization; + + private String baseUrl; + private String model; + + private List imageFields; + + public Builder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public Builder model(String model) { + this.model = model; + return this; + } + + /** Add BLOB properties to include in the embedding. */ + public Builder imageFields(List fields) { + imageFields = fields; + return this; + } + + /** Add BLOB properties to include in the embedding. */ + public Builder imageFields(String... fields) { + return imageFields(Arrays.asList(fields)); + } + + /** + * Override default vector index configuration. + * + * HNSW + * is the default vector index. + */ + public Builder vectorIndex(VectorIndex vectorIndex) { + this.vectorIndex = vectorIndex; + return this; + } + + public Builder quantization(Quantization quantization) { + this.quantization = quantization; + return this; + } + + @Override + public Multi2MultiVecWeaviateVectorizer build() { + return new Multi2MultiVecWeaviateVectorizer(this); + } + } +} diff --git a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java index ffb39f6cd..6f7abf2aa 100644 --- a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java +++ b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java @@ -40,6 +40,7 @@ import io.weaviate.client6.v1.api.collections.vectorindex.MultiVector.Aggregation; import io.weaviate.client6.v1.api.collections.vectorizers.Img2VecNeuralVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecJinaAiVectorizer; +import io.weaviate.client6.v1.api.collections.vectorizers.Multi2MultiVecWeaviateVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecAwsVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecClipVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Multi2VecCohereVectorizer; @@ -78,7 +79,6 @@ import io.weaviate.client6.v1.api.rbac.UsersPermission; import io.weaviate.client6.v1.api.rbac.groups.GroupType; -/** Unit tests for custom POJO-to-JSON serialization. */ @RunWith(JParamsTestRunner.class) public class JSONTest { public static Object[][] testCases() { @@ -632,6 +632,39 @@ public static Object[][] testCases() { } """, }, + { + VectorConfig.class, + Multi2MultiVecWeaviateVectorizer.of(v -> v + .baseUrl("example.com") + .model(Multi2MultiVecWeaviateVectorizer.MODERNVBERT_COLMODERNVBERT) + .imageFields("a", "b")), + """ + { + "vectorIndexType": "hnsw", + "vectorIndexConfig": {}, + "vectorizer": { + "multi2multivec-weaviate": { + "baseURL": "example.com", + "model": "ModernVBERT/colmodernvbert", + "imageFields": ["a", "b"] + } + } + } + """, + }, + { + VectorConfig.class, + Multi2MultiVecWeaviateVectorizer.of(), + """ + { + "vectorIndexType": "hnsw", + "vectorIndexConfig": {}, + "vectorizer": { + "multi2multivec-weaviate": { } + } + } + """, + }, { VectorConfig.class, Multi2VecClipVectorizer.of(v -> v.imageFields("a", "b").textFields("c")),