Add comprehensive credential validation and troubleshooting tools

This commit adds robust diagnostic tools to help users identify and fix
authentication issues with Twitch OAuth and Perplexity API.

New Features:
- test_credentials.py: Comprehensive credential validator with detailed diagnostics
  - Tests Twitch OAuth token with IRC authentication
  - Validates Perplexity API key and model access
  - Provides specific error messages and actionable fixes
  - Automatically tests fallback models (sonar-pro → sonar)

- TROUBLESHOOTING.md: Complete troubleshooting guide
  - Common error messages and solutions
  - Step-by-step diagnostic procedures
  - Quick reference for file locations and commands

Improvements to setup_wizard.py:
- Enhanced Twitch token validation with detailed error messages
- Added Perplexity model fallback (sonar-pro → sonar)
- Better error handling with specific solutions
- Recommends working model if primary model unavailable

Documentation Updates:
- README.md: Added credential testing section with examples
- CLAUDE.md: Updated with new tools and testing procedures
- Comprehensive troubleshooting section in README

This addresses the common authentication failures users encounter during
initial setup and provides clear paths to resolution.
This commit is contained in:
Claude 2026-01-06 15:58:46 +00:00
parent f45f73e335
commit ddedd4867c
No known key found for this signature in database
5 changed files with 807 additions and 53 deletions

View file

@ -28,6 +28,8 @@
```
eugen/
├── chatbot.py # Main entry point
├── setup_wizard.py # Interactive setup wizard
├── test_credentials.py # Credential validation tool
├── config.py # Configuration management
├── gui.py # Dashboard GUI
├── ai_provider.py # Perplexity API integration
@ -102,12 +104,32 @@ python -m venv venv
# Install dependencies
pip install -r requirements.txt
# Run interactive setup wizard
python setup_wizard.py
# Test credentials (recommended before first run)
python test_credentials.py
# Run the bot
python chatbot.py
```
## Testing API Keys
## Testing Credentials
Use the credential validator for comprehensive testing:
```bash
python test_credentials.py
```
This tool:
- Tests Twitch OAuth token with IRC authentication
- Validates Perplexity API key and model access
- Provides detailed error diagnostics
- Suggests fixes for common issues
- Automatically tests fallback models (sonar-pro → sonar)
Manual testing:
- **Twitch**: Test IRC connection to irc.chat.twitch.tv:6667
- **Perplexity**: POST to https://api.perplexity.ai/chat/completions with a simple test message

View file

