email testing

This commit is contained in:
2026-01-26 12:55:56 +01:00
parent e64465a7e6
commit f8684077a2
7 changed files with 447 additions and 12 deletions

View File

@@ -1,11 +1,13 @@
# OpenRouter API Configuration
OPENROUTER_API_KEY=your_api_key_here
# No quotes needed - just paste your key directly
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional: Your site info for OpenRouter rankings
OPENROUTER_SITE_URL=https://your-site.com
OPENROUTER_SITE_NAME=YourSiteName
# SMTP Credentials for your mail server
# No quotes needed - even if your password contains special characters
SMTP_USERNAME=your-email@yourdomain.com
SMTP_PASSWORD=your-smtp-password

161
MODELS.md Normal file
View File

@@ -0,0 +1,161 @@
# OpenRouter Model Reference
Quick reference for choosing the right AI model for News Agent.
## Recommended Models
### Best Overall: `google/gemini-flash-1.5-8b`
- **Cost:** ~$0.05-0.15/day
- **Quality:** Excellent
- **Speed:** Very fast
- **Best for:** Production use, daily digests
### Best Free: `google/gemini-2.0-flash-exp:free`
- **Cost:** FREE
- **Quality:** Good (experimental)
- **Speed:** Fast
- **Best for:** Testing, low-budget setups
- **Note:** Experimental, may change
### Budget Option: `meta-llama/llama-3.1-8b-instruct:free`
- **Cost:** FREE
- **Quality:** Decent
- **Speed:** Moderate
- **Best for:** Testing, development
### High Quality: `anthropic/claude-3.5-haiku`
- **Cost:** ~$0.10-0.25/day
- **Quality:** Excellent
- **Speed:** Fast
- **Best for:** When quality matters most
### OpenAI Option: `openai/gpt-4o-mini`
- **Cost:** ~$0.08-0.20/day
- **Quality:** Very good
- **Speed:** Fast
- **Best for:** Balanced quality/cost
## How to Change Model
Edit `config.yaml`:
```yaml
ai:
model: "google/gemini-flash-1.5-8b" # Change this line
```
## Full Model List
See all available models at: https://openrouter.ai/models
Filter by:
- **Free models** - Search for `:free` suffix
- **Context length** - Important for long articles
- **Supported features** - JSON mode, function calling, etc.
## Cost Comparison (Daily Estimates)
Based on processing ~50 articles/day with 15 summaries:
| Model | Daily Cost | Monthly Cost | Quality |
|-------|-----------|--------------|---------|
| `google/gemini-2.0-flash-exp:free` | $0.00 | $0.00 | Good |
| `meta-llama/llama-3.1-8b-instruct:free` | $0.00 | $0.00 | Decent |
| `google/gemini-flash-1.5-8b` | $0.05-0.15 | $1.50-4.50 | Excellent |
| `openai/gpt-4o-mini` | $0.08-0.20 | $2.40-6.00 | Very Good |
| `anthropic/claude-3.5-haiku` | $0.10-0.25 | $3.00-7.50 | Excellent |
| `openai/gpt-4o` | $0.50-1.50 | $15-45 | Outstanding |
*Costs vary based on article length and quantity*
## Testing a New Model
1. Update `config.yaml`:
```yaml
ai:
model: "new-model-name"
```
2. Run a test:
```bash
source .venv/bin/activate
python -m src.main
```
3. Check quality of summaries in the email
4. Monitor costs at: https://openrouter.ai/activity
## Model Selection Tips
### Choose FREE models if:
- You're testing the system
- Cost is a major concern
- Article quality/accuracy is less critical
### Choose PAID models if:
- You want best quality summaries
- You need reliable daily digests
- You value accurate relevance scoring
### Performance vs Cost:
- **Gemini Flash 1.5-8b** - Best balance
- **Claude Haiku** - Best quality for cost
- **GPT-4o-mini** - Good all-rounder
- **Free models** - Testing/development
## Troubleshooting
### Error: "No endpoints found for [model]"
The model name is incorrect or not available on OpenRouter.
**Solution:**
1. Check model name at: https://openrouter.ai/models
2. Copy exact model ID (e.g., `google/gemini-flash-1.5-8b`)
3. Update `config.yaml`
4. Restart the service
### Model Seems Slow
Some models are slower than others.
**Solutions:**
- Try `google/gemini-flash-1.5-8b` (fastest)
- Reduce `max_articles` in config (process fewer articles)
- Use cheaper/faster models for filtering, premium for summarization
### Poor Summary Quality
The model might not be good at summarization.
**Solutions:**
- Try `anthropic/claude-3.5-haiku` (excellent summarization)
- Adjust prompts in `src/ai/prompts.py`
- Increase temperature for more creative summaries
- Try different models
### High Costs
You're using an expensive model or processing too many articles.
**Solutions:**
1. Switch to cheaper model (Gemini Flash or free options)
2. Increase `min_score` to filter more aggressively
3. Reduce `max_articles` limit
4. Monitor usage: https://openrouter.ai/activity
## Advanced: Using Different Models for Different Tasks
You could modify the code to use:
- **Fast/cheap model** for filtering (scoring articles)
- **High-quality model** for summarization
Edit `src/main.py` to instantiate different clients for different tasks.
## Need Help?
- **Model pricing:** https://openrouter.ai/models (click model for details)
- **API docs:** https://openrouter.ai/docs
- **Check costs:** https://openrouter.ai/activity
- **Model comparison:** Test different models and compare results

