DITTO is a local-first digital twin studio built with Next.js, Ollama, and ChromaDB. It parses WhatsApp chat exports, builds a structured personality profile for a selected speaker, stores semantic memories as vector embeddings, and generates persona-grounded replies — entirely on your machine with no external APIs.
- Upload a WhatsApp chat export and select a speaker
- DITTO parses the chat, extracts the speaker's personality profile via LLM, and stores conversation-context embeddings in ChromaDB
- Chat with the persona — replies are grounded in retrieved memory and the personality profile
- Next.js App Router + React + TypeScript
- Ollama — local LLM (
llama3) and embeddings (nomic-embed-text) - ChromaDB — vector memory store (
ditto_pairs_v1collection) - shadcn/ui + Tailwind CSS
Two local services must be running before starting the app:
# Ollama (pull required models first)
ollama pull llama3
ollama pull nomic-embed-text
ollama serve # runs on http://127.0.0.1:11434
# ChromaDB
chroma run --path ./chroma # runs on http://127.0.0.1:8000bun install
bun run devOpen http://localhost:3000.
bun run dev # Start dev server with Turbopack
bun run build # Production build
bun run lint # ESLint
bun run format # Prettier
bun run typecheck # Type check (tsc --noEmit)No .env file is required. Defaults:
| Variable | Default |
|---|---|
OLLAMA_URL |
http://127.0.0.1:11434 |
OLLAMA_MODEL |
llama3 |
OLLAMA_EMBED_MODEL |
nomic-embed-text |
CHROMA_URL |
http://127.0.0.1:8000 |
| File | Role |
|---|---|
| components/ditto-studio.tsx | Main UI client component |
| app/api/personas/route.ts | Persona creation endpoint |
| app/api/personas/chat/route.ts | Reply generation endpoint |
| lib/chat-parser.ts | WhatsApp format regex parsing |
| lib/personality.ts | LLM-driven personality profile extraction |
| lib/ollama.ts | Ollama generation and embedding wrappers |
| lib/chroma.ts | ChromaDB store and similarity search |
| lib/types.ts | Central type definitions |