diff --git a/PACKAGES.md b/PACKAGES.md index eab2cdf0..1cb5d9aa 100644 --- a/PACKAGES.md +++ b/PACKAGES.md @@ -40,7 +40,7 @@ A BOM is provided that can be used to define the versions of all Semantic Kernel : Provides a connector that can be used to interact with the OpenAI API. `semantickernel-aiservices-voyageai` -: Provides connectors for VoyageAI's embedding and reranking services, including text embeddings, contextualized embeddings, multimodal embeddings, and document reranking. +: Provides connectors for VoyageAI by MongoDB embedding and reranking services, including text embeddings, contextualized embeddings, multimodal embeddings, and document reranking. ## Example Configurations @@ -75,9 +75,9 @@ POM XML for a simple project that uses OpenAI. ``` -### Example: VoyageAI Embeddings and Reranking +### Example: VoyageAI by MongoDB Embeddings and Reranking -POM XML for a project that uses VoyageAI for embeddings and reranking. +POM XML for a project that uses VoyageAI by MongoDB for embeddings and reranking. ```xml diff --git a/aiservices/voyageai/pom.xml b/aiservices/voyageai/pom.xml index b359128d..cfdd100b 100644 --- a/aiservices/voyageai/pom.xml +++ b/aiservices/voyageai/pom.xml @@ -9,8 +9,8 @@ semantickernel-aiservices-voyageai - Semantic Kernel VoyageAI Services - VoyageAI services for Semantic Kernel + Semantic Kernel VoyageAI by MongoDB Services + VoyageAI by MongoDB services for Semantic Kernel diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/contextualizedembedding/VoyageAIContextualizedEmbeddingGenerationService.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/contextualizedembedding/VoyageAIContextualizedEmbeddingGenerationService.java index 2ccb3990..e199930e 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/contextualizedembedding/VoyageAIContextualizedEmbeddingGenerationService.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/contextualizedembedding/VoyageAIContextualizedEmbeddingGenerationService.java @@ -19,14 +19,20 @@ import java.util.stream.Collectors; /** - * VoyageAI contextualized embedding generation service. + * VoyageAI by MongoDB contextualized embedding generation service. * Generates embeddings that capture both local chunk details and global document-level metadata. - * Supports models like voyage-3. + * Supports models like voyage-context-4 (voyage-context-3 is the previous generation). */ public final class VoyageAIContextualizedEmbeddingGenerationService implements TextEmbeddingGenerationService { private static final Logger LOGGER = LoggerFactory.getLogger(VoyageAIContextualizedEmbeddingGenerationService.class); + /** + * Target chunk size in tokens used when the backend auto-chunks flat document + * inputs. VoyageAI allows values up to 32K tokens. + */ + private static final int AUTO_CHUNK_SIZE = 32000; + private final VoyageAIClient client; private final String modelId; private final String serviceId; @@ -35,7 +41,7 @@ public final class VoyageAIContextualizedEmbeddingGenerationService implements T * Creates a new instance of VoyageAI contextualized embedding generation service. * * @param client VoyageAI client - * @param modelId Model ID (e.g., "voyage-3") + * @param modelId Model ID (e.g., "voyage-context-4") * @param serviceId Optional service ID */ public VoyageAIContextualizedEmbeddingGenerationService( @@ -88,18 +94,23 @@ public Mono> generateContextualizedEmbeddingsAsync(List { - List embeddings = new ArrayList<>(); - // Parse nested data structure: {"data":[{"data":[{"embedding":[...]}]}]} - for (VoyageAIModels.ContextualizedEmbeddingDataList dataList : response.getData()) { - for (VoyageAIModels.EmbeddingDataItem item : dataList.getData()) { - embeddings.add(new Embedding(item.getEmbedding())); - } - } + .map(this::parseEmbeddings); + } - LOGGER.debug("Received {} contextualized embeddings from VoyageAI", embeddings.size()); - return embeddings; - }); + /** + * Parses the nested contextualized embedding response + * ({@code {"data":[{"data":[{"embedding":[...]}]}]}}) into a flat list of embeddings. + */ + private List parseEmbeddings(VoyageAIModels.ContextualizedEmbeddingResponse response) { + List embeddings = new ArrayList<>(); + for (VoyageAIModels.ContextualizedEmbeddingDataList dataList : response.getData()) { + for (VoyageAIModels.EmbeddingDataItem item : dataList.getData()) { + embeddings.add(new Embedding(item.getEmbedding())); + } + } + + LOGGER.debug("Received {} contextualized embeddings from VoyageAI by MongoDB", embeddings.size()); + return embeddings; } /** @@ -122,7 +133,10 @@ public Mono generateEmbeddingAsync(String data) { /** * Generates embeddings for the given texts. - * Each text is treated as a separate document for contextualized embeddings. + * Each text is treated as a separate document and chunked by the VoyageAI by MongoDB + * backend. The {@code contextualizedembeddings} API is called with a flat list of + * documents, {@code enable_auto_chunking=true} and {@code chunk_size=32000} + * (which requires {@code input_type="document"}). * * @param data The texts to generate embeddings for * @return A Mono that completes with the list of embeddings @@ -133,13 +147,22 @@ public Mono> generateEmbeddingsAsync(List data) { return Mono.just(Collections.emptyList()); } - // Convert each string to a single-element list for contextualized embeddings - List> inputs = new ArrayList<>(); - for (String text : data) { - inputs.add(Arrays.asList(text)); - } + LOGGER.debug("Generating contextualized embeddings for {} documents (auto-chunking, " + + "chunk_size={}) using model {}", data.size(), AUTO_CHUNK_SIZE, modelId); + + VoyageAIModels.ContextualizedEmbeddingRequest request = + new VoyageAIModels.ContextualizedEmbeddingRequest(); + request.setFlatInputs(data); + request.setModel(modelId); + request.setInputType("document"); + request.setEnableAutoChunking(true); + request.setChunkSize(AUTO_CHUNK_SIZE); - return generateContextualizedEmbeddingsAsync(inputs); + return client.sendRequestAsync( + "contextualizedembeddings", + request, + VoyageAIModels.ContextualizedEmbeddingResponse.class) + .map(this::parseEmbeddings); } /** @@ -173,7 +196,7 @@ public Builder withClient(VoyageAIClient client) { /** * Sets the model ID. * - * @param modelId Model ID (e.g., "voyage-3") + * @param modelId Model ID (e.g., "voyage-context-4") * @return This builder */ public Builder withModelId(String modelId) { diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIClient.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIClient.java index 856a3397..b8f24657 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIClient.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIClient.java @@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit; /** - * HTTP client for VoyageAI API. + * HTTP client for the VoyageAI by MongoDB API. */ public final class VoyageAIClient { private static final Logger LOGGER = LoggerFactory.getLogger(VoyageAIClient.class); diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIModels.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIModels.java index c1e85387..8b80eb64 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIModels.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/core/VoyageAIModels.java @@ -8,7 +8,7 @@ import java.util.List; /** - * VoyageAI API request and response models. + * VoyageAI by MongoDB API request and response models. */ public class VoyageAIModels { @@ -122,6 +122,7 @@ public void setUsage(EmbeddingUsage usage) { /** * Embedding data item. */ + @JsonIgnoreProperties(ignoreUnknown = true) public static class EmbeddingDataItem { @JsonProperty("object") private String object; @@ -306,8 +307,10 @@ public void setRelevanceScore(double relevanceScore) { */ @JsonInclude(JsonInclude.Include.NON_NULL) public static class ContextualizedEmbeddingRequest { + // Holds either a flat List<String> (when auto-chunking is enabled) or a + // nested List<List<String>> of pre-chunked documents. @JsonProperty("inputs") - private List> inputs; + private Object inputs; @JsonProperty("model") private String model; @@ -324,16 +327,48 @@ public static class ContextualizedEmbeddingRequest { @JsonProperty("output_dtype") private String outputDtype; + @JsonProperty("enable_auto_chunking") + private Boolean enableAutoChunking; + + @JsonProperty("chunk_size") + private Integer chunkSize; + @SuppressFBWarnings("EI_EXPOSE_REP") - public List> getInputs() { + public Object getInputs() { return inputs; } - @SuppressFBWarnings("EI_EXPOSE_REP2") + /** + * Sets pre-chunked inputs: one inner list of chunks per document. + */ public void setInputs(List> inputs) { this.inputs = inputs; } + /** + * Sets a flat list of documents to be chunked by the backend. Requires + * {@code enable_auto_chunking=true} and {@code input_type="document"}. + */ + public void setFlatInputs(List inputs) { + this.inputs = inputs; + } + + public Boolean getEnableAutoChunking() { + return enableAutoChunking; + } + + public void setEnableAutoChunking(Boolean enableAutoChunking) { + this.enableAutoChunking = enableAutoChunking; + } + + public Integer getChunkSize() { + return chunkSize; + } + + public void setChunkSize(Integer chunkSize) { + this.chunkSize = chunkSize; + } + public String getModel() { return model; } diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/multimodalembedding/VoyageAIMultimodalEmbeddingGenerationService.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/multimodalembedding/VoyageAIMultimodalEmbeddingGenerationService.java index 89304d37..ef2376c4 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/multimodalembedding/VoyageAIMultimodalEmbeddingGenerationService.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/multimodalembedding/VoyageAIMultimodalEmbeddingGenerationService.java @@ -19,9 +19,9 @@ import java.util.stream.Collectors; /** - * VoyageAI multimodal embedding generation service. + * VoyageAI by MongoDB multimodal embedding generation service. * Generates embeddings for text, images, or interleaved text and images. - * Supports the voyage-multimodal-3 model. + * Supports models like voyage-multimodal-3.5, voyage-multimodal-3. *

