Add files via upload
This commit is contained in:
parent
f06f078eab
commit
d992aabc70
2 changed files with 957 additions and 0 deletions
865
eugen_claude.md
Normal file
865
eugen_claude.md
Normal file
|
|
@ -0,0 +1,865 @@
|
||||||
|
# Eugen – Intelligenter Gaming & 3D-Druck Twitch-Bot
|
||||||
|
## Komplettes Setup & Implementierungs-Guide für Windows
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Inhaltsverzeichnis
|
||||||
|
|
||||||
|
1. [Überblick](#überblick)
|
||||||
|
2. [Systemanforderungen](#systemanforderungen)
|
||||||
|
3. [Installation & Setup](#installation--setup)
|
||||||
|
4. [Konfigurationsassistent](#konfigurationsassistent)
|
||||||
|
5. [GUI Dashboard](#gui-dashboard)
|
||||||
|
6. [Architektur & Implementierung](#architektur--implementierung)
|
||||||
|
7. [API-Integration & Debugging](#api-integration--debugging)
|
||||||
|
8. [Fehlerbehandlung](#fehlerbehandlung)
|
||||||
|
9. [Projektstruktur](#projektstruktur)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Überblick
|
||||||
|
|
||||||
|
**Eugen** ist ein intelligenter Twitch-Chat-Agent für:
|
||||||
|
- **Gaming**: World of Warcraft, Elden Ring, Gamedev
|
||||||
|
- **3D-Druck**: Prusa i3, Bambu, Creality
|
||||||
|
- **Tech**: Python, Linux, Home Automation
|
||||||
|
|
||||||
|
### Kernfeatures
|
||||||
|
|
||||||
|
| Feature | Beschreibung |
|
||||||
|
|---------|-------------|
|
||||||
|
| **Name Recognition** | Erkennt automatisch wenn angesprochen (@Eugen, Eugen:, etc.) |
|
||||||
|
| **Persistent Memory** | Speichert Chat-History pro User (max 25 Nachrichten) |
|
||||||
|
| **Context-Aware** | Antwortet basierend auf vorherigem Gesprächsverlauf |
|
||||||
|
| **Perplexity Integration** | Nutzt Perplexity Sonar für Echtzeit-Web-Suche |
|
||||||
|
| **Live Monitoring** | GUI zeigt alle API-Calls, Responses, Fehler in Echtzeit |
|
||||||
|
| **Windows-Native** | Vollständige Windows-Unterstützung, keine Linux-Tools nötig |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Systemanforderungen
|
||||||
|
|
||||||
|
### Minimal
|
||||||
|
- Windows 10/11
|
||||||
|
- Python 3.9+
|
||||||
|
- 100 MB Festplatte
|
||||||
|
- Internetverbindung
|
||||||
|
|
||||||
|
### Empfohlen
|
||||||
|
- Python 3.11+
|
||||||
|
- 500 MB Festplatte (für Chat-History & Logs)
|
||||||
|
- Stabiles Netzwerk (für IRC & API)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation & Setup
|
||||||
|
|
||||||
|
### Schritt 1: Python installieren
|
||||||
|
|
||||||
|
1. Gehe zu [python.org](https://www.python.org/downloads/)
|
||||||
|
2. Lade **Python 3.11+** herunter
|
||||||
|
3. **WICHTIG**: Häkchen setzen bei "Add Python to PATH"
|
||||||
|
4. Installieren
|
||||||
|
|
||||||
|
**Verifizieren:**
|
||||||
|
```powershell
|
||||||
|
python --version
|
||||||
|
pip --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 2: Projekt initialisieren
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Neuer Ordner für Eugen
|
||||||
|
mkdir C:\Users\YourUsername\eugen
|
||||||
|
cd C:\Users\YourUsername\eugen
|
||||||
|
|
||||||
|
# Virtual Environment erstellen
|
||||||
|
python -m venv venv
|
||||||
|
|
||||||
|
# Aktivieren (Windows PowerShell)
|
||||||
|
.\venv\Scripts\Activate.ps1
|
||||||
|
|
||||||
|
# Falls Fehler bei Ausführungsrichtlinie:
|
||||||
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
# Dann nochmal: .\venv\Scripts\Activate.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 3: Dependencies installieren
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
**requirements.txt:**
|
||||||
|
```
|
||||||
|
perplexity-python-client==1.0.0
|
||||||
|
irc==20.1.0
|
||||||
|
python-dotenv==1.0.0
|
||||||
|
PySimpleGUI==4.60.0
|
||||||
|
requests==2.31.0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfigurationsassistent
|
||||||
|
|
||||||
|
### Setup-Flow (Automatisch beim ersten Start)
|
||||||
|
|
||||||
|
Beim ersten Start wird ein **interaktives Setup-Fenster** angezeigt:
|
||||||
|
|
||||||
|
```
|
||||||
|
╔════════════════════════════════════════════════════════════════╗
|
||||||
|
║ EUGEN KONFIGURATIONSASSISTENT ║
|
||||||
|
╠════════════════════════════════════════════════════════════════╣
|
||||||
|
║ ║
|
||||||
|
║ 1️⃣ TWITCH KONFIGURATION ║
|
||||||
|
║ ─────────────────────────────────────────────────────────── ║
|
||||||
|
║ Bot-Name: [___________________________] ║
|
||||||
|
║ OAuth Token: [***hidden***] [🔑 Anleitung] ║
|
||||||
|
║ Channel: [___________________________] ║
|
||||||
|
║ ║
|
||||||
|
║ 2️⃣ PERPLEXITY KONFIGURATION ║
|
||||||
|
║ ─────────────────────────────────────────────────────────── ║
|
||||||
|
║ API Key: [***hidden***] [🔑 Anleitung] ║
|
||||||
|
║ Model: [sonar-pro ▼] ║
|
||||||
|
║ Max Tokens: [450] ║
|
||||||
|
║ ║
|
||||||
|
║ 3️⃣ BOT-VERHALTEN ║
|
||||||
|
║ ─────────────────────────────────────────────────────────── ║
|
||||||
|
║ ☑ Context Memory aktivieren ║
|
||||||
|
║ ☑ Name Recognition aktivieren ║
|
||||||
|
║ ☑ Debug-Mode (zeigt API-Calls) ║
|
||||||
|
║ ║
|
||||||
|
║ [Speichern & Starten] [Abbrechen] ║
|
||||||
|
║ ║
|
||||||
|
╚════════════════════════════════════════════════════════════════╝
|
||||||
|
```
|
||||||
|
|
||||||
|
### API-Keys beschaffen
|
||||||
|
|
||||||
|
#### Twitch OAuth Token
|
||||||
|
|
||||||
|
1. Gehe zu [twitchtokengenerator.com](https://twitchtokengenerator.com/) **ODER** manuell:
|
||||||
|
- [Twitch Developer Console](https://dev.twitch.tv/console/apps)
|
||||||
|
- Neue Anwendung erstellen
|
||||||
|
- OAuth-Authentifizierung
|
||||||
|
- Scopes: `chat:read`, `chat:edit`
|
||||||
|
- Token generieren
|
||||||
|
|
||||||
|
2. **Token Format:** `oauth:abcd1234efgh5678...`
|
||||||
|
3. **Speichern in Setup-Fenster**
|
||||||
|
|
||||||
|
**⚠️ WICHTIG:** Token niemals ins Repository committen!
|
||||||
|
|
||||||
|
#### Perplexity API Key
|
||||||
|
|
||||||
|
1. Gehe zu [perplexity.ai/api](https://www.perplexity.ai/api)
|
||||||
|
2. Registrieren / Anmelden
|
||||||
|
3. API Keys → Neuen Key generieren
|
||||||
|
4. **Format:** `pplx-abcd1234efgh5678...`
|
||||||
|
5. **Speichern in Setup-Fenster**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GUI Dashboard
|
||||||
|
|
||||||
|
### Live Monitoring Interface
|
||||||
|
|
||||||
|
Während der Bot läuft, zeigt das Dashboard in Echtzeit:
|
||||||
|
|
||||||
|
```
|
||||||
|
╔════════════════════════════════════════════════════════════════════╗
|
||||||
|
║ EUGEN BOT - LIVE DASHBOARD ║
|
||||||
|
╠════════════════════════════════════════════════════════════════════╣
|
||||||
|
║ ║
|
||||||
|
║ STATUS: 🟢 VERBUNDEN (Kanal: #dein_kanal) ║
|
||||||
|
║ Uptime: 00:45:23 | Messages: 12 | Errors: 0 ║
|
||||||
|
║ ║
|
||||||
|
║ ┌────────────────────────────────────────────────────────────┐ ║
|
||||||
|
║ │ LIVE CHAT AKTIVITÄT │ ║
|
||||||
|
║ ├────────────────────────────────────────────────────────────┤ ║
|
||||||
|
║ │ 12:02:15 | User123: Eugen, was ist dein Lieblings-Game? │ ║
|
||||||
|
║ │ 12:02:16 | [API] → Perplexity (sonar-pro) │ ║
|
||||||
|
║ │ 12:02:18 | [RESPONSE] Mein Lieblings-Game ist WoW... │ ║
|
||||||
|
║ │ 12:02:19 | Eugen: @User123 Mein Lieblings-Game ist WoW... │ ║
|
||||||
|
║ │ │ ║
|
||||||
|
║ │ 12:03:05 | User456: Eugen, wie levelt man schnell? │ ║
|
||||||
|
║ │ 12:03:06 | [CONTEXT] Gefundener History (3 msgs) │ ║
|
||||||
|
║ │ 12:03:06 | [API] → Perplexity (sonar-pro) │ ║
|
||||||
|
║ │ 12:03:08 | [RESPONSE] Die besten Leveling-Spots sind... │ ║
|
||||||
|
║ │ 12:03:09 | Eugen: @User456 Die besten Leveling-Spots... │ ║
|
||||||
|
║ └────────────────────────────────────────────────────────────┘ ║
|
||||||
|
║ ║
|
||||||
|
║ ┌─────────────────────┬─────────────────────────────────────┐ ║
|
||||||
|
║ │ API STATISTIKEN │ FEHLER LOG │ ║
|
||||||
|
║ ├─────────────────────┼─────────────────────────────────────┤ ║
|
||||||
|
║ │ Requests: 12 │ (Leer - alles OK!) │ ║
|
||||||
|
║ │ Avg Response: 620ms │ │ ║
|
||||||
|
║ │ Costs: $0.0036 │ │ ║
|
||||||
|
║ │ Erfolgsrate: 100% │ │ ║
|
||||||
|
║ └─────────────────────┴─────────────────────────────────────┘ ║
|
||||||
|
║ ║
|
||||||
|
║ [Settings] [Clear Logs] [Export Data] [Stop Bot] ║
|
||||||
|
║ ║
|
||||||
|
╚════════════════════════════════════════════════════════════════════╝
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dashboard-Tabs
|
||||||
|
|
||||||
|
#### 1. **Live Feed**
|
||||||
|
Zeigt Echtzeit-Aktivität:
|
||||||
|
- Chat-Messages
|
||||||
|
- API-Calls (Prompt → Perplexity)
|
||||||
|
- Responses von der KI
|
||||||
|
- Fehler & Warnungen
|
||||||
|
|
||||||
|
#### 2. **API Debug**
|
||||||
|
Detaillierte API-Logs mit:
|
||||||
|
```
|
||||||
|
[12:02:16] REQUEST SENT
|
||||||
|
├─ Endpoint: chat.completions
|
||||||
|
├─ Model: sonar-pro
|
||||||
|
├─ Messages: 4
|
||||||
|
├─ Prompt: "was ist dein Lieblings-Game?"
|
||||||
|
├─ Max Tokens: 450
|
||||||
|
├─ Temperature: 0.7
|
||||||
|
└─ Timestamp: 2026-01-02 12:02:16
|
||||||
|
|
||||||
|
[12:02:18] RESPONSE RECEIVED
|
||||||
|
├─ Status: 200 OK
|
||||||
|
├─ Tokens Used: 127
|
||||||
|
├─ Response: "Mein Lieblings-Game ist WoW wegen..."
|
||||||
|
├─ Processing Time: 1.834s
|
||||||
|
└─ Cost: $0.0003
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. **User Statistics**
|
||||||
|
- Nutzer mit den meisten Interaktionen
|
||||||
|
- Top-Topics (Gaming, 3D-Druck, Tech)
|
||||||
|
- Chat-History pro User anschauen
|
||||||
|
- Context-Memory Status
|
||||||
|
|
||||||
|
#### 4. **Settings**
|
||||||
|
- API-Keys ändern
|
||||||
|
- Model auswählen
|
||||||
|
- Max Tokens anpassen
|
||||||
|
- Debug-Mode togglen
|
||||||
|
- Auto-Reconnect konfigurieren
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architektur & Implementierung
|
||||||
|
|
||||||
|
### Dateisystem
|
||||||
|
|
||||||
|
```
|
||||||
|
C:\Users\YourUsername\eugen\
|
||||||
|
├── chatbot.py # Hauptprogramm
|
||||||
|
├── config.py # Config-Management
|
||||||
|
├── gui.py # Dashboard GUI
|
||||||
|
├── ai_provider.py # Perplexity Integration
|
||||||
|
├── memory.py # Conversation Memory
|
||||||
|
├── utils.py # Hilfsfunktionen
|
||||||
|
├── requirements.txt # Dependencies
|
||||||
|
├── .env # Secrets (NICHT committen!)
|
||||||
|
│
|
||||||
|
├── data/
|
||||||
|
│ ├── conversations/ # User Chat-Histories
|
||||||
|
│ │ ├── user1.json
|
||||||
|
│ │ ├── user2.json
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── config.json # Gespeicherte Konfiguration
|
||||||
|
│
|
||||||
|
└── logs/
|
||||||
|
├── eugen.log # Hauptlogfile
|
||||||
|
└── api_debug.log # API Debug-Logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kernklassen
|
||||||
|
|
||||||
|
#### `MentionDetector`
|
||||||
|
```python
|
||||||
|
class MentionDetector:
|
||||||
|
"""Erkennt ob Bot angesprochen wurde"""
|
||||||
|
|
||||||
|
def is_mentioned(self, message: str) -> bool:
|
||||||
|
"""True wenn @Eugen, Eugen:, eugen, etc. erwähnt"""
|
||||||
|
|
||||||
|
def extract_content(self, message: str) -> str:
|
||||||
|
"""Extrahiert Nachricht ohne Mention"""
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `ConversationMemory`
|
||||||
|
```python
|
||||||
|
class ConversationMemory:
|
||||||
|
"""Speichert & lädt Chat-History pro User"""
|
||||||
|
|
||||||
|
def get_user_history(self, username: str) -> list:
|
||||||
|
"""Letzte 5 Messages für Context"""
|
||||||
|
|
||||||
|
def add_message(self, username: str, role: str, content: str):
|
||||||
|
"""Speichert Message (user/assistant)"""
|
||||||
|
|
||||||
|
def format_for_prompt(self, history: list) -> str:
|
||||||
|
"""Konvertiert zu Prompt-Format"""
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `PerplexityProvider`
|
||||||
|
```python
|
||||||
|
class PerplexityProvider:
|
||||||
|
"""Kommunikiert mit Perplexity API"""
|
||||||
|
|
||||||
|
async def get_response(self, prompt: str, history: list) -> str:
|
||||||
|
"""Sendet Prompt + History, empfängt Response"""
|
||||||
|
|
||||||
|
def validate_api_key(self, key: str) -> bool:
|
||||||
|
"""Prüft ob API-Key gültig ist"""
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `EugenBot` (Main)
|
||||||
|
```python
|
||||||
|
class EugenBot:
|
||||||
|
"""Orchestriert alles: IRC, Memory, AI, GUI"""
|
||||||
|
|
||||||
|
async def on_chat_message(self, username: str, message: str):
|
||||||
|
"""Wird aufgerufen wenn Chat-Message ankommt"""
|
||||||
|
|
||||||
|
def send_response(self, channel: str, username: str, response: str):
|
||||||
|
"""Sendet Antwort im Chat"""
|
||||||
|
|
||||||
|
def log_event(self, event_type: str, data: dict):
|
||||||
|
"""Loggt alles für Debug-Dashboard"""
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API-Integration & Debugging
|
||||||
|
|
||||||
|
### Was passiert beim Chat?
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Chat-Message empfangen
|
||||||
|
↓
|
||||||
|
2. [MentionDetector] → Wurde Bot angesprochen?
|
||||||
|
↓ Ja
|
||||||
|
3. [ConversationMemory] → Lade letzte 5 Messages dieses Users
|
||||||
|
↓
|
||||||
|
4. [Prompt Builder]
|
||||||
|
├─ System Prompt: "Du bist Eugen, Gamer & 3D-Druck Experte"
|
||||||
|
├─ Context History: Letzte Konversation
|
||||||
|
└─ Current Message: Die neue Frage
|
||||||
|
↓
|
||||||
|
5. [API Call] → Perplexity Sonar
|
||||||
|
├─ Method: POST /chat/completions
|
||||||
|
├─ Model: sonar-pro
|
||||||
|
├─ Messages: 4 (system, history, history, user)
|
||||||
|
└─ Max Tokens: 450
|
||||||
|
↓
|
||||||
|
6. [Perplexity Processing] ~600-1000ms
|
||||||
|
↓
|
||||||
|
7. [Response] → KI-Antwort (z.B. "Mein Lieblings-Game ist WoW...")
|
||||||
|
↓
|
||||||
|
8. [ConversationMemory] → Speichere in user.json
|
||||||
|
↓
|
||||||
|
9. [IRC Send] → Sende im Chat: "@Username KI-Antwort"
|
||||||
|
↓
|
||||||
|
10. [Dashboard Update] → Zeige alles in Live-Feed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debug-Mode aktivieren
|
||||||
|
|
||||||
|
In der GUI oder `.env`:
|
||||||
|
```
|
||||||
|
DEBUG_MODE=true
|
||||||
|
```
|
||||||
|
|
||||||
|
Dann wird in der CLI ausgegeben:
|
||||||
|
```
|
||||||
|
[DEBUG] 12:02:16 - Message received from User123
|
||||||
|
[DEBUG] 12:02:16 - Mention detected: @Eugen
|
||||||
|
[DEBUG] 12:02:16 - Content extracted: "was ist dein Lieblings-Game?"
|
||||||
|
[DEBUG] 12:02:16 - History loaded: 3 messages
|
||||||
|
[DEBUG] 12:02:16 - Building prompt...
|
||||||
|
[DEBUG] 12:02:16 - SYSTEM: "Du bist Eugen..."
|
||||||
|
[DEBUG] 12:02:16 - HISTORY[0]: User: "Wie geht es dir?"
|
||||||
|
[DEBUG] 12:02:16 - HISTORY[1]: Assistant: "Mir geht's gut!"
|
||||||
|
[DEBUG] 12:02:16 - HISTORY[2]: User: "Spielst du WoW?"
|
||||||
|
[DEBUG] 12:02:16 - CURRENT: "was ist dein Lieblings-Game?"
|
||||||
|
[DEBUG] 12:02:16 - Sending to Perplexity API...
|
||||||
|
[DEBUG] 12:02:16 - REQUEST: {"model": "sonar-pro", "messages": [...], ...}
|
||||||
|
[DEBUG] 12:02:18 - RESPONSE: 200 OK
|
||||||
|
[DEBUG] 12:02:18 - Content: "Mein Lieblings-Game ist WoW..."
|
||||||
|
[DEBUG] 12:02:18 - Tokens used: 127 (cost: $0.0003)
|
||||||
|
[DEBUG] 12:02:18 - Saving to memory...
|
||||||
|
[DEBUG] 12:02:18 - Sending IRC: "@User123 Mein Lieblings-Game ist WoW..."
|
||||||
|
[DEBUG] 12:02:19 - Message sent successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
### API-Keys validieren
|
||||||
|
|
||||||
|
Setup-Fenster prüft automatisch:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Twitch Token
|
||||||
|
def validate_twitch_token(token: str) -> bool:
|
||||||
|
"""Test mit Twitch IRC Connection"""
|
||||||
|
try:
|
||||||
|
irc.client.IRC().connect(
|
||||||
|
"irc.chat.twitch.tv", 6667,
|
||||||
|
nickname, token=token
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Perplexity API Key
|
||||||
|
def validate_perplexity_key(key: str) -> bool:
|
||||||
|
"""Test mit einfachem API Call"""
|
||||||
|
try:
|
||||||
|
response = requests.post(
|
||||||
|
"https://api.perplexity.ai/chat/completions",
|
||||||
|
headers={"Authorization": f"Bearer {key}"},
|
||||||
|
json={
|
||||||
|
"model": "sonar-pro",
|
||||||
|
"messages": [{"role": "user", "content": "test"}],
|
||||||
|
"max_tokens": 10
|
||||||
|
},
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
return response.status_code == 200
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fehlerbehandlung
|
||||||
|
|
||||||
|
### Häufige Fehler & Lösungen
|
||||||
|
|
||||||
|
#### 1. **"Invalid Twitch Token"**
|
||||||
|
```
|
||||||
|
Fehler: Setup schlägt fehl
|
||||||
|
Grund: Token abgelaufen oder falsch
|
||||||
|
|
||||||
|
Lösung:
|
||||||
|
1. Gehe zu twitchtokengenerator.com
|
||||||
|
2. Generiere neuen Token
|
||||||
|
3. Kopiere: oauth:... (mit oauth: Prefix!)
|
||||||
|
4. Paste in Setup-Fenster
|
||||||
|
5. Validierung sollte grün werden
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. **"Perplexity API Error 401"**
|
||||||
|
```
|
||||||
|
Fehler: Bot startet, aber keine Responses
|
||||||
|
Grund: Ungültiger API-Key oder Account-Issue
|
||||||
|
|
||||||
|
Lösung:
|
||||||
|
1. Prüfe API-Key auf perplexity.ai
|
||||||
|
2. Stelle sicher Account hat Credits (kostenlos gibt es $5/Monat)
|
||||||
|
3. Copy-paste genau (ohne Spaces)
|
||||||
|
4. Teste mit Setup-Validierung
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. **"Cannot connect to Twitch IRC"**
|
||||||
|
```
|
||||||
|
Fehler: Bot startet nicht
|
||||||
|
Grund: Netzwerk oder Twitch offline
|
||||||
|
|
||||||
|
Lösung:
|
||||||
|
1. Prüfe Internet-Verbindung
|
||||||
|
2. Teste: ping irc.chat.twitch.tv
|
||||||
|
3. Firewall-Regel für Python hinzufügen
|
||||||
|
4. Auto-Reconnect wartet 10 Sekunden, versucht erneut
|
||||||
|
5. Dashboard zeigt Reconnect-Versuche
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. **"Memory File Corrupted"**
|
||||||
|
```
|
||||||
|
Fehler: Chat-History wird nicht geladen
|
||||||
|
Grund: JSON-Datei beschädigt
|
||||||
|
|
||||||
|
Lösung:
|
||||||
|
1. Dashboard → Settings → "Reset Memory"
|
||||||
|
2. Oder manuell: Lösche data/conversations/username.json
|
||||||
|
3. Nächster Chat-Start erstellt neue Datei
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. **"Response Rate Limited"**
|
||||||
|
```
|
||||||
|
Fehler: Lange Wartezeiten, Timeout
|
||||||
|
Grund: Zu viele API-Calls zu schnell
|
||||||
|
|
||||||
|
Lösung:
|
||||||
|
1. Perplexity hat Rate-Limit pro Account
|
||||||
|
2. Warte 1-2 Sekunden zwischen Messages
|
||||||
|
3. Dashboard zeigt "Rate Limit - Waiting..."
|
||||||
|
4. Nach 60 Sekunden Auto-Retry
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Dashboard
|
||||||
|
|
||||||
|
Alle Fehler werden im Dashboard gesammelt:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ FEHLER (LETZTE 24H) │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ❌ 12:05:22 | Perplexity Timeout │
|
||||||
|
│ Message von User123 │
|
||||||
|
│ → Auto-Retry in 10 Sekunden │
|
||||||
|
│ │
|
||||||
|
│ ❌ 11:45:15 | API Rate Limited │
|
||||||
|
│ 10 Requests in 5 Sekunden │
|
||||||
|
│ → Auto-Wait aktiviert │
|
||||||
|
│ │
|
||||||
|
│ [Clear Errors] [Export Report] │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
### Wichtigste Dateien für Programmiere r
|
||||||
|
|
||||||
|
#### `chatbot.py` (Hauptprogramm)
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
from config import Config
|
||||||
|
from memory import ConversationMemory
|
||||||
|
from ai_provider import PerplexityProvider
|
||||||
|
from gui import Dashboard
|
||||||
|
from utils import MentionDetector, Logger
|
||||||
|
|
||||||
|
class EugenBot:
|
||||||
|
def __init__(self):
|
||||||
|
self.config = Config()
|
||||||
|
self.memory = ConversationMemory()
|
||||||
|
self.ai = PerplexityProvider(self.config.perplexity_key)
|
||||||
|
self.detector = MentionDetector()
|
||||||
|
self.logger = Logger()
|
||||||
|
self.dashboard = Dashboard(self)
|
||||||
|
|
||||||
|
async def run(self):
|
||||||
|
# IRC Connection
|
||||||
|
# Listen for messages
|
||||||
|
# Process & respond
|
||||||
|
# Update dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `config.py` (Konfiguration)
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
def __init__(self):
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
self.twitch_token = os.getenv("TWITCH_OAUTH_TOKEN")
|
||||||
|
self.twitch_channel = os.getenv("TWITCH_CHANNEL")
|
||||||
|
self.bot_name = os.getenv("TWITCH_BOT_NICKNAME", "Eugen")
|
||||||
|
|
||||||
|
self.perplexity_key = os.getenv("PERPLEXITY_API_KEY")
|
||||||
|
self.model = os.getenv("PERPLEXITY_MODEL", "sonar-pro")
|
||||||
|
self.max_tokens = int(os.getenv("MAX_TOKENS", "450"))
|
||||||
|
|
||||||
|
self.debug_mode = os.getenv("DEBUG_MODE", "false").lower() == "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `ai_provider.py` (Perplexity API)
|
||||||
|
```python
|
||||||
|
import httpx
|
||||||
|
import json
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
class PerplexityProvider:
|
||||||
|
def __init__(self, api_key: str):
|
||||||
|
self.api_key = api_key
|
||||||
|
self.base_url = "https://api.perplexity.ai"
|
||||||
|
self.model = "sonar-pro"
|
||||||
|
|
||||||
|
async def get_response(self, messages: List[Dict]) -> str:
|
||||||
|
"""
|
||||||
|
Sendet Messages zu Perplexity, erhält Response
|
||||||
|
|
||||||
|
Args:
|
||||||
|
messages: [
|
||||||
|
{"role": "system", "content": "..."},
|
||||||
|
{"role": "user", "content": "..."},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response-Text von der KI
|
||||||
|
"""
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {self.api_key}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"model": self.model,
|
||||||
|
"messages": messages,
|
||||||
|
"max_tokens": 450,
|
||||||
|
"temperature": 0.7
|
||||||
|
}
|
||||||
|
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.post(
|
||||||
|
f"{self.base_url}/chat/completions",
|
||||||
|
json=payload,
|
||||||
|
headers=headers,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
return data['choices'][0]['message']['content']
|
||||||
|
else:
|
||||||
|
raise Exception(f"API Error {response.status_code}: {response.text}")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `memory.py` (Chat-Speicher)
|
||||||
|
```python
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
class ConversationMemory:
|
||||||
|
def __init__(self, max_messages=25, data_dir="data/conversations"):
|
||||||
|
self.data_dir = Path(data_dir)
|
||||||
|
self.data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
self.max_messages = max_messages
|
||||||
|
|
||||||
|
def get_user_history(self, username: str, limit: int = 5) -> List[Dict]:
|
||||||
|
"""Lädt letzte Chat-Messages für User"""
|
||||||
|
file_path = self.data_dir / f"{username.lower()}.json"
|
||||||
|
|
||||||
|
if not file_path.exists():
|
||||||
|
return []
|
||||||
|
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
history = json.load(f)
|
||||||
|
|
||||||
|
# Nur Messages der letzten 1 Stunde
|
||||||
|
cutoff_time = datetime.now() - timedelta(hours=1)
|
||||||
|
recent = [
|
||||||
|
msg for msg in history[-limit:]
|
||||||
|
if datetime.fromisoformat(msg['timestamp']) > cutoff_time
|
||||||
|
]
|
||||||
|
|
||||||
|
return recent
|
||||||
|
|
||||||
|
def add_message(self, username: str, role: str, content: str):
|
||||||
|
"""Speichert eine Message (role: 'user' oder 'assistant')"""
|
||||||
|
file_path = self.data_dir / f"{username.lower()}.json"
|
||||||
|
|
||||||
|
history = []
|
||||||
|
if file_path.exists():
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
history = json.load(f)
|
||||||
|
|
||||||
|
history.append({
|
||||||
|
"role": role,
|
||||||
|
"content": content,
|
||||||
|
"timestamp": datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
# Max Nachrichten-Limit einhalten
|
||||||
|
history = history[-self.max_messages:]
|
||||||
|
|
||||||
|
with open(file_path, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(history, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
def format_for_prompt(self, history: List[Dict]) -> List[Dict]:
|
||||||
|
"""Konvertiert History zu Message-Format für AI-API"""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"role": msg['role'],
|
||||||
|
"content": msg['content']
|
||||||
|
}
|
||||||
|
for msg in history
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `gui.py` (Dashboard)
|
||||||
|
```python
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
import threading
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
class Dashboard:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
sg.theme('DarkBlue3')
|
||||||
|
|
||||||
|
# Event-Queue für Thread-Safe Updates
|
||||||
|
self.event_queue = []
|
||||||
|
|
||||||
|
def log_event(self, event_type: str, data: Dict):
|
||||||
|
"""Protokolliert Event für Dashboard"""
|
||||||
|
timestamp = datetime.now().strftime("%H:%M:%S")
|
||||||
|
|
||||||
|
if event_type == "chat_message":
|
||||||
|
msg = f"{timestamp} | {data['username']}: {data['content']}"
|
||||||
|
elif event_type == "api_call":
|
||||||
|
msg = f"{timestamp} | [API] → {data['model']}"
|
||||||
|
elif event_type == "api_response":
|
||||||
|
msg = f"{timestamp} | [RESPONSE] {data['content'][:50]}..."
|
||||||
|
elif event_type == "error":
|
||||||
|
msg = f"{timestamp} | ❌ {data['error']}"
|
||||||
|
|
||||||
|
self.event_queue.append(msg)
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
"""Rendet GUI-Fenster"""
|
||||||
|
layout = [
|
||||||
|
[sg.Text("EUGEN BOT - LIVE DASHBOARD", font=("Arial", 16, "bold"))],
|
||||||
|
[sg.Text(f"Status: 🟢 VERBUNDEN", key="-STATUS-")],
|
||||||
|
[sg.Multiline(
|
||||||
|
size=(120, 30),
|
||||||
|
key="-LOG-",
|
||||||
|
disabled=True,
|
||||||
|
autoscroll=True
|
||||||
|
)],
|
||||||
|
[sg.Button("Settings"), sg.Button("Clear"), sg.Button("Stop")]
|
||||||
|
]
|
||||||
|
|
||||||
|
window = sg.Window("Eugen Bot", layout)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
event, values = window.read(timeout=100)
|
||||||
|
|
||||||
|
# Update Log
|
||||||
|
if self.event_queue:
|
||||||
|
for msg in self.event_queue:
|
||||||
|
window["-LOG-"].print(msg)
|
||||||
|
self.event_queue = []
|
||||||
|
|
||||||
|
if event == sg.WINDOW_CLOSED or event == "Stop":
|
||||||
|
break
|
||||||
|
|
||||||
|
window.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `.env` (Secrets)
|
||||||
|
```
|
||||||
|
# Twitch Configuration
|
||||||
|
TWITCH_OAUTH_TOKEN=oauth:xxxxxxxxxxxxx
|
||||||
|
TWITCH_BOT_NICKNAME=Eugen
|
||||||
|
TWITCH_CHANNEL=#dein_kanal
|
||||||
|
|
||||||
|
# Perplexity Configuration
|
||||||
|
PERPLEXITY_API_KEY=pplx-xxxxxxxxxxxxx
|
||||||
|
PERPLEXITY_MODEL=sonar-pro
|
||||||
|
MAX_TOKENS=450
|
||||||
|
|
||||||
|
# Bot Configuration
|
||||||
|
DEBUG_MODE=true
|
||||||
|
AUTO_RECONNECT=true
|
||||||
|
RECONNECT_DELAY=10
|
||||||
|
|
||||||
|
# Data Configuration
|
||||||
|
DATA_DIR=data/conversations
|
||||||
|
LOG_DIR=logs
|
||||||
|
CONTEXT_RETENTION_HOURS=1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start für Windows
|
||||||
|
|
||||||
|
### Installation (5 Minuten)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# 1. Python installiert? Wenn nicht: python.org
|
||||||
|
python --version
|
||||||
|
|
||||||
|
# 2. Projekt clonen/downlaoden
|
||||||
|
cd C:\Users\YourUsername\eugen
|
||||||
|
|
||||||
|
# 3. Virtual Environment
|
||||||
|
python -m venv venv
|
||||||
|
.\venv\Scripts\Activate.ps1
|
||||||
|
|
||||||
|
# 4. Dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# 5. Konfigurieren
|
||||||
|
python chatbot.py
|
||||||
|
# → Setup-Fenster öffnet sich
|
||||||
|
# → API-Keys eingeben
|
||||||
|
# → Validierung läuft
|
||||||
|
# → Speichern & Starten
|
||||||
|
|
||||||
|
# 6. Dashboard öffnet sich mit Live-Feed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fehlersuche
|
||||||
|
|
||||||
|
**Problem: Module nicht gefunden?**
|
||||||
|
```powershell
|
||||||
|
# Sicherstellen dass venv aktiviert ist:
|
||||||
|
.\venv\Scripts\Activate.ps1
|
||||||
|
|
||||||
|
# Dann reinstallieren:
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem: Port 6667 blocked?**
|
||||||
|
```powershell
|
||||||
|
# Firewall-Exception für Python:
|
||||||
|
# Windows Defender → "Firewall & Netzwerkschutz"
|
||||||
|
# → "App durch Firewall zulassen"
|
||||||
|
# → Python hinzufügen
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verbesserungen & Erweiterungen
|
||||||
|
|
||||||
|
### Einfache Adds (für später)
|
||||||
|
|
||||||
|
- [ ] Multi-Channel Support (mehrere Kanäle gleichzeitig)
|
||||||
|
- [ ] Custom Commands (!gaming, !3dprint)
|
||||||
|
- [ ] User-Blacklist (bestimmte User ignorieren)
|
||||||
|
- [ ] Response-Timeout (wenn API zu langsam)
|
||||||
|
- [ ] Discord Webhook (errori an Discord schicken)
|
||||||
|
- [ ] Analytics Export (CSV mit Stats)
|
||||||
|
|
||||||
|
### Für Programmiere r: Custom Features
|
||||||
|
|
||||||
|
Neue Commands hinzufügen:
|
||||||
|
```python
|
||||||
|
class CommandHandler:
|
||||||
|
def handle_command(self, cmd: str, args: str) -> str:
|
||||||
|
if cmd == "gaming":
|
||||||
|
return "Tipps für WoW, Elden Ring..."
|
||||||
|
elif cmd == "3dprint":
|
||||||
|
return "3D-Druck Hilfe..."
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support & Debugging
|
||||||
|
|
||||||
|
Bei Fehlern:
|
||||||
|
|
||||||
|
1. **Prüfe Dashboard** → "Fehler" Tab
|
||||||
|
2. **Debug-Mode aktivieren** → `.env` → `DEBUG_MODE=true`
|
||||||
|
3. **Logs anschauen** → `logs/eugen.log`
|
||||||
|
4. **API Key validieren** → Setup-Fenster erneut öffnen
|
||||||
|
5. **Internet prüfen** → ping google.com
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
92
gitignore
Normal file
92
gitignore
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
# Python Virtual Environment
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
.venv
|
||||||
|
|
||||||
|
# Python Cache
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# IDE & Editor
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
# Environment Variables (SECRETS!)
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
|
eugen.log
|
||||||
|
api_debug.log
|
||||||
|
|
||||||
|
# OS specific
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
.pytest_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# IDE Temp Files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Chat History (optional - keep für Backup, aber nicht unbedingt committen)
|
||||||
|
# Wenn ihr die History NICHT committen wollt, uncomment:
|
||||||
|
# data/conversations/
|
||||||
|
# data/config.json
|
||||||
|
|
||||||
|
# Temporary Files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
*~
|
||||||
|
.~lock.*
|
||||||
|
|
||||||
|
# OS Specific
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
Loading…
Add table
Add a link
Reference in a new issue