gates.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from __future__ import annotations
  2. from dataclasses import dataclass
  3. from typing import Any
  4. @dataclass(frozen=True)
  5. class GateDecision:
  6. passed: bool
  7. error_code: str | None = None
  8. error_message: str | None = None
  9. def evaluate_step_gate(step_key: str, payload: dict[str, Any]) -> GateDecision:
  10. if payload.get("success") is False:
  11. return GateDecision(
  12. passed=False,
  13. error_code=str(payload.get("error_code") or "step_reported_failure"),
  14. error_message=str(payload.get("error") or "Step returned success=false"),
  15. )
  16. if step_key in {"demand_grade", "demand_expand", "video_discovery"}:
  17. failed = int(payload.get("failed", payload.get("failed_count", 0)) or 0)
  18. if failed > 0:
  19. return GateDecision(
  20. False,
  21. "business_failures",
  22. f"{step_key} reported {failed} failed item(s)",
  23. )
  24. if step_key == "aigc_write_record":
  25. request_made = payload.get("external_request_made") is True
  26. if request_made and (
  27. payload.get("effect_recorded") is not True
  28. or not payload.get("outbox_ids")
  29. ):
  30. return GateDecision(
  31. False,
  32. "aigc_record_incomplete",
  33. "AIGC publish batches were not durably recorded before dispatch",
  34. )
  35. failed_batches = int(payload.get("failed_batch_count", 0) or 0)
  36. if failed_batches > 0:
  37. return GateDecision(
  38. False,
  39. "aigc_publish_failed",
  40. f"AIGC publish reported {failed_batches} failed batch(es)",
  41. )
  42. return GateDecision(True)