Files
ulfbot/CLAUDE.md
sarah e49bd060d2
Some checks failed
Auto Build and Push Docker Image / build (push) Failing after 46s
Docs: Update README and CLAUDE.md for recent architecture changes
- Updated docs to reflect switch to Bigrams (order 1)
- Documented incremental DB updates and performance caching
- Added mention of @-ping protection in features
- Updated AI context guidance (20 messages instead of 50)
- Fixed AI_SYSTEM_PROMPT env fallback in index.ts
2026-05-14 13:38:23 +02:00

3.6 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 bigrams 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 bigram support (order 1)
├── database.ts   # SQLite persistence layer (optimized)
└── ai.ts         # OpenAI-compatible client

Data flow (Markov):

  1. Message received → chain.learn(text)updateChain(learned) → SQLite (incremental)
  2. Trigger check (reply/mention/random)
  3. If triggered → chain.generate() → sanitize (@-removal) → reply

Data flow (AI):

  1. /ask-ai or trigger word detected
  2. Load last 20 messages as context
  3. Build prompt (global + group prompt)
  4. Call OpenAI-compatible API → sanitize (@-removal) → reply

Per-chat isolation:

  • Each chat has separate Markov chain data
  • Each chat has separate AI settings
  • Each chat has separate message context (20 messages)

Key Implementation Details

Markov Chain (markov.ts)

  • Uses bigrams (order=1): "word1" → "word2" for higher creativity
  • Weighted random selection based on frequency
  • No character filtering (keeps emojis/punctuation)

Database (database.ts)

  • SQLite with better-sqlite3 (synchronous API)
  • Optimized storage: updateChain uses ON CONFLICT for incremental updates (no full rewrites)
  • Tables:
    • chat_settings - Markov probability
    • markov_transitions - Word transitions
    • markov_starts - Sentence starts
    • ai_settings - KI configuration per chat
    • message_context - Last 20 messages per chat
    • setup_sessions - Setup wizard state
  • Automatic cleanup every 24h

AI Client (ai.ts)

  • OpenAI-compatible API (works with OpenAI, Ollama, OpenRouter, etc.)
  • Parameters: temperature: 0.8, presence_penalty: 0.6, frequency_penalty: 0.6
  • Prompt system:
    • Global: data/system-prompt.txt.env fallback → default
    • Group-specific: stored in DB per chat
  • API key masking for security
  • Context: Last 20 messages

Setup Wizard

  • Started via /ai setup in group
  • Continues in private chat for security
  • API keys never shown in full
  • Steps: Provider → API Key → Model → URL → Trigger/Prob → Group Prompt

Performance Features

  • Admin Cache: 5-minute cache for chat administrators to reduce API calls
  • Bot Info Cache: Cached bot username and ID
  • Incremental DB: Markov updates don't delete existing data
  • Typing Status: AI responses show "typing" status while generating

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)

System Prompt Loading:

  1. data/system-prompt.txt (persistent, editable without rebuild)
  2. AI_SYSTEM_PROMPT env variable (fallback)
  3. Hardcoded default (last resort)

Response Triggers & Sanitization

  • @-Ping Protection: All responses (AI & Markov) have @ symbols removed before sending to prevent user notifications.