run_production.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """从 GlobalDataStageDelivery 启动或恢复 Production 0.7 正式闭环。"""
  2. from __future__ import annotations
  3. import argparse
  4. import json
  5. from pathlib import Path
  6. from uuid import uuid4
  7. from dotenv import load_dotenv
  8. from production_build_agents.production.runtime import run_production_graph
  9. PROJECT_ROOT = Path(__file__).resolve().parent
  10. def run_full_production(
  11. global_data_delivery_path: Path,
  12. *,
  13. output_root: Path,
  14. thread_id: str,
  15. shared_visual_anchor_path: Path,
  16. **runtime_options,
  17. ):
  18. """Production 0.7 CLI façade;正式控制流只存在于 LangGraph。"""
  19. load_dotenv(PROJECT_ROOT / ".env", override=False)
  20. return run_production_graph(
  21. global_data_delivery_path,
  22. output_root=output_root,
  23. thread_id=thread_id,
  24. shared_visual_anchor_path=shared_visual_anchor_path,
  25. **runtime_options,
  26. )
  27. def _build_parser() -> argparse.ArgumentParser:
  28. parser = argparse.ArgumentParser(
  29. description=(
  30. "运行或恢复 Production 0.7:Planner → Segment DAG → "
  31. "Assembly → Production Validator → Replan"
  32. )
  33. )
  34. parser.add_argument(
  35. "global_data_delivery",
  36. type=Path,
  37. help="Global Data 阶段正式 GlobalDataStageDelivery JSON",
  38. )
  39. parser.add_argument(
  40. "--output-dir",
  41. type=Path,
  42. default=Path("demo_output"),
  43. )
  44. parser.add_argument("--thread-id", default=None)
  45. parser.add_argument(
  46. "--shared-visual-anchor",
  47. type=Path,
  48. required=True,
  49. help="已在 Production 外部封印并接纳的共享视觉锚点图片",
  50. )
  51. parser.add_argument(
  52. "--max-plan-revisions",
  53. type=int,
  54. default=5,
  55. choices=range(0, 6),
  56. metavar="{0..5}",
  57. help="本次运行允许的 ADAPT/REPLAN 总次数;协议硬上限为 5",
  58. )
  59. parser.add_argument(
  60. "--pause-after-progress-review",
  61. action="store_true",
  62. help=(
  63. "在下一次 Segment Progress Review 完成并保存 checkpoint 后"
  64. "以 RUNNING 状态安全暂停;恢复时省略此参数"
  65. ),
  66. )
  67. return parser
  68. def main() -> None:
  69. args = _build_parser().parse_args()
  70. result = run_full_production(
  71. args.global_data_delivery,
  72. output_root=args.output_dir,
  73. thread_id=args.thread_id or f"production-{uuid4()}",
  74. shared_visual_anchor_path=args.shared_visual_anchor,
  75. max_plan_revisions=args.max_plan_revisions,
  76. pause_after_progress_review=args.pause_after_progress_review,
  77. )
  78. print(json.dumps(result, ensure_ascii=False, indent=2))
  79. if result.get("status") == "COMPLETED":
  80. return
  81. if (
  82. args.pause_after_progress_review
  83. and result.get("status") == "RUNNING"
  84. ):
  85. return
  86. raise SystemExit(1)
  87. if __name__ == "__main__":
  88. main()