"""LLM prompt for AI report commentary. Provider-agnostic system + user prompt builder. Output contract: JSON with keys summary, highlights, concerns, next_actions.""" SYSTEM_PROMPT = """You are an experienced CFO providing executive-level commentary on a financial report. Your output MUST be valid JSON of this exact shape: { "summary": "<2-3 sentence executive summary of the report period>", "highlights": ["", "", ...], "concerns": ["", ...], "next_actions": ["", ...] } Rules: - Use the data provided. Do not invent numbers. - Tone: professional, concise, factual. - Currency formatting: always include the $ symbol and 2 decimal places. - For anomalies: explicitly mention the variance percentage AND the dollar amount. - Do NOT include markdown code fences. Do NOT include any prose outside the JSON. """ def build_prompt(report_result: dict, anomalies: list) -> tuple[str, str]: """Build (system_prompt, user_prompt) tuple.""" parts = [] # Report context parts.append(f"REPORT: {report_result.get('report_name', 'Untitled')}") period = report_result.get('period', {}) parts.append(f"PERIOD: {period.get('label', '')} " f"({period.get('date_from', '')} to {period.get('date_to', '')})") comp_period = report_result.get('comparison_period') if comp_period: parts.append(f"COMPARED TO: {comp_period.get('label', '')} " f"({comp_period.get('date_from', '')} to {comp_period.get('date_to', '')})") parts.append("") # Rows (the actual numbers) parts.append("REPORT LINES:") for row in report_result.get('rows', []): line = f" - {row.get('label', '?')}: ${row.get('amount', 0):,.2f}" if row.get('amount_comparison') is not None: line += f" (comparison: ${row['amount_comparison']:,.2f}" if row.get('variance_pct') is not None: line += f", {row['variance_pct']:+.1f}%" line += ")" if row.get('is_subtotal'): line += " [SUBTOTAL]" parts.append(line) parts.append("") # Anomalies if anomalies: parts.append("ANOMALIES (variances exceeding threshold):") for a in anomalies[:10]: parts.append( f" - {a['label']}: {a['direction']}d {a['variance_pct']:.1f}% " f"(${a['variance_amount']:+,.2f}, severity: {a['severity']})" ) parts.append("") parts.append("Generate the JSON commentary per the system prompt.") return (SYSTEM_PROMPT, "\n".join(parts))