101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""Analysis tasks for VoIdea."""
|
|
|
|
import asyncio
|
|
import time
|
|
from functools import lru_cache
|
|
from uuid import uuid4
|
|
|
|
from sqlalchemy import select
|
|
|
|
from app.agents.models import AgentReport
|
|
from app.core.database import async_session_maker
|
|
from app.integrations.ai.prompt_loader import get_prompt_config
|
|
from app.models.idea import Idea
|
|
from app.tasks import celery_app
|
|
|
|
|
|
@lru_cache
|
|
def _get_fallback():
|
|
from app.integrations.ai.fallback import FallbackChain
|
|
|
|
return FallbackChain()
|
|
|
|
|
|
@celery_app.task(bind=True, max_retries=2, name="analyze_idea")
|
|
def analyze_idea(self, idea_id: str, role: str) -> dict:
|
|
"""Analyze an idea using AI fallback chain.
|
|
|
|
Args:
|
|
idea_id: UUID of the idea
|
|
role: Agent role (e.g. "coordinator", "business_analyst")
|
|
|
|
Returns:
|
|
Dict with analysis result
|
|
"""
|
|
return asyncio.run(_analyze_idea_async(idea_id, role, self.request.id))
|
|
|
|
|
|
async def _analyze_idea_async(idea_id: str, role: str, task_id: str) -> dict:
|
|
"""Async implementation of idea analysis."""
|
|
start = time.time()
|
|
report_id = str(uuid4())
|
|
|
|
fallback = _get_fallback()
|
|
|
|
async with async_session_maker() as db:
|
|
result = await db.execute(select(Idea).where(Idea.id == idea_id))
|
|
idea = result.scalar_one_or_none()
|
|
|
|
if not idea:
|
|
return {"status": "error", "error": "Idea not found"}
|
|
|
|
prompt_config = get_prompt_config(role)
|
|
if not prompt_config:
|
|
return {"status": "error", "error": f"No prompt config for role: {role}"}
|
|
|
|
system_prompt = prompt_config.get("system_prompt", "")
|
|
user_prompt = f"Проанализируй идею:\n\nНазвание: {idea.title}\n\nОписание: {idea.content}"
|
|
|
|
if idea.tags:
|
|
user_prompt += f"\n\nТеги: {', '.join(idea.tags)}"
|
|
|
|
full_prompt = f"{system_prompt}\n\n{user_prompt}"
|
|
|
|
ai_result = await fallback.analyze(
|
|
full_prompt,
|
|
temperature=prompt_config.get("temperature", 0.7),
|
|
max_tokens=prompt_config.get("max_tokens", 2000),
|
|
)
|
|
|
|
duration_ms = int((time.time() - start) * 1000)
|
|
|
|
report = AgentReport(
|
|
id=report_id,
|
|
agent_id=f"ai_{role}",
|
|
status="completed" if ai_result.success else "failed",
|
|
message=ai_result.content[:500] if ai_result.success else ai_result.error,
|
|
details={
|
|
"idea_id": idea_id,
|
|
"role": role,
|
|
"model": ai_result.model,
|
|
"provider": ai_result.provider,
|
|
"tokens_used": ai_result.tokens_used,
|
|
"task_id": task_id,
|
|
} | ({"full_content": ai_result.content} if ai_result.success else {}),
|
|
duration_ms=duration_ms,
|
|
success=ai_result.success,
|
|
errors=[] if ai_result.success else [ai_result.error],
|
|
context={"idea_title": idea.title, "role": role},
|
|
)
|
|
db.add(report)
|
|
await db.commit()
|
|
|
|
return {
|
|
"status": "completed" if ai_result.success else "failed",
|
|
"report_id": report_id,
|
|
"idea_id": idea_id,
|
|
"role": role,
|
|
"duration_ms": duration_ms,
|
|
"success": ai_result.success,
|
|
}
|