@ -80,6 +80,27 @@ PERPLEXITY_API_KEY=pplx-your_key_here
3. Generate new API key
4. Copy the key (should start with `pplx-`)
### Testing Credentials (Recommended)
Before running the bot, test your credentials:
```bash
python test_credentials.py
```
This will:
- Validate your Twitch OAuth token with detailed diagnostics
- Test your Perplexity API key and check model access
- Provide specific error messages and fixes for common issues
- Automatically detect if `sonar-pro` is unavailable and suggest `sonar` fallback
**Example output:**
```
✓ Twitch IRC: PASS
✓ Perplexity API: PASS
🎉 All credentials valid! Bot is ready to run.
```
### Running the Bot
```bash
@ -105,6 +126,8 @@ Eugen: @User For bed leveling, start by...
```
eugen/
├── chatbot.py # Main entry point
├── setup_wizard.py # Interactive setup tool
├── test_credentials.py # Credential validator
├── config.py # Configuration management
├── gui.py # Dashboard GUI
├── ai_provider.py # Perplexity API integration
@ -135,20 +158,51 @@ The bot is built with:
## Troubleshooting
**Bot doesn't respond:**
- Check that .env has correct OAuth token and API key
- Verify bot is in the correct channel
- Check logs/eugen.log for errors
### Quick Diagnosis
**API errors:**
- Verify Perplexity API key is valid
- Check your API credits at perplexity.ai
- Enable DEBUG_MODE=true in .env for detailed logs
**First step: Run the credential validator**
```bash
python test_credentials.py
```
This will identify exactly what's wrong and provide specific fixes.
### Common Issues
**Twitch OAuth Token Invalid:**
- ✗ Error: `Login authentication failed`
- **Fix:**
1. Go to https://twitchtokengenerator.com
2. Select "Bot Chat Token"
3. Make sure you're logged in as the bot account
4. Copy the new token (including `oauth:` prefix)
5. Update `TWITCH_OAUTH_TOKEN` in `.env`
**Bot nickname mismatch:**
- Token must be generated by the same account as `TWITCH_BOT_NICKNAME`
- If bot nickname is `EugenBot`, you must be logged into Twitch as `EugenBot` when generating the token
**Perplexity Model Not Available:**
- ✗ Error: `400 Bad Request` or model not accessible
- **Fix:**
- Your API key might not have access to `sonar-pro`
- The setup wizard will automatically suggest `sonar` as fallback
- Or manually change `PERPLEXITY_MODEL=sonar` in `.env`
**Bot doesn't respond in chat:**
- Run `python test_credentials.py` to verify credentials
- Check that bot is in the correct channel
- Check `logs/eugen.log` for errors
- Verify bot was mentioned correctly (`@Eugen` or `Eugen:`)
**IRC connection failed:**
- Verify internet connection
- Check firewall settings for port 6667
- Regenerate Twitch OAuth token if expired
- Check internet connection
- Verify firewall allows port 6667
- Run credential validator for detailed diagnostics
**API rate limits:**
- Check your Perplexity API credits at https://www.perplexity.ai/settings/api
- Enable `DEBUG_MODE=true` in `.env` for detailed API logs
## License

279
TROUBLESHOOTING.md Normal file
View file

