Skip to content
Open
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
1 change: 1 addition & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
video_generator_v3: VideoIcon,
vision: EyeIcon,
vision_v2: EyeIcon,
voyageai: EmbeddingsIcon,
wait: CirclePause,
wealthbox: WealthboxIcon,
webflow: WebflowIcon,
Expand Down
32 changes: 31 additions & 1 deletion apps/docs/content/docs/integrations/embeddings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Knowledge bases embed separately. Each base fixes an embedding model and vector

## Use the block [#usage-instructions]

Turn text into embedding vectors for semantic search, clustering, and similarity. Supports OpenAI, OpenRouter, Google Gemini, Cohere, and Mistral embedding models, plus embedding models on a self-hosted Ollama.
Turn text into embedding vectors for semantic search, clustering, and similarity. Supports OpenAI, OpenRouter, Google Gemini, Cohere, Mistral, and Voyage AI embedding models, plus embedding models on a self-hosted Ollama.

## Actions

Expand Down Expand Up @@ -189,6 +189,36 @@ Generate embeddings from text using Mistral's embedding models

</ReferenceDetails>

### Voyage AI Embeddings

Generate embeddings from text using Voyage AI's embedding models

<ReferenceDetails>

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `input` | string | Yes | Text to embed, or an array of texts to embed in one call |
| `model` | string | Yes | Embedding model to use |
| `taskType` | string | No | What the embedding is for, when the model supports task conditioning: document, query, similarity, classification, or clustering |
| `dimensions` | number | No | Output dimensions, when the model supports truncation. Defaults to native. |
| `apiKey` | string | Yes | API key for the selected embedding provider |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `embeddings` | json | Generated embedding vectors, one per input, in input order |
| `model` | string | Model used |
| `provider` | string | Provider used |
| `dimensions` | number | Dimensionality of each returned vector |
| `usage` | json | Token usage |
| ↳ `prompt_tokens` | number | Tokens in the input |
| ↳ `total_tokens` | number | Total tokens billed |

</ReferenceDetails>

### Ollama Embeddings

Generate embeddings on a self-hosted Ollama server
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/integrations/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
"uptimerobot",
"vanta",
"vercel",
"voyageai",
"wealthbox",
"wealthbox-service-account",
"webflow",
Expand Down
88 changes: 88 additions & 0 deletions apps/docs/content/docs/integrations/voyageai.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Voyage AI
description: Contextualized embeddings and reranking
integration:
type: "voyageai"
color: "#7B4DFF"
---

import { ReferenceDetails } from "@/components/ui/reference-details"


