feat: add EN/ES/RO language selector for AI pitch generation
- db.py: add `language` column to ai_queue; migration; queue_ai() accepts language param and re-queues with ON CONFLICT UPDATE so changing language works - main.py: batch and single assess endpoints accept `language` from request body - enricher.py: ai_worker_loop reads language column, passes to _assess_one() - replicate_ai.py: assess_domain() and _build_prompt() accept language param; OUTPUT LANGUAGE section injected into prompt so Gemini writes pitch/email in the requested language (EN/ES/RO) - index.html: flag dropdown (🇪🇸/🇬🇧/🇷🇴) next to AI Assess button; aiLang state default ES; language sent in all batch assessment requests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -328,19 +328,19 @@ async def worker_loop():
|
||||
|
||||
# ── AI assessment worker ──────────────────────────────────────────────────────
|
||||
|
||||
async def _assess_one(domain: str) -> None:
|
||||
async def _assess_one(domain: str, language: str = "ES") -> None:
|
||||
"""Process a single AI assessment — safe to call concurrently."""
|
||||
from app.replicate_ai import assess_domain as gemini_assess
|
||||
from app.site_analyzer import analyze_site
|
||||
|
||||
logger.info("AI: starting analysis for %s", domain)
|
||||
logger.info("AI: starting analysis for %s (lang=%s)", domain, language)
|
||||
try:
|
||||
# Hard 3-minute ceiling so stuck jobs never block the worker forever
|
||||
async with asyncio.timeout(180):
|
||||
analysis = await analyze_site(domain)
|
||||
logger.info("AI: site analyzed %s (reachable=%s, words=%s)",
|
||||
domain, analysis.get("reachable"), analysis.get("word_count"))
|
||||
assessment = await gemini_assess(analysis)
|
||||
assessment = await gemini_assess(analysis, language=language)
|
||||
logger.info("AI: Gemini done %s → quality=%s",
|
||||
domain, assessment.get("lead_quality"))
|
||||
await save_ai_assessment(domain, assessment, site_analysis=analysis)
|
||||
@@ -377,7 +377,7 @@ async def ai_worker_loop():
|
||||
try:
|
||||
async with aiosqlite.connect(SQLITE_PATH) as db:
|
||||
async with db.execute(
|
||||
"SELECT domain FROM ai_queue WHERE status='pending' LIMIT 5"
|
||||
"SELECT domain, COALESCE(language,'ES') FROM ai_queue WHERE status='pending' LIMIT 5"
|
||||
) as cur:
|
||||
rows = await cur.fetchall()
|
||||
if rows:
|
||||
@@ -399,7 +399,7 @@ async def ai_worker_loop():
|
||||
|
||||
# Run assessments concurrently (semaphore in replicate_ai enforces AI_CONCURRENCY)
|
||||
results = await asyncio.gather(
|
||||
*[_assess_one(r[0]) for r in rows],
|
||||
*[_assess_one(r[0], r[1]) for r in rows],
|
||||
return_exceptions=True,
|
||||
)
|
||||
for r, exc in zip(rows, results):
|
||||
|
||||
Reference in New Issue
Block a user