Cortex

Getting Started

Install, configure, and use Cortex step by step

Installation

bun add @thaletto/cortex @thaletto/zvec

Cortex requires effect v4 as a peer dependency.

1. Upsert a Document

All operations in Cortex happen through the VectorDB service. You define your program logic first, deferring the choice of storage adapter until execution.

import { Effect } from "effect";
import { VectorDB, DocumentId, Vector } from "@thaletto/cortex";

const program = Effect.gen(function* () {
  const db = yield* VectorDB;

  const id = DocumentId.make("user-1-preference");
  
  yield* db.upsert({
    id,
    content: "User prefers TypeScript over JavaScript",
    category: "preferences",
    tags: "typescript",
    metadata_json: JSON.stringify({ source: "onboarding" }),
    vector: Vector.make(new Array(384).fill(0)),
    expires_at: new Date("2026-12-31"),
  });
});

2. Search by Similarity

Search for documents by providing a query vector and a limit.

const program = Effect.gen(function* () {
  const db = yield* VectorDB;

  const results = yield* db.search(queryVector, 10, {
    category: "preferences",
  });

  for (const { document, score } of results) {
    console.log(`[${score.toFixed(3)}] ${document.content}`);
  }
});

3. Handle Errors

Cortex uses Effect's tagged errors for robust error handling.

import { Effect } from "effect";
import { VectorDB, DocumentId } from "@thaletto/cortex";

const program = Effect.gen(function* () {
  const db = yield* VectorDB;
  yield* db.getById(DocumentId.make("missing"));
}).pipe(
  Effect.catchTags({
    DocumentNotFound: (e) => Effect.log(`Not found: ${e.id}`),
    DimensionMismatch: (e) => Effect.fail(`Vector dimension mismatch: expected ${e.expected}, got ${e.actual}`),
    VectorDBError: (e) => Effect.fail(`Storage error: ${e.message}`),
  }),
);

To run these programs, you must provide a database adapter (like ZVec) using a Layer. See the Adapters guide to learn how to wire up your infrastructure.

On this page