View File

@@ -102,7 +102,7 @@ email:
- **SendGrid**: `smtp.sendgrid.net:587`, use API key as password
Optionally adjust:
- AI model (default: `google/gemini-flash-1.5` - fast and cheap)
- AI model (default: `google/gemini-flash-1.5-8b` - fast and cheap)
- Filtering threshold (default: 6.5/10)
- Max articles per digest (default: 15)
- RSS sources (add/remove feeds)
@@ -204,11 +204,15 @@ sources:
### AI Configuration
**Models** (from cheap to expensive):
- `google/gemini-flash-1.5` - Fast, cheap, good quality (recommended)
- `meta-llama/llama-3.1-8b-instruct` - Very cheap
- `google/gemini-flash-1.5-8b` - Fast, cheap, good quality (recommended)
- `google/gemini-2.0-flash-exp:free` - Free, experimental (good for testing)
- `meta-llama/llama-3.1-8b-instruct:free` - Free, decent quality
- `anthropic/claude-3.5-haiku` - Better quality, slightly more expensive
- `openai/gpt-4o-mini` - Good quality, moderate price
See **[MODELS.md](MODELS.md)** for detailed comparison and selection guide.
Full list at: https://openrouter.ai/models
**Filtering:**
```yaml
ai:
@@ -263,9 +267,16 @@ systemctl --user restart news-agent.timer
### API Errors
**Error: "No endpoints found for [model]"**
- The model name is incorrect
- Check correct model names in `MODELS.md`
- Update `config.yaml` with correct model ID
**Other API errors:**
1. **Verify API key in `.env`**
2. **Check OpenRouter credit balance:** https://openrouter.ai/credits
3. **Check rate limits in logs**
4. **Try a different model** (see `MODELS.md`)
### Service Not Running
@@ -290,12 +301,16 @@ python -m src.main
## Cost Estimation
Using `google/gemini-flash-1.5` (recommended):
Using `google/gemini-flash-1.5-8b` (recommended):
- **Daily:** ~$0.05-0.15 (varies by article count)
- **Monthly:** ~$1.50-4.50
- **Yearly:** ~$18-54
**Free Options:**
- `google/gemini-2.0-flash-exp:free` - Completely free (experimental)
- `meta-llama/llama-3.1-8b-instruct:free` - Completely free
Factors affecting cost:
- Number of new articles
- Content length

View File

@@ -23,7 +23,21 @@ SMTP_USERNAME=your-email@yourdomain.com
SMTP_PASSWORD=your-password-or-app-password
```
**Security Note:** The `.env` file is gitignored and should never be committed to version control.
**Important Notes:**
- **NO quotes needed** - Values should be plain text without quotes
- **Special characters are OK** - Passwords with `!@#$%` etc. work fine
- **Security:** The `.env` file is gitignored and should never be committed to version control
**Examples:**
```env
# Correct - no quotes
SMTP_USERNAME=admin@example.com
SMTP_PASSWORD=P@ssw0rd!123
# Wrong - don't use quotes
SMTP_USERNAME="admin@example.com" # ❌
SMTP_PASSWORD='P@ssw0rd!123' # ❌
```
### 2. Edit `config.yaml`

