- Load system prompt from data/system-prompt.txt (persistent) - Fallback to AI_SYSTEM_PROMPT env variable - Fallback to hardcoded default - File can be edited without rebuilding container - Includes default UlfBot/SchrottBot personality Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.9 KiB
3.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Telegram bot built with TypeScript and Telegraf. Uses Markov chains with trigrams to generate sentences from learned messages. Optional KI/LLM integration via OpenAI-compatible API. Each chat has its own isolated data.
Commands
npm run dev # Development with hot-reload (tsx watch)
npm run build # Compile TypeScript to dist/
npm start # Run production build
docker compose up -d --build # Docker deployment
Architecture
src/
├── index.ts # Bot entry point, commands, setup wizard
├── markov.ts # Markov chain with trigram support
├── database.ts # SQLite persistence layer
└── ai.ts # OpenAI-compatible client
Data flow (Markov):
- Message received →
chain.learn(text)→ SQLite - Trigger check (reply/mention/random)
- If triggered →
chain.generate()→ reply
Data flow (AI):
/ask-aior trigger word detected- Load last 50 messages as context
- Build prompt (global + group prompt)
- Call OpenAI-compatible API → reply
Per-chat isolation:
- Each chat has separate Markov chain data
- Each chat has separate AI settings
- Each chat has separate message context (50 messages)
Key Implementation Details
Markov Chain (markov.ts)
- Uses trigrams (order=2): "word1 word2" → "word3"
- Weighted random selection based on frequency
- Generates sentences up to 20 words
Database (database.ts)
- SQLite with
better-sqlite3(synchronous API) - Tables:
chat_settings- Markov probabilitymarkov_transitions- Word transitionsmarkov_starts- Sentence startsai_settings- KI configuration per chatmessage_context- Last 50 messages per chatsetup_sessions- Setup wizard state
- Automatic cleanup every 24h
AI Client (ai.ts)
- OpenAI-compatible API (works with OpenAI, Ollama, OpenRouter, etc.)
- Prompt system:
- Global:
data/system-prompt.txt→.envfallback → default - Group-specific: stored in DB per chat
- Global:
- API key masking for security
- Context: Last 50 messages
Setup Wizard
- Started via
/ai setupin group - Continues in private chat for security
- API keys never shown in full
- Steps: Provider → API Key → Model → URL → Trigger/Prob → Group Prompt
Environment
BOT_TOKEN= # Telegram bot token (required)
AI_DEFAULT_API_KEY= # Default API key (optional)
AI_DEFAULT_BASE_URL= # Default API URL (default: OpenAI)
AI_DEFAULT_MODEL= # Default model (default: gpt-4o-mini)
AI_SYSTEM_PROMPT= # Global system prompt (fallback, see below)
System Prompt Loading:
data/system-prompt.txt(persistent, editable without rebuild)AI_SYSTEM_PROMPTenv variable (fallback)- Hardcoded default (last resort) AI_DEFAULT_MODEL= # Default model (default: gpt-4o-mini) AI_SYSTEM_PROMPT= # Global system prompt
## Database Schema
```sql
-- Markov
chat_settings (chat_id, probability)
markov_transitions (chat_id, key, next_word, count)
markov_starts (chat_id, key, count)
-- AI
ai_settings (chat_id, enabled, trigger_word, random_prob, group_prompt, provider, base_url, model, api_key)
message_context (chat_id, role, content, timestamp)
setup_sessions (user_id, chat_id, step, data)
Response Triggers
Markov (always active)
- Reply to bot's message → always respond
- @username mention → always respond
- Random probability (configurable per chat)
AI (when enabled)
/ask-ai [text]command- Trigger word (configurable, default: "ask-ai")
- Random probability (configurable, default: 0%)
Security
- API keys stored in database, never logged
- API keys masked in
/ai statusoutput:sk-***...***xyz - Setup only via private chat
- Admin-only configuration commands