Vex · guide

An assistant asks

A question nobody stored. A model writes the query once, and from then on the fingerprint is enough.

Install it
pnpm add @niscorp/vex @niscorp/signal @niscorp/cortex @niscorp/prism @niscorp/strata zod openai @electric-sql/pglite
Step 1 of 4

The database

Three bookings. This file asks a question of them that nobody wrote a query for.

The database
import { PGlite } from '@electric-sql/pglite';
import { createSignal } from '@niscorp/signal';
import { createPostgresAdapter, createQueryEngine } from '@niscorp/vex';
import { createQueryDsl, createShapeMapper } from '@niscorp/vex/agent';
import { createPglitePool } from '@niscorp/vex/pglite';

const db = new PGlite();
await db.exec(`
  CREATE TABLE bookings (id text PRIMARY KEY, member text, seats integer);
  INSERT INTO bookings VALUES ('B-2040', 'Ada', 1), ('B-2041', 'Grace', 2), ('B-2043', 'Alan', 3);
`);
Step 2 of 4

The two hooks

The engine has no model in it. It takes two hooks: generateDsl, from an intent and a shape to a document in the grammar, and mapToShape, from rows to the shape. Vex ships both, built on Cortex and Signal, in a subpath of its own, so an engine without them pulls in no model client.

The model client is Signal’s, and createSignal('groq') reads GROQ_API_KEY. The query hook needs the grammar as JSON Schema, which any engine hands out before it has introspected.

The two hooks
const llm = createSignal('groq');
const adapter = createPostgresAdapter({ pool: createPglitePool(db) });
const engine = createQueryEngine({
  adapter,
  generateDsl: createQueryDsl({ llm, queryJsonSchema: createQueryEngine({ adapter }).getDslSchema() }),
  mapToShape: createShapeMapper(llm),
});
await engine.introspect();
Step 3 of 4

A question nobody stored

A request with an intent and a shape, and no name. The model is shown the schema of the tables the caller may read, the grammar, and one line about the caller, and it tests its draft through the engine before it may finish. The answer comes back under a fingerprint Vex made.

A question nobody stored
const generated = await engine.execute({ intent: 'Who booked the most seats?', shape: { member: '', seats: 0 }, context: {} });
console.log(generated.meta.cache.fingerprint, generated.result);
Step 4 of 4

Replay it

From then on the fingerprint is enough. The second call is a replay: hit: true, the same row, and no model asked.

Replay it
const replayed = await engine.execute({ fingerprint: generated.meta.cache.fingerprint ?? '', context: {} });
console.log(replayed.meta.cache.hit, replayed.result);
Then

Run it.

This one needs a model, and no page on this site calls one, so nothing is printed here. What comes back is the row in the shape asked for under a fingerprint that begins fp_, and on the second call hit: true with the same row.

Run it
GROQ_API_KEY=your-key npx tsx assistant.mts