FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
"""Task F: alert summarization. Produces the concise, non-exaggerated text
|
|
shown in the alert/email/SMS (Phase 8) - short by design, honest about
|
|
confidence, no hype language.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.analysis.llm.base import LLMProvider
|
|
from app.prompts.base import build_user_prompt
|
|
|
|
SYSTEM_PROMPT = (
|
|
"You write concise, factual alert summaries for a competitive intelligence tool. Never "
|
|
"exaggerate. State what changed, cite the evidence type, and note the confidence level "
|
|
"plainly. The title must be under 100 characters and must not use hype words like "
|
|
"'huge', 'massive', or 'game-changing'."
|
|
)
|
|
|
|
|
|
class AlertSummary(BaseModel):
|
|
title: str = Field(max_length=100)
|
|
summary: str
|
|
why_it_matters: str
|
|
|
|
|
|
async def summarize_alert(
|
|
llm: LLMProvider,
|
|
*,
|
|
company_name: str,
|
|
change_type: str,
|
|
change_summary: str,
|
|
severity: str,
|
|
confidence: float,
|
|
evidence_snippets: list[str],
|
|
) -> AlertSummary:
|
|
evidence = {
|
|
"company_name": company_name,
|
|
"change_type": change_type,
|
|
"change_summary": change_summary,
|
|
"severity": severity,
|
|
"confidence": confidence,
|
|
"evidence_snippets": evidence_snippets[:10],
|
|
}
|
|
user_prompt = build_user_prompt("Write a concise alert summary for this change.", evidence)
|
|
return await llm.generate_structured(SYSTEM_PROMPT, user_prompt, AlertSummary)
|