feat: Auto-adapt content to platform limits when creating posts

- Add adapt_with_ai() method to PlatformAdapter that uses DeepSeek
  to condense content when it exceeds platform character limits
- Add adapt_for_all_platforms_smart() for batch adaptation
- Modify create_post endpoint to auto-generate content_x, content_threads,
  content_instagram, content_facebook with adapted versions
- Modify update_post to re-adapt content when main content changes
- If content fits within limit, use as-is (no AI call)
- If content exceeds limit, AI condenses while preserving message
- Fallback to rule-based truncation if DeepSeek API unavailable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 21:20:04 +00:00
parent cf1e06bb11
commit 9008c5d945
2 changed files with 140 additions and 3 deletions

View File

@@ -369,6 +369,112 @@ Responde SOLO con el contenido adaptado, sin explicaciones."""
return prompt
# === Adaptación con IA ===
async def adapt_with_ai(
self,
content: str,
platform: str
) -> AdaptedContent:
"""
Adaptar contenido usando IA si excede el límite.
Si el contenido cabe en el límite, lo retorna tal cual.
Si excede, usa DeepSeek para condensar manteniendo el mensaje.
Args:
content: Contenido a adaptar
platform: Plataforma destino
Returns:
AdaptedContent con el contenido adaptado
"""
limits = self.get_limits(platform)
max_chars = limits.get("max_characters", 2000)
# Si cabe, solo aplicar formato básico
if len(content) <= max_chars:
return AdaptedContent(
content=content,
platform=platform,
original_content=content,
truncated=False,
hashtags_adjusted=False,
changes_made=[]
)
# Excede límite: usar IA para condensar
from openai import OpenAI
from app.core.config import settings
if not settings.DEEPSEEK_API_KEY:
# Fallback a adaptación por reglas si no hay API
return self.adapt(content, platform)
client = OpenAI(
api_key=settings.DEEPSEEK_API_KEY,
base_url=settings.DEEPSEEK_BASE_URL or "https://api.deepseek.com"
)
# Dejar margen de 10 chars para seguridad
target_chars = max_chars - 10
prompt = f"""Condensa este contenido a máximo {target_chars} caracteres para {platform}.
CONTENIDO ORIGINAL:
{content}
REGLAS:
- Máximo {target_chars} caracteres (incluyendo hashtags y espacios)
- Mantén la esencia y mensaje principal
- Conserva el call-to-action si existe
- Incluye hashtags relevantes (máximo {limits.get('max_hashtags', 2)})
- NO uses emojis a menos que estén en el original
- Tono profesional
Responde SOLO con el contenido adaptado, sin explicaciones."""
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=500
)
adapted_content = response.choices[0].message.content.strip()
return AdaptedContent(
content=adapted_content,
platform=platform,
original_content=content,
truncated=True,
hashtags_adjusted=False,
changes_made=[f"Contenido adaptado con IA: {len(content)}{len(adapted_content)} caracteres"]
)
async def adapt_for_all_platforms_smart(
self,
content: str,
platforms: List[str]
) -> Dict[str, str]:
"""
Adaptar contenido para múltiples plataformas usando IA cuando sea necesario.
Args:
content: Contenido base
platforms: Lista de plataformas
Returns:
Dict de plataforma -> contenido adaptado
"""
results = {}
for platform in platforms:
adapted = await self.adapt_with_ai(content, platform)
results[platform] = adapted.content
return results
# Instancia global
platform_adapter = PlatformAdapter()