from __future__ import annotations import json import sys from pathlib import Path from statistics import mean ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from bdo_ai_env.baseline_agent import greedy_policy, stingy_policy from models import BDOAction from server.bdo_environment import BDOEnvironment def run_policy(policy_name: str, scenario: str): policy_fn = {"greedy": greedy_policy, "stingy": stingy_policy}[policy_name] env = BDOEnvironment(scenario=scenario) observation = env.reset() monthly = [] while not observation.done: action_batch = policy_fn(observation.model_dump(mode="json", exclude_none=True)) observation = env.step(BDOAction.model_validate(action_batch)) step_info = observation.info or observation.metadata monthly.append( { "month": observation.meta.month - 1, "reward": observation.reward, **step_info["reward_breakdown"], } ) final = monthly[-1] return { "policy": policy_name, "scenario": scenario, "shock_month": env.state.shock_month, "final_reward": round(final["total"], 4), "avg_reward": round(mean(float(item["reward"] or 0.0) for item in monthly), 4), "min_reward": round(min(float(item["reward"] or 0.0) for item in monthly), 4), "final_coverage": final["coverage"], "final_security": final["fraud_prevention"], "final_solvency": final["solvency"], "final_stability": final["stability"], "final_belief": final["belief_accuracy"], "monthly": monthly, } def main() -> None: scenario = sys.argv[1] if len(sys.argv) > 1 else "black_swan" output_path = sys.argv[2] if len(sys.argv) > 2 else None report = { "scenario": scenario, "results": [ run_policy("greedy", scenario), run_policy("stingy", scenario), ], } rendered = json.dumps(report, indent=2) if output_path: output = Path(output_path) output.parent.mkdir(parents=True, exist_ok=True) output.write_text(rendered, encoding="utf-8") print(rendered) if __name__ == "__main__": main()