@ -0,0 +1,279 @@
# Eugen Bot - Troubleshooting Guide
Quick reference for diagnosing and fixing common issues with the Eugen Twitch bot.
## Quick Start Diagnostic Tool
**Before anything else**, run the credential validator:
```bash
python test_credentials.py
```
This tool will:
- Test your Twitch OAuth token
- Validate your Perplexity API key
- Check model availability (sonar-pro vs sonar)
- Provide specific error messages
- Suggest exact fixes
---
## Common Error Messages
### 1. Twitch IRC Authentication Failed
**Error Output:**
```
IRC EVENT: privnotice | Source: tmi.twitch.tv | Args: ['Login authentication failed']
```
**Causes:**
- Token is expired or invalid
- Token doesn't match the bot nickname
- Bot account is banned/suspended
**Solution:**
1. **Verify Bot Nickname Match**
- If `TWITCH_BOT_NICKNAME=Eugen`, you must generate the token while logged into Twitch as `Eugen`
- Token and bot nickname MUST match the same account
2. **Generate New Token**
```
1. Go to: https://twitchtokengenerator.com
2. Log into Twitch as the bot account
3. Select "Bot Chat Token"
4. Copy the full token (including oauth: prefix)
5. Update .env file:
TWITCH_OAUTH_TOKEN=oauth:your_new_token_here
```
3. **Test the Token**
```bash
python test_credentials.py
```
### 2. Perplexity API 400 Bad Request
**Error Output:**
```
⚠ Unerwartete Antwort: 400
```
**Causes:**
- API key doesn't have access to `sonar-pro` model
- Invalid request format
- Model not available on your plan
**Solution:**
1. **Use Model Fallback**
- The setup wizard automatically tries `sonar` if `sonar-pro` fails
- Manually update `.env`:
```
PERPLEXITY_MODEL=sonar
```
2. **Verify API Key**
```bash
python test_credentials.py
```
3. **Check API Credits**
- Go to: https://www.perplexity.ai/settings/api
- Verify your account has credits
- Check API key is active
### 3. Perplexity API 401 Unauthorized
**Error Output:**
```
✗ Perplexity API-Key ist ungültig (401 Unauthorized)
```
**Causes:**
- Invalid API key
- API key was revoked
- Typo in `.env` file
**Solution:**
1. **Generate New API Key**
```
1. Go to: https://www.perplexity.ai/settings/api
2. Create new API key
3. Copy the key (starts with pplx-)
4. Update .env:
PERPLEXITY_API_KEY=pplx-your_new_key_here
```
2. **Verify No Extra Spaces**
- Check `.env` file has no spaces around the `=` sign
- Format: `PERPLEXITY_API_KEY=pplx-abc123` (no spaces)
### 4. Bot Doesn't Respond in Chat
**Symptoms:**
- Bot connects successfully
- Bot joins channel
- But doesn't respond to mentions
**Checklist:**
1. **Verify Bot is Mentioned Correctly**
```
@Eugen how are you?
✓ Eugen: tell me about WoW
✓ Eugen, what's new?
✗ eugen (lowercase doesn't work)
```
2. **Check Debug Logs**
```bash
tail -f logs/eugen.log
```
Look for:
- `Mention detected from {user}`
- `API call to Perplexity`
- Any error messages
3. **Enable Debug Mode**
```
DEBUG_MODE=true
```
Restart the bot and check logs again
4. **Test Credentials**
```bash
python test_credentials.py
```
### 5. Connection Reset by Peer
**Error Output:**
```
IRC EVENT: disconnect | Args: ['Connection reset by peer']
```
**Causes:**
- Network interruption
- Firewall blocking port 6667
- Invalid authentication (see #1)
**Solution:**
1. **Check Firewall**
- Allow outbound connections on port 6667
- Try temporarily disabling firewall to test
2. **Verify Internet Connection**
```bash
ping irc.chat.twitch.tv
```
3. **Check OAuth Token** (most common cause)
```bash
python test_credentials.py
```
### 6. Rate Limiting / API Quota Exceeded
**Error Output:**
```
429 Too Many Requests
```
**Causes:**
- Too many API calls in short time
- Perplexity API quota exceeded
**Solution:**
1. **Check API Usage**
- Go to: https://www.perplexity.ai/settings/api
- View usage and limits
2. **Reduce Request Frequency**
- Consider implementing cooldowns
- Limit responses to specific users
3. **Wait and Retry**
- Wait a few minutes
- Restart the bot
---
## Diagnostic Commands
### Check Configuration
```bash
cat .env
```
### View Recent Logs
```bash
tail -n 50 logs/eugen.log
```
### View API Debug Logs
```bash
tail -n 50 logs/api_debug.log
```
### Test Credentials
```bash
python test_credentials.py
```
### Run Setup Wizard Again
```bash
python setup_wizard.py
```
---
## Getting Help
### Before Asking for Help
1. Run `python test_credentials.py`
2. Check `logs/eugen.log`
3. Enable `DEBUG_MODE=true` and restart
4. Review this troubleshooting guide
### Information to Include
When reporting issues, include:
- Error messages from logs
- Output of `python test_credentials.py`
- Contents of `.env` (REDACT secrets!)
- Python version: `python --version`
- OS: Windows/Linux/Mac
### Resources
- **GitHub Issues**: https://github.com/Kenearos/KI-Chat-Bot-Eugen/issues
- **Twitch Token Generator**: https://twitchtokengenerator.com
- **Perplexity API**: https://www.perplexity.ai/settings/api
---
## Quick Reference
### File Locations
- Configuration: `.env`
- Main log: `logs/eugen.log`
- API debug: `logs/api_debug.log`
- Conversations: `data/conversations/`
### Required Credentials
- Twitch OAuth Token (starts with `oauth:`)
- Twitch Bot Nickname (must match token account)
- Twitch Channel (starts with `#`)
- Perplexity API Key (starts with `pplx-`)
### Testing Tools
- `python setup_wizard.py` - Interactive setup
- `python test_credentials.py` - Validate credentials
- `python chatbot.py` - Run the bot

View file

@ -69,20 +69,47 @@ async def validate_twitch_token(token, bot_nickname):
try:
print_info("Validiere Twitch-Verbindung...")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(5)
sock.connect(('irc.chat.twitch.tv', 6667))
sock.settimeout(10)
# Connect
try:
sock.connect(('irc.chat.twitch.tv', 6667))
except socket.timeout:
print_warning("Verbindung zu Twitch IRC hat zu lange gedauert")
print_info("Prüfe deine Internetverbindung und Firewall-Einstellungen")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return True
# Send authentication
sock.send(f"PASS {token}\r\n".encode())
sock.send(f"NICK {bot_nickname}\r\n".encode())
response = sock.recv(1024).decode()
# Receive response
response = sock.recv(2048).decode()
if "Login authentication failed" in response:
print_error("Twitch OAuth Token ist ungültig!")
print_info("\nMögliche Gründe:")
print(f" • Token ist abgelaufen oder ungültig")
print(f" • Token passt nicht zum Bot-Namen '{bot_nickname}'")
print(f" • Account ist gesperrt oder eingeschränkt")
print_info("\nLösung:")
print(f" → Gehe zu: https://twitchtokengenerator.com")
print(f" → Stelle sicher, dass du als '{bot_nickname}' eingeloggt bist")
print(f" → Generiere einen neuen 'Bot Chat Token'")
return False
print_success("Twitch-Verbindung erfolgreich!")
if ":tmi.twitch.tv 001" in response or "Welcome" in response:
print_success("Twitch-Verbindung erfolgreich!")
return True
# Ambiguous - probably OK
if "authentication failed" not in response.lower():
print_success("Twitch-Verbindung scheinbar erfolgreich (kein Fehler erkannt)")
return True
print_warning(f"Unerwartete Antwort von Twitch IRC")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return True
except Exception as e:
@ -93,8 +120,8 @@ async def validate_twitch_token(token, bot_nickname):
async def validate_perplexity_key(api_key, model="sonar-pro"):
"""
Validate Perplexity API key with test request
Validate Perplexity API key with test request and model fallback
Note: Validation uses the specified model (default: sonar-pro).
If your API key doesn't have access to this model, validation may fail
even with a valid key for other models.
@ -104,40 +131,73 @@ async def validate_perplexity_key(api_key, model="sonar-pro"):
model (str): Model to test with (defaults to sonar-pro)
Returns:
tuple: (bool success, bool should_retry) - success indicates if validation passed,
should_retry indicates if user should be prompted to retry
tuple: (bool success, bool should_retry, str recommended_model)
success indicates if validation passed,
should_retry indicates if user should be prompted to retry,
recommended_model is the working model if different from requested
"""
try:
print_info(f"Validiere Perplexity API-Key mit Modell '{model}'...")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(
"https://api.perplexity.ai/chat/completions",
json={
"model": model,
"messages": [{"role": "user", "content": "test"}],
"max_tokens": 10
},
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
)
# Test with multiple models
models_to_test = [model]
if model != "sonar":
models_to_test.append("sonar")
if response.status_code == 200:
print_success("Perplexity API-Key ist gültig!")
return (True, False)
elif response.status_code == 401:
print_error("Perplexity API-Key ist ungültig!")
return (False, True)
else:
print_warning(f"Unerwartete Antwort: {response.status_code}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False)
for test_model in models_to_test:
try:
print_info(f"Validiere Perplexity API-Key mit Modell '{test_model}'...")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(
"https://api.perplexity.ai/chat/completions",
json={
"model": test_model,
"messages": [{"role": "user", "content": "test"}],
"max_tokens": 10
},
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
)
except Exception as e:
print_warning(f"Konnte Perplexity API nicht testen: {e}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False)
if response.status_code == 200:
print_success(f"Perplexity API-Key ist gültig mit Modell '{test_model}'!")
if test_model != model:
print_warning(f"Hinweis: Modell '{model}' nicht verfügbar, verwende '{test_model}'")
return (True, False, test_model)
elif response.status_code == 401:
print_error("Perplexity API-Key ist ungültig (401 Unauthorized)!")
print_info("Bitte überprüfe deinen API-Key auf: https://www.perplexity.ai/settings/api")
return (False, True, None)
elif response.status_code == 400:
try:
error_data = response.json()
error_msg = error_data.get("error", {}).get("message", "Unbekannter Fehler")
# Check if model access issue
if "model" in error_msg.lower() and test_model != models_to_test[-1]:
print_warning(f"Modell '{test_model}' nicht verfügbar: {error_msg}")
print_info("Versuche Fallback-Modell...")
continue
else:
print_warning(f"400 Fehler: {error_msg}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False, model)
except:
print_warning(f"Unerwartete Antwort: {response.status_code}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False, model)
else:
print_warning(f"Unerwartete Antwort: {response.status_code}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False, model)
except Exception as e:
print_warning(f"Konnte Perplexity API nicht testen: {e}")
print_info("Fahre trotzdem fort - bitte später manuell prüfen!")
return (True, False, model)
# All models failed
print_error("Alle Modelle fehlgeschlagen!")
return (False, True, None)
def create_env_file(config):
@ -279,14 +339,17 @@ async def run_wizard():
print(" → Kopiere den Key (beginnt mit 'pplx-...')")
print()
recommended_model = "sonar-pro"
while True:
api_key = get_input("Perplexity API Key", secret=True, required=True)
config['PERPLEXITY_API_KEY'] = api_key
success, should_retry = await validate_perplexity_key(api_key)
success, should_retry, working_model = await validate_perplexity_key(api_key, "sonar-pro")
if success:
if working_model:
recommended_model = working_model
break
if should_retry:
retry = input("\nErneut versuchen? (j/n): ")
if retry.lower() != 'j':
@ -302,7 +365,7 @@ async def run_wizard():
if advanced:
config['PERPLEXITY_MODEL'] = get_input(
"Perplexity Modell",
default="sonar-pro"
default=recommended_model
)
config['MAX_TOKENS'] = get_input(
"Max Tokens pro Antwort",
@ -317,7 +380,7 @@ async def run_wizard():
default="1"
)
else:
config['PERPLEXITY_MODEL'] = "sonar-pro"
config['PERPLEXITY_MODEL'] = recommended_model
config['MAX_TOKENS'] = "450"
config['DEBUG_MODE'] = "false"
config['CONTEXT_RETENTION_HOURS'] = "1"

336
test_credentials.py Normal file
View file

@ -0,0 +1,336 @@
"""
Credential Testing Utility for Eugen Bot
Tests and validates Twitch OAuth tokens and Perplexity API keys
"""
import asyncio
import socket
import sys
import os
import httpx
from dotenv import load_dotenv
class Colors:
"""ANSI color codes"""
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
def print_header(text):
"""Print colored header"""
print(f"\n{Colors.HEADER}{Colors.BOLD}{'='*70}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{text.center(70)}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{'='*70}{Colors.ENDC}\n")
def print_success(text):
"""Print success message"""
print(f"{Colors.OKGREEN}{text}{Colors.ENDC}")
def print_error(text):
"""Print error message"""
print(f"{Colors.FAIL}{text}{Colors.ENDC}")
def print_info(text):
"""Print info message"""
print(f"{Colors.OKCYAN} {text}{Colors.ENDC}")
def print_warning(text):
"""Print warning message"""
print(f"{Colors.WARNING}{text}{Colors.ENDC}")
async def test_twitch_token(token, nickname):
"""
Test Twitch OAuth token with detailed diagnostics
Args:
token (str): OAuth token
nickname (str): Bot nickname
Returns:
bool: True if valid
"""
print_header("TESTING TWITCH CREDENTIALS")
# Check token format
if not token:
print_error("Token is empty!")
print_info("Get a token from: https://twitchtokengenerator.com")
return False
if not token.startswith("oauth:"):
print_warning(f"Token doesn't start with 'oauth:' (got: {token[:10]}...)")
print_info("Token should look like: oauth:abcd1234...")
return False
print_info(f"Token format: ✓ Starts with 'oauth:'")
print_info(f"Token length: {len(token)} characters")
print_info(f"Bot nickname: {nickname}")
# Test IRC connection
print_info("\nConnecting to Twitch IRC (irc.chat.twitch.tv:6667)...")
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(10)
# Connect
try:
sock.connect(('irc.chat.twitch.tv', 6667))
print_success("Connected to IRC server")
except socket.timeout:
print_error("Connection timed out!")
print_info("Check your internet connection and firewall settings")
return False
except Exception as e:
print_error(f"Connection failed: {e}")
return False
# Send authentication
print_info("Sending authentication...")
sock.send(f"PASS {token}\r\n".encode())
sock.send(f"NICK {nickname}\r\n".encode())
# Wait for response
response = ""
try:
response = sock.recv(2048).decode()
except socket.timeout:
print_error("No response from server (timeout)")
return False
# Parse response
print_info(f"\nServer response received ({len(response)} bytes)")
if "Login authentication failed" in response:
print_error("AUTHENTICATION FAILED!")
print_info("\nPossible reasons:")
print(f" 1. Token is expired or invalid")
print(f" 2. Token doesn't match the bot nickname '{nickname}'")
print(f" 3. Account that generated the token is banned/restricted")
print_info("\nHow to fix:")
print(f" → Go to: https://twitchtokengenerator.com")
print(f" → Make sure you're logged into Twitch as '{nickname}'")
print(f" → Generate a new 'Bot Chat Token'")
print(f" → Update TWITCH_OAUTH_TOKEN in .env")
return False
if ":tmi.twitch.tv 001" in response or "Welcome" in response:
print_success("AUTHENTICATION SUCCESSFUL!")
print_info(f"Bot '{nickname}' can connect to Twitch IRC")
return True
# Ambiguous response
print_warning("Received unexpected response:")
for line in response.split('\r\n'):
if line:
print(f" {line[:100]}")
# If we got this far without clear failure, consider it success
if "authentication failed" not in response.lower():
print_success("Authentication appears successful (no error detected)")
return True
return False
except Exception as e:
print_error(f"Error testing Twitch token: {e}")
import traceback
traceback.print_exc()
return False
async def test_perplexity_key(api_key, model="sonar-pro"):
"""
Test Perplexity API key with model fallback
Args:
api_key (str): Perplexity API key
model (str): Model to test (will fallback to 'sonar' if needed)
Returns:
tuple: (success, recommended_model)
"""
print_header("TESTING PERPLEXITY API")
# Check key format
if not api_key:
print_error("API key is empty!")
print_info("Get a key from: https://www.perplexity.ai/settings/api")
return False, None
if not api_key.startswith("pplx-"):
print_warning(f"API key doesn't start with 'pplx-' (got: {api_key[:10]}...)")
print_info("Key should look like: pplx-abc123...")
print_info(f"API key format: Starts with '{api_key[:5]}...'")
print_info(f"API key length: {len(api_key)} characters")
# Test with different models
models_to_test = [model]
if model != "sonar":
models_to_test.append("sonar")
for test_model in models_to_test:
print_info(f"\nTesting with model: {test_model}")
try:
async with httpx.AsyncClient(timeout=15.0) as client:
response = await client.post(
"https://api.perplexity.ai/chat/completions",
json={
"model": test_model,
"messages": [{"role": "user", "content": "Say 'test successful' and nothing else"}],
"max_tokens": 10
},
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
)
print_info(f"Response status: {response.status_code}")
if response.status_code == 200:
print_success(f"API KEY VALID with model '{test_model}'!")
# Try to parse response
try:
data = response.json()
if "choices" in data and len(data["choices"]) > 0:
content = data["choices"][0]["message"]["content"]
print_info(f"Test response: '{content}'")
except:
pass
return True, test_model
elif response.status_code == 401:
print_error("API key is INVALID (401 Unauthorized)")
print_info("\nHow to fix:")
print(f" → Go to: https://www.perplexity.ai/settings/api")
print(f" → Generate a new API key")
print(f" → Update PERPLEXITY_API_KEY in .env")
return False, None
elif response.status_code == 400:
try:
error_data = response.json()
error_msg = error_data.get("error", {}).get("message", "Unknown error")
print_warning(f"400 Bad Request: {error_msg}")
# Check if it's a model access issue
if "model" in error_msg.lower():
print_info(f"Model '{test_model}' not available on your plan")
if test_model != models_to_test[-1]:
print_info("Trying fallback model...")
continue
else:
print_info(f"Error details: {error_msg}")
except:
print_warning(f"400 Bad Request (couldn't parse error)")
# If this was the last model, fail
if test_model == models_to_test[-1]:
print_error("All models failed!")
return False, None
elif response.status_code == 429:
print_error("Rate limited! Too many requests.")
print_info("Wait a few minutes and try again")
return False, None
else:
print_warning(f"Unexpected status code: {response.status_code}")
try:
print_info(f"Response: {response.text[:200]}")
except:
pass
# Try next model if available
if test_model != models_to_test[-1]:
continue
return False, None
except httpx.TimeoutException:
print_error("Request timed out!")
print_info("Check your internet connection")
return False, None
except Exception as e:
print_error(f"Error testing API: {e}")
import traceback
traceback.print_exc()
return False, None
return False, None
async def main():
"""Main test runner"""
print(f"""
{Colors.HEADER}{Colors.BOLD}
EUGEN BOT - CREDENTIAL VALIDATOR
Tests Twitch & Perplexity Credentials
{Colors.ENDC}
""")
# Load .env file
if not os.path.exists('.env'):
print_error("No .env file found!")
print_info("Please run: python setup_wizard.py")
sys.exit(1)
load_dotenv()
# Get credentials
twitch_token = os.getenv('TWITCH_OAUTH_TOKEN', '')
twitch_nickname = os.getenv('TWITCH_BOT_NICKNAME', '')
twitch_channel = os.getenv('TWITCH_CHANNEL', '')
perplexity_key = os.getenv('PERPLEXITY_API_KEY', '')
perplexity_model = os.getenv('PERPLEXITY_MODEL', 'sonar-pro')
print_info("Loaded configuration from .env:")
print(f" • Bot Nickname: {twitch_nickname}")
print(f" • Channel: {twitch_channel}")
print(f" • Model: {perplexity_model}")
# Test credentials
results = {}
# Test Twitch
results['twitch'] = await test_twitch_token(twitch_token, twitch_nickname)
# Test Perplexity
results['perplexity'], recommended_model = await test_perplexity_key(perplexity_key, perplexity_model)
# Final summary
print_header("VALIDATION SUMMARY")
print(f"Twitch IRC: {'✓ PASS' if results['twitch'] else '✗ FAIL'}")
print(f"Perplexity API: {'✓ PASS' if results['perplexity'] else '✗ FAIL'}")
if recommended_model and recommended_model != perplexity_model:
print_warning(f"\nRecommendation: Update PERPLEXITY_MODEL to '{recommended_model}' in .env")
if all(results.values()):
print_success("\n🎉 All credentials valid! Bot is ready to run.")
print_info("Start the bot with: python chatbot.py")
sys.exit(0)
else:
print_error("\n❌ Some credentials are invalid. Please fix and re-test.")
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())