* Constraints: * - Maximum 1,000 inputs per request @@ -41,7 +41,7 @@ public final class VoyageAIMultimodalEmbeddingGenerationService implements TextE * Creates a new instance of VoyageAI multimodal embedding generation service. * * @param client VoyageAI client - * @param modelId Model ID (e.g., "voyage-multimodal-3") + * @param modelId Model ID (e.g., "voyage-multimodal-3.5") * @param serviceId Optional service ID */ public VoyageAIMultimodalEmbeddingGenerationService( @@ -196,7 +196,7 @@ public Builder withClient(VoyageAIClient client) { /** * Sets the model ID. * - * @param modelId Model ID (e.g., "voyage-multimodal-3") + * @param modelId Model ID (e.g., "voyage-multimodal-3.5") * @return This builder */ public Builder withModelId(String modelId) { diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/reranking/VoyageAITextRerankingService.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/reranking/VoyageAITextRerankingService.java index cda093d7..26a6b194 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/reranking/VoyageAITextRerankingService.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/reranking/VoyageAITextRerankingService.java @@ -17,8 +17,8 @@ import java.util.stream.Collectors; /** - * VoyageAI implementation of {@link TextRerankingService}. - * Supports models like rerank-2, rerank-2-lite. + * VoyageAI by MongoDB implementation of {@link TextRerankingService}. + * Supports models like rerank-3, rerank-3-lite, rerank-2.5, rerank-2.5-lite. */ public final class VoyageAITextRerankingService implements TextRerankingService { @@ -33,7 +33,7 @@ public final class VoyageAITextRerankingService implements TextRerankingService * Creates a new instance of VoyageAI text reranking service. * * @param client VoyageAI client - * @param modelId Model ID (e.g., "rerank-2") + * @param modelId Model ID (e.g., "rerank-3") * @param serviceId Optional service ID * @param topK Optional top K results to return */ @@ -140,7 +140,7 @@ public Builder withClient(VoyageAIClient client) { /** * Sets the model ID. * - * @param modelId Model ID (e.g., "rerank-2") + * @param modelId Model ID (e.g., "rerank-3") * @return This builder */ public Builder withModelId(String modelId) { diff --git a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/textembedding/VoyageAITextEmbeddingGenerationService.java b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/textembedding/VoyageAITextEmbeddingGenerationService.java index 4345aca5..5d8fd9f0 100644 --- a/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/textembedding/VoyageAITextEmbeddingGenerationService.java +++ b/aiservices/voyageai/src/main/java/com/microsoft/semantickernel/aiservices/voyageai/textembedding/VoyageAITextEmbeddingGenerationService.java @@ -18,8 +18,8 @@ import java.util.stream.Collectors; /** - * VoyageAI implementation of {@link TextEmbeddingGenerationService}. - * Supports models like voyage-3-large, voyage-3.5, voyage-code-3, voyage-finance-2, voyage-law-2. + * VoyageAI by MongoDB implementation of {@link TextEmbeddingGenerationService}. + * Supports models like voyage-4-large, voyage-4, voyage-4-lite, voyage-code-4, voyage-finance-2, voyage-law-2. */ public final class VoyageAITextEmbeddingGenerationService implements TextEmbeddingGenerationService { @@ -33,7 +33,7 @@ public final class VoyageAITextEmbeddingGenerationService implements TextEmbeddi * Creates a new instance of VoyageAI text embedding generation service. * * @param client VoyageAI client - * @param modelId Model ID (e.g., "voyage-3-large") + * @param modelId Model ID (e.g., "voyage-4-large") * @param serviceId Optional service ID */ public VoyageAITextEmbeddingGenerationService( @@ -143,7 +143,7 @@ public Builder withClient(VoyageAIClient client) { /** * Sets the model ID. * - * @param modelId Model ID (e.g., "voyage-3-large") + * @param modelId Model ID (e.g., "voyage-4-large") * @return This builder */ public Builder withModelId(String modelId) {