Mister Fritz is an AI-powered Discord bot with a sophisticated, sardonic personality modeled after an English butler. It uses LangChain, LangGraph, and a locally-installed Ollama instance to provide conversational responses with persistent per-user memory, web search, document retrieval, image generation, voice synthesis, and more.
| Feature | Details |
|---|---|
| Conversational AI | Witty butler-like responses via local Ollama LLMs |
| Per-user Memory | Conversation summaries stored and retrieved from ChromaDB |
| Document RAG | Query local Word/PDF documents with /lore |
| Web Integration | Live web search (DuckDuckGo) and website scraping |
| Image Generation | Text-to-image via Stable Diffusion XL (GPU-accelerated, long-prompt capable) |
| Voice Synthesis | Text-to-speech via Coqui XTTS v2 (plays in voice channel or uploads as file) |
| Vision Analysis | Analyze user-attached images via LLaVA |
| File Operations | Sandboxed file read/write/edit/search/execute for the configured root user |
| Card Game | Built-in deck system with success/failure mechanics for tabletop-style play |
| Observability | Prometheus metrics on :8000/metrics, health on :8000/health, pre-built Grafana dashboard |
| Canary deployment | Argo Rollouts canary steps with Prometheus-based promotion gates |
| Local DevOps sim | Full canary pipeline simulation via Docker Compose — no cloud cluster required |
| Command | Description |
|---|---|
/hello |
Greet the bot |
/lore <query> |
Search local RAG documents |
/gen <prompt> |
Generate an image from a text description |
/voice <message> |
Synthesize speech (plays in voice channel or uploads file) |
/join / /leave |
Join or leave the current voice channel |
/draw [n] |
Draw cards from a deck |
/cards_remaining |
Check how many cards remain |
/reload_deck |
Reset your deck |
/health |
Show system health and metrics |
/workspace <path> |
(Root user only) Set the file operations workspace |
Direct messages or @mentions trigger the full agent with all tools.
Attach images or Discord voice messages — Fritz can analyze both.
Download from python.org.
Ollama is not included in Docker Compose. Install it directly:
| Platform | Installation |
|---|---|
| Windows | Download from ollama.com/download/windows |
| macOS | brew install ollama or ollama.com/download/mac |
| Linux | curl -fsSL https://ollama.com/install.sh | sh |
After installing, pull the required models:
ollama create -f modelfiles/gpt-oss-20b-modelfile.txt gpt-oss
ollama create -f modelfiles/llama3.2-modelfile.txt llama3.2
ollama create -f modelfiles/llava-modelfile.txt llava
ollama run gpt-oss /bye
ollama run llama3.2 /bye
ollama run llava /bye
ollama pull mxbai-embed-large- Windows: The repo includes
ffmpeg.exe/ffprobe.exe— no extra install needed for native runs. Docker builds install FFmpeg viaapt-get. - macOS/Linux:
brew install ffmpegorapt-get install -y ffmpeg
# CUDA (Windows/Linux)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
# CPU-only / macOS
pip install torch torchvision torchaudiogit clone <repository-url>
cd MisterFritz
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
pip install -r requirements.txtConfigure the bot — copy .env.example to .env and fill in your values:
cp .env.example .env# .env
DISCORD_BOT_TOKEN=your_token_here
ROOT_USER=your_discord_username
OLLAMA_HOST=http://127.0.0.1:11434All config previously in
config.jsonis now read from environment variables.config.jsonstill works as a fallback, but.envis the preferred approach.
Start the bot:
python main_discord.pyOllama must still be running natively on your host. The compose stack runs the bot itself plus Prometheus and Grafana.
cp .env.example .env # fill in DISCORD_BOT_TOKEN and ROOT_USER
docker compose up -d| Service | URL |
|---|---|
| Grafana dashboards | http://localhost:3000 (default login: admin / admin) |
| Prometheus | http://localhost:9090 |
On Linux, set
OLLAMA_HOST=http://172.17.0.1:11434in.env(Docker bridge IP) or add--add-host=host.docker.internal:host-gatewayto your compose config.
All settings can be set as environment variables or in a .env file. See .env.example for the full list.
| Variable | Default | Description |
|---|---|---|
DISCORD_BOT_TOKEN |
— | Required. Your Discord bot token |
ROOT_USER |
— | Required. Discord username with file operation access |
OLLAMA_HOST |
http://127.0.0.1:11434 |
Ollama API endpoint |
THINKING_OLLAMA_MODEL |
gpt-oss |
Primary reasoning model |
FAST_OLLAMA_MODEL |
llama3.2 |
Fast model for quick tasks |
EMBEDDING_MODEL |
mxbai-embed-large |
Embedding model for ChromaDB |
VISION_MODEL |
llava |
Vision model for image analysis |
DOC_STORAGE_DESCRIPTION |
anything you don't know about. |
Hint for when the agent queries documents |
DOC_FOLDER |
./input |
Directory watched for RAG documents |
CHROMA_DB_PATH |
./chroma_store |
ChromaDB persistence path |
FFMPEG_PATH |
auto-detected | Override FFmpeg binary path |
User (Discord)
│
▼
main_discord.py ── slash commands, on_message, streaming handler
│
▼
mister_fritz.py ── LangGraph state machine
├─ CONVERSATION_NODE ── ReAct agent, tool dispatch
│ ├─ get_current_time, roll_dice
│ ├─ scrape_web, search_web
│ ├─ search_documents → document_engine → Chroma RAG
│ ├─ search_memories → chroma_store → Chroma KV
│ ├─ generate_image → image_generator → SDXL
│ ├─ analyze_image → Ollama LLaVA
│ └─ file tools (root only) → file_tools.py
└─ SUMMARIZE_NODE ── auto-summarise at 15+ messages, store to Chroma
Conversation state is checkpointed per-user in chat_history.db (SQLite).
pip install pytest pytest-cov pytest-asyncio
pytest tests/ -v --cov=. --cov-report=term-missingThe test suite covers:
fritz_utils— config loading, env var overrides,validate_configsqlite_store— CRUD, namespace isolation, prefix searchdeck_of_cards— Card logic, Deck, draw/reload/remainingfile_tools— all 6 tools, authorization, path traversal preventionobservability— counters, latency rolling window, error tracking, health textagent_tools—get_current_time,format_prompt,scrape_web(mocked),search_web(mocked),roll_dicediscord_commands—split_into_chunks,StreamingMessageHandlerrate limiting
CI runs on every push via GitHub Actions (see .github/workflows/ci.yml).
The bot exposes a metrics server on port 8000 (configurable via METRICS_PORT):
| Endpoint | Description |
|---|---|
GET :8000/health |
JSON health snapshot (uptime, error rate, p99 latency) |
GET :8000/metrics |
Prometheus text format |
| Metric | Type | Labels |
|---|---|---|
misterfritz_discord_messages_total |
Counter | — |
misterfritz_tool_calls_total |
Counter | tool |
misterfritz_errors_total |
Counter | operation |
misterfritz_request_duration_seconds |
Histogram | operation |
misterfritz_uptime_seconds |
Gauge | — |
The compose stack in docker-compose.yml includes Prometheus and Grafana with a pre-provisioned dashboard.
Simulate the full canary deployment pipeline without a Discord token or cloud cluster using Docker Compose and synthetic traffic:
cd local-sim
make up # start stable stack (Grafana, Prometheus, nginx)
make deploy-canary # introduce canary at 10% traffic
make watch-canary-auto # auto promote or rollback based on metrics
make chaos-errors # inject 25% error rate → triggers automatic rollback
make down # tear everything downOpen Grafana at http://localhost:3000 (admin/admin) to see the MisterFritz — Canary Deployment dashboard with real-time error rates, P99 latency, and throughput split by version.
See local-sim/README.md for the full guide including chaos experiments, canary controller options, and optional Kubernetes setup with kind.
For a real or local Kubernetes cluster, manifests are in infra/k8s/:
# Bootstrap a local kind cluster (installs Argo Rollouts, ArgoCD, Prometheus stack)
bash local-sim/kind/setup.sh
# Trigger a canary rollout
kubectl argo rollouts set image misterfritz misterfritz=<image> -n misterfritz
kubectl argo rollouts status misterfritz -n misterfritz --watchThe CI workflow (.github/workflows/release.yml) builds the image on tag push, runs a smoke test, and triggers a canary rollout with a manual approval gate.
"Ollama connection refused"
Make sure Ollama is running: ollama serve. Check models with ollama list.
Missing DISCORD_BOT_TOKEN error on startup
Copy .env.example → .env and fill in the required values.
Bot not responding in Discord Ensure "Message Content Intent" is enabled in the Discord Developer Portal under your bot's settings.
No documents found by /lore
Add supported files (.pdf, .docx, .xlsx, .csv, .txt, .md) to the input/ folder. The engine watches for changes and indexes automatically.
Image generation is slow or fails
The first run downloads Stable Diffusion XL (~7 GB). GPU (CUDA) is strongly recommended. Check: python -c "import torch; print(torch.cuda.is_available())".
OCR not working for scanned PDFs
Install optional deps: pip install easyocr PyMuPDF pillow.
Contributions are welcome. Please open an issue or pull request.
See repository for license information.