Implement GuardDen Discord moderation bot

Features:
- Core moderation: warn, kick, ban, timeout, strike system
- Automod: banned words filter, scam detection, anti-spam, link filtering
- AI moderation: Claude/OpenAI integration, NSFW detection, phishing analysis
- Verification system: button, captcha, math, emoji challenges
- Rate limiting system with configurable scopes
- Event logging: joins, leaves, message edits/deletes, voice activity
- Per-guild configuration with caching
- Docker deployment support

Bug fixes applied:
- Fixed await on session.delete() in guild_config.py
- Fixed memory leak in AI moderation message tracking (use deque)
- Added error handling to bot shutdown
- Added error handling to timeout command
- Removed unused Literal import
- Added prefix validation
- Added image analysis limit (3 per message)
- Fixed test mock for SQLAlchemy model
This commit is contained in:
2026-01-16 19:27:48 +01:00
parent ffe42b6d51
commit 4e16777f25
45 changed files with 5802 additions and 1 deletions

View File

@@ -0,0 +1,67 @@
"""Factory for creating AI providers."""
import logging
from typing import Literal
from guardden.services.ai.base import AIProvider
logger = logging.getLogger(__name__)
class NullProvider(AIProvider):
"""Null provider that does nothing (for when AI is disabled)."""
async def moderate_text(self, content, context=None, sensitivity=50):
from guardden.services.ai.base import ModerationResult
return ModerationResult()
async def analyze_image(self, image_url, sensitivity=50):
from guardden.services.ai.base import ImageAnalysisResult
return ImageAnalysisResult()
async def analyze_phishing(self, url, message_content=None):
from guardden.services.ai.base import PhishingAnalysisResult
return PhishingAnalysisResult()
async def close(self):
pass
def create_ai_provider(
provider: Literal["anthropic", "openai", "none"],
api_key: str | None = None,
) -> AIProvider:
"""
Create an AI provider instance.
Args:
provider: The provider type to create
api_key: API key for the provider
Returns:
AIProvider instance
Raises:
ValueError: If provider is unknown or API key is missing
"""
if provider == "none":
logger.info("AI moderation disabled")
return NullProvider()
if not api_key:
raise ValueError(f"API key required for {provider} provider")
if provider == "anthropic":
from guardden.services.ai.anthropic_provider import AnthropicProvider
return AnthropicProvider(api_key)
if provider == "openai":
from guardden.services.ai.openai_provider import OpenAIProvider
return OpenAIProvider(api_key)
raise ValueError(f"Unknown AI provider: {provider}")