Spaces:
Sleeping
Sleeping
| """Direct (non-agent) Bayesian compute endpoints. | |
| These are useful both as a fallback (when no API key is configured) and as a | |
| fast path the frontend can call directly when the user is hand-driving the | |
| workbench instead of talking to the Agent. | |
| """ | |
| from __future__ import annotations | |
| from fastapi import APIRouter, HTTPException | |
| from app.api.schemas import ( | |
| BayesComputeRequest, | |
| BayesResultModel, | |
| SensitivityPointModel, | |
| SensitivityRequest, | |
| SensitivityResponse, | |
| bayes_result_to_model, | |
| ) | |
| from app.domain.bayesian import compute, kde, sensitivity_analysis | |
| from app.domain.report import render_markdown_report | |
| router = APIRouter(prefix="/api/bayesian", tags=["bayesian"]) | |
| async def post_compute(req: BayesComputeRequest) -> BayesResultModel: | |
| try: | |
| result = compute(req.data, req.judgments, req.R) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) from e | |
| return bayes_result_to_model(result) | |
| async def post_sensitivity(req: SensitivityRequest) -> SensitivityResponse: | |
| try: | |
| points = sensitivity_analysis(req.data, req.judgments, req.r_values) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) from e | |
| return SensitivityResponse( | |
| points=[ | |
| SensitivityPointModel(R=p["R"], result=bayes_result_to_model(p["result"])) | |
| for p in points | |
| ] | |
| ) | |
| async def post_kde(req: BayesComputeRequest) -> dict: | |
| """Return the KDE curve for the dataset (200 points). Used by the | |
| PriorPosterior / KDE chart on the frontend.""" | |
| try: | |
| pts = kde(req.data, n_points=200) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) from e | |
| return {"points": pts} | |
| async def post_report(req: BayesComputeRequest) -> dict: | |
| """Compute + render a structured Markdown report in one call.""" | |
| try: | |
| result = compute(req.data, req.judgments, req.R) | |
| sweep = sensitivity_analysis(req.data, req.judgments, [2.0, 5.0, 10.0, 20.0, 50.0]) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) from e | |
| sens_rows = [ | |
| { | |
| "R": p["R"], | |
| "posterior_mean": p["result"].posterior.stats.mean, | |
| "posterior_std": p["result"].posterior.stats.std, | |
| "ci95_lower": p["result"].posterior.stats.ci95_lower, | |
| "ci95_upper": p["result"].posterior.stats.ci95_upper, | |
| } | |
| for p in sweep | |
| ] | |
| md = render_markdown_report( | |
| result, | |
| scenario_name=req.scenario_name or "未命名情景", | |
| reference_case=req.reference_case or "", | |
| sensitivity_rows=sens_rows, | |
| ) | |
| return {"markdown": md, "result": bayes_result_to_model(result).model_dump()} | |