Cross-encoder reranking over Hugging Face Text Embeddings Inference (TEI), Cohere/Jina and Voyage rerank endpoints, built on @intx/inference retries and error classification. A retrieval building block for Corbits and Interchange agents that also works standalone.
- One call for three wire formats.
rerankDocumentsspeaks TEI, Cohere (also Jina) and Voyage. Switching providers is a config change. - Your ids back, sorted. Providers score by array position. The client maps each score back to your
idand returns{ id, score }, best first. - Interchange retry semantics. 429s and 5xx are retried under the
@intx/inferenceretry policy, and every failure is aRerankRequestErrorcarrying a classifiedInferenceError.
bun add @corbits/reranking @intx/inference@^0.4.0 @intx/types@^0.4.0Runs on Bun >= 1.2 or Node >= 24.
This example needs a local TEI reranker:
docker run -p 8080:80 ghcr.io/huggingface/text-embeddings-inference:cpu-latest \
--model-id BAAI/bge-reranker-baseimport { rerankDocuments } from "@corbits/reranking";
const docs = [
{ id: "weather", text: "Rain is expected across the valley tomorrow." },
{ id: "paris", text: "Paris is the capital and largest city of France." },
{ id: "recipe", text: "Whisk the eggs before folding in the flour." },
];
const ranked = await rerankDocuments("What is the capital of France?", docs, {
baseURL: "http://localhost:8080",
apiStyle: "tei",
});
console.log(ranked[0]?.id); // parisInterchange runs AI agents with their own identity and permissions. Corbits packages add the parts an agent product needs around it.
- Runs in: any process. That can be the Interchange hub (the server that manages tenants and agents), an agent sidecar (the runtime next to each agent), or a plain script. No hub is needed.
- Plugs into:
@intx/inferencefor retries and error types, and@intx/types. - Pairs with:
@corbits/embeddingto turn text into vectors, and@corbits/memoryto store and search them.
| Export | Description |
|---|---|
rerankDocuments(query, docs, config, options?) |
Scores each doc and returns { id, score }, best first. |
RerankConfigSchema, RerankConfig |
Schema and type for config. |
RerankOptions |
Type for options. |
rerankAdapterRegistry |
The built-in formats: tei, cohere and voyage. |
createRerankAdapterRegistry(adapters) |
Builds a registry with your own formats. |
RerankRequestError |
Thrown when a request fails. |
RerankAdapter, RerankRequestBuilder, RerankResponseParser |
Types for writing an adapter. |
RerankRequestConfig |
Config an adapter's buildRequest receives. |
RerankAdapterRegistry, RerankAPIStyle |
Types for registries and built-in style names. |
RerankDoc, RerankResult |
Types for docs and results. |
RequestDependencies, RetryAfterExtractor |
Types for options.deps and RerankAdapter.extractRetryAfterMs. |
| Field | Type | Description |
|---|---|---|
baseURL |
string |
Server root, such as http://localhost:8080. |
apiStyle |
string |
Wire format: tei, cohere (also Jina) or voyage. |
model |
string? |
Model name. Required by cohere (and Jina) and voyage. TEI serves its own model. |
apiKey |
string? |
Sent as a bearer token. |
timeoutMs |
number? |
Time limit per attempt, so retries can exceed it. Defaults to 30000. |
| Field | Description |
|---|---|
deps |
{ fetch, scheduler }. Defaults to global fetch and Interchange's scheduler. |
retryPolicy |
Decides when to retry. Defaults to Interchange's policy. |
registry |
Wire formats to choose from. Defaults to rerankAdapterRegistry. |
signal |
Cancels the request. |
apiStyle |
Endpoint | Request | Reply |
|---|---|---|---|
tei |
/rerank |
{query, texts} |
[{index, score}] |
cohere |
/v2/rerank |
{query, documents} |
{results: [{index, relevance_score}]} |
voyage |
/v1/rerank |
{query, documents} |
{data: [{index, relevance_score}]} |
To add your own format, build a registry and pass it as registry. This one serves TEI-shaped replies at /score:
import {
createRerankAdapterRegistry,
rerankAdapterRegistry,
} from "@corbits/reranking";
const tei = rerankAdapterRegistry.resolve("tei");
const registry = createRerankAdapterRegistry({
tei,
house: {
buildRequest: (query, docs, config) => ({
url: `${config.baseURL}/score`,
headers: { "content-type": "application/json" },
body: JSON.stringify({ query, texts: docs.map((doc) => doc.text) }),
}),
parseResponse: tei.parseResponse,
},
});- A failed request throws
RerankRequestError. Itsreasonsays what went wrong, andurlsays where. Network errors, timeouts, rate limits and server errors are retried first under the retry policy. - A bad config throws arktype's
TraversalErrorbefore any request is sent. - An
apiStylethe registry does not know throws anErrorthat names it. With non-emptydocs, a missingmodelforcohereorvoyagethrowsTraversalError. - A reply with an out-of-range or repeated index throws
RerankRequestErrorwith aprotocol_mismatchreason. Retry-Afteris honored up to 60 seconds.- A custom
parseResponseshould throwProtocolMismatchErrorfrom@intx/inferenceso the failure becomes aRerankRequestError. Anything else it throws is rethrown as is.
An empty docs list returns [] without a request. To keep search working when the reranker is down, catch the error and keep your original order.
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 toRerankRequestError.rerankAdaptersis no longer exported. UsererankAdapterRegistryorcreateRerankAdapterRegistry.runJSONRequest,extractRetryAfterMsandRunRequestOptionsare no longer exported.- A missing
modelfor Cohere or Voyage now throwsTraversalErrorinstead of a plainError. - Config, wire requests and results are unchanged.