Batched text embeddings over any OpenAI-compatible /v1/embeddings endpoint, built on @intx/inference retries and error classification. A retrieval building block for Corbits and Interchange agents that also works standalone.
- One client for every provider. OpenAI, Ollama, TEI, vLLM and Jina all speak the same wire format. Switching models is a config change.
- Order-safe batching. Inputs are split into batches, and vectors come back in input order, placed by the index each response echoes. Short or duplicate replies throw instead of misaligning results.
- Interchange retry semantics. Requests run through
@intx/inference, so a 429 backs off and a 401 fails the same way it does for inference calls. Failures throw a typedEmbeddingRequestError.
It does not store or search vectors. For that, pair it with @corbits/memory.
bun add @corbits/embedding @intx/inference@^0.4.0 @intx/types@^0.4.0Runs on Bun >= 1.2 or Node >= 24.
Needs a local Ollama with nomic-embed-text pulled.
import { embedTexts } from "@corbits/embedding";
const vectors = await embedTexts(["a", "b"], {
baseURL: "http://localhost:11434/v1",
model: "nomic-embed-text",
});
console.log(vectors.length, vectors[0]?.length); // 2 768Interchange runs AI agents as principals (accounts that hold their own identity, permissions and credentials). Corbits packages add what an agent product needs around it.
- Runs in: any process: the Interchange hub (the multi-tenant control plane), an agent sidecar (the runtime next to each agent), or a plain script. No hub is required.
- Plugs into:
@intx/inferencefor transport, retries and error classification, and@intx/types. - Pairs with:
@corbits/rerankingto reorder results and@corbits/memoryto store and search vectors.
| Export | Description |
|---|---|
embedTexts(texts, config, options?) |
Embeds the texts and returns one vector per text, in order. |
probeEmbedDims(config, options?) |
Embeds one probe string and returns the vector dimension. |
EmbedConfigSchema, EmbedConfig |
Schema and type for config. |
EmbedOptions |
Type for options. |
EmbeddingRequestError |
Thrown when a request fails. |
RequestDependencies, RetryAfterExtractor |
Types for options.deps and options.extractRetryAfterMs. |
| Field | Type | Description |
|---|---|---|
baseURL |
string |
Server root with its version path, such as http://host:11434/v1. Trailing slashes are ignored. |
model |
string |
Model name. |
apiKey |
string? |
Sent as a bearer token. |
dimensions |
number? |
Requested output dimension. Sent only when set; a reply of any other dimension is rejected. |
encodingFormat |
"float" | "base64"? |
Wire format. Defaults to float. Results are always number[]. |
batchSize |
number? |
Texts per request. Defaults to 32. |
timeoutMs |
number? |
Per-attempt timeout; a timed-out attempt is retried. Defaults to 30000. |
| Field | Description |
|---|---|
deps |
{ fetch, scheduler }. Defaults to global fetch and Interchange's scheduler. |
retryPolicy |
Retry policy. Defaults to Interchange's policy. |
extractRetryAfterMs |
Reads the server's retry delay. Defaults to parsing Retry-After, capped at 60 seconds. |
signal |
Aborts all pending requests. |
A failed request throws EmbeddingRequestError with a classified reason and the request url. An invalid config throws before any request is sent.
Each model has a fixed output dimension: 768 for nomic-embed-text, 1536 for OpenAI text-embedding-3-small. If you store vectors, call probeEmbedDims at startup. Changing models changes the dimension, so treat it as a schema migration. Every vector from one call has the same non-zero dimension, or the call throws EmbeddingRequestError with protocol_mismatch.
@intx/inference and @intx/types are peer dependencies, so your host's Interchange version supplies them.
To share your host's retry scheduler, pass it as options.deps.scheduler along with fetch.
- Install
@intx/inferenceand@intx/types(^0.4.0) yourself. They are now peer dependencies. ModelRequestErroris renamed toEmbeddingRequestError.runJSONRequest,extractRetryAfterMsandRunRequestOptionsare no longer exported. To change how retry waits are read, passoptions.extractRetryAfterMs.- Config and returned vectors are unchanged.