Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions PACKAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -75,9 +75,9 @@ POM XML for a simple project that uses OpenAI.
</project>
```

### 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

Expand Down
4 changes: 2 additions & 2 deletions aiservices/voyageai/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</parent>

<artifactId>semantickernel-aiservices-voyageai</artifactId>
<name>Semantic Kernel VoyageAI Services</name>
<description>VoyageAI services for Semantic Kernel</description>
<name>Semantic Kernel VoyageAI by MongoDB Services</name>
<description>VoyageAI by MongoDB services for Semantic Kernel</description>

<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(
Expand Down Expand Up @@ -88,18 +94,23 @@ public Mono<List<Embedding>> generateContextualizedEmbeddingsAsync(List<List<Str
"contextualizedembeddings",
request,
VoyageAIModels.ContextualizedEmbeddingResponse.class)
.map(response -> {
List<Embedding> 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<Embedding> parseEmbeddings(VoyageAIModels.ContextualizedEmbeddingResponse response) {
List<Embedding> 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;
}

/**
Expand All @@ -122,7 +133,10 @@ public Mono<Embedding> 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
Expand All @@ -133,13 +147,22 @@ public Mono<List<Embedding>> generateEmbeddingsAsync(List<String> data) {
return Mono.just(Collections.emptyList());
}

// Convert each string to a single-element list for contextualized embeddings
List<List<String>> 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);
}

/**
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -122,6 +122,7 @@ public void setUsage(EmbeddingUsage usage) {
/**
* Embedding data item.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public static class EmbeddingDataItem {
@JsonProperty("object")
private String object;
Expand Down Expand Up @@ -306,8 +307,10 @@ public void setRelevanceScore(double relevanceScore) {
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ContextualizedEmbeddingRequest {
// Holds either a flat List&lt;String&gt; (when auto-chunking is enabled) or a
// nested List&lt;List&lt;String&gt;&gt; of pre-chunked documents.
@JsonProperty("inputs")
private List<List<String>> inputs;
private Object inputs;

@JsonProperty("model")
private String model;
Expand All @@ -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<List<String>> 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<List<String>> 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<String> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* Constraints:
* - Maximum 1,000 inputs per request
Expand All @@ -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(
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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
*/
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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(
Expand Down Expand Up @@ -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) {
Expand Down