`_compact_old_tool_returns`, `PRIOR_TURN_NOTICE` and `turn_start` leave `RAGCapabilityBase`, along with its `wrap_model_request` hook. The evidence capabilities now retrieve and validate, and nothing else. Registering the compaction capability is what rewrites a request; leaving it out sends the transcript untouched, which was never a choice a host could make before. The boundary is the recorded question identity rather than message shape, so a resumption compacts what lies below the question in progress instead of switching compaction off for the whole run. The newest earlier evidence return carries the capsule and every other becomes a receipt, so one capsule exists by construction and every return stays paired with its call. Pictures of cited evidence are fetched through the capability that retrieved them and re-attached beside the capsule with fresh labels. Ownership of a picture on the wire requires the machine tag we write and an image directly after it, since neither position nor prose is proof: several tools' results can arrive in one request, and a user quoting our wording above their own picture had it removed. A picture that cannot be fetched or decoded is emitted with neither its image nor its label. The chat TUI and the example backend register the compactor, being multi-turn. `client.ask`, `client.analyze` and the MCP tools do not: a single-shot question has nothing earlier to compact. |
||
|---|---|---|
| .. | ||
| backend | ||
| frontend | ||
| .env.example | ||
| docker-compose.dev.yml | ||
| docker-compose.yml | ||
| haiku.rag.yaml.example | ||
| README.md | ||
haiku.rag Chat App
A conversational RAG interface built with CopilotKit and pydantic-ai's AG-UI protocol.
Note: An illustrative example meant as a starting point, with no authentication. The compose files bind the backend to
127.0.0.1; don't expose it to an untrusted network.
Prerequisites
- Docker and Docker Compose
- A haiku.rag database (created via the
haiku-ragCLI) - An LLM API key (Anthropic, OpenAI, or local Ollama)
Quick Start
-
Set up environment variables:
cp .env.example .env # Edit .env with your API keys and database path -
Configure the LLM and embedding models:
cp haiku.rag.yaml.example haiku.rag.yaml # Edit haiku.rag.yaml to configure your models -
Start the app:
docker compose up -d -
Open the chat interface: http://localhost:3000
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
DB_PATH |
Path to your haiku.rag LanceDB database | Yes |
ANTHROPIC_API_KEY |
Anthropic API key | One LLM key required |
OPENAI_API_KEY |
OpenAI API key | One LLM key required |
OLLAMA_BASE_URL |
Ollama server URL (default: http://host.docker.internal:11434) |
For local models |
LOGFIRE_TOKEN |
Pydantic Logfire token for debugging | No |
haiku.rag.yaml
Configure the LLM, embeddings, and search settings:
qa:
model:
provider: anthropic # or openai, ollama
name: claude-sonnet-4-20250514
embeddings:
model:
provider: ollama
name: nomic-embed-text
search:
limit: 10
See haiku.rag.yaml.example for all options.
Development
For local development with hot reloading:
docker compose -f docker-compose.dev.yml up -d --build
- Backend code changes reload automatically
- Frontend available at http://localhost:3000
- Backend API at http://localhost:8001
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │────▶│ Backend │────▶│ haiku.rag │
│ (CopilotKit) │ │ (pydantic-ai) │ │ (LanceDB) │
│ localhost:3000 │ │ localhost:8001 │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Backend Endpoints
| Endpoint | Method | Description |
|---|---|---|
/v1/chat/stream |
POST | AG-UI chat streaming |
/api/documents |
GET | List documents in database |
/api/info |
GET | Database statistics |
/api/visualize/{chunk_id} |
GET | Visual grounding for chunks |
/health |
GET | Health check |
Chat Capabilities
The chat can:
- Search your documents with hybrid vector + full-text search
- Answer questions with citations from your knowledge base
- Filter by document when you ask about specific files
- Show visual grounding for PDF/image sources