AI

AI primitives, batteries included

Embeddings, vector search and RAG — built on pgvector and the Lovable AI Gateway.

gemini-2.5-pro
gemini-2.5-flash
claude-sonnet-4.5
text-embedding-3-large

Generate embeddings

typescript
const { data } = await nb.ai.embeddings.create({
  model: "text-embedding-3-large",
  input: ["Hello world", "indxBASE is awesome"],
});

// data.embeddings : number[][]

Store vectors in Postgres

sql
create extension if not exists vector;

create table public.documents (
  id        uuid primary key default gen_random_uuid(),
  content   text not null,
  embedding vector(1536)
);
create index on public.documents using hnsw (embedding vector_cosine_ops);

Vector search

typescript
const { data: hits } = await nb.rpc("match_documents", {
  query_embedding: queryVec,
  match_count: 5,
  threshold: 0.78,
});
sql
create or replace function public.match_documents(
  query_embedding vector(1536),
  match_count int,
  threshold float
) returns table (id uuid, content text, similarity float)
language sql stable as $$
  select id, content, 1 - (embedding <=> query_embedding) as similarity
  from public.documents
  where 1 - (embedding <=> query_embedding) > threshold
  order by embedding <=> query_embedding
  limit match_count;
$$;

RAG: ask your data

typescript
const question = "What changed in v2.0?";
const queryVec = (await nb.ai.embeddings.create({ model: "text-embedding-3-large", input: question })).data.embeddings[0];

const { data: ctx } = await nb.rpc("match_documents", {
  query_embedding: queryVec, match_count: 5, threshold: 0.75,
});

const answer = await nb.ai.chat.completions.create({
  model: "google/gemini-2.5-flash",
  messages: [
    { role: "system", content: "Answer using the provided context only." },
    { role: "user", content: `Context:\n${ctx.map(c => c.content).join("\n---\n")}\n\nQ: ${question}` },
  ],
});

Streaming chat

typescript
const stream = await nb.ai.chat.completions.stream({
  model: "google/gemini-2.5-pro",
  messages: [{ role: "user", content: "Write a haiku about Postgres." }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}