npm install latticesql

SQLite ↔ LLM
context bridge.

Keeps a database and a set of text files in sync so AI agents always start a session with accurate, up-to-date state. No opinions about your schema, your agents, or your file format.

What it does

01

Sync loop

Renders DB rows into agent-readable text files, watches for changes, and re-renders automatically. One call to db.watch() keeps everything current.

02

Entity context directories

Per-entity file trees via defineEntityContext(). One subdirectory per row, one file per relationship — with orphan cleanup, budget limits, and combined context files.

03

Writeback pipeline

Ingest agent-written output back into the database. defineWriteback() watches output files, calls your parse() function, and persists entries — with deduplication and offset tracking.

04

YAML config

Declare your entire schema in a lattice.config.yml file. Use lattice generate to produce TypeScript types and SQL migrations. Zero boilerplate.

The sync loop

LLM context windows are ephemeral. Your application state lives in a database. Every agent session starts cold unless something bridges them. Lattice is that bridge.

text
Your DB (SQLite)
     │  Lattice reads rows → render → text
     ▼
Context files (Markdown, JSON, etc.)
     │  LLM agents read these at session start
     ▼
Agent output files
     │  Lattice writeback parses these
     ▼
Your DB (rows inserted/updated)

Lattice never modifies your existing rows — it only reads for rendering and appends via the writeback pipeline.

typescript
import { Lattice } from 'latticesql';

const db = new Lattice('./state.db');

db.define('agents', {
  columns: {
    id: 'TEXT PRIMARY KEY',
    name: 'TEXT NOT NULL',
    persona: 'TEXT',
    active: 'INTEGER DEFAULT 1',
  },
  render(rows) {
    return rows
      .filter((r) => r.active)
      .map((r) => `## ${r.name}\n\n${r.persona ?? ''}`)
      .join('\n\n---\n\n');
  },
  outputFile: 'AGENTS.md',
});

await db.init();
await db.insert('agents', { name: 'Alpha', persona: 'Research assistant.' });

// Render DB → context files
await db.render('./context');
// Writes: context/AGENTS.md

// Watch for changes, re-render every 5 seconds
const stop = await db.watch('./context', { interval: 5000 });

Entity context directories

One directory per entity. One file per relationship. Agents load exactly what they need — no giant context dumps.

typescript
db.defineEntityContext('agents', {
  slug: (row) => row.slug as string,

  index: {
    outputFile: 'agents/AGENTS.md',
    render: (rows) => rows.map((r) => `- ${r.name}`).join('\n'),
  },

  files: {
    'AGENT.md': {
      source: { type: 'self' },
      render: ([r]) => `# ${r.name}\n\n${r.bio ?? ''}`,
    },
    'TASKS.md': {
      source: { type: 'hasMany', table: 'tasks', foreignKey: 'agent_id' },
      render: (rows) => rows.map((r) => `- ${r.title}`).join('\n'),
      omitIfEmpty: true,
    },
  },

  combined: { outputFile: 'CONTEXT.md', exclude: [] },
  protectedFiles: ['SESSION.md'],
});

// Produces per-agent directories:
// context/agents/alpha/AGENT.md
// context/agents/alpha/TASKS.md
// context/agents/alpha/CONTEXT.md
Generated tree
text
context/
├── agents/
│   └── AGENTS.md          ← global index
├── agents/alpha/
│   ├── AGENT.md
│   ├── TASKS.md           ← omitted when empty
│   └── CONTEXT.md         ← all files combined
└── agents/beta/
    ├── AGENT.md
    └── CONTEXT.md

Also included

  • Protected files agents write are never deleted during cleanup
  • Budget limits truncate large relationship files
  • reconcile() removes orphaned directories when entities are deleted
  • Manifest-driven — Lattice knows exactly what it wrote

CLI

lattice generate

Generate TypeScript types and SQL migration from YAML config

lattice render

One-shot render — write all context files from the database

lattice reconcile

Render + orphan cleanup — remove stale entity directories

lattice status

Dry-run reconcile — preview what would change

lattice watch

Poll the DB and re-render on every interval

Zero opinions. Full control.

Define your schema, write your render functions, and Lattice handles the rest. Works with any agent framework, any file format.