"""Prompt registry for LLM parsing.""" from __future__ import annotations from typing import Any PROMPT_VERSION = "v1" _SYSTEM_EVENT_CLASSIFIER = """\ You are a financial document analyst specializing in SEC filings (8-K, 6-K). Your task is to classify events and extract structured information from earnings press releases and other material corporate disclosures. Output ONLY valid JSON matching the specified schema. Do not add commentary outside the JSON. """.strip() _USER_EVENT_CLASSIFIER = """\ Analyze the following corporate filing excerpt and return a JSON object with these fields: - event_type: one of ["earnings_release", "guidance_update", "material_contract", "regulatory_or_approval", "capital_markets_or_financing", "management_change", "litigation_or_investigation", "other_material_event", "unknown"] - event_direction: one of ["bullish", "bearish", "mixed", "neutral", "unknown"] - headline: short 1-sentence headline (max 120 chars) - summary: 2-3 sentence summary of the key facts - guidance_status: one of ["raised", "inline_or_maintained", "lowered", "withdrawn", "not_provided", "unclear"] - guidance_scope: one of ["quarterly", "annual", "both", "unknown"] - demand_strength: one of ["strong", "stable", "weakening", "unknown"] - pricing_power: one of ["present", "mixed", "absent", "unknown"] - backlog_or_bookings: one of ["present", "mixed", "absent", "unknown"] - customer_expansion: one of ["present", "mixed", "absent", "unknown"] - margin_quality: one of ["improving", "stable", "deteriorating", "unknown"] - oneoff_item: true/false — unusual one-time item inflating results - tax_benefit: true/false - valuation_gain: true/false - non_gaap_heavy: true/false — results rely heavily on non-GAAP metrics - financing_related: true/false - legal_or_regulatory_overhang: true/false - confidence_overall: float 0.0-1.0 - confidence_event_type: float 0.0-1.0 - confidence_event_direction: float 0.0-1.0 Document metadata: Form type: {form_type} Filing date: {filing_date} Time bucket: {filing_time_bucket} Rule hints: {rule_hints} Filing text (truncated to {max_chars} chars): --- {text} --- Return ONLY the JSON object. """.strip() PROMPT_REGISTRY: dict[str, dict[str, Any]] = { "event_classifier_v1": { "version": PROMPT_VERSION, "system": _SYSTEM_EVENT_CLASSIFIER, "user_template": _USER_EVENT_CLASSIFIER, } } def render_prompt( prompt_name: str, doc_meta: dict[str, Any], text: str, rule_hints: dict[str, Any], max_chars: int = 8000, ) -> list[dict[str, str]]: """Render a named prompt into an Ollama messages list. Args: prompt_name: Key in PROMPT_REGISTRY. doc_meta: Document metadata dict (form_type, filing_date, filing_time_bucket). text: Exhibit text (will be truncated to max_chars). rule_hints: Summary of rule parser output for context. max_chars: Max characters of text to include. Returns: List of {role, content} dicts for Ollama chat API. """ entry = PROMPT_REGISTRY[prompt_name] user_content = entry["user_template"].format( form_type=doc_meta.get("form_type", "unknown"), filing_date=doc_meta.get("filing_date", "unknown"), filing_time_bucket=doc_meta.get("filing_time_bucket", "unknown"), rule_hints=rule_hints, text=text[:max_chars], max_chars=max_chars, ) return [ {"role": "system", "content": entry["system"]}, {"role": "user", "content": user_content}, ]