UNPKG

@nestbox-ai/cli

Version:

The cli tools that helps developers to build agents

444 lines (385 loc) 18.1 kB
# VC Portfolio Monitoring Report # Use case: Monthly portfolio review across multiple portfolio companies. # Each company has its own docset (separate GraphRAG index). # Extracts ARR, burn, runway, headcount, and key risks per company, # then synthesises a cross-portfolio dashboard. # Schema v2.2 schema_version: "2.2" report: id: vc_portfolio_monitoring_q1_2026 name: "VC Portfolio Monitoring — Q1 2026" description: | Cross-portfolio KPI dashboard extracting key metrics from each portfolio company's board update or monthly investor report. Covers ARR/revenue, burn/runway, headcount, recent milestones, and risks. version: "2026.Q1" context: fund_name: "Acme Ventures Fund III" reporting_period: "Q1 2026" as_of_date: "2026-03-31" currency: "USD" units_policy: | Return raw full-dollar numbers. Convert abbreviations: "$2.5M" → 2500000, "$350K" → 350000, "$1.2B" → 1200000000. Percentages as whole numbers: 92.3 not 0.923. Return null for any value not explicitly found in the document. answer_quality_policy: numeric_requirements: - "Every numeric value must have a citation (c_xxxxxxxx format)" - "Return null for values not explicitly stated — never estimate" labeling_requirements: - "Always include the reporting period with each metric" doc_repository: api_base_url: ${DOC_REPO_URL:-http://localhost:8080} api_key: ${DOC_REPO_API_KEY} rotation: 200 mcp: [] # Each portfolio company is its own docset with its own GraphRAG index docsets: - id: company_alpha description: "Alpha Inc — Q1 2026 board update" api_key: ${OPENAI_API_KEY} docs: - id: alpha_board_update locator: "repo:doc-alpha0001" description: "Alpha Inc Q1 2026 Board Update" - id: company_beta description: "Beta Systems — Q1 2026 monthly investor report" api_key: ${OPENAI_API_KEY} docs: - id: beta_investor_report locator: "repo:doc-beta0002" description: "Beta Systems Q1 2026 Investor Report" - id: company_gamma description: "Gamma Health — Q1 2026 board deck" api_key: ${OPENAI_API_KEY} docs: - id: gamma_board_deck locator: "repo:doc-gamma003" description: "Gamma Health Q1 2026 Board Deck" llamaindex: model: gpt-4o base_url: ${OPENAI_BASE_URL:-https://api.openai.com/v1} api_key: ${OPENAI_API_KEY} max_tool_calls: 40 tool_timeout_seconds: 150 max_agent_iterations: 35 system_prompt: | You are a venture capital analyst extracting KPIs from portfolio company reports. ## ANTI-FABRICATION RULE ALL values MUST come from your search tool results. Never guess. Return null if not found. ## Rules 1. Return raw full-dollar numbers (9700000 not "$9.7M") 2. Percentages as whole numbers (92.3 not 0.923) 3. Every numeric value needs a c_xxxxxxxx citation 4. Return null for any value not explicitly stated in the document 5. Negative values are valid (e.g., churn ARR, net cash burn) computations: fields: # ── Company Alpha KPIs ───────────────────────────────────────────────────── - id: alpha_kpis label: "Alpha Inc — Q1 2026 KPIs" type: object priority: 1 docset_id: company_alpha agents: - id: alpha_extract prompt: | Extract the following KPIs for Alpha Inc from their Q1 2026 board update. ## Financial Metrics - arr_end: Ending ARR for the most recent period (full dollars) - arr_mom_growth_pct: MoM or QoQ ARR growth % (whole number) - monthly_burn: Net monthly cash burn (full dollars) - cash_on_hand: Current cash balance (full dollars) - runway_months: Months of runway at current burn ## Operating Metrics - headcount: Total employee count - customer_count: Total paying customer or logo count - nrr: Net Revenue Retention % (if stated) ## Qualitative - top_milestone: Single most important milestone this quarter (string) - top_risk: Single most important risk mentioned (string) ## Search Strategy 1. basic_search: "ARR revenue growth Q1 2026 monthly" 2. basic_search: "cash burn runway headcount customers" 3. basic_search: "highlights milestones risks challenges" Set to null anything not explicitly stated. output_schema: type: object properties: company: { type: string } period: { type: string } arr_end: { type: number } arr_mom_growth_pct: { type: number } monthly_burn: { type: number } cash_on_hand: { type: number } runway_months: { type: number } headcount: { type: number } customer_count: { type: number } nrr: { type: number } top_milestone: { type: string } top_risk: { type: string } citations: { type: array, items: { type: string } } notes: { type: string } mcp_scope: [] prompt: "Return Alpha Inc Q1 2026 KPIs with citations." # ── Company Beta KPIs ────────────────────────────────────────────────────── - id: beta_kpis label: "Beta Systems — Q1 2026 KPIs" type: object priority: 1 docset_id: company_beta agents: - id: beta_extract prompt: | Extract the following KPIs for Beta Systems from their Q1 2026 investor report. ## Financial Metrics - arr_end: Ending ARR for the most recent period - arr_mom_growth_pct: MoM or QoQ ARR growth % - monthly_burn: Net monthly cash burn - cash_on_hand: Current cash balance - runway_months: Months of runway at current burn ## Operating Metrics - headcount: Total employee count - customer_count: Total paying customer count - nrr: Net Revenue Retention % (if stated) ## Qualitative - top_milestone: Most important milestone this quarter - top_risk: Most important risk mentioned ## Search Strategy 1. basic_search: "ARR revenue MRR monthly quarterly growth" 2. basic_search: "cash burn runway balance headcount team" 3. basic_search: "highlights wins milestones risks concerns" Set to null anything not explicitly stated. output_schema: type: object properties: company: { type: string } period: { type: string } arr_end: { type: number } arr_mom_growth_pct: { type: number } monthly_burn: { type: number } cash_on_hand: { type: number } runway_months: { type: number } headcount: { type: number } customer_count: { type: number } nrr: { type: number } top_milestone: { type: string } top_risk: { type: string } citations: { type: array, items: { type: string } } notes: { type: string } mcp_scope: [] prompt: "Return Beta Systems Q1 2026 KPIs with citations." # ── Company Gamma KPIs ───────────────────────────────────────────────────── - id: gamma_kpis label: "Gamma Health — Q1 2026 KPIs" type: object priority: 1 docset_id: company_gamma agents: - id: gamma_extract prompt: | Extract KPIs for Gamma Health from their Q1 2026 board deck. ## Financial Metrics - arr_end or revenue_end: ARR or revenue for the quarter - arr_mom_growth_pct: MoM or QoQ growth % - monthly_burn: Net monthly cash burn - cash_on_hand: Current cash balance - runway_months: Months of runway ## Operating Metrics - headcount: Total employee count - customer_count: Patients, clients, or paying customer count - nrr: Net Revenue Retention % (if applicable) ## Qualitative - top_milestone: Most important milestone - top_risk: Most important risk ## Search Strategy 1. basic_search: "revenue ARR growth quarterly monthly" 2. basic_search: "cash burn runway balance employees headcount" 3. basic_search: "milestones highlights risks" Set to null anything not explicitly stated. output_schema: type: object properties: company: { type: string } period: { type: string } arr_end: { type: number } arr_mom_growth_pct: { type: number } monthly_burn: { type: number } cash_on_hand: { type: number } runway_months: { type: number } headcount: { type: number } customer_count: { type: number } nrr: { type: number } top_milestone: { type: string } top_risk: { type: string } citations: { type: array, items: { type: string } } notes: { type: string } mcp_scope: [] prompt: "Return Gamma Health Q1 2026 KPIs with citations." # ── Cross-Portfolio Summary (depends on all 3 companies) ────────────────── - id: portfolio_summary label: "Cross-Portfolio Summary" type: object priority: 2 depends_on: [alpha_kpis, beta_kpis, gamma_kpis] agents: - id: portfolio_summary_extract docset_id: company_alpha # use any docset — this agent synthesises from context prompt: | Summarise the overall health of the portfolio based on the individual company KPIs available in your context (from depends_on). ## What to Produce - total_portfolio_arr: Sum of all companies' ARR (null if any are missing) - portfolio_avg_runway_months: Average runway across companies - healthiest_company: Company name with strongest metrics - most_at_risk_company: Company name with lowest runway or highest burn - common_themes: 2-3 themes appearing across multiple companies - portfolio_outlook: "positive" | "cautious" | "mixed" | "concerning" Base your answer entirely on the company KPIs from context. If a company KPI is null, exclude it from calculations and note it. output_schema: type: object properties: total_portfolio_arr: { type: number } portfolio_avg_runway_months: { type: number } healthiest_company: { type: string } most_at_risk_company: { type: string } common_themes: { type: array, items: { type: string } } portfolio_outlook: { type: string } notes: { type: string } mcp_scope: [] prompt: "Return cross-portfolio summary derived from company KPIs." tables: # ── Portfolio Dashboard Table ────────────────────────────────────────────── - id: portfolio_dashboard title: "Portfolio Company Dashboard — Q1 2026" priority: 2 depends_on: [alpha_kpis, beta_kpis, gamma_kpis] agents: - id: dashboard_build docset_id: company_alpha # placeholder — values come from context prompt: | Build the portfolio dashboard table from the company KPI results available in your context (from depends_on). For each of the 3 companies (Alpha Inc, Beta Systems, Gamma Health), create one row with: - company: Company name - arr_end: Ending ARR (full dollars) - arr_growth_pct: QoQ ARR growth % - monthly_burn: Monthly burn (full dollars) - runway_months: Runway in months - headcount: Employee count - nrr: NRR % (if available) - outlook: "green" | "yellow" | "red" based on runway and growth Use only values from the company KPIs in context. Set null where missing. Return {"rows": [...]} with one object per company. output_schema: type: object properties: rows: type: array items: type: object properties: company: { type: string } arr_end: { type: number } arr_growth_pct: { type: number } monthly_burn: { type: number } runway_months: { type: number } headcount: { type: number } nrr: { type: number } outlook: { type: string } mcp_scope: [] prompt: "Build portfolio dashboard table from company KPIs." template: format: markdown sections: header: | # {{report.name}} > **Fund:** {{context.fund_name}} | **As of:** {{context.as_of_date}} | **Period:** {{context.reporting_period}} content: | {{sections.header}} --- ## Portfolio Dashboard {{table.portfolio_dashboard}} **Overall outlook:** {{ field.portfolio_summary.portfolio_outlook | default("—") }} **Combined portfolio ARR:** {{ field.portfolio_summary.total_portfolio_arr | currency("$", 0) | default("—") }} **Average runway:** {{ field.portfolio_summary.portfolio_avg_runway_months | number(1) | default("—") }} months **Common themes:** {{ field.portfolio_summary.common_themes | default("—") }} **Healthiest:** {{ field.portfolio_summary.healthiest_company | default("—") }} **Most at risk:** {{ field.portfolio_summary.most_at_risk_company | default("—") }} --- ## Alpha Inc | Metric | Value | |--------|-------| | ARR | {{ field.alpha_kpis.arr_end | currency("$", 0) | default("—") }} | | QoQ Growth | {{ field.alpha_kpis.arr_mom_growth_pct | number(1) | default("—") }}% | | Monthly Burn | {{ field.alpha_kpis.monthly_burn | currency("$", 0) | default("—") }}/mo | | Cash | {{ field.alpha_kpis.cash_on_hand | currency("$", 0) | default("—") }} | | Runway | {{ field.alpha_kpis.runway_months | number(1) | default("—") }} months | | Headcount | {{ field.alpha_kpis.headcount | number(0) | default("—") }} | | NRR | {{ field.alpha_kpis.nrr | number(1) | default("—") }}% | **Milestone:** {{ field.alpha_kpis.top_milestone | default("—") }} **Risk:** {{ field.alpha_kpis.top_risk | default("—") }} --- ## Beta Systems | Metric | Value | |--------|-------| | ARR | {{ field.beta_kpis.arr_end | currency("$", 0) | default("—") }} | | QoQ Growth | {{ field.beta_kpis.arr_mom_growth_pct | number(1) | default("—") }}% | | Monthly Burn | {{ field.beta_kpis.monthly_burn | currency("$", 0) | default("—") }}/mo | | Cash | {{ field.beta_kpis.cash_on_hand | currency("$", 0) | default("—") }} | | Runway | {{ field.beta_kpis.runway_months | number(1) | default("—") }} months | | Headcount | {{ field.beta_kpis.headcount | number(0) | default("—") }} | | NRR | {{ field.beta_kpis.nrr | number(1) | default("—") }}% | **Milestone:** {{ field.beta_kpis.top_milestone | default("—") }} **Risk:** {{ field.beta_kpis.top_risk | default("—") }} --- ## Gamma Health | Metric | Value | |--------|-------| | ARR | {{ field.gamma_kpis.arr_end | currency("$", 0) | default("—") }} | | QoQ Growth | {{ field.gamma_kpis.arr_mom_growth_pct | number(1) | default("—") }}% | | Monthly Burn | {{ field.gamma_kpis.monthly_burn | currency("$", 0) | default("—") }}/mo | | Cash | {{ field.gamma_kpis.cash_on_hand | currency("$", 0) | default("—") }} | | Runway | {{ field.gamma_kpis.runway_months | number(1) | default("—") }} months | | Headcount | {{ field.gamma_kpis.headcount | number(0) | default("—") }} | | NRR | {{ field.gamma_kpis.nrr | number(1) | default("—") }}% | **Milestone:** {{ field.gamma_kpis.top_milestone | default("—") }} **Risk:** {{ field.gamma_kpis.top_risk | default("—") }} guardrails: - id: gr_no_fabrication target: computations on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "Detect fabricated or placeholder values" prompt: | FAIL if you find: citations like "Source A"/"Source B" (real ones use c_xxxxxxxx), ARR values that are ALL round multiples of 100000, or retention values below 1.0. Return JSON: {"pass": boolean, "issues": []} Content: {{content}} - id: gr_runway_sanity target: computations on_fail: warn model: gpt-4.1-mini api_key: ${OPENAI_API_KEY} description: "Runway values must be positive and plausible" prompt: | Check all runway_months values. FAIL if any are negative or greater than 120 months. Check all monthly_burn values. FAIL if any are positive (burn should be stored as positive number, but flag if burn is implausibly large compared to cash, e.g., burn > cash). Return JSON: {"pass": boolean, "issues": []} Content: {{content}} execution: retries: max_attempts: 3 backoff_seconds: 2.0 output: directory: ./output timestamp_suffix: true include_final_report: true include_computed_json: true include_evidence: true include_guardrails: true