runtime_event_projection.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from __future__ import annotations
  2. from datetime import datetime, timezone
  3. from typing import Any, Iterable
  4. from .evaluation_event_projection import EvaluationEventProjector
  5. from .creative_event_projection import CreativeEventProjector
  6. from .main_agent_decision_projection import MainAgentDecisionProjector
  7. from .retrieval_event_projection import RetrievalEventProjector
  8. from .runtime_event_index import RuntimeEventIndex
  9. class RuntimeEventProjector:
  10. """Facade that builds one event index and composes business projections."""
  11. def __init__(
  12. self,
  13. *,
  14. retrieval_projector: RetrievalEventProjector | None = None,
  15. evaluation_projector: EvaluationEventProjector | None = None,
  16. main_agent_projector: MainAgentDecisionProjector | None = None,
  17. creative_projector: CreativeEventProjector | None = None,
  18. ):
  19. self._retrieval_projector = retrieval_projector or RetrievalEventProjector()
  20. self._evaluation_projector = evaluation_projector or EvaluationEventProjector()
  21. self._main_agent_projector = main_agent_projector or MainAgentDecisionProjector()
  22. self._creative_projector = creative_projector or CreativeEventProjector()
  23. def project(
  24. self,
  25. events: list[dict[str, Any]],
  26. *,
  27. valid_rounds: set[int],
  28. valid_branches: set[int],
  29. captured_at: datetime | None = None,
  30. run_status: str | None = None,
  31. script_direction: str | None = None,
  32. rounds: Iterable[dict[str, Any]] = (),
  33. multipath_decisions: Iterable[dict[str, Any]] = (),
  34. ) -> dict[str, Any]:
  35. captured_at = captured_at or datetime.now(timezone.utc)
  36. index = RuntimeEventIndex(events)
  37. retrieval = self._retrieval_projector.project(
  38. index,
  39. valid_rounds=valid_rounds,
  40. valid_branches=valid_branches,
  41. captured_at=captured_at,
  42. run_status=run_status,
  43. )
  44. evaluations = self._evaluation_projector.project(
  45. index,
  46. valid_rounds=valid_rounds,
  47. valid_branches=valid_branches,
  48. )
  49. main_agent = self._main_agent_projector.project(
  50. index,
  51. script_direction=script_direction,
  52. rounds=rounds,
  53. multipath_decisions=multipath_decisions,
  54. )
  55. creative = self._creative_projector.project(
  56. index,
  57. valid_rounds=valid_rounds,
  58. valid_branches=valid_branches,
  59. )
  60. unassigned = [
  61. *retrieval.get("unassigned", []),
  62. *evaluations.get("unassigned", []),
  63. *main_agent.get("unassigned", []),
  64. *creative.get("unassigned", []),
  65. ]
  66. return {
  67. "multipathReviewsByRound": evaluations.get(
  68. "multipathReviewsByRound", {}
  69. ),
  70. "overallEvaluationsByRound": evaluations.get(
  71. "overallEvaluationsByRound", {}
  72. ),
  73. "retrievalStagesByBranch": retrieval.get(
  74. "retrievalStagesByBranch", {}
  75. ),
  76. "mainAgentDecisions": main_agent,
  77. "creativeByBranch": creative.get("creativeByBranch", {}),
  78. "unassigned": unassigned,
  79. }