MicroFish/backend/app/api
LoryGlory 00a2150365 feat(report): add POST /api/report/<id>/signal — extract miro_signal from simulation report
Adds a canonical machine-readable probability signal endpoint that distils
a completed simulation report into a structured prediction thesis.

New: backend/app/services/signal_extractor.py
- SignalExtractor.extract() calls chat_json() (3 attempts, temp 0.1, step 0.05)
  against the report markdown and returns a validated MiroSignal dataclass
- Validates and normalises all fields: p_yes clamped to [0.01, 0.99],
  confidence/action enums enforced, action recomputed from p_yes when invalid
- _trim_report() keeps the tail (conclusions) for long reports to stay within
  token limits
- _salvage() fallback_parser recovers a minimal signal from partial LLM output
  using regex probability extraction

New endpoint: POST /api/report/<report_id>/signal
- 404 if report not found
- 400 if report not yet completed or content is empty
- 422 if LLM fails after all retry attempts
- Returns canonical signal with thesis.{p_yes, confidence, action, regime,
  summary, drivers, invalidators} — schema_version 1.1

New: backend/tests/services/test_signal_extractor.py
- 27 tests covering happy path, field validation/normalisation, report
  trimming, _salvage fallback, and LLM failure propagation
- No real API calls — LLMClient fully mocked

Closes #277

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 16:18:50 +01:00
..
__init__.py Implement Report Agent for automated report generation and interaction 2025-12-09 15:10:55 +08:00
graph.py Refactor project creation process in API documentation and code 2025-11-29 00:47:54 +08:00
report.py feat(report): add POST /api/report/<id>/signal — extract miro_signal from simulation report 2026-03-23 16:18:50 +01:00
simulation.py feat(SimulationAPI): add function to retrieve latest report ID for a given simulation 2026-01-09 16:04:35 +08:00