View File

@@ -61,9 +61,9 @@ sources:
url: "https://www.engadget.com/rss.xml"
category: "gadgets"
- name: "AnandTech"
url: "https://www.anandtech.com/rss/"
category: "gadgets"
#- name: "AnandTech"
# url: "https://www.anandtech.com/rss/"
# category: "gadgets"
- name: "Tom's Hardware"
url: "https://www.tomshardware.com/feeds/all"
@@ -72,10 +72,12 @@ sources:
ai:
provider: "openrouter"
base_url: "https://openrouter.ai/api/v1"
model: "google/gemini-flash-1.5"
# Alternative models:
model: "google/gemini-flash-1.5-8b"
# Alternative models (see https://openrouter.ai/models for full list):
# - "google/gemini-2.0-flash-exp:free" (free, experimental)
# - "anthropic/claude-3.5-haiku" (better quality, slightly more expensive)
# - "meta-llama/llama-3.1-8b-instruct" (very cheap)
# - "meta-llama/llama-3.1-8b-instruct:free" (free, good quality)
# - "openai/gpt-4o-mini" (good quality, moderate price)
filtering:
enabled: true

109
src/test_email_simple.py Normal file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""Simple email test - run with: python -m src.test_email_simple"""
from datetime import datetime
from .config import get_config
from .logger import setup_logger
from .email.sender import EmailSender
def main():
"""Send a test email"""
setup_logger()
config = get_config()
print("\n" + "=" * 60)
print("Testing Email Configuration")
print("=" * 60)
print(f"\nSMTP Server: {config.email.smtp.host}:{config.email.smtp.port}")
print(f"TLS: {config.email.smtp.use_tls}")
print(f"SSL: {config.email.smtp.use_ssl}")
print(f"From: {config.email.from_}")
print(f"To: {config.email.to}")
print(f"Username: {config.env.smtp_username or '(not set)'}")
print(f"Password: {'***' if config.env.smtp_password else '(not set)'}")
print("\nSending test email...")
# Create test email content
subject = "News Agent Test Email"
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; padding: 20px; }}
.header {{ background-color: #2563eb; color: white; padding: 20px; border-radius: 8px; }}
.content {{ margin-top: 20px; line-height: 1.6; }}
.success {{ color: #16a34a; font-weight: bold; }}
</style>
</head>
<body>
<div class="header">
<h1>✓ News Agent Email Test</h1>
</div>
<div class="content">
<p class="success">Congratulations! Your email configuration is working correctly.</p>
<p><strong>Test Details:</strong></p>
<ul>
<li>Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</li>
<li>SMTP Server: {config.email.smtp.host}:{config.email.smtp.port}</li>
<li>Encryption: {"TLS" if config.email.smtp.use_tls else "SSL" if config.email.smtp.use_ssl else "None"}</li>
</ul>
<p>Your News Agent is now ready to send daily digests!</p>
<hr>
<p style="color: #6b7280; font-size: 12px;">
This is a test email from News Agent. If you received this,
your SMTP configuration is correct and you should start receiving
daily news digests.
</p>
</div>
</body>
</html>
"""
text_content = f"""
News Agent Email Test
=====================
✓ Congratulations! Your email configuration is working correctly.
Test Details:
- Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
- SMTP Server: {config.email.smtp.host}:{config.email.smtp.port}
- Encryption: {"TLS" if config.email.smtp.use_tls else "SSL" if config.email.smtp.use_ssl else "None"}
Your News Agent is now ready to send daily digests!
---
This is a test email from News Agent. If you received this,
your SMTP configuration is correct and you should start receiving
daily news digests.
"""
# Send email
sender = EmailSender()
success = sender.send(subject, html_content, text_content)
print("\n" + "=" * 60)
if success:
print("✓ SUCCESS! Test email sent successfully!")
print(f"✓ Check your inbox: {config.email.to}")
else:
print("✗ FAILED! Email could not be sent.")
print("✗ Check the error messages above.")
print("\nTroubleshooting steps:")
print("1. Verify SMTP credentials in .env file")
print("2. Check SMTP server settings in config.yaml")
print("3. Review logs: cat data/logs/news-agent.log")
print("4. See SMTP_CONFIG.md for detailed troubleshooting")
print("=" * 60 + "\n")
if __name__ == "__main__":
main()

