debug: expose full inputs/outputs in Recalculer response for diagnosis

_run_auto_analysis now returns a rich dict {ok, inputs, node_values, actual_moves, error}
instead of bool. The refresh endpoint captures and forwards:
- inputs: what values were fed to evaluate_graph
- node_keys: which nodes were computed in prediction
- actual_moves: actual price pips fetched
- run_error: exception message if it failed

Frontend shows all of this after clicking Recalculer so the root cause is visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-29 23:09:49 +02:00
parent af73b77cba
commit c73bedd7d0
2 changed files with 29 additions and 18 deletions

View File

@@ -1127,11 +1127,10 @@ def _build_graph_json_from_spec(spec: dict) -> dict:
}
def _run_auto_analysis(event: dict, template_id: int) -> bool:
def _run_auto_analysis(event: dict, template_id: int) -> dict:
"""
Causal analysis for the auto_template pipeline.
Builds inputs from event fields, evaluates the graph, fetches actual prices,
and upserts into causal_event_analyses so the instrument frise can score it.
Returns {"ok": bool, "inputs": dict, "node_values": dict, "actual_moves": dict, "error": str}.
"""
try:
from services.database import get_conn
@@ -1142,7 +1141,7 @@ def _run_auto_analysis(event: dict, template_id: int) -> bool:
if not tmpl:
conn.close()
logger.warning(f"[auto_analysis] template #{template_id} introuvable")
return False
return {"ok": False, "error": f"template #{template_id} introuvable"}
graph = tmpl["graph_json"]
inputs = {}
@@ -1310,11 +1309,17 @@ def _run_auto_analysis(event: dict, template_id: int) -> bool:
conn.commit()
conn.close()
logger.info(f"[auto_analysis] upserted event #{event_id}, tmpl #{template_id}, actual_moves={actual_moves}")
return True
return {
"ok": True,
"inputs": inputs,
"node_values": node_values,
"actual_moves": actual_moves,
"instruments": instruments,
}
except Exception as e:
logger.error(f"[auto_analysis] event #{event.get('id')}: {e}")
return False
logger.error(f"[auto_analysis] event #{event.get('id')}: {e}", exc_info=True)
return {"ok": False, "error": str(e)}
def auto_assign_template(event_id: int) -> dict:
@@ -1481,13 +1486,16 @@ def refresh_auto_analyses():
detail["actual_value"] = ev.get("actual_value")
detail["expected_value"] = ev.get("expected_value")
detail["start_date"] = ev.get("start_date")
ok = _run_auto_analysis(ev, row["template_id"])
detail["result"] = "ok" if ok else "failed"
if ok:
res = _run_auto_analysis(ev, row["template_id"])
detail["result"] = "ok" if res["ok"] else "failed"
detail["inputs"] = res.get("inputs", {})
detail["node_keys"] = list(res.get("node_values", {}).keys())
detail["actual_moves"] = res.get("actual_moves", {})
detail["run_error"] = res.get("error")
if res["ok"]:
refreshed += 1
else:
failed += 1
detail["result"] = "run_returned_false"
except Exception as _e:
logger.warning(f"[refresh_auto_analyses] cea#{row['cea_id']}: {_e}")
detail["result"] = f"exception: {_e}"