- Switch from pydantic-ai to pydantic-ai-slim[openai] - Removes unused provider SDKs (anthropic, boto3, cohere, google, groq, huggingface) - Production packages: 53 (down from ~158) - Production footprint: 178MB - Add DEPENDENCY_SLIM.md with rollback instructions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
Tatlock - Your Homelab Butler
📖 For the complete system vision and architectural philosophy, see PHILOSOPHY.md
A privacy-first, offline-capable personal assistant system that coordinates specialized AI agents to help with research, development, home automation, and daily organization.
Current Status
- ✅ Production-ready API with OpenAI Responses API format
- ✅ Open WebUI integration with reasoning bubbles (
<think>tags) - ✅ Two-tier architecture - The Steward analyzes requests, Tatlock coordinates execution
- ✅ Multi-agent coordination - Expert household staff for specialized tasks
- ✅ Memory system - User profile, preferences, and semantic recall
- ✅ Comprehensive testing - 399 tests with good coverage
The Household Staff
| Agent | Role | Status |
|---|---|---|
| Tatlock | The Butler - Primary interface with witty personality | ✅ Active |
| The Steward | Request analysis and capability recommendation | ✅ Active |
| The Librarian | Research, wiki management, knowledge synthesis | ✅ Active |
| The Biographer | User memory - profiles, preferences, facts | ✅ Active |
| The Developer | Code assistance, debugging, architecture | 🔜 Planned |
| The Secretary | Scheduling, calendars, reminders | 🔜 Planned |
| The Handyman | System administration, monitoring | 🔜 Planned |
| The Housekeeper | Home automation (Home Assistant) | 🔜 Planned |
Features
API Endpoints
-
Responses API (
/v1/responses) - OpenAI Responses API format with structured output- Reasoning items for displaying thinking process
- Function call items for tool execution
- Message items for assistant responses
- Streaming and non-streaming support
-
Chat Completions (
/v1/chat/completions) - OpenAI Chat Completions compatibility- Automatic reasoning conversion to
<think>tags for Open WebUI - Full OpenAI API compatibility
- Streaming support
- Automatic reasoning conversion to
-
Models (
/v1/models) - List available models
Advanced Capabilities
- Conversation History: Auto-generated IDs, configurable max turns (default: 20)
- Context Management: Token counting, automatic trimming, usage statistics
- Parameter Validation: Temperature (0.0-2.0), reasoning effort levels, max tokens, stop sequences
- Real-time Enforcement: Stop sequence detection and max token limits during streaming
Available Models
-
lorem-tester: Full-featured mock agent with realistic behavior
- Configurable reasoning effort levels
- Random tool/function calls
- Error triggers for testing (rate_limit, context_overflow)
-
Tatlock: Real PydanticAI agent with butler personality
- LLM Backend: Ollama (mistral-nemo:latest by default)
- Personality: Witty British butler, research-oriented
- Core Tools:
- Calculator: Safe mathematical expression evaluation
- Date/Time Toolkit: Current time, relative dates, time differences
- Web Search: Privacy-preserving search via SearXNG
- Household Coordination:
- The Steward: Analyzes requests and recommends capabilities
- The Librarian: Research via library-desk HybridRAG + wiki
- The Biographer: User memory and preference management
- Capabilities: Streaming, reasoning, tool calling, multi-agent delegation
Requirements
- Python 3.12+ (Python 3.12.11 recommended)
- External Services (must be running separately):
- Ollama: LLM inference (mistral-nemo:latest, nomic-embed-text)
- Redis: Caching and session memory
- Qdrant: Vector storage for The Biographer's memory
- SearXNG: Web search (optional)
- library-desk: Research API for The Librarian (optional)
Quick Start
Installation
# Clone the repository
git clone https://git.schweitz.net/jpmschweitzer/tatlock.git
cd tatlock
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
Run the Server
uvicorn src.main:app --reload
API available at http://localhost:8000
Usage Examples
Responses API
Generate a response with reasoning:
curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "lorem-tester",
"input": [
{"role": "user", "content": "Explain quantum computing"}
],
"reasoning": {
"effort": "medium",
"summary": "auto"
},
"max_output_tokens": 500,
"stream": false
}'
Response Structure:
{
"id": "resp_abc123",
"object": "response",
"created_at": 1733529600,
"model": "lorem-tester",
"status": "completed",
"output": [
{
"type": "reasoning",
"summary": ["Analyzing the request...", "Considering quantum mechanics..."]
},
{
"type": "message",
"role": "assistant",
"content": [{"type": "output_text", "text": "Quantum computing uses..."}]
}
],
"usage": {
"input_tokens": 10,
"output_tokens": 50,
"reasoning_tokens": 20,
"total_tokens": 80
}
}
Chat Completions (OpenAI-compatible)
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "lorem-tester",
"messages": [
{"role": "user", "content": "Hello!"}
],
"temperature": 0.7,
"stream": true
}'
List Models
curl http://localhost:8000/v1/models
Conversation History
Optionally track conversations using metadata:
curl http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "lorem-tester",
"input": [{"role": "user", "content": "Hello"}],
"metadata": {"conversation_id": "conv_abc123"}
}'
Note: Client must send full conversation history in input array (OpenAI compatible). Server optionally tracks via metadata.conversation_id for future features.
Using Tatlock with Tools
Tatlock automatically uses his permanent tools when appropriate:
# Mathematical calculation
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Tatlock",
"messages": [{"role": "user", "content": "What is sqrt(144) + 25?"}]
}'
# Date/time queries
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Tatlock",
"messages": [{"role": "user", "content": "What was the date 2 weeks ago?"}]
}'
# Web search for current information
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Tatlock",
"messages": [{"role": "user", "content": "Search for recent Python 3.12 features"}]
}'
Tatlock's Tool Usage Philosophy:
- Uses calculator for ALL mathematics (even simple arithmetic)
- Uses date/time tools instead of guessing dates
- Searches for current/volatile information to verify facts
- Maintains a researcher's mindset with tool-assisted verification
Open WebUI Integration
Connection
If running Open WebUI in Docker and API on host:
# Use Docker bridge gateway IP
http://172.17.0.1:8000/v1/chat/completions
Reasoning Display
The Chat Completions endpoint automatically:
- Enables reasoning generation
- Converts reasoning to
<think>tags - Streams thinking before the response
Open WebUI displays this as thought bubbles separate from the main response.
Testing Error Handling
Use special triggers in user messages:
"trigger_rate_limit"- Simulates rate limit error"trigger_context_overflow"- Simulates context length error
API Documentation
Interactive documentation available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
Testing
# Run all tests
pytest
# Run unit tests only (no external services needed)
pytest --ignore=tests/e2e --ignore=tests/integration
# Run with coverage
pytest --cov=src --cov-report=term-missing
# Current: ~400 tests
Test Categories:
- Unit tests: Agent tools, capabilities, schemas, memory service
- Integration tests: Full API stack with real Ollama
- End-to-end tests: Chat completions, responses API
Deployment
Production Server
# Multiple workers for production
uvicorn src.main:app --host 0.0.0.0 --port 8000 --workers 4
Recommendations
- Use reverse proxy (nginx/caddy) for HTTPS
- Enable rate limiting
- Set up monitoring and logging
- Configure resource limits
- Use process manager (systemd/supervisor)
Configuration
Create a .env file for custom configuration:
# API Configuration
API_HOST=0.0.0.0
API_PORT=8000
# Ollama Configuration
OLLAMA_HOST=http://localhost:11434
OLLAMA_DEFAULT_MODEL=mistral-nemo:latest
OLLAMA_EMBEDDING_MODEL=nomic-embed-text
OLLAMA_TIMEOUT=120
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_MEMORY_DB=2
REDIS_MEMORY_TTL_HOURS=24
# Qdrant Configuration (for memory)
QDRANT_HOST=localhost
QDRANT_PORT=6333
QDRANT_EMBEDDING_DIM=768
# Library-desk Configuration (for The Librarian)
LIBRARY_DESK_HOST=http://localhost:8089
LIBRARY_DESK_TIMEOUT=60
# SearXNG Configuration (for web search)
SEARXNG_HOST=http://localhost:8087
SEARXNG_TIMEOUT=30
# Logging
LOG_LEVEL=INFO
# CORS (default: allow all)
CORS_ORIGINS=["*"]
See .env.example for full configuration options.
Troubleshooting
Streaming not working
- Verify SSE-Starlette is installed
- Check client supports Server-Sent Events
- Test with:
pytest tests/responses/ -k streaming
Open WebUI can't connect
- Use Docker bridge gateway IP:
172.17.0.1:8000 - Check firewall settings
- Verify server is running on
0.0.0.0
Reasoning not showing
- Ensure using Chat Completions endpoint (auto-enables reasoning)
- Or manually enable in Responses API:
"reasoning": {"effort": "medium", "summary": "auto"} - Check Open WebUI version supports
<think>tags
Tatlock agent errors
- Verify Ollama is running:
curl http://localhost:11434/api/tags - Check model is downloaded:
ollama list - Review environment variables:
OLLAMA_HOST,OLLAMA_DEFAULT_MODEL - Check logs:
tail -f logs/server.log
Web search not working
- Verify SearXNG is running:
curl http://localhost:8087/ - Check
SEARXNG_HOSTenvironment variable - SearXNG is optional - Tatlock will note if search is unavailable
Project Structure
tatlock/
├── src/
│ ├── agents/ # Agent implementations
│ │ ├── biographer/ # The Biographer - memory management
│ │ ├── librarian/ # The Librarian - research & wiki
│ │ ├── steward/ # The Steward - request analysis
│ │ ├── tatlock_core/ # Core butler tools
│ │ ├── tatlock.py # Tatlock PydanticAI agent
│ │ ├── coordination.py # Multi-agent coordination
│ │ ├── delegation.py # Expert delegation wrappers
│ │ └── protocol.py # Agent communication protocol
│ ├── responses/ # Responses API (primary endpoint)
│ ├── chat/ # Chat Completions wrapper
│ ├── models/ # Models listing
│ ├── core/ # Shared infrastructure
│ │ ├── config.py # Configuration management
│ │ ├── context.py # Request context (ContextVar)
│ │ ├── memory_service.py # Direct memory access
│ │ ├── memory_cache.py # Redis session cache
│ │ ├── embeddings.py # Ollama embedding client
│ │ ├── qdrant.py # Vector database client
│ │ └── multi_tenancy.py # User isolation utilities
│ └── main.py # Application entry point
├── tests/ # Comprehensive test suite
├── PHILOSOPHY.md # System vision and architecture
├── IMPLEMENTATION_ROADMAP.md # Development phases
├── CHANGELOG.md # Version history
└── README.md # This file
Development
For LLM agent development guidelines and architectural decisions, see AGENTS.md.
Contributing
- Fork the repository
- Create a feature branch
- Make changes with tests
- Ensure tests pass:
pytest - Submit pull request
Documentation
- System Philosophy: PHILOSOPHY.md - Vision, goals, and architectural patterns
- User Guide: This file - Installation, usage, and examples
- Developer Guidelines: AGENTS.md - LLM agent development patterns
- Version History: CHANGELOG.md - Changes and releases
External References
- OpenAI Responses API: https://platform.openai.com/docs/api-reference/responses
- FastAPI: https://fastapi.tiangolo.com/
- PydanticAI: https://ai.pydantic.dev/
License
[Add your license here]
Version
Current version: 1.2.1 - Dependency slimming
Note: Tatlock is a production-ready homelab butler. All household staff use PydanticAI with Ollama for local LLM inference.