132
test_email.py Normal file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python3
"""Quick email sending test script"""
import sys
from datetime import datetime
# Add src to path
sys.path.insert(0, "src")
from src.config import get_config
from src.logger import setup_logger
from src.email.sender import EmailSender
def test_email():
"""Send a test email"""
setup_logger()
config = get_config()
print("\n" + "=" * 60)
print("Testing Email Configuration")
print("=" * 60)
print(f"\nSMTP Server: {config.email.smtp.host}:{config.email.smtp.port}")
print(f"TLS: {config.email.smtp.use_tls}")
print(f"SSL: {config.email.smtp.use_ssl}")
print(f"From: {config.email.from_}")
print(f"To: {config.email.to}")
print(f"Username: {config.env.smtp_username or '(not set)'}")
print(f"Password: {'***' if config.env.smtp_password else '(not set)'}")
print("\nSending test email...")
# Create test email content
subject = "News Agent Test Email"
html_content = (
"""
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.header { background-color: #2563eb; color: white; padding: 20px; border-radius: 8px; }
.content { margin-top: 20px; line-height: 1.6; }
.success { color: #16a34a; font-weight: bold; }
</style>
</head>
<body>
<div class="header">
<h1>✓ News Agent Email Test</h1>
</div>
<div class="content">
<p class="success">Congratulations! Your email configuration is working correctly.</p>
<p><strong>Test Details:</strong></p>
<ul>
<li>Date: """
+ datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ """</li>
<li>SMTP Server: """
+ f"{config.email.smtp.host}:{config.email.smtp.port}"
+ """</li>
<li>Encryption: """
+ ("TLS" if config.email.smtp.use_tls else "SSL" if config.email.smtp.use_ssl else "None")
+ """</li>
</ul>
<p>Your News Agent is now ready to send daily digests!</p>
<hr>
<p style="color: #6b7280; font-size: 12px;">
This is a test email from News Agent. If you received this,
your SMTP configuration is correct and you should start receiving
daily news digests.
</p>
</div>
</body>
</html>
"""
)
text_content = f"""
News Agent Email Test
=====================
✓ Congratulations! Your email configuration is working correctly.
Test Details:
- Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
- SMTP Server: {config.email.smtp.host}:{config.email.smtp.port}
- Encryption: {"TLS" if config.email.smtp.use_tls else "SSL" if config.email.smtp.use_ssl else "None"}
Your News Agent is now ready to send daily digests!
---
This is a test email from News Agent. If you received this,
your SMTP configuration is correct and you should start receiving
daily news digests.
"""
# Send email
sender = EmailSender()
success = sender.send(subject, html_content, text_content)
print("\n" + "=" * 60)
if success:
print("✓ SUCCESS! Test email sent successfully!")
print(f"✓ Check your inbox: {config.email.to}")
else:
print("✗ FAILED! Email could not be sent.")
print("✗ Check the error messages above.")
print("\nTroubleshooting steps:")
print("1. Verify SMTP credentials in .env file")
print("2. Check SMTP server settings in config.yaml")
print("3. Review logs: cat data/logs/news-agent.log")
print("4. See SMTP_CONFIG.md for detailed troubleshooting")
print("=" * 60 + "\n")
return success
if __name__ == "__main__":
try:
success = test_email()
sys.exit(0 if success else 1)
except Exception as e:
print(f"\n✗ ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)