Spaces:
Sleeping
Sleeping
Commit History
-
fix: Margin-consistency gate check and final-evaluation labelβ
- data_gate cross-checks net_margin against net_income/revenue; a disagreement (period mixing upstream) quarantines the pair so a wrong margin can never be cited (companion to the Researcher-side duration fix in fundamentals extraction) - Critic's 4th evaluation after max revisions now labeled 'final evaluation' instead of the confusing 'iteration 4/3'c90d619 -
feat: Deterministic data gate on the Researcher->Analyzer edgeβ
Applies the AgentAsk edge-contract principle deterministically (no LLM): - DG: per-category required-metric rules audited on the exact extracted view the Analyzer consumes; gaps render as an explicit MISSING section in the reference table instructing 'DATA NOT PROVIDED' - the silent empty-valuation case can no longer pass unflagged, and the Critic's existing constraint rule finally has something to enforce - SC: sanity bounds quarantine impossible magnitudes (decimal/unit slips) before they can enter the reference table and be cited; bounds reject the impossible, not the unusual (Boeing's real 9.92 D/E passes) - Both findings logged to the activity stream; 7 gate tests added7abf8e9 -
fix: Gateway resilience to Researcher restarts at submit timeβ
Observed live: a transient Researcher outage returned a non-JSON error page at submission, crashing the workflow with a raw JSONDecodeError. Non-JSON responses now surface as ResearchGatewayError with the HTTP status, and a failed submission retries once after 10s (mirroring the existing lost-task resubmission).8a1264b -
fix: Boeing-run findings β canonical refs, edge contracts, guardrailsβ
1. Canonical [M##] alignment: final result now carries metric_reference (the analyzer's own numbered list); the Quantitative Data table renders from it so table refs match SWOT text citations exactly (was: positional row numbering that diverged from the analyzer's 16-item list) 2. Numeric validator: accept citations exact at displayed precision ("$2.2B" for 2.237e9); mismatch messages now include raw values 3. Parser edge contract: only [M##]-cited lines enter the quadrants; uncited action lines route to a new Recommendations block, data-quality prose to quality notes; markdown headers can no longer leak as rows 4. Interpretation guardrails in analyzer prompts (VIX bands, margin benchmarks, internal-W/external-T classification) and a critic rubric line penalizing misclassification and W/T metric duplication 5. Citation coverage counts distinct cited metrics (no more 125%); provider failure logs deduped to one line per provider Contract tests added (tests/tesβ¦e961a43 -
fix: Resubmit research task once when the service loses it mid-runβ
The Researcher's task store is in-memory, so an HF Space deploy or restart between task submission and completion drops in-flight tasks and polling fails with 'Task not found' (-32001). Observed live when a push rebuilt the Space during an analysis. One resubmission converts that into a short delay; the emitted-metrics dedup set is shared across the retry so the UI does not double-log metrics.8d71395 -
feat: JSON-mode structured outputs for critic scoringβ
- llm_client.query gains json_mode: response_format json_object on Groq/OpenRouter, responseMimeType application/json on Gemini; validated against all three live providers - Critic evaluation now requests JSON mode; existing brace-slice parsing retained as fallback - Fix stale LANGCHAIN_PROJECT name in .env.example04accf1
-
debug: Add detailed logging for numeric mismatches in criticβ
Shows exact mismatch details (cited vs expected) to help identify why validation is failing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>0e30a8c -
fix: Align analyzer field names with MCP data structureβ
Valuation: - Use pb_ratio/ps_ratio instead of price_to_book/price_to_sales - Check both yahoo_finance and alpha_vantage sources (fallback) Macro: - Use interest_rate instead of fed_funds_rate - Use cpi_inflation instead of cpi_yoy - Use unemployment instead of unemployment_rate Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>2db41a2
-
fix: Improve SWOT output formattingβ
- Format large numbers with B/M suffixes ($177.6B instead of $177,556,000,000) - Fix SWOT line parsing to require spaces around separator ( - not just -) - Prevents dates like 2024-12-31 from being split across columns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>1f4f8e3 -
fix: Add MCP 'executing' state for process flow visualizationβ
- Add set_mcp_executing() to workflow_store.py - Call it at start of research phase in researcher.py - MCP containers now show 'executing' while fetching data Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>dc70069 -
fix: Handle temporal dict format for revenue_cagr_3yr in analyzerβ
The metric was being passed as {value: X, end_date: Y} dict but the formatter expected a scalar float. Added proper type checking. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>dd14be4 -
fix: Update analyzer to handle new MCP source-keyed structureβ
- Add _extract_valuation_metric() for temporal wrappers with as_of - Update valuation extraction to use new structure - Update volatility extraction for fred/yahoo_finance sources - Update macro extraction for bea/bls/fred sources - Update news extraction for tavily/nyt/newsapi arrays - Update sentiment extraction for finnhub/reddit arrays Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>1492943 -
fix: Handle 'sources' wrapper in fundamentals data structureβ
The Researcher-Agent returns fundamentals wrapped in a "sources" key: {"sources": {"sec_edgar": {"data": {...}}, "yahoo_finance": {...}}} But analyzer expected flat structure: {"sec_edgar": {"data": {...}}, "yahoo_finance": {...}} This caused fundamentals (revenue, net_income, margins, etc.) to be silently missing from SWOT analysis. Fixed in 3 places: - _extract_company_profile() - for company profile extraction - _generate_data_report() - for Data Report tables - _extract_key_metrics() - for metric reference table Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>146876d -
fix: Only validate SWOT section for uncited numbersβ
The uncited number detection was scanning the entire draft_report including the Data Report tables (raw MCP metrics). This caused 18+ false positives since Data Report tables don't have [M##] citations. Now extracts just the "## SWOT Analysis" section before validation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>a8d1079 -
feat: SWOT output as structured text parsed into HTML tablesβ
- Backend: Updated analyzer prompt OUTPUT FORMAT to use structured text format: [M##] Metric: Value - Insight - Backend: Updated revision prompt to match the same format - Frontend: Added parseSwotLine() parser to extract ref, metric, insight - Frontend: Replaced SWOT list display with HTML tables (3 columns) - Frontend: Removed unused icon imports (Zap, AlertCircle) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>6fd7fcd -
Fix revision loop: add critique_details to AgentStateβ
Bug: critique_details was not defined in AgentState TypedDict, causing LangGraph to drop it between nodes. Revisions never triggered because analyzer couldn't see critic's REJECTED status. - Add critique_details: Optional[dict] to AgentState - Add analyzer_revision_skipped: Optional[bool] to AgentState - Add debug logging to trace state flow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>95ae0b4 -
Reformat SWOT output: concise 3-column table formatβ
Backend: - Update analyzer prompt to output SWOT as tables - Format: | Ref | Metric | Insight | - Update revision prompt to use same table format Frontend: - Add cleanMarkdown() to strip asterisks and bold markers - Apply to all SWOT item displays and copy text Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>0fb19bd -
Remove duplicate Company Details from markdown outputβ
Company profile info is already displayed in frontend's Company Profile section - no need to duplicate in backend markdown. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>69cd30e -
UI improvements: metric refs, company details, remove status labelsβ
- Add M01/M02 metric reference format in data table - Add Company Details section (sector, industry, HQ, employees) - Capitalize acronyms (GDP, VIX, P/B, P/S, EPS, etc.) - Remove status labels (REJECTED, Acceptable, Board-ready, PASSED) - Use human-readable metric names in data quality notes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>86951ae -
Decrease quality threshold from 7 to 6β
- Weighted score threshold: 7.0 β 6.0 - Evidence grounding hard floor: 7 β 6 - Updated conditions.py, graph_cyclic.py, critic.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>07bfcf6
-
Fix: Metric extraction to match MCP data structureβ
- Fix fundamentals to use sec_edgar/yahoo_finance structure - Fix valuation to use yahoo_finance.data structure - Fix volatility to use yahoo_finance.data + market_volatility_context - Fix macro to use bea_bls/fred structure - Reduce critic source_data truncation to 4000 chars (was 8000) - Fallback to multi_source if metrics path empty Fixes "No metrics extracted" error and 413 Payload Too Large. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>b3daac3 -
Increase LLM rate limit delays from 5s to 10sβ
Prevents 429 errors when Critic rejects and Analyzer retries. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>df1355a -
Fix: Handle temporal dict structure in _format_metrics_for_promptβ
- Add _get_val helper to extract value from dict or plain value - Fix operator precedence in date extraction (add parentheses) - Prevents TypeError when formatting temporal metrics Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>f80bf1d -
Fix: Temporal data extraction and frontend date displayβ
Backend: - Extract dates for valuation/volatility/macro in analyzer.py - Fix workflow_store.py to use regular_market_time for valuation - Fix workflow_store.py to use generated_at for volatility - Add Layer 2 (minimum citation count) to numeric_validator.py - Add Layer 3 (uncited number detection) to numeric_validator.py - Integrate Layers 2/3 in critic.py Frontend: - Add normalizeDate() for YYYY-MM-DD format (2025Q3β2025-09-30) - Add inferDataType() "Spot" for valuation metrics - Add extractDate() with multiple field fallbacks for news Fixes issues 2, 3, 5, 6, 8 from frontend data display audit. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>09c3333 -
Add SWOT output enhancementsβ
1. Display business_address below company header 2. Replace Quality Evaluation with DATA QUALITY NOTES section - High confidence metrics - Data gaps or staleness (>30 days) - Assumptions made 3. Add toast notifications on completion/error using Sonner Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>faf1006 -
Add VADER sentiment analysis for news and redditβ
- Add VADER helper functions (_get_vader, _compute_vader_sentiment) - Extract VADER scores from news headlines in _extract_key_metrics - Extract VADER scores from reddit post titles - Update metric reference table to include sentiment metrics (M##) - Display VADER breakdown in formatted prompt output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>4ec98e2 -
Layer 4: Add deterministic numeric validation in Criticβ
Enforces machine-verifiable numeric accuracy: 1. Prompt changes (analyzer.py): - Require [M##] citations for all metric values - Example: "Revenue of $394.3B [M01] demonstrates..." - Clear warning that citations are auto-verified 2. New validator (numeric_validator.py): - Extract [M##] citations from SWOT output - Normalize values ($394.3B -> 394300000000) - Compare against metric_reference with tolerance - Return specific mismatch descriptions 3. Critic integration (critic.py): - Validate citations after LLM evaluation - If mismatches: cap evidence_grounding at 4, force rejection - Add specific feedback for revision - Log validation results to activity log Tested with Ford hallucination case: - Detects: market_cap $43.4B vs expected $56.6B - Detects: pe_trailing 21.3 vs expected 12.14 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>a2c9702 -
Add compact activity log for Analyzer reference valuesβ
- Log metric reference values in compact format for manual verification - Format: revenue=$394.3B, net_margin=25.3%, pe_trailing=32.5, beta=1.23 - Shortens large numbers (B/M) and removes dates for readability - Creates audit trail: MCP data β Analyzer reference β SWOT output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>484a7a7 -
Layer 1: Add metric reference table to prevent LLM hallucinationβ
- Add immutable metric reference table at top of analyzer prompts - Use exact 'as of' dates (e.g., 2024-09-28) instead of ambiguous FY labels - Store metric_reference dict and SHA256 hash in state for integrity verification - Include reference table in both initial and revision prompts - Instruct LLM to copy values verbatim, not round or estimate New functions: - _format_metric_for_reference(): Format single metric with as-of date - _generate_metric_reference_table(): Build numbered reference table - _compute_reference_hash(): SHA256 hash for integrity check - _verify_reference_integrity(): Verify dict hasn't been corrupted Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>d2df6b8 -
Fix: Increase rate limit delays and fix revision detectionβ
1. Increase pre-call delays: 2s β 5s 2. Increase backoff times: 2s,4s,8s β 3s,6s,12s 3. Fix revision mode detection: check critique_details.status instead of revision_count (which was still 0 on first loop) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>efcfc92 -
Fix: Add rate limit handling with retry and delaysβ
1. LLM client: Add exponential backoff retry on 429 errors - MAX_RETRIES=3, delays of 2s, 4s, 8s - New _request_with_retry() helper method 2. Critic: Add 2s delay before LLM call - Avoids hitting rate limit after Analyzer's call 3. Analyzer: Add 2s delay before revision LLM call - Avoids hitting rate limit after Critic's call This prevents 429 errors from cascading through the workflow. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>de66f3b -
Fix: Critic LLM failure now triggers graceful exitβ
When Critic's LLM evaluation fails (e.g., 429 rate limit), it was returning score=5.0 without setting an error flag, causing should_continue() to return "retry" and creating an infinite loop. Now sets analyzer_revision_skipped=True on LLM error to trigger graceful exit with current draft instead of retrying. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>379f970 -
Refactor: Analyzer handles revisions directly, remove Editor nodeβ
Architecture change: Researcher β Analyzer β Critic β Analyzer (revision loop) - Add conditional focus area blocks to Analyzer based on failed rubric criteria - Add _build_revision_prompt() for structured Critic feedback integration - Analyzer detects revision mode via revision_count > 0 and critique_details - Route "retry" from Critic back to Analyzer instead of Editor - Rename editor_skipped β analyzer_revision_skipped in conditions.py - Delete redundant src/nodes/editor.py - Update Critic to LLM-only weighted rubric evaluation - Update workflow version to 2.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>53fe655
-
Fix: Process partial_metrics on completed statusβ
News and sentiment metrics were not appearing because the polling loop only processed partial_metrics during WORKING status. When the task transitioned to COMPLETED, the final poll returned immediately without emitting the remaining metrics from the last sources. Fix: Also process partial_metrics when status is 'completed' to ensure all metrics (including news and sentiment) are captured. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>e3dd83d -
Rename financials to fundamentals across frontend and backendβ
- Update MCPStatus interface and defaults to use 'fundamentals' - Update ProcessFlow MCP server list to use 'fundamentals' id - Update MCPDataPanel grouped metrics key to 'fundamentals' - Update CORE_SOURCES in researcher.py to use 'fundamentals' - Update mcp_status initialization in workflow_store.py and analysis.py - Update source_keywords in critic.py to use 'fundamentals' Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>5766b78 -
Rename financials to fundamentals for schema consistencyβ
- Update analyzer.py to use fundamentals_all instead of financials_all - Align with Researcher-Agent schema normalization changes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>3e0da39
-
Fix analyzer.py to handle temporal dict format for marginsβ
- Extract net_margin_pct, gross_margin_pct, operating_margin_pct as temporal dicts - Fix revenue_cagr_3yr field name (was revenue_cagr_3yr, source has revenue_growth_3yr) - Update formatting code to handle dict format for net_margin and debt_to_equity - Add fiscal period labels to margin and debt metrics in LLM prompt π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>19c947a -
Fix temporal data flow with structured payload patternβ
- research_gateway.py: Pass dict payload instead of positional args - researcher.py: Add backwards-compatible callback supporting both formats Ensures fiscal_year, end_date, form fields are preserved through the A2A β progress_callback β add_metric pipeline. π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>176e3c1 -
Pass temporal fields through A2A to frontendβ
- Update research_gateway.py to extract temporal fields from partial_metrics - Update researcher.py progress_callback to pass temporal data to add_metric - Enables fiscal period display (FY 2023, Q3 2024) in Key Data panel π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>67b4836 -
Add null checks for partial metrics and research resultβ
- research_gateway.py: Skip None/invalid metrics in partial_metrics array - researcher.py: Validate result is a valid dict before processing Fixes: 'NoneType' object has no attribute 'get' error π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>5336338 -
Add temporal data (fiscal year, period) to financials displayβ
Backend: - analyzer.py: Preserve fiscal year, period end date, form type from SEC EDGAR - workflow_store.py: add_metric() accepts temporal params (end_date, fiscal_year, form) Frontend: - types.ts: Add TemporalMetric interface for SEC EDGAR metrics - api.ts: Extend MetricEntry with temporal fields - MCPDataPanel.tsx: Display fiscal period labels (e.g., "FY 2023", "Q3 2024") with hover tooltip showing period end date π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>255d8a9 -
Add error logging to Activity Log for researcher failuresβ
- Log errors to Activity Log before re-raising exceptions - Add A2A request failure logging in research_gateway - Users can now see WHY research failed in the Activity Log π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>be3e4c5 -
Fix LLM failure visibility and abort handlingβ
- Update LLM status in real-time as providers fail (not just at end) - Log individual LLM provider failures to activity log - Mark "All LLM providers failed" as abort condition (not retryable error) - Move LLM status update before error check so frontend sees failures - Show "Aborted" button instead of "Failed-Retry" for LLM failures π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>fa01e42
-
Initial commit: Instant SWOT Agentβ
Multi-agent strategic analysis system with: - Research Gateway (A2A client to Researcher-Agent) - Analyzer, Critic, Editor workflow nodes - Data grounding enforcement in all LLM calls - React frontend with real-time progress π€ Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>0c591a7