{/* MANUAL-CONTENT-START:intro */}
[Voyage AI](https://www.voyageai.com/) provides embedding and reranking models for search and retrieval.

With the Voyage AI block, you can:

- **Embed documents with context**: Send the full text of each document. Voyage splits it into chunks, and every chunk vector reflects the whole document around it, so retrieval finds the right passage even when the chunk alone is ambiguous. Search queries are embedded with the same model and Input Type set to Query.
- **Rerank results**: Reorder retrieved texts by relevance to a query, so your agent reads the best matches first.

Create an API key in the [Voyage AI dashboard](https://dash.voyageai.com/) and paste it into the block, or store it once as a workspace key under Settings > BYOK.

In Sim, the Voyage AI block lets your agents index documents for search and tighten the results they retrieve before answering.
{/* MANUAL-CONTENT-END */}

## Use the block [#usage-instructions]

Embed documents with Voyage AI contextualized models, so each chunk vector reflects the whole document around it, and rerank texts against a query with Voyage AI rerankers.

## Actions

### Voyage AI Contextualized Embeddings

Embed documents with a contextualized model: Voyage splits each document into chunks, and every chunk vector also reflects the whole document it came from

<ReferenceDetails>

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `input` | array | Yes | Texts to embed, as a list of strings. For document: the full text of each document, which Voyage chunks itself. For query: one search query per entry. |
| `model` | string | Yes | Embedding model: voyage-context-4 or voyage-context-3 |
| `inputType` | string | Yes | What the embeddings are for: document \(documents to index, chunked by Voyage\) or query \(search queries\) |
| `dimensions` | number | No | Output dimensions: 256, 512, 1024 \(default\), or 2048 |
| `apiKey` | string | Yes | Your Voyage AI API key |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `embeddings` | json | Embedding vectors grouped by document: one list per input document, one vector per chunk, in input order |
| `chunks` | json | The text of each chunk, grouped like embeddings. Returned for documents, which Voyage chunks itself |
| `model` | string | Model used |
| `dimensions` | number | Dimensionality of each vector |
| `totalTokens` | number | Tokens billed for the request |

</ReferenceDetails>

### Voyage AI Rerank

Rank a list of texts by relevance to a query with a Voyage AI reranker, most relevant first

<ReferenceDetails>

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `query` | string | Yes | The query to rank the documents against |
| `documents` | array | Yes | The texts to rank, as a list of strings \(up to 1,000\) |
| `model` | string | Yes | Reranker model: rerank-3, rerank-3-lite, rerank-2.5 or rerank-2.5-lite |
| `topK` | number | No | Number of most relevant documents to return. Defaults to all of them. |
| `apiKey` | string | Yes | Your Voyage AI API key |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `results` | array | Documents ranked by relevance, most relevant first |
| ↳ `index` | number | Position of the document in the input list |
| ↳ `relevanceScore` | number | Relevance of the document to the query |
| ↳ `document` | string | The document text |
| `model` | string | Reranker model used |
| `totalTokens` | number | Tokens billed for the request |

</ReferenceDetails>


1 change: 1 addition & 0 deletions apps/sim/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ CRON_SECRET=your_cron_secret # Use `openssl rand -hex 32` to generate. Authentic
# NEXT_PUBLIC_AZURE_CONFIGURED=true # Set when Azure credentials are pre-configured above. Hides endpoint/key/version fields in Agent block UI.
# COHERE_API_KEY= # Cohere API key for the Knowledge block reranker (rerank-v4.0-pro/-fast, rerank-v3.5). Alternatively set COHERE_API_KEY_1/2/3 for rotation.
# NEXT_PUBLIC_COHERE_CONFIGURED=true # Set when COHERE_API_KEY (or rotation keys) are pre-configured above. Hides the Cohere API Key field on the Knowledge block UI.
# VOYAGE_API_KEY= # Voyage AI API key for the Embeddings block (voyage-4-large, voyage-4, voyage-4-lite, voyage-code-4, ...) and the Voyage AI block (contextualized embeddings, rerank).

# Hosted tool API keys (Optional - lets Sim supply the key so users don't have to bring their own).
# Each provider reads `{PREFIX}_COUNT` then `{PREFIX}_1..N`, distributing requests round-robin across the keys.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ContextDevIcon,
DatagmaIcon,
DropcontactIcon,
EmbeddingsIcon,
EnrowIcon,
ExaAIIcon,
FalIcon,
Expand Down Expand Up @@ -106,6 +107,13 @@ const PROVIDERS: (BYOKManagerProvider & { id: BYOKProviderId })[] = [
description: 'LLM calls and Knowledge Base OCR',
placeholder: 'Enter your API key',
},
{
id: 'voyage',
name: 'Voyage AI',
icon: EmbeddingsIcon,
description: 'Embeddings, contextualized embeddings and reranking',
placeholder: 'pa-...',
},
{
id: 'zai',
name: 'Z.ai',
Expand Down Expand Up @@ -382,6 +390,7 @@ const PROVIDER_SECTIONS: BYOKProviderSection[] = [
'mistral',
'zai',
'cohere',
'voyage',
'xai',
'kimi',
'typesafe',
Expand Down
39 changes: 32 additions & 7 deletions apps/sim/blocks/blocks/embeddings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const TOOL_ID_BY_PROVIDER: Record<EmbeddingBlockProvider, string> = {
gemini: 'embeddings_gemini',
cohere: 'embeddings_cohere',
mistral: 'embeddings_mistral',
voyage: 'embeddings_voyage',
ollama: 'embeddings_ollama',
}

Expand All @@ -42,6 +43,7 @@ const PROVIDER_LABELS: Record<EmbeddingBlockProvider, string> = {
gemini: 'Google Gemini',
cohere: 'Cohere',
mistral: 'Mistral',
voyage: 'Voyage AI',
ollama: 'Ollama',
}

Expand All @@ -62,16 +64,37 @@ const TASK_TYPE_LABELS: Record<EmbeddingTaskType, string> = {
* sub-block id, so each is scoped by a `condition` naming the provider.
*/
const MODEL_SUB_BLOCKS: SubBlockConfig[] = EMBEDDING_CATALOG_PROVIDERS.map((provider) => {
const defaultModel = DEFAULT_MODEL_BY_PROVIDER[provider]
const options = getModelsForProvider(provider).map((id) => ({
label: EMBEDDING_MODELS[id].label,
id,
}))
const condition = { field: 'provider', value: provider }
/**
* A provider with no default model must not have one picked for the user: a
* dropdown selects its first option on its own, so this is a combobox whose
* `emptyIsValid` suppresses that, left empty until a model is chosen.
*/
if (!defaultModel) {
return {
id: 'model',
title: 'Model',
type: 'combobox',
options,
placeholder: 'Select a model',
required: true,
emptyIsValid: true,
condition,
dependsOn: ['provider'],
}
}
return {
id: 'model',
title: 'Model',
type: 'dropdown',
options: getModelsForProvider(provider).map((id) => ({
label: EMBEDDING_MODELS[id].label,
id,
})),
value: () => DEFAULT_MODEL_BY_PROVIDER[provider],
condition: { field: 'provider', value: provider },
options,
value: () => defaultModel,
condition,
dependsOn: ['provider'],
}
})
Expand Down Expand Up @@ -164,7 +187,7 @@ export const EmbeddingsBlock: BlockConfig = {
description: 'Generate embeddings',
authMode: AuthMode.ApiKey,
longDescription:
'Turn text into embedding vectors for semantic search, clustering, and similarity. Supports OpenAI, OpenRouter, Google Gemini, Cohere, and Mistral embedding models, plus embedding models on a self-hosted Ollama.',
'Turn text into embedding vectors for semantic search, clustering, and similarity. Supports OpenAI, OpenRouter, Google Gemini, Cohere, Mistral, and Voyage AI embedding models, plus embedding models on a self-hosted Ollama.',
category: 'tools',
integrationType: IntegrationType.AI,
docsLink: 'https://docs.sim.ai/integrations/embeddings',
Expand Down Expand Up @@ -237,6 +260,7 @@ export const EmbeddingsBlock: BlockConfig = {
'embeddings_gemini',
'embeddings_cohere',
'embeddings_mistral',
'embeddings_voyage',
'embeddings_ollama',
],
config: {
Expand Down Expand Up @@ -327,6 +351,7 @@ export const EmbeddingsBlock: BlockConfig = {
savedModel && EMBEDDING_MODELS[savedModel]?.provider === catalogProvider
? savedModel
: DEFAULT_MODEL_BY_PROVIDER[catalogProvider]
if (!model) throw new Error(`A ${PROVIDER_LABELS[catalogProvider]} model is required`)

const info = EMBEDDING_MODELS[model]
const requested =
Expand Down
Loading