Files
saksham 1a4c80958f Initial commit: CI Agent competitive-intelligence monitoring app
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).
2026-08-05 10:48:20 -04:00

55 lines
2.0 KiB
Python

"""Task C: cross-source synthesis. Combines related signals from multiple
documents/changes into a conclusion (e.g. "hiring battery engineers" +
"filed a battery patent" + "announced a facility expansion" = "possible
battery manufacturing initiative"), always with alternative explanations and
an explicit accounting of what's still unknown.
"""
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 are a competitive intelligence analyst. Given a set of independently-extracted "
"signals about a company, identify conclusions that multiple signals point toward "
"together. Only draw a conclusion when the evidence actually supports it - state your "
"confidence honestly, list plausible alternative explanations, and note what evidence "
"would be needed to be more certain. Do not synthesize a conclusion from a single signal."
)
class SynthesizedConclusion(BaseModel):
conclusion: str
evidence_summary: list[str] = Field(default_factory=list)
source_count: int = Field(ge=0)
confidence: float = Field(ge=0.0, le=1.0)
alternative_explanations: list[str] = Field(default_factory=list)
missing_information: list[str] = Field(default_factory=list)
class SynthesisResult(BaseModel):
conclusions: list[SynthesizedConclusion] = Field(default_factory=list)
async def synthesize_signals(
llm: LLMProvider,
*,
company_name: str,
monitoring_focus: str | None,
signals: list[dict],
) -> SynthesisResult:
evidence = {
"company_name": company_name,
"monitoring_focus": monitoring_focus,
"signals": signals,
}
user_prompt = build_user_prompt(
"Identify conclusions supported by two or more of these signals together. Do not "
"synthesize from a single signal alone.",
evidence,
)
return await llm.generate_structured(SYSTEM_PROMPT, user_prompt, SynthesisResult)