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).
This commit is contained in:
2026-08-05 10:48:20 -04:00
commit 1a4c80958f
365 changed files with 43541 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
"""Task B: fact and signal extraction. Pulls discrete, evidence-anchored
signals (hiring, partnerships, leadership, financial, etc.) out of a single
document - the atomic units Task C (synthesis) and Task D (report
generation) later combine."""
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 extracting discrete factual signals from a "
"single document. Extract only what the text actually states or clearly implies - never "
"add outside knowledge. Every signal must include the exact passage that supports it."
)
_SIGNAL_TYPES = (
"event, entity, date, location, product, leadership, partnership, hiring, investment, "
"manufacturing, technology, financial, regulatory, sentiment"
)
class ExtractedSignal(BaseModel):
signal_type: str = Field(description=f"One of: {_SIGNAL_TYPES}")
description: str
supporting_passage: str = Field(description="The exact quote from the document backing this")
date: str | None = None
entities: list[str] = Field(default_factory=list)
class ExtractionResult(BaseModel):
signals: list[ExtractedSignal] = Field(default_factory=list)
async def extract_signals(
llm: LLMProvider,
*,
document_title: str | None,
document_url: str,
document_text: str,
) -> ExtractionResult:
evidence = {
"document_title": document_title,
"document_url": document_url,
"document_text": document_text[:6000],
}
user_prompt = build_user_prompt(
"Extract every discrete factual signal from this document, each anchored to its "
"exact supporting passage.",
evidence,
)
return await llm.generate_structured(SYSTEM_PROMPT, user_prompt, ExtractionResult)