3.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Frankenbot is a multi-agent event management system for the Diversity Ball Wien 2026. It's a Flask app (single-file app.py, ~3400 lines) with 13 specialized AI agents that handle tasks like budgeting, catering, music rights, tax advice, and team coordination. Agents are executed via OpenCode CLI (opencode run) which connects to Claude models via Anthropic.
Running the App
# Start directly
python3 app.py
# Or via systemd (production)
sudo systemctl restart frankenbot
sudo systemctl status frankenbot
sudo journalctl -u frankenbot -f
# App runs on port 5050 (not 5000, that's Zou/Kitsu)
# Accessible at https://frankenbot.equalizent.media/
Architecture
Agent System
Each agent lives in agents/<name>/ with:
systemprompt.md- Role and instructionspersonality.md- Behavioral traitsreminders.md- Persistent notesmemory/- JSON files (tasks.json, notes.json, conversations.json, max 100 entries each)work/- Agent output directory (used as cwd during execution)
Execution flow: User prompt → load systemprompt + personality + memory summary + team summary → call opencode run --model <model> --format json <combined_prompt> → parse response for special commands (@CREATE_SUBTASK, @SEND_EMAIL, @ASK_ORCHESTRATOR, etc.) → return to user.
Model assignments are in agent_config.json. Fallback model: opencode/big-pickle.
Database (SQLite: email_journal.db)
Four tables: email_journal (IMAP message tracking), tasks (persistent task queue with status pending→in_progress→completed), team_members (real people with roles/contact), app_settings (key-value config). Auto-migrated on startup.
Background Threads (5 daemon threads)
- EmailPoller - IMAP check every 2 min, whitelist-filtered (@diversityball.at)
- TaskWorker - Processes email tasks from queue every 10s
- TaskBeat - Auto-delegates pending orchestrator tasks every 10s
- OrchestratorBeat - Escalates stuck tasks every 30 min
- TelegramBot - Polls for messages (if configured)
SSE Streaming
/api/agent-stream uses subprocess.Popen with OpenCode, reads stdout line-by-line, yields JSON SSE events. Browser uses fetch() + ReadableStream. Nginx must have proxy_buffering off.
Authentication
Single shared password (APP_PASSWORD in .env). @login_required decorator on all routes except /login and /logout. Flask session with 7-day lifetime.
Key Files
| File | What it does |
|---|---|
app.py |
Everything: routes, agent execution, DB, email, telegram, background threads |
agent_config.json |
Agent → model mapping (editable via web UI /agents) |
.env |
APP_PASSWORD, email credentials (IMAP/SMTP), Telegram token |
templates/base.html |
Shared layout (Bootstrap 5, dark theme, navbar) |
static/style.css |
All custom styles |
Important Patterns
- Agent commands: Agents can embed
@CREATE_SUBTASK,@SEND_EMAIL,@ASK_ORCHESTRATOR,@SUGGEST_AGENT,@READ_KNOWLEDGE,@SEND_TELEGRAM,@UPDATE_TEAM_MEMBERin their responses. These are parsed byparse_agent_commands()and executed by the system. - Session cookie limit: Don't store large data in Flask session (4KB cookie limit). The orchestrator knowledge base and agent prompts must be loaded on-demand, not cached in session.
- Port 5050: Port 5000 is used by Zou/Kitsu on this server. Don't change back to 5000.
- OpenCode CLI: Must be installed and authenticated separately (
opencode auth). Binary at~/.opencode/bin/opencode.
Deployment
- Server: 212.186.132.27 (signtime-kitsu)
- nginx: Reverse proxy on
frankenbot.equalizent.media→ localhost:5050 - SSL: Let's Encrypt via certbot (auto-renew)
- systemd:
/etc/systemd/system/frankenbot.service, runs as usereric - Git remote:
https://git.poweroftwo.studio/Pjot/frankenbot.git