UNPKG

@nestbox-ai/cli

Version:

The cli tools that helps developers to build agents

634 lines (564 loc) 28.2 kB
# Public Company Annual Report / 10-K Analysis # Use case: Structured extraction from a public company's annual report or SEC 10-K filing. # Extracts the income statement, balance sheet, cash flow, key ratios, segment breakdown, # management outlook (MD&A), and risk factors for equity research or credit analysis. # Schema v2.2 schema_version: "2.2" report: id: annual_report_acme_fy2025 name: "Annual Report Analysis — Acme Technologies, FY2025 10-K" description: | Structured extraction from Acme Technologies FY2025 Annual Report / 10-K. Covers consolidated income statement, balance sheet, cash flow statement, segment performance, key financial ratios, MD&A highlights, and risk factors. version: "FY2025" context: company_name: "Acme Technologies, Inc." ticker: "ACME" fiscal_year: "FY2025" fiscal_year_end: "2025-12-31" currency: "USD" reporting_units: "thousands" # most 10-Ks report in $thousands — adjust if different units_policy: | The 10-K reports values in thousands of dollars. Return values as STATED in the filing. If the filing says "$1,234,567" that is already in thousands — return 1234567 (not 1234567000). Clarify the unit in the notes field. Return percentages as whole numbers (34.5 not 0.345). Return null for any value not explicitly stated. answer_quality_policy: numeric_requirements: - "Every financial statement line must have a citation" - "Note the reporting units (thousands, millions) for each figure" - "Distinguish between continuing and discontinued operations where relevant" doc_repository: api_base_url: ${DOC_REPO_URL:-http://localhost:8080} api_key: ${DOC_REPO_API_KEY} rotation: 200 mcp: [] docsets: - id: annual_report description: "Acme Technologies FY2025 Annual Report / 10-K Filing" api_key: ${OPENAI_API_KEY} docs: - id: ten_k_filing locator: "repo:doc-acme-10k-fy25" description: "Acme Technologies 10-K FY2025 Full Filing" alias: ten_k llamaindex: model: gpt-4o base_url: ${OPENAI_BASE_URL:-https://api.openai.com/v1} api_key: ${OPENAI_API_KEY} max_tool_calls: 60 tool_timeout_seconds: 180 max_agent_iterations: 45 system_prompt: | You are an equity research analyst extracting structured data from a public company 10-K. ## ANTI-FABRICATION RULE ALL values MUST come from your search tool results the actual 10-K text. Never use prior knowledge of this company's financials. Return null for any value not explicitly stated in the filing. ## 10-K Extraction Rules 1. Financial statements are typically reported in thousands note this in output 2. Use the audited figures from the financial statements, not the MD&A summaries 3. Always extract both the current year and prior year comparatives 4. Segment data may be in a separate note search explicitly for segment disclosures 5. Non-GAAP measures (Adjusted EBITDA, etc.) are in MD&A distinguish from GAAP 6. Risk factors are in Item 1A use global_search to find cross-cutting themes computations: fields: # ── Income Statement ────────────────────────────────────────────────────── - id: income_statement label: "Consolidated Income Statement (FY2025 & FY2024)" type: object priority: 1 docset_id: annual_report agents: - id: income_stmt_extract search_type: basic # income statement tables are best retrieved by basic search options: basic_search: k: 15 prompt: | Extract the consolidated income statement for FY2025 and FY2024. ## What to Find For each year (fy2025, fy2024): - revenue: Total net revenue - cost_of_revenue: Cost of revenue / cost of goods sold - gross_profit: Gross profit - gross_margin_pct: Gross profit / revenue × 100 - r_and_d: Research and development expense - sales_and_marketing: Sales and marketing expense - g_and_a: General and administrative expense - total_opex: Total operating expenses (below gross profit line) - operating_income: Operating income (EBIT) - operating_margin_pct: Operating income / revenue × 100 - interest_expense: Interest expense (net) - other_income_expense: Other income/expense - pretax_income: Income before income taxes - income_tax_expense: Income tax expense (benefit) - net_income: Net income - net_margin_pct: Net income / revenue × 100 - eps_diluted: Diluted EPS - shares_diluted: Diluted weighted average shares outstanding - units_label: What units are used ("thousands" / "millions") ## Search Strategy 1. basic_search: "consolidated statements of operations income revenue FY2025" 2. basic_search: "gross profit operating income net income EPS diluted" 3. Look for the formal income statement tables output_schema: type: object properties: units_label: { type: string } fy2025: type: object properties: revenue: { type: number } cost_of_revenue: { type: number } gross_profit: { type: number } gross_margin_pct: { type: number } r_and_d: { type: number } sales_and_marketing: { type: number } g_and_a: { type: number } total_opex: { type: number } operating_income: { type: number } operating_margin_pct: { type: number } interest_expense: { type: number } pretax_income: { type: number } income_tax_expense: { type: number } net_income: { type: number } net_margin_pct: { type: number } eps_diluted: { type: number } shares_diluted: { type: number } fy2024: type: object properties: revenue: { type: number } gross_profit: { type: number } gross_margin_pct: { type: number } operating_income: { type: number } net_income: { type: number } eps_diluted: { type: number } citations: { type: array, items: { type: string } } notes: { type: string } mcp_scope: [] prompt: "Return consolidated income statement for FY2025 and FY2024." # ── Balance Sheet ───────────────────────────────────────────────────────── - id: balance_sheet label: "Consolidated Balance Sheet (FY2025 & FY2024)" type: object priority: 1 docset_id: annual_report agents: - id: balance_sheet_extract search_type: basic options: basic_search: k: 15 prompt: | Extract the consolidated balance sheet as of FY2025 year-end and FY2024 year-end. ## Current Assets - cash_and_equivalents: Cash and cash equivalents - short_term_investments: Short-term investments / marketable securities - accounts_receivable: Net accounts receivable - inventory: Inventory (if applicable) - prepaid_and_other_current: Prepaid expenses and other current assets - total_current_assets: Total current assets ## Non-Current Assets - ppe_net: Property, plant and equipment, net - goodwill: Goodwill - intangible_assets_net: Intangible assets, net - operating_lease_rou: Operating lease right-of-use assets (if stated separately) - other_long_term_assets: Other long-term assets - total_assets: Total assets ## Current Liabilities - accounts_payable: Accounts payable - accrued_liabilities: Accrued liabilities / accrued expenses - deferred_revenue_current: Deferred revenue (current) - current_debt: Current portion of long-term debt - total_current_liabilities: Total current liabilities ## Non-Current Liabilities - long_term_debt: Long-term debt (net of current portion) - deferred_revenue_lt: Deferred revenue (long-term) - operating_lease_lt: Long-term operating lease liabilities - other_long_term_liabilities: Other long-term liabilities - total_liabilities: Total liabilities ## Equity - total_stockholders_equity: Total stockholders' equity - total_liabilities_and_equity: Total liabilities and stockholders' equity ## Search Strategy 1. basic_search: "consolidated balance sheet total assets liabilities equity" 2. basic_search: "cash receivable goodwill debt long-term" output_schema: type: object properties: units_label: { type: string } fy2025: type: object properties: cash_and_equivalents: { type: number } short_term_investments: { type: number } accounts_receivable: { type: number } total_current_assets: { type: number } ppe_net: { type: number } goodwill: { type: number } intangible_assets_net: { type: number } total_assets: { type: number } accounts_payable: { type: number } current_debt: { type: number } total_current_liabilities: { type: number } long_term_debt: { type: number } total_liabilities: { type: number } total_stockholders_equity: { type: number } fy2024: type: object properties: cash_and_equivalents: { type: number } total_assets: { type: number } long_term_debt: { type: number } total_stockholders_equity: { type: number } citations: { type: array, items: { type: string } } mcp_scope: [] prompt: "Return consolidated balance sheet for FY2025 and FY2024." # ── Cash Flow Statement ─────────────────────────────────────────────────── - id: cash_flow label: "Consolidated Cash Flow Statement (FY2025)" type: object priority: 1 docset_id: annual_report agents: - id: cash_flow_extract search_type: basic options: basic_search: k: 15 prompt: | Extract the consolidated cash flow statement for FY2025. ## Operating Activities - net_income_cf: Net income (starting line) - depreciation_and_amortization: D&A - stock_based_compensation: Stock-based compensation - changes_in_working_capital: Net change in working capital - other_operating_adjustments: Other adjustments - net_cash_from_operations: Net cash provided by operating activities ## Investing Activities - capex: Capital expenditures (should be negative) - acquisitions: Cash paid for acquisitions (negative) - purchases_of_investments: Purchases of investments - proceeds_from_investments: Proceeds from maturities/sales of investments - net_cash_from_investing: Net cash from investing activities ## Financing Activities - proceeds_from_debt: Proceeds from borrowings - repayments_of_debt: Repayments of debt (negative) - share_repurchases: Common stock repurchases (negative) - dividends_paid: Dividends paid (negative, null if none) - net_cash_from_financing: Net cash from financing activities ## Summary - net_change_in_cash: Net change in cash and equivalents - free_cash_flow: net_cash_from_operations + capex (compute this) - fcf_margin_pct: Free cash flow / revenue × 100 ## Search Strategy 1. basic_search: "cash flow operations investing financing activities FY2025" 2. basic_search: "capital expenditures free cash flow stock compensation" output_schema: type: object properties: units_label: { type: string } net_income_cf: { type: number } depreciation_and_amortization: { type: number } stock_based_compensation: { type: number } net_cash_from_operations: { type: number } capex: { type: number } acquisitions: { type: number } net_cash_from_investing: { type: number } share_repurchases: { type: number } dividends_paid: { type: number } net_cash_from_financing: { type: number } net_change_in_cash: { type: number } free_cash_flow: { type: number } fcf_margin_pct: { type: number } citations: { type: array, items: { type: string } } notes: { type: string } mcp_scope: [] prompt: "Return consolidated cash flow statement for FY2025." # ── Key Financial Ratios ────────────────────────────────────────────────── - id: key_ratios label: "Key Financial Ratios & Metrics" type: object priority: 2 depends_on: [income_statement, balance_sheet, cash_flow] docset_id: annual_report agents: - id: ratios_extract docset_id: annual_report prompt: | Compute or extract key financial ratios from the financial statements. Use the FY2025 figures from the statements in your context (from depends_on). ## Profitability - gross_margin_pct: Gross profit / Revenue × 100 (from income statement) - operating_margin_pct: Operating income / Revenue × 100 - net_margin_pct: Net income / Revenue × 100 - fcf_margin_pct: Free cash flow / Revenue × 100 (from cash flow) - roa_pct: Net income / Total assets × 100 - roe_pct: Net income / Stockholders equity × 100 ## Liquidity - current_ratio: Current assets / Current liabilities - quick_ratio: (Cash + Short-term investments + AR) / Current liabilities - cash_and_investments: Cash + short-term investments ## Leverage - net_debt: Long-term debt + current debt - cash and investments - net_debt_to_ebitda: Use reported EBITDA if available; otherwise skip - interest_coverage: Operating income / Interest expense ## Growth (YoY) - revenue_growth_yoy_pct: (FY2025 revenue - FY2024 revenue) / FY2024 revenue × 100 - operating_income_growth_yoy_pct: YoY operating income growth % - eps_growth_yoy_pct: YoY diluted EPS growth % Compute from the financial statement data in your context. Note: If a prior-year figure is not available, set growth metrics to null. output_schema: type: object properties: gross_margin_pct: { type: number } operating_margin_pct: { type: number } net_margin_pct: { type: number } fcf_margin_pct: { type: number } roa_pct: { type: number } roe_pct: { type: number } current_ratio: { type: number } quick_ratio: { type: number } cash_and_investments: { type: number } net_debt: { type: number } interest_coverage: { type: number } revenue_growth_yoy_pct: { type: number } eps_growth_yoy_pct: { type: number } notes: { type: string } mcp_scope: [] prompt: "Return key financial ratios computed from FY2025 financial statements." # ── MD&A Highlights & Outlook ───────────────────────────────────────────── - id: mda_and_outlook label: "MD&A Highlights & Management Outlook" type: object priority: 2 docset_id: annual_report agents: - id: mda_extract prompt: | Extract the key highlights from Management's Discussion & Analysis (MD&A) and the company's forward-looking guidance. ## What to Find - performance_narrative: Management's explanation of FY2025 performance (2-3 sentences) - revenue_drivers: Key factors that drove revenue growth or decline - margin_commentary: Management commentary on margin changes - fy2026_revenue_guidance: FY2026 revenue guidance (full dollars or range) - fy2026_eps_guidance: FY2026 diluted EPS guidance - fy2026_other_guidance: Any other FY2026 metrics guided (operating margin, FCF, etc.) - non_gaap_measures: Any non-GAAP measures highlighted (Adjusted EBITDA, Non-GAAP EPS, etc.) - capital_allocation_commentary: Buybacks, dividends, M&A intent mentioned ## Search Strategy 1. basic_search: "management discussion analysis MD&A results operations" 2. basic_search: "fiscal 2026 guidance outlook revenue earnings per share" 3. global_search: "strategic priorities company direction growth drivers" output_schema: type: object properties: performance_narrative: { type: string } revenue_drivers: { type: array, items: { type: string } } margin_commentary: { type: string } fy2026_revenue_guidance: { type: string } fy2026_eps_guidance: { type: string } fy2026_other_guidance: { type: array, items: { type: string } } non_gaap_measures: { type: array, items: { type: string } } capital_allocation_commentary: { type: string } citations: { type: array, items: { type: string } } mcp_scope: [] prompt: "Return MD&A highlights and FY2026 guidance." # ── Risk Factors ────────────────────────────────────────────────────────── - id: risk_factors label: "Key Risk Factors (Item 1A)" type: object priority: 2 docset_id: annual_report agents: - id: risks_extract search_type: global # risk factors are cross-cutting — global search is best prompt: | Extract the key risk factors from Item 1A of the 10-K. ## What to Find Identify 6-10 of the most material risks across these categories: - business_risks: Competition, technology, product, operational - financial_risks: Debt, liquidity, covenant, foreign exchange - regulatory_risks: Compliance, government, data privacy, IP - macro_risks: Economic conditions, interest rates, supply chain - cyber_risks: Cybersecurity, data breaches, system failures For each risk: - category: One of the above - title: Short risk title (as used in the 10-K if possible) - summary: 1-sentence summary of the risk ## Search Strategy Use global_search to extract cross-cutting risk themes: Query 1: "risk factors competition market technology" Query 2: "regulatory compliance data privacy cybersecurity" Query 3: "financial risks debt interest liquidity" output_schema: type: object properties: risks: type: array items: type: object properties: category: { type: string } title: { type: string } summary: { type: string } citations: { type: array, items: { type: string } } citations: { type: array, items: { type: string } } mcp_scope: [] prompt: "Return the most material risk factors from Item 1A." tables: - id: income_statement_table title: "Consolidated Income Statement (FY2025 vs FY2024)" priority: 1 depends_on: [income_statement] docset_id: annual_report agents: - id: income_table_build docset_id: annual_report prompt: | Build the income statement comparison table from the data in your context. For each line item, create one row: - metric: Line item name - fy2025: FY2025 value - fy2024: FY2024 value - change_pct: YoY change % (null if FY2024 not available) Include: Revenue, Cost of Revenue, Gross Profit, Gross Margin %, R&D, S&M, G&A, Operating Income, Operating Margin %, Net Income, Diluted EPS. Return {"rows": [...]} output_schema: type: object properties: rows: type: array items: type: object properties: metric: { type: string } fy2025: { type: number } fy2024: { type: number } change_pct: { type: number } mcp_scope: [] prompt: "Return income statement comparison table." template: format: markdown sections: header: | # {{report.name}} > **Company:** {{context.company_name}} ({{context.ticker}}) | **Fiscal Year:** {{context.fiscal_year}} > **Reporting units:** USD {{context.reporting_units}} content: | {{sections.header}} --- ## Income Statement {{table.income_statement_table}} --- ## Balance Sheet Highlights | Metric | FY2025 | FY2024 | |--------|--------|--------| | Cash & Equivalents | {{ field.balance_sheet.fy2025.cash_and_equivalents | number(0) | default("—") }} | {{ field.balance_sheet.fy2024.cash_and_equivalents | number(0) | default("—") }} | | Total Current Assets | {{ field.balance_sheet.fy2025.total_current_assets | number(0) | default("—") }} | — | | Total Assets | {{ field.balance_sheet.fy2025.total_assets | number(0) | default("—") }} | {{ field.balance_sheet.fy2024.total_assets | number(0) | default("—") }} | | Long-Term Debt | {{ field.balance_sheet.fy2025.long_term_debt | number(0) | default("—") }} | {{ field.balance_sheet.fy2024.long_term_debt | number(0) | default("—") }} | | Total Stockholders' Equity | {{ field.balance_sheet.fy2025.total_stockholders_equity | number(0) | default("—") }} | {{ field.balance_sheet.fy2024.total_stockholders_equity | number(0) | default("—") }} | --- ## Cash Flow | | FY2025 | |-|--------| | Cash from Operations | {{ field.cash_flow.net_cash_from_operations | number(0) | default("—") }} | | Capital Expenditures | {{ field.cash_flow.capex | number(0) | default("—") }} | | **Free Cash Flow** | **{{ field.cash_flow.free_cash_flow | number(0) | default("—") }}** | | FCF Margin | {{ field.cash_flow.fcf_margin_pct | number(1) | default("—") }}% | | Stock-Based Compensation | {{ field.cash_flow.stock_based_compensation | number(0) | default("—") }} | | Share Repurchases | {{ field.cash_flow.share_repurchases | number(0) | default("—") }} | --- ## Key Financial Ratios (FY2025) | Ratio | Value | |-------|-------| | Gross Margin | {{ field.key_ratios.gross_margin_pct | number(1) | default("—") }}% | | Operating Margin | {{ field.key_ratios.operating_margin_pct | number(1) | default("—") }}% | | Net Margin | {{ field.key_ratios.net_margin_pct | number(1) | default("—") }}% | | FCF Margin | {{ field.key_ratios.fcf_margin_pct | number(1) | default("—") }}% | | ROE | {{ field.key_ratios.roe_pct | number(1) | default("—") }}% | | Current Ratio | {{ field.key_ratios.current_ratio | number(2) | default("—") }}x | | Net Debt | {{ field.key_ratios.net_debt | number(0) | default("—") }} | | Revenue Growth YoY | {{ field.key_ratios.revenue_growth_yoy_pct | number(1) | default("—") }}% | | EPS Growth YoY | {{ field.key_ratios.eps_growth_yoy_pct | number(1) | default("—") }}% | --- ## MD&A Highlights & FY2026 Guidance {{ field.mda_and_outlook.performance_narrative | default("—") }} **Revenue drivers:** {{ field.mda_and_outlook.revenue_drivers | default("—") }} **Margin commentary:** {{ field.mda_and_outlook.margin_commentary | default("—") }} ### FY2026 Guidance | | | |-|-| | Revenue | {{ field.mda_and_outlook.fy2026_revenue_guidance | default("Not provided") }} | | EPS | {{ field.mda_and_outlook.fy2026_eps_guidance | default("Not provided") }} | | Other | {{ field.mda_and_outlook.fy2026_other_guidance | default("—") }} | **Capital allocation:** {{ field.mda_and_outlook.capital_allocation_commentary | default("—") }} --- ## Key Risk Factors {{ field.risk_factors.risks | default("—") }} guardrails: - id: gr_balance_sheet_balances target: field.balance_sheet on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "Total assets must equal total liabilities plus equity" prompt: | Verify: total_assets ≈ total_liabilities + total_stockholders_equity (within 1%) Also verify: total_current_assets < total_assets Return JSON: {"pass": boolean, "issues": []} Content: {{content}} - id: gr_income_stmt_math target: field.income_statement on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "Income statement lines must add up correctly" prompt: | Verify for FY2025: gross_profit ≈ revenue - cost_of_revenue (within 1%) Verify: net_income < gross_profit (unless extraordinary items) Verify: eps_diluted ≈ net_income / shares_diluted (within 5%) Return JSON: {"pass": boolean, "issues": []} Content: {{content}} - id: gr_fcf_math target: field.cash_flow on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "FCF must equal operating cash flow plus capex" prompt: | Verify: free_cash_flow ≈ net_cash_from_operations + capex (capex is negative, so this is effectively subtracted) Allow 1% tolerance for rounding. Return JSON: {"pass": boolean, "issues": []} Content: {{content}} - id: gr_no_fabrication target: computations on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "Detect fabricated values" prompt: | FAIL if citations are "Source A"/"Source B" style (real ones use c_xxxxxxxx). FAIL if ALL financial statement values are round multiples of 100000. Return JSON: {"pass": boolean, "issues": []} Content: {{content}} execution: retries: max_attempts: 3 backoff_seconds: 2.0 output: directory: ./output timestamp_suffix: false include_final_report: true include_computed_json: true include_evidence: true include_guardrails: true