agentevolve-optimizer 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. agent_evolve/__init__.py +722 -0
  2. agent_evolve/agentic.py +2800 -0
  3. agent_evolve/api.py +767 -0
  4. agent_evolve/application/__init__.py +1580 -0
  5. agent_evolve/application/action_allocation.py +744 -0
  6. agent_evolve/application/action_allocation_frame.py +347 -0
  7. agent_evolve/application/action_allocation_frame_commit.py +185 -0
  8. agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
  9. agent_evolve/application/action_allocation_frame_v3.py +338 -0
  10. agent_evolve/application/action_archive_value.py +497 -0
  11. agent_evolve/application/action_evidence_consistency.py +455 -0
  12. agent_evolve/application/action_forecast_partitioning.py +1471 -0
  13. agent_evolve/application/action_metric_projection.py +211 -0
  14. agent_evolve/application/action_role_value.py +680 -0
  15. agent_evolve/application/action_score_authorities.py +363 -0
  16. agent_evolve/application/action_structural_signature.py +116 -0
  17. agent_evolve/application/action_target_realization.py +402 -0
  18. agent_evolve/application/agentic_evolution.py +7734 -0
  19. agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
  20. agent_evolve/application/anchor_residual_identification.py +463 -0
  21. agent_evolve/application/archive_conditioned_action_target.py +208 -0
  22. agent_evolve/application/artifact_journal.py +246 -0
  23. agent_evolve/application/artifact_replay.py +347 -0
  24. agent_evolve/application/budgeted_optimizer.py +1828 -0
  25. agent_evolve/application/calibrated_campaign.py +485 -0
  26. agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
  27. agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
  28. agent_evolve/application/campaign_capacity_recourse.py +254 -0
  29. agent_evolve/application/campaign_contextual_outcomes.py +119 -0
  30. agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
  31. agent_evolve/application/campaign_evidence_registry.py +262 -0
  32. agent_evolve/application/campaign_execution.py +2537 -0
  33. agent_evolve/application/campaign_generation_audit.py +942 -0
  34. agent_evolve/application/campaign_learning.py +1812 -0
  35. agent_evolve/application/campaign_learning_runtime.py +1977 -0
  36. agent_evolve/application/campaign_search_phase.py +227 -0
  37. agent_evolve/application/campaign_selector_context_extension.py +220 -0
  38. agent_evolve/application/campaign_variation_envelope.py +649 -0
  39. agent_evolve/application/campaign_variation_trace.py +451 -0
  40. agent_evolve/application/candidate_archive_consequence.py +128 -0
  41. agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
  42. agent_evolve/application/composite_outcome_updater.py +145 -0
  43. agent_evolve/application/composition_portfolio_selection.py +363 -0
  44. agent_evolve/application/concurrent_stage.py +144 -0
  45. agent_evolve/application/contextual_action_allocation.py +181 -0
  46. agent_evolve/application/contextual_campaign_outcomes.py +267 -0
  47. agent_evolve/application/contextual_campaign_planning.py +1366 -0
  48. agent_evolve/application/contextual_delayed_credit.py +651 -0
  49. agent_evolve/application/contextual_search_controller.py +2374 -0
  50. agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
  51. agent_evolve/application/decision_metric_projection.py +112 -0
  52. agent_evolve/application/derived_action_semantics.py +129 -0
  53. agent_evolve/application/detailed_evaluation.py +449 -0
  54. agent_evolve/application/earned_lineage.py +1011 -0
  55. agent_evolve/application/effective_choice_audit.py +484 -0
  56. agent_evolve/application/empirical_consequence_calibration.py +908 -0
  57. agent_evolve/application/evaluation_accounting.py +325 -0
  58. agent_evolve/application/evaluation_cache.py +199 -0
  59. agent_evolve/application/evaluation_escrow.py +547 -0
  60. agent_evolve/application/evaluation_recourse.py +253 -0
  61. agent_evolve/application/event_recorder.py +151 -0
  62. agent_evolve/application/evolution_campaign.py +1840 -0
  63. agent_evolve/application/executable_hypothesis.py +323 -0
  64. agent_evolve/application/factorial_branch_pilot.py +772 -0
  65. agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
  66. agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
  67. agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
  68. agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
  69. agent_evolve/application/finite_action_selection.py +188 -0
  70. agent_evolve/application/finite_action_set.py +306 -0
  71. agent_evolve/application/finite_action_transition.py +537 -0
  72. agent_evolve/application/finite_variation_eligibility.py +296 -0
  73. agent_evolve/application/forecast_geometry_portfolio.py +799 -0
  74. agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
  75. agent_evolve/application/front_proximity_admission.py +311 -0
  76. agent_evolve/application/front_proximity_parent_basis.py +458 -0
  77. agent_evolve/application/frozen_hurdle_score.py +659 -0
  78. agent_evolve/application/g3_causal_screen.py +2257 -0
  79. agent_evolve/application/g3_causal_validation.py +1046 -0
  80. agent_evolve/application/g3_postseal_curation.py +818 -0
  81. agent_evolve/application/gated_agentic_generator.py +205 -0
  82. agent_evolve/application/generation_feedback.py +293 -0
  83. agent_evolve/application/generative_proposal_journal.py +185 -0
  84. agent_evolve/application/geometry_conditional_elasticity.py +453 -0
  85. agent_evolve/application/global_wave_action_allocation.py +1151 -0
  86. agent_evolve/application/head_mass_conditional_seat.py +268 -0
  87. agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
  88. agent_evolve/application/identifiable_reflection_learning.py +395 -0
  89. agent_evolve/application/identifiable_reflection_request.py +364 -0
  90. agent_evolve/application/in_memory_residual_archive.py +341 -0
  91. agent_evolve/application/insight_memory.py +1804 -0
  92. agent_evolve/application/live_runtime_manifest.py +758 -0
  93. agent_evolve/application/llm_task_queue.py +769 -0
  94. agent_evolve/application/matched_finite_action_block.py +409 -0
  95. agent_evolve/application/materialized_action_broker.py +2328 -0
  96. agent_evolve/application/materialized_action_constraints.py +83 -0
  97. agent_evolve/application/materialized_variation.py +211 -0
  98. agent_evolve/application/multi_option_evolution.py +1536 -0
  99. agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
  100. agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
  101. agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
  102. agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
  103. agent_evolve/application/outcome_relation.py +193 -0
  104. agent_evolve/application/paired_allocation_comparison.py +241 -0
  105. agent_evolve/application/paired_block_schedule.py +127 -0
  106. agent_evolve/application/parent_measurement.py +226 -0
  107. agent_evolve/application/pareto_archive.py +811 -0
  108. agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
  109. agent_evolve/application/portfolio_evolution.py +2950 -0
  110. agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
  111. agent_evolve/application/portfolio_memory_attribution.py +581 -0
  112. agent_evolve/application/portfolio_memory_dose.py +788 -0
  113. agent_evolve/application/portfolio_memory_matched_control.py +938 -0
  114. agent_evolve/application/portfolio_memory_transfer.py +297 -0
  115. agent_evolve/application/portfolio_optimization_memory.py +363 -0
  116. agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
  117. agent_evolve/application/portfolio_projection.py +335 -0
  118. agent_evolve/application/portfolio_recombination.py +2032 -0
  119. agent_evolve/application/post_evolution_reflection.py +834 -0
  120. agent_evolve/application/postcommit_rank_authority.py +245 -0
  121. agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
  122. agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
  123. agent_evolve/application/prequential_residual_exploration.py +343 -0
  124. agent_evolve/application/prequential_score_portfolio.py +954 -0
  125. agent_evolve/application/projections.py +292 -0
  126. agent_evolve/application/protected_action_committee.py +1027 -0
  127. agent_evolve/application/protected_branch_pilot.py +376 -0
  128. agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
  129. agent_evolve/application/provider_replay.py +910 -0
  130. agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
  131. agent_evolve/application/recombination_residual_expert.py +403 -0
  132. agent_evolve/application/reflection_workflow.py +571 -0
  133. agent_evolve/application/region_conditional_credit.py +911 -0
  134. agent_evolve/application/residual_campaign_runtime.py +531 -0
  135. agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
  136. agent_evolve/application/residual_headroom_ledger.py +1544 -0
  137. agent_evolve/application/residual_learning_transaction.py +396 -0
  138. agent_evolve/application/residual_portfolio_evolution.py +1228 -0
  139. agent_evolve/application/residual_reachability.py +749 -0
  140. agent_evolve/application/residual_stage_credit.py +499 -0
  141. agent_evolve/application/same_prefix_paired_audit.py +1580 -0
  142. agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
  143. agent_evolve/application/sequential_lineage_allocation.py +1017 -0
  144. agent_evolve/application/sequential_market_replay.py +1395 -0
  145. agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
  146. agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
  147. agent_evolve/application/single_score_action_allocation.py +299 -0
  148. agent_evolve/application/source_exposure_allocation.py +906 -0
  149. agent_evolve/application/staged_memory.py +210 -0
  150. agent_evolve/application/stratified_cold_start_allocation.py +732 -0
  151. agent_evolve/application/support_guarded_hurdle_score.py +549 -0
  152. agent_evolve/application/target_conditioned_action_forecast.py +595 -0
  153. agent_evolve/application/target_conditioned_campaign.py +566 -0
  154. agent_evolve/application/treatment_assignment.py +201 -0
  155. agent_evolve/application/trusted_objective_evidence.py +217 -0
  156. agent_evolve/application/two_stage_action_evolution.py +1131 -0
  157. agent_evolve/application/v8lite_allocation_policy.py +1083 -0
  158. agent_evolve/application/v9_candidate_policy.py +1303 -0
  159. agent_evolve/bootstrap.py +108 -0
  160. agent_evolve/campaign_presets.py +517 -0
  161. agent_evolve/campaign_profiles.py +452 -0
  162. agent_evolve/campaign_variation_topology.py +288 -0
  163. agent_evolve/campaign_workload.py +950 -0
  164. agent_evolve/cli.py +797 -0
  165. agent_evolve/contract.py +241 -0
  166. agent_evolve/core/__init__.py +91 -0
  167. agent_evolve/core/action_semantics.py +411 -0
  168. agent_evolve/core/authored.py +105 -0
  169. agent_evolve/core/formatting.py +286 -0
  170. agent_evolve/core/optimization_semantics.py +324 -0
  171. agent_evolve/core/problem.py +167 -0
  172. agent_evolve/core/results.py +323 -0
  173. agent_evolve/core/stats.py +70 -0
  174. agent_evolve/core/telemetry.py +100 -0
  175. agent_evolve/domain/__init__.py +89 -0
  176. agent_evolve/domain/artifact.py +162 -0
  177. agent_evolve/domain/durable_text.py +68 -0
  178. agent_evolve/domain/event.py +1454 -0
  179. agent_evolve/domain/finite_action_set.py +426 -0
  180. agent_evolve/domain/finite_variation.py +526 -0
  181. agent_evolve/domain/generative_emission.py +559 -0
  182. agent_evolve/domain/ids.py +163 -0
  183. agent_evolve/domain/inline_text.py +106 -0
  184. agent_evolve/domain/insight.py +27 -0
  185. agent_evolve/domain/lineage.py +737 -0
  186. agent_evolve/domain/llm_task_queue.py +960 -0
  187. agent_evolve/domain/outcome.py +96 -0
  188. agent_evolve/domain/patch.py +854 -0
  189. agent_evolve/domain/typed_json.py +542 -0
  190. agent_evolve/domain/variation_space.py +158 -0
  191. agent_evolve/driver.py +1014 -0
  192. agent_evolve/harness/__init__.py +29 -0
  193. agent_evolve/harness/base.py +242 -0
  194. agent_evolve/harness/directives.py +163 -0
  195. agent_evolve/harness/generative_seal.py +479 -0
  196. agent_evolve/harness/registry.py +41 -0
  197. agent_evolve/infrastructure/__init__.py +39 -0
  198. agent_evolve/infrastructure/artifacts/__init__.py +6 -0
  199. agent_evolve/infrastructure/artifacts/_verification.py +67 -0
  200. agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
  201. agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
  202. agent_evolve/infrastructure/asyncio_runtime.py +109 -0
  203. agent_evolve/infrastructure/authored_runtime.py +188 -0
  204. agent_evolve/infrastructure/authored_worker.py +171 -0
  205. agent_evolve/infrastructure/clock.py +53 -0
  206. agent_evolve/infrastructure/events/__init__.py +6 -0
  207. agent_evolve/infrastructure/events/_validation.py +89 -0
  208. agent_evolve/infrastructure/events/in_memory.py +56 -0
  209. agent_evolve/infrastructure/events/jsonl.py +193 -0
  210. agent_evolve/infrastructure/exception_provenance.py +215 -0
  211. agent_evolve/infrastructure/ids.py +118 -0
  212. agent_evolve/infrastructure/lineage_codec.py +1836 -0
  213. agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
  214. agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
  215. agent_evolve/infrastructure/resource_lease.py +370 -0
  216. agent_evolve/infrastructure/sanitization/__init__.py +8 -0
  217. agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
  218. agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
  219. agent_evolve/infrastructure/stream_liveness.py +383 -0
  220. agent_evolve/infrastructure/subprocess_boundary.py +136 -0
  221. agent_evolve/integrations/__init__.py +1 -0
  222. agent_evolve/integrations/botorch/__init__.py +28 -0
  223. agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
  224. agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
  225. agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
  226. agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
  227. agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
  228. agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
  229. agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
  230. agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
  231. agent_evolve/integrations/completion.py +242 -0
  232. agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
  233. agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
  234. agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
  235. agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
  236. agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
  237. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
  238. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
  239. agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
  240. agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
  241. agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
  242. agent_evolve/integrations/pydantic_ai/harness.py +159 -0
  243. agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
  244. agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
  245. agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
  246. agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
  247. agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
  248. agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
  249. agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
  250. agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
  251. agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
  252. agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
  253. agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
  254. agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
  255. agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
  256. agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
  257. agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
  258. agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
  259. agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
  260. agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
  261. agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
  262. agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
  263. agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
  264. agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
  265. agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
  266. agent_evolve/integrations/pymoo_adapter.py +242 -0
  267. agent_evolve/policies/__init__.py +17 -0
  268. agent_evolve/policies/check.py +469 -0
  269. agent_evolve/policies/emit_scaffold.py +451 -0
  270. agent_evolve/policies/feedback/__init__.py +37 -0
  271. agent_evolve/policies/feedback/held_out_asn.py +1325 -0
  272. agent_evolve/policies/genetic.py +607 -0
  273. agent_evolve/policies/llm_backoff.py +183 -0
  274. agent_evolve/policies/llm_chooser.py +226 -0
  275. agent_evolve/policies/llm_generator.py +1760 -0
  276. agent_evolve/policies/llm_init.py +267 -0
  277. agent_evolve/policies/llm_operator.py +109 -0
  278. agent_evolve/policies/llm_prior.py +194 -0
  279. agent_evolve/policies/llm_surrogate.py +334 -0
  280. agent_evolve/policies/measurement_evidence.py +704 -0
  281. agent_evolve/policies/memory/__init__.py +223 -0
  282. agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
  283. agent_evolve/policies/memory/compatibility_matching.py +593 -0
  284. agent_evolve/policies/memory/global_falsification.py +1841 -0
  285. agent_evolve/policies/memory/prompt_shape.py +503 -0
  286. agent_evolve/policies/memory/randomized_subset.py +714 -0
  287. agent_evolve/policies/memory/staged_causal.py +1270 -0
  288. agent_evolve/policies/memory/treatment_compliance.py +759 -0
  289. agent_evolve/policies/objective_resolution/__init__.py +17 -0
  290. agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
  291. agent_evolve/policies/operator_portfolio.py +407 -0
  292. agent_evolve/policies/reguidance.py +1133 -0
  293. agent_evolve/policies/reward/__init__.py +83 -0
  294. agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
  295. agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
  296. agent_evolve/policies/reward/affine_hypervolume.py +490 -0
  297. agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
  298. agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
  299. agent_evolve/policies/reward/frozen_archive.py +360 -0
  300. agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
  301. agent_evolve/policies/search_state.py +208 -0
  302. agent_evolve/policies/selection/__init__.py +345 -0
  303. agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
  304. agent_evolve/policies/selection/affine_frontier_context.py +330 -0
  305. agent_evolve/policies/selection/affine_frontier_target.py +473 -0
  306. agent_evolve/policies/selection/archive_elite.py +1346 -0
  307. agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
  308. agent_evolve/policies/selection/calibrated_slate.py +1394 -0
  309. agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
  310. agent_evolve/policies/selection/common_candidate_pool.py +685 -0
  311. agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
  312. agent_evolve/policies/selection/disjoint_pairs.py +479 -0
  313. agent_evolve/policies/selection/elite_explorer.py +719 -0
  314. agent_evolve/policies/selection/finite_action.py +187 -0
  315. agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
  316. agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
  317. agent_evolve/policies/selection/forecast_calibration.py +922 -0
  318. agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
  319. agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
  320. agent_evolve/policies/selection/full_support_slate.py +91 -0
  321. agent_evolve/policies/selection/meaningful_direction.py +240 -0
  322. agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
  323. agent_evolve/policies/selection/model_anchored_slate.py +826 -0
  324. agent_evolve/policies/selection/phenotype_recourse.py +979 -0
  325. agent_evolve/policies/selection/proposal_support.py +368 -0
  326. agent_evolve/policies/selection/random_portfolio.py +254 -0
  327. agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
  328. agent_evolve/policies/selection/residual_frontier.py +463 -0
  329. agent_evolve/policies/selection/residual_frontier_target.py +605 -0
  330. agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
  331. agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
  332. agent_evolve/policies/selection/target_conditioned_features.py +812 -0
  333. agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
  334. agent_evolve/policies/selection/task_keyed_palette.py +906 -0
  335. agent_evolve/policies/semantics.py +147 -0
  336. agent_evolve/policies/structure.py +362 -0
  337. agent_evolve/policies/structured_output_budget.py +62 -0
  338. agent_evolve/policies/surrogate.py +696 -0
  339. agent_evolve/policies/variation/__init__.py +1 -0
  340. agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
  341. agent_evolve/policies/variation/crossover_inheritance.py +575 -0
  342. agent_evolve/policies/variation/disjoint_recombination.py +611 -0
  343. agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
  344. agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
  345. agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
  346. agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
  347. agent_evolve/policies/variation/typed_patch.py +1981 -0
  348. agent_evolve/policies/weighted_prior.py +394 -0
  349. agent_evolve/ports/__init__.py +383 -0
  350. agent_evolve/ports/action_allocation.py +733 -0
  351. agent_evolve/ports/action_allocation_frame.py +1153 -0
  352. agent_evolve/ports/action_allocation_frame_commit.py +294 -0
  353. agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
  354. agent_evolve/ports/action_allocation_frame_v3.py +995 -0
  355. agent_evolve/ports/action_forecast.py +1568 -0
  356. agent_evolve/ports/action_metric_projection.py +165 -0
  357. agent_evolve/ports/agentic_generator.py +1561 -0
  358. agent_evolve/ports/archive_context.py +136 -0
  359. agent_evolve/ports/artifact_sanitizer.py +44 -0
  360. agent_evolve/ports/artifact_store.py +225 -0
  361. agent_evolve/ports/clock.py +13 -0
  362. agent_evolve/ports/contextual_search_allocation.py +827 -0
  363. agent_evolve/ports/decision_metric_projection.py +258 -0
  364. agent_evolve/ports/event_store.py +55 -0
  365. agent_evolve/ports/executable_hypothesis.py +557 -0
  366. agent_evolve/ports/finite_acquisition.py +377 -0
  367. agent_evolve/ports/finite_acquisition_batch.py +296 -0
  368. agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
  369. agent_evolve/ports/finite_acquisition_json.py +247 -0
  370. agent_evolve/ports/finite_acquisition_space.py +168 -0
  371. agent_evolve/ports/finite_action_selection.py +348 -0
  372. agent_evolve/ports/finite_action_set.py +256 -0
  373. agent_evolve/ports/frontier_target.py +396 -0
  374. agent_evolve/ports/generation_failure.py +43 -0
  375. agent_evolve/ports/hard_feasibility.py +233 -0
  376. agent_evolve/ports/id_factory.py +34 -0
  377. agent_evolve/ports/llm_task_queue.py +93 -0
  378. agent_evolve/ports/objective_resolution.py +419 -0
  379. agent_evolve/ports/paired_allocation_comparison.py +401 -0
  380. agent_evolve/ports/paired_block_schedule.py +475 -0
  381. agent_evolve/ports/parent_measurement.py +336 -0
  382. agent_evolve/ports/portfolio_memory_dose.py +643 -0
  383. agent_evolve/ports/portfolio_selection.py +3169 -0
  384. agent_evolve/ports/postcommit_rank_authority.py +467 -0
  385. agent_evolve/ports/presented_action_evidence.py +794 -0
  386. agent_evolve/ports/resource_lease.py +162 -0
  387. agent_evolve/ports/structured_generator.py +734 -0
  388. agent_evolve/ports/structured_output_budget.py +120 -0
  389. agent_evolve/ports/subprocess_boundary.py +138 -0
  390. agent_evolve/ports/treatment_assignment.py +466 -0
  391. agent_evolve/ports/variation_catalog.py +76 -0
  392. agent_evolve/ports/variation_source.py +226 -0
  393. agent_evolve/proposal_mode.py +157 -0
  394. agent_evolve/proposers/__init__.py +10 -0
  395. agent_evolve/proposers/random_proposer.py +188 -0
  396. agent_evolve/provider_accounting.py +163 -0
  397. agent_evolve/py.typed +0 -0
  398. agent_evolve/reference_method.py +1570 -0
  399. agent_evolve/session/__init__.py +11 -0
  400. agent_evolve/session/authorship.py +864 -0
  401. agent_evolve/session/evaluate.py +236 -0
  402. agent_evolve/session/fidelity.py +237 -0
  403. agent_evolve/session/genetic_loop.py +742 -0
  404. agent_evolve/session/loop.py +803 -0
  405. agent_evolve/session/screening.py +671 -0
  406. agent_evolve/settings.py +376 -0
  407. agent_evolve/workload_kit.py +368 -0
  408. agent_evolve/workload_prompt.py +398 -0
  409. agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
  410. agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
  411. agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
  412. agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
  413. agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
  414. agentevolve_optimizer-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1068 @@
1
+ """Fail-closed replay of accepted structured outputs before live continuation.
2
+
3
+ The replay boundary consumes the three durable channels produced by the
4
+ queued Pydantic-AI integration: logical request evidence, typed output
5
+ evidence, and terminal queue outcomes. Exact file digests are supplied by an
6
+ external launch/finalization contract. No provider, credential, environment,
7
+ or network dependency exists in this module.
8
+
9
+ Logical call IDs are deliberately excluded from replay matching because a
10
+ continuation run has a fresh identity namespace. Every semantic request field
11
+ is retained, including the exact wire-prompt digest, complete output schema,
12
+ generation settings, and requested model. While accepted source entries
13
+ remain, a non-matching request is drift and cannot fall through to the live
14
+ provider. Live execution becomes possible only after the complete sealed
15
+ prefix has been consumed.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import asyncio
21
+ import hashlib
22
+ import json
23
+ import re
24
+ from collections.abc import Awaitable, Callable, Mapping, Sequence
25
+ from dataclasses import InitVar, dataclass, field
26
+ from decimal import Decimal, InvalidOperation
27
+ from enum import Enum
28
+ from pathlib import Path
29
+ from typing import Any, Generic, cast
30
+
31
+ from pydantic import BaseModel
32
+
33
+ from agent_evolve.domain.ids import LLMCallId
34
+ from agent_evolve.integrations.pydantic_ai.agentic_generator import (
35
+ AttemptedStructuredGenerationResponse,
36
+ )
37
+ from agent_evolve.integrations.pydantic_ai.provider_attempt_join import (
38
+ validate_structured_generation_outcome_record,
39
+ )
40
+ from agent_evolve.integrations.pydantic_ai.queued_runner import (
41
+ structured_generation_request_evidence_record,
42
+ validate_structured_generation_output_evidence_record,
43
+ validate_structured_generation_request_evidence_record,
44
+ )
45
+ from agent_evolve.ports.artifact_store import canonical_json_bytes, decode_json_bytes
46
+ from agent_evolve.ports.structured_generator import (
47
+ OutputT,
48
+ StructuredGenerationRequest,
49
+ StructuredGenerationResponse,
50
+ )
51
+
52
+
53
+ SEALED_ACCEPTED_OUTPUT_REPLAY_SCHEMA_VERSION = 1
54
+ SEALED_REPLAY_DECISION_RECEIPT_SCHEMA_VERSION = 1
55
+ MAX_REPLAY_JSONL_BYTES = 256 * 1024 * 1024
56
+ MAX_REPLAY_JSONL_ROWS = 100_000
57
+
58
+ _SOURCE_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,255}$")
59
+ _LOWER_SHA256 = re.compile(r"^[0-9a-f]{64}$")
60
+ _REQUEST_IDENTITY_DOMAIN = b"agent-evolve:sealed-replay-request-identity:v1\x00"
61
+ _SOURCE_IDENTITY_DOMAIN = b"agent-evolve:sealed-replay-source-identity:v1\x00"
62
+ _DECISION_RECEIPT_DOMAIN = b"agent-evolve:sealed-replay-decision:v1\x00"
63
+ _BUILD_TOKEN = object()
64
+
65
+ _JOURNAL_ENVELOPE_FIELDS = frozenset({"authenticated_record", "observation"})
66
+ _OBSERVATION_FIELDS = frozenset(
67
+ {"monotonic_ns_since_execution_start", "observed_at_utc"}
68
+ )
69
+ _OUTCOME_RESPONSE_FIELDS = frozenset(
70
+ {
71
+ "requested_model",
72
+ "resolved_model",
73
+ "resolved_provider",
74
+ "provider_response_id",
75
+ "finish_reason",
76
+ "input_tokens",
77
+ "output_tokens",
78
+ "reasoning_tokens",
79
+ "cache_read_tokens",
80
+ "cache_write_tokens",
81
+ "cost_usd",
82
+ "latency_ns",
83
+ }
84
+ )
85
+ _SOURCE_RECEIPT_FIELDS = frozenset(
86
+ {
87
+ "schema_version",
88
+ "source_id",
89
+ "files",
90
+ "accepted_output_count",
91
+ "entries",
92
+ "raw_prompt_or_output_persisted_in_receipt",
93
+ "source_identity_sha256",
94
+ }
95
+ )
96
+ _SOURCE_FILE_ROLES = frozenset(
97
+ {"request_evidence", "output_evidence", "terminal_outcomes"}
98
+ )
99
+ _SOURCE_FILE_FIELDS = frozenset({"sha256", "size_bytes", "row_count"})
100
+ _SOURCE_ENTRY_FIELDS = frozenset(
101
+ {
102
+ "request_identity_sha256",
103
+ "requested_model",
104
+ "source_call_id",
105
+ "source_request_evidence_sha256",
106
+ "source_output_evidence_sha256",
107
+ "typed_output_sha256",
108
+ "response_record_sha256",
109
+ "attempt_count",
110
+ }
111
+ )
112
+ _DECISION_RECEIPT_FIELDS = frozenset(
113
+ {
114
+ "schema_version",
115
+ "decision",
116
+ "current_call_id",
117
+ "request_identity_sha256",
118
+ "requested_model",
119
+ "source_id",
120
+ "source_identity_sha256",
121
+ "remaining_entry_count",
122
+ "source_call_id",
123
+ "source_request_evidence_sha256",
124
+ "source_output_evidence_sha256",
125
+ "typed_output_sha256",
126
+ "historical_response_record_sha256",
127
+ "historical_attempt_count",
128
+ "response_telemetry_origin",
129
+ "provider_dispatched_by_replay_boundary",
130
+ "typed_output_persisted_in_receipt",
131
+ "replay_decision_receipt_sha256",
132
+ }
133
+ )
134
+
135
+
136
+ class SealedAcceptedOutputReplayError(RuntimeError):
137
+ """A sealed replay source or decision violates its generic contract."""
138
+
139
+
140
+ class SealedReplayRequestDriftError(SealedAcceptedOutputReplayError):
141
+ """A request failed to match while accepted prefix entries remained."""
142
+
143
+
144
+ class SealedReplayTypedOutputError(SealedAcceptedOutputReplayError):
145
+ """Recorded typed JSON is not exact under the current trusted output type."""
146
+
147
+
148
+ class SealedReplayReceiptPublicationError(SealedAcceptedOutputReplayError):
149
+ """The required replay decision receipt could not be published."""
150
+
151
+
152
+ @dataclass(frozen=True, slots=True)
153
+ class SealedReplayJsonlFile:
154
+ """One immutable expected digest for a canonical durable JSONL channel."""
155
+
156
+ path: Path
157
+ sha256: str
158
+
159
+ def __post_init__(self) -> None:
160
+ if not isinstance(self.path, Path):
161
+ raise TypeError("path must be a pathlib.Path")
162
+ if type(self.sha256) is not str or _LOWER_SHA256.fullmatch(self.sha256) is None:
163
+ raise ValueError("sha256 must be a lowercase SHA-256 digest")
164
+
165
+
166
+ @dataclass(frozen=True, slots=True)
167
+ class _LoadedJsonl:
168
+ sha256: str
169
+ size_bytes: int
170
+ rows: tuple[dict[str, object], ...]
171
+
172
+
173
+ @dataclass(frozen=True, slots=True)
174
+ class _AcceptedReplayEntry:
175
+ request_identity_sha256: str
176
+ requested_model: str
177
+ source_call_id: str
178
+ source_request_evidence_sha256: str
179
+ source_output_evidence_sha256: str
180
+ typed_output_sha256: str
181
+ typed_output_bytes: bytes = field(repr=False)
182
+ response_record_bytes: bytes = field(repr=False)
183
+ response_record_sha256: str
184
+ attempt_count: int
185
+
186
+
187
+ @dataclass(frozen=True, slots=True)
188
+ class SealedAcceptedOutputReplaySource:
189
+ """Verified accepted-output prefix detached from its source files."""
190
+
191
+ source_id: str
192
+ source_identity_sha256: str
193
+ source_receipt_bytes: bytes = field(repr=False)
194
+ _entries: tuple[_AcceptedReplayEntry, ...] = field(repr=False)
195
+ _construction_token: InitVar[object] = None
196
+
197
+ def __post_init__(self, _construction_token: object) -> None:
198
+ if _construction_token is not _BUILD_TOKEN:
199
+ raise TypeError("sealed replay sources are constructed only by verification")
200
+ if type(self.source_id) is not str or _SOURCE_ID.fullmatch(self.source_id) is None:
201
+ raise ValueError("source_id is outside the closed replay grammar")
202
+ _require_sha256(self.source_identity_sha256, label="source_identity_sha256")
203
+ if type(self.source_receipt_bytes) is not bytes:
204
+ raise TypeError("source_receipt_bytes must be exact bytes")
205
+ if type(self._entries) is not tuple or any(
206
+ type(entry) is not _AcceptedReplayEntry for entry in self._entries
207
+ ):
208
+ raise TypeError("replay entries must be an immutable verified tuple")
209
+ receipt = validate_sealed_accepted_output_replay_source_receipt(
210
+ _canonical_mapping(
211
+ decode_json_bytes(self.source_receipt_bytes),
212
+ label="source receipt",
213
+ )
214
+ )
215
+ if receipt.get("source_identity_sha256") != self.source_identity_sha256:
216
+ raise ValueError("source receipt does not authenticate the source identity")
217
+ if receipt.get("accepted_output_count") != len(self._entries):
218
+ raise ValueError("source receipt accepted-output count drifted")
219
+
220
+ @property
221
+ def accepted_output_count(self) -> int:
222
+ return len(self._entries)
223
+
224
+ @property
225
+ def requested_models(self) -> tuple[str, ...]:
226
+ return tuple(sorted({entry.requested_model for entry in self._entries}))
227
+
228
+ def source_receipt(self) -> dict[str, object]:
229
+ """Return a detached JSON-safe receipt without typed output content."""
230
+
231
+ return _canonical_mapping(
232
+ decode_json_bytes(self.source_receipt_bytes),
233
+ label="source receipt",
234
+ )
235
+
236
+
237
+ def _require_sha256(value: object, *, label: str) -> str:
238
+ if type(value) is not str or _LOWER_SHA256.fullmatch(value) is None:
239
+ raise ValueError(f"{label} must be a lowercase SHA-256 digest")
240
+ return value
241
+
242
+
243
+ def validate_sealed_accepted_output_replay_source_receipt(
244
+ value: Mapping[str, object],
245
+ ) -> dict[str, object]:
246
+ """Strictly verify a content-free sealed replay-source receipt."""
247
+
248
+ record = _canonical_mapping(value, label="sealed replay source receipt")
249
+ if frozenset(record) != _SOURCE_RECEIPT_FIELDS:
250
+ raise ValueError("sealed replay source receipt has unexpected fields")
251
+ if record["schema_version"] != SEALED_ACCEPTED_OUTPUT_REPLAY_SCHEMA_VERSION:
252
+ raise ValueError("sealed replay source receipt schema is unsupported")
253
+ source_id = record["source_id"]
254
+ if type(source_id) is not str or _SOURCE_ID.fullmatch(source_id) is None:
255
+ raise ValueError("sealed replay source ID is invalid")
256
+ if record["raw_prompt_or_output_persisted_in_receipt"] is not False:
257
+ raise ValueError("sealed replay source receipt crossed the content boundary")
258
+
259
+ files = record["files"]
260
+ if type(files) is not dict or frozenset(files) != _SOURCE_FILE_ROLES:
261
+ raise ValueError("sealed replay source files have unexpected roles")
262
+ for role in _SOURCE_FILE_ROLES:
263
+ file_record = files[role]
264
+ if type(file_record) is not dict or frozenset(file_record) != _SOURCE_FILE_FIELDS:
265
+ raise ValueError("sealed replay source file receipt is invalid")
266
+ _require_sha256(file_record["sha256"], label=f"{role}.sha256")
267
+ for name in ("size_bytes", "row_count"):
268
+ count = file_record[name]
269
+ if type(count) is not int or count < 0:
270
+ raise ValueError(f"{role}.{name} must be non-negative")
271
+
272
+ entries = record["entries"]
273
+ accepted_count = record["accepted_output_count"]
274
+ if (
275
+ type(entries) is not list
276
+ or type(accepted_count) is not int
277
+ or accepted_count < 0
278
+ or accepted_count != len(entries)
279
+ ):
280
+ raise ValueError("sealed replay accepted-output count is invalid")
281
+ identities: set[str] = set()
282
+ for entry in entries:
283
+ if type(entry) is not dict or frozenset(entry) != _SOURCE_ENTRY_FIELDS:
284
+ raise ValueError("sealed replay source entry has unexpected fields")
285
+ identity = _require_sha256(
286
+ entry["request_identity_sha256"],
287
+ label="request_identity_sha256",
288
+ )
289
+ if identity in identities:
290
+ raise ValueError("sealed replay source receipt contains duplicate identities")
291
+ identities.add(identity)
292
+ _validate_requested_model(entry["requested_model"])
293
+ LLMCallId(entry["source_call_id"])
294
+ for name in (
295
+ "source_request_evidence_sha256",
296
+ "source_output_evidence_sha256",
297
+ "typed_output_sha256",
298
+ "response_record_sha256",
299
+ ):
300
+ _require_sha256(entry[name], label=name)
301
+ if type(entry["attempt_count"]) is not int or entry["attempt_count"] < 1:
302
+ raise ValueError("sealed replay source attempt count is invalid")
303
+
304
+ supplied = _require_sha256(
305
+ record["source_identity_sha256"],
306
+ label="source_identity_sha256",
307
+ )
308
+ authenticated = dict(record)
309
+ del authenticated["source_identity_sha256"]
310
+ if supplied != _domain_sha256(_SOURCE_IDENTITY_DOMAIN, authenticated):
311
+ raise ValueError("source_identity_sha256 does not authenticate the receipt")
312
+ return record
313
+
314
+
315
+ def _canonical_mapping(value: object, *, label: str) -> dict[str, object]:
316
+ if not isinstance(value, Mapping):
317
+ raise TypeError(f"{label} must be a mapping")
318
+ try:
319
+ detached = json.loads(canonical_json_bytes(dict(value)))
320
+ except (TypeError, ValueError):
321
+ raise ValueError(f"{label} must contain canonical JSON values") from None
322
+ if type(detached) is not dict:
323
+ raise ValueError(f"{label} must encode one exact object")
324
+ return detached
325
+
326
+
327
+ def _domain_sha256(domain: bytes, value: object) -> str:
328
+ return hashlib.sha256(domain + canonical_json_bytes(value)).hexdigest()
329
+
330
+
331
+ def _validate_requested_model(value: object) -> str:
332
+ if type(value) is not str or not value or value != value.strip():
333
+ raise ValueError("requested_model must be a non-empty exact string")
334
+ return value
335
+
336
+
337
+ def _request_identity_record(
338
+ request_record: Mapping[str, object],
339
+ *,
340
+ requested_model: str,
341
+ ) -> dict[str, object]:
342
+ validated = validate_structured_generation_request_evidence_record(request_record)
343
+ model = _validate_requested_model(requested_model)
344
+ logical_request = dict(validated)
345
+ del logical_request["call_id"]
346
+ del logical_request["request_evidence_sha256"]
347
+ return {
348
+ "schema_version": SEALED_ACCEPTED_OUTPUT_REPLAY_SCHEMA_VERSION,
349
+ "requested_model": model,
350
+ "logical_request": logical_request,
351
+ }
352
+
353
+
354
+ def structured_replay_request_identity_sha256(
355
+ request: StructuredGenerationRequest[Any],
356
+ *,
357
+ requested_model: str,
358
+ ) -> str:
359
+ """Commit a current request independent of its fresh logical call ID."""
360
+
361
+ if type(request) is not StructuredGenerationRequest:
362
+ raise TypeError("request must be an exact StructuredGenerationRequest")
363
+ StructuredGenerationRequest.__post_init__(request)
364
+ identity = _request_identity_record(
365
+ structured_generation_request_evidence_record(request),
366
+ requested_model=requested_model,
367
+ )
368
+ return _domain_sha256(_REQUEST_IDENTITY_DOMAIN, identity)
369
+
370
+
371
+ def _record_request_identity_sha256(
372
+ request_record: Mapping[str, object],
373
+ *,
374
+ requested_model: str,
375
+ ) -> str:
376
+ return _domain_sha256(
377
+ _REQUEST_IDENTITY_DOMAIN,
378
+ _request_identity_record(
379
+ request_record,
380
+ requested_model=requested_model,
381
+ ),
382
+ )
383
+
384
+
385
+ def _unwrap_durable_row(row: object) -> dict[str, object]:
386
+ envelope = _canonical_mapping(row, label="durable JSONL row")
387
+ if frozenset(envelope) != _JOURNAL_ENVELOPE_FIELDS:
388
+ raise ValueError("durable JSONL row has unexpected envelope fields")
389
+ observation = envelope["observation"]
390
+ if type(observation) is not dict or frozenset(observation) != _OBSERVATION_FIELDS:
391
+ raise ValueError("durable JSONL observation has unexpected fields")
392
+ monotonic_ns = observation["monotonic_ns_since_execution_start"]
393
+ observed_at = observation["observed_at_utc"]
394
+ if type(monotonic_ns) is not int or monotonic_ns < 0:
395
+ raise ValueError("durable JSONL monotonic observation is invalid")
396
+ if type(observed_at) is not str or not observed_at:
397
+ raise ValueError("durable JSONL UTC observation is invalid")
398
+ return _canonical_mapping(
399
+ envelope["authenticated_record"],
400
+ label="authenticated durable record",
401
+ )
402
+
403
+
404
+ def _load_jsonl(spec: SealedReplayJsonlFile) -> _LoadedJsonl:
405
+ SealedReplayJsonlFile.__post_init__(spec)
406
+ try:
407
+ path = spec.path.expanduser().resolve(strict=True)
408
+ payload = path.read_bytes()
409
+ except OSError:
410
+ raise SealedAcceptedOutputReplayError(
411
+ "sealed replay JSONL could not be read"
412
+ ) from None
413
+ if len(payload) > MAX_REPLAY_JSONL_BYTES:
414
+ raise SealedAcceptedOutputReplayError("sealed replay JSONL exceeds its bound")
415
+ observed_sha256 = hashlib.sha256(payload).hexdigest()
416
+ if observed_sha256 != spec.sha256:
417
+ raise SealedAcceptedOutputReplayError("sealed replay JSONL digest drifted")
418
+ lines = payload.splitlines(keepends=True)
419
+ if len(lines) > MAX_REPLAY_JSONL_ROWS:
420
+ raise SealedAcceptedOutputReplayError("sealed replay JSONL row count exceeds bound")
421
+ rows: list[dict[str, object]] = []
422
+ try:
423
+ for line in lines:
424
+ if not line.endswith(b"\n") or line == b"\n":
425
+ raise ValueError("JSONL rows must be non-empty and newline terminated")
426
+ decoded = decode_json_bytes(line[:-1])
427
+ if canonical_json_bytes(decoded) + b"\n" != line:
428
+ raise ValueError("JSONL row is not canonical")
429
+ rows.append(_unwrap_durable_row(decoded))
430
+ except (TypeError, ValueError):
431
+ raise SealedAcceptedOutputReplayError(
432
+ "sealed replay JSONL violates its canonical envelope"
433
+ ) from None
434
+ return _LoadedJsonl(
435
+ sha256=observed_sha256,
436
+ size_bytes=len(payload),
437
+ rows=tuple(rows),
438
+ )
439
+
440
+
441
+ def _unique_by_call_id(
442
+ records: Sequence[dict[str, object]],
443
+ *,
444
+ call_id_field: str,
445
+ label: str,
446
+ ) -> dict[str, dict[str, object]]:
447
+ result: dict[str, dict[str, object]] = {}
448
+ for record in records:
449
+ call_id = record.get(call_id_field)
450
+ if type(call_id) is not str:
451
+ raise SealedAcceptedOutputReplayError(f"{label} lacks an exact call ID")
452
+ try:
453
+ LLMCallId(call_id)
454
+ except (TypeError, ValueError):
455
+ raise SealedAcceptedOutputReplayError(
456
+ f"{label} has an invalid call ID"
457
+ ) from None
458
+ if call_id in result:
459
+ raise SealedAcceptedOutputReplayError(f"{label} has duplicate call IDs")
460
+ result[call_id] = record
461
+ return result
462
+
463
+
464
+ def _validated_success_response(
465
+ outcome: Mapping[str, object],
466
+ *,
467
+ request_record: Mapping[str, object],
468
+ output_record: Mapping[str, object],
469
+ ) -> tuple[dict[str, object], int]:
470
+ if outcome["status"] != "succeeded" or outcome["cancellation_reason"] is not None:
471
+ raise SealedAcceptedOutputReplayError(
472
+ "typed output evidence does not join a successful provider outcome"
473
+ )
474
+ response = outcome["response"]
475
+ attempts = outcome["attempts"]
476
+ if type(response) is not dict or frozenset(response) != _OUTCOME_RESPONSE_FIELDS:
477
+ raise SealedAcceptedOutputReplayError(
478
+ "successful provider outcome response is unavailable"
479
+ )
480
+ if type(attempts) is not list or not attempts:
481
+ raise SealedAcceptedOutputReplayError(
482
+ "successful provider outcome has no physical attempt"
483
+ )
484
+ succeeded = [attempt for attempt in attempts if attempt.get("status") == "succeeded"]
485
+ if len(succeeded) != 1 or succeeded[0] is not attempts[-1]:
486
+ raise SealedAcceptedOutputReplayError(
487
+ "successful provider outcome has ambiguous terminal attempts"
488
+ )
489
+ request_evidence = succeeded[0].get("request_evidence")
490
+ if type(request_evidence) is not dict:
491
+ raise SealedAcceptedOutputReplayError(
492
+ "successful provider attempt lacks request evidence"
493
+ )
494
+ if (
495
+ request_evidence.get("variant") != "original"
496
+ or request_evidence.get("prompt_sha256")
497
+ != request_record["wire_prompt_sha256"]
498
+ ):
499
+ raise SealedAcceptedOutputReplayError(
500
+ "accepted output was not produced from the exact original wire prompt"
501
+ )
502
+ if response["provider_response_id"] != output_record["provider_response_id"]:
503
+ raise SealedAcceptedOutputReplayError(
504
+ "provider response identity does not join typed output evidence"
505
+ )
506
+ _validate_requested_model(response["requested_model"])
507
+ return dict(response), len(attempts)
508
+
509
+
510
+ def _response_record_sha256(response: Mapping[str, object]) -> str:
511
+ return hashlib.sha256(canonical_json_bytes(response)).hexdigest()
512
+
513
+
514
+ def load_sealed_accepted_output_replay_jsonl(
515
+ *,
516
+ source_id: str,
517
+ request_evidence: SealedReplayJsonlFile,
518
+ output_evidence: SealedReplayJsonlFile,
519
+ terminal_outcomes: SealedReplayJsonlFile,
520
+ ) -> SealedAcceptedOutputReplaySource:
521
+ """Load one accepted prefix from exact, externally sealed JSONL files.
522
+
523
+ Requests and failed outcomes without typed-output evidence are validated but
524
+ never become replay entries. Conversely, every output-evidence row must
525
+ join one exact request and one successful outcome. Duplicate replay
526
+ identities are rejected because selecting among different accepted outputs
527
+ for one logical request would be nondeterministic under concurrency.
528
+ """
529
+
530
+ if type(source_id) is not str or _SOURCE_ID.fullmatch(source_id) is None:
531
+ raise ValueError("source_id is outside the closed replay grammar")
532
+ request_file = _load_jsonl(request_evidence)
533
+ output_file = _load_jsonl(output_evidence)
534
+ outcome_file = _load_jsonl(terminal_outcomes)
535
+
536
+ try:
537
+ requests = tuple(
538
+ validate_structured_generation_request_evidence_record(row)
539
+ for row in request_file.rows
540
+ )
541
+ outputs = tuple(
542
+ validate_structured_generation_output_evidence_record(row)
543
+ for row in output_file.rows
544
+ )
545
+ outcomes = tuple(
546
+ validate_structured_generation_outcome_record(row)
547
+ for row in outcome_file.rows
548
+ )
549
+ except (TypeError, ValueError):
550
+ raise SealedAcceptedOutputReplayError(
551
+ "sealed replay evidence failed strict record validation"
552
+ ) from None
553
+
554
+ requests_by_call = _unique_by_call_id(
555
+ requests,
556
+ call_id_field="call_id",
557
+ label="request evidence",
558
+ )
559
+ _unique_by_call_id(
560
+ outputs,
561
+ call_id_field="call_id",
562
+ label="output evidence",
563
+ )
564
+ outcomes_by_call = _unique_by_call_id(
565
+ outcomes,
566
+ call_id_field="task_id",
567
+ label="provider outcomes",
568
+ )
569
+
570
+ entries: list[_AcceptedReplayEntry] = []
571
+ seen_identities: set[str] = set()
572
+ for output in outputs:
573
+ call_id = cast(str, output["call_id"])
574
+ request = requests_by_call.get(call_id)
575
+ outcome = outcomes_by_call.get(call_id)
576
+ if request is None or outcome is None:
577
+ raise SealedAcceptedOutputReplayError(
578
+ "typed output evidence lacks its request or terminal outcome"
579
+ )
580
+ try:
581
+ output = validate_structured_generation_output_evidence_record(
582
+ output,
583
+ request_evidence=request,
584
+ )
585
+ except (TypeError, ValueError):
586
+ raise SealedAcceptedOutputReplayError(
587
+ "typed output evidence does not join its logical request"
588
+ ) from None
589
+ response, attempt_count = _validated_success_response(
590
+ outcome,
591
+ request_record=request,
592
+ output_record=output,
593
+ )
594
+ requested_model = cast(str, response["requested_model"])
595
+ request_identity_sha256 = _record_request_identity_sha256(
596
+ request,
597
+ requested_model=requested_model,
598
+ )
599
+ if request_identity_sha256 in seen_identities:
600
+ raise SealedAcceptedOutputReplayError(
601
+ "sealed accepted outputs contain a duplicate replay identity"
602
+ )
603
+ seen_identities.add(request_identity_sha256)
604
+ typed_output_bytes = canonical_json_bytes(output["typed_output"])
605
+ response_record_bytes = canonical_json_bytes(response)
606
+ entries.append(
607
+ _AcceptedReplayEntry(
608
+ request_identity_sha256=request_identity_sha256,
609
+ requested_model=requested_model,
610
+ source_call_id=call_id,
611
+ source_request_evidence_sha256=cast(
612
+ str,
613
+ request["request_evidence_sha256"],
614
+ ),
615
+ source_output_evidence_sha256=cast(
616
+ str,
617
+ output["output_evidence_sha256"],
618
+ ),
619
+ typed_output_sha256=cast(str, output["typed_output_sha256"]),
620
+ typed_output_bytes=typed_output_bytes,
621
+ response_record_bytes=response_record_bytes,
622
+ response_record_sha256=_response_record_sha256(response),
623
+ attempt_count=attempt_count,
624
+ )
625
+ )
626
+
627
+ entry_projection = [
628
+ {
629
+ "request_identity_sha256": entry.request_identity_sha256,
630
+ "requested_model": entry.requested_model,
631
+ "source_call_id": entry.source_call_id,
632
+ "source_request_evidence_sha256": (
633
+ entry.source_request_evidence_sha256
634
+ ),
635
+ "source_output_evidence_sha256": entry.source_output_evidence_sha256,
636
+ "typed_output_sha256": entry.typed_output_sha256,
637
+ "response_record_sha256": entry.response_record_sha256,
638
+ "attempt_count": entry.attempt_count,
639
+ }
640
+ for entry in entries
641
+ ]
642
+ receipt: dict[str, object] = {
643
+ "schema_version": SEALED_ACCEPTED_OUTPUT_REPLAY_SCHEMA_VERSION,
644
+ "source_id": source_id,
645
+ "files": {
646
+ "request_evidence": {
647
+ "sha256": request_file.sha256,
648
+ "size_bytes": request_file.size_bytes,
649
+ "row_count": len(request_file.rows),
650
+ },
651
+ "output_evidence": {
652
+ "sha256": output_file.sha256,
653
+ "size_bytes": output_file.size_bytes,
654
+ "row_count": len(output_file.rows),
655
+ },
656
+ "terminal_outcomes": {
657
+ "sha256": outcome_file.sha256,
658
+ "size_bytes": outcome_file.size_bytes,
659
+ "row_count": len(outcome_file.rows),
660
+ },
661
+ },
662
+ "accepted_output_count": len(entries),
663
+ "entries": entry_projection,
664
+ "raw_prompt_or_output_persisted_in_receipt": False,
665
+ }
666
+ receipt["source_identity_sha256"] = _domain_sha256(
667
+ _SOURCE_IDENTITY_DOMAIN,
668
+ receipt,
669
+ )
670
+ return SealedAcceptedOutputReplaySource(
671
+ source_id=source_id,
672
+ source_identity_sha256=cast(str, receipt["source_identity_sha256"]),
673
+ source_receipt_bytes=canonical_json_bytes(receipt),
674
+ _entries=tuple(entries),
675
+ _construction_token=_BUILD_TOKEN,
676
+ )
677
+
678
+
679
+ class SealedReplayDecision(str, Enum):
680
+ REPLAYED = "replayed"
681
+ LIVE_AFTER_PREFIX = "live_after_prefix"
682
+ REQUEST_DRIFT = "request_drift"
683
+
684
+
685
+ ReplayDecisionReceiptSink = Callable[[dict[str, object]], None]
686
+ LowLevelStructuredRunner = Callable[
687
+ [StructuredGenerationRequest[Any]],
688
+ Awaitable[
689
+ StructuredGenerationResponse[Any]
690
+ | AttemptedStructuredGenerationResponse[Any]
691
+ ],
692
+ ]
693
+
694
+
695
+ def _decision_receipt(
696
+ *,
697
+ decision: SealedReplayDecision,
698
+ current_call_id: str,
699
+ request_identity_sha256: str,
700
+ requested_model: str,
701
+ source: SealedAcceptedOutputReplaySource,
702
+ remaining_entry_count: int,
703
+ entry: _AcceptedReplayEntry | None,
704
+ ) -> dict[str, object]:
705
+ if type(decision) is not SealedReplayDecision:
706
+ raise TypeError("decision must be a SealedReplayDecision")
707
+ record: dict[str, object] = {
708
+ "schema_version": SEALED_REPLAY_DECISION_RECEIPT_SCHEMA_VERSION,
709
+ "decision": decision.value,
710
+ "current_call_id": current_call_id,
711
+ "request_identity_sha256": request_identity_sha256,
712
+ "requested_model": requested_model,
713
+ "source_id": source.source_id,
714
+ "source_identity_sha256": source.source_identity_sha256,
715
+ "remaining_entry_count": remaining_entry_count,
716
+ "source_call_id": None if entry is None else entry.source_call_id,
717
+ "source_request_evidence_sha256": (
718
+ None if entry is None else entry.source_request_evidence_sha256
719
+ ),
720
+ "source_output_evidence_sha256": (
721
+ None if entry is None else entry.source_output_evidence_sha256
722
+ ),
723
+ "typed_output_sha256": None if entry is None else entry.typed_output_sha256,
724
+ "historical_response_record_sha256": (
725
+ None if entry is None else entry.response_record_sha256
726
+ ),
727
+ "historical_attempt_count": None if entry is None else entry.attempt_count,
728
+ "response_telemetry_origin": (
729
+ None if entry is None else "historical_source_attempt"
730
+ ),
731
+ "provider_dispatched_by_replay_boundary": False,
732
+ "typed_output_persisted_in_receipt": False,
733
+ }
734
+ record["replay_decision_receipt_sha256"] = _domain_sha256(
735
+ _DECISION_RECEIPT_DOMAIN,
736
+ record,
737
+ )
738
+ return record
739
+
740
+
741
+ def validate_sealed_replay_decision_receipt(
742
+ value: Mapping[str, object],
743
+ ) -> dict[str, object]:
744
+ """Strictly verify one content-free replay, live, or drift decision."""
745
+
746
+ record = _canonical_mapping(value, label="sealed replay decision receipt")
747
+ if frozenset(record) != _DECISION_RECEIPT_FIELDS:
748
+ raise ValueError("sealed replay decision receipt has unexpected fields")
749
+ if record["schema_version"] != SEALED_REPLAY_DECISION_RECEIPT_SCHEMA_VERSION:
750
+ raise ValueError("sealed replay decision receipt schema is unsupported")
751
+ try:
752
+ decision = SealedReplayDecision(record["decision"])
753
+ except (TypeError, ValueError):
754
+ raise ValueError("sealed replay decision is invalid") from None
755
+ LLMCallId(record["current_call_id"])
756
+ _require_sha256(
757
+ record["request_identity_sha256"],
758
+ label="request_identity_sha256",
759
+ )
760
+ _validate_requested_model(record["requested_model"])
761
+ source_id = record["source_id"]
762
+ if type(source_id) is not str or _SOURCE_ID.fullmatch(source_id) is None:
763
+ raise ValueError("sealed replay decision source ID is invalid")
764
+ _require_sha256(
765
+ record["source_identity_sha256"],
766
+ label="source_identity_sha256",
767
+ )
768
+ remaining = record["remaining_entry_count"]
769
+ if type(remaining) is not int or remaining < 0:
770
+ raise ValueError("remaining_entry_count must be non-negative")
771
+ if (
772
+ record["provider_dispatched_by_replay_boundary"] is not False
773
+ or record["typed_output_persisted_in_receipt"] is not False
774
+ ):
775
+ raise ValueError("sealed replay decision crossed its content/I/O boundary")
776
+
777
+ source_fields = (
778
+ "source_call_id",
779
+ "source_request_evidence_sha256",
780
+ "source_output_evidence_sha256",
781
+ "typed_output_sha256",
782
+ "historical_response_record_sha256",
783
+ "historical_attempt_count",
784
+ "response_telemetry_origin",
785
+ )
786
+ if decision is SealedReplayDecision.REPLAYED:
787
+ LLMCallId(record["source_call_id"])
788
+ for name in (
789
+ "source_request_evidence_sha256",
790
+ "source_output_evidence_sha256",
791
+ "typed_output_sha256",
792
+ "historical_response_record_sha256",
793
+ ):
794
+ _require_sha256(record[name], label=name)
795
+ if (
796
+ type(record["historical_attempt_count"]) is not int
797
+ or record["historical_attempt_count"] < 1
798
+ or record["response_telemetry_origin"] != "historical_source_attempt"
799
+ ):
800
+ raise ValueError("replayed historical telemetry provenance is invalid")
801
+ elif any(record[name] is not None for name in source_fields):
802
+ raise ValueError("non-replay decision carries a source output identity")
803
+
804
+ supplied = _require_sha256(
805
+ record["replay_decision_receipt_sha256"],
806
+ label="replay_decision_receipt_sha256",
807
+ )
808
+ authenticated = dict(record)
809
+ del authenticated["replay_decision_receipt_sha256"]
810
+ if supplied != _domain_sha256(_DECISION_RECEIPT_DOMAIN, authenticated):
811
+ raise ValueError("replay decision receipt hash is invalid")
812
+ return record
813
+
814
+
815
+ def _parse_cost(value: object) -> Decimal | None:
816
+ if value is None:
817
+ return None
818
+ if type(value) is not str:
819
+ raise SealedReplayTypedOutputError("recorded response cost is invalid")
820
+ try:
821
+ result = Decimal(value)
822
+ except InvalidOperation:
823
+ raise SealedReplayTypedOutputError(
824
+ "recorded response cost is invalid"
825
+ ) from None
826
+ if not result.is_finite() or result < 0 or str(result) != value:
827
+ raise SealedReplayTypedOutputError("recorded response cost is not canonical")
828
+ return result
829
+
830
+
831
+ def _materialize_replayed_response(
832
+ entry: _AcceptedReplayEntry,
833
+ request: StructuredGenerationRequest[OutputT],
834
+ ) -> AttemptedStructuredGenerationResponse[OutputT]:
835
+ output_type = request.output_type
836
+ if not isinstance(output_type, type) or not issubclass(output_type, BaseModel):
837
+ raise SealedReplayTypedOutputError(
838
+ "replay requires a trusted Pydantic BaseModel output type"
839
+ )
840
+ try:
841
+ value = output_type.model_validate_json(
842
+ entry.typed_output_bytes,
843
+ strict=True,
844
+ )
845
+ round_trip = canonical_json_bytes(
846
+ BaseModel.model_dump(
847
+ value,
848
+ mode="json",
849
+ by_alias=False,
850
+ exclude_unset=False,
851
+ exclude_defaults=False,
852
+ exclude_none=False,
853
+ exclude_computed_fields=True,
854
+ round_trip=True,
855
+ warnings="error",
856
+ fallback=None,
857
+ serialize_as_any=False,
858
+ )
859
+ )
860
+ except Exception:
861
+ raise SealedReplayTypedOutputError(
862
+ "recorded typed output fails its current trusted output contract"
863
+ ) from None
864
+ if round_trip != entry.typed_output_bytes or (
865
+ hashlib.sha256(round_trip).hexdigest() != entry.typed_output_sha256
866
+ ):
867
+ raise SealedReplayTypedOutputError(
868
+ "recorded typed output is not an exact canonical round trip"
869
+ )
870
+ response = _canonical_mapping(
871
+ decode_json_bytes(entry.response_record_bytes),
872
+ label="historical response record",
873
+ )
874
+ if hashlib.sha256(entry.response_record_bytes).hexdigest() != (
875
+ entry.response_record_sha256
876
+ ):
877
+ raise SealedReplayTypedOutputError("historical response record hash drifted")
878
+ structured = StructuredGenerationResponse(
879
+ value=value,
880
+ requested_model=cast(str, response["requested_model"]),
881
+ resolved_model=cast(str, response["resolved_model"]),
882
+ resolved_provider=cast(str, response["resolved_provider"]),
883
+ provider_response_id=cast(str | None, response["provider_response_id"]),
884
+ finish_reason=cast(str | None, response["finish_reason"]),
885
+ input_tokens=cast(int, response["input_tokens"]),
886
+ output_tokens=cast(int, response["output_tokens"]),
887
+ reasoning_tokens=cast(int, response["reasoning_tokens"]),
888
+ cache_read_tokens=cast(int, response["cache_read_tokens"]),
889
+ cache_write_tokens=cast(int, response["cache_write_tokens"]),
890
+ cost_usd=_parse_cost(response["cost_usd"]),
891
+ latency_ns=cast(int, response["latency_ns"]),
892
+ )
893
+ return AttemptedStructuredGenerationResponse(
894
+ response=structured,
895
+ attempt_count=entry.attempt_count,
896
+ )
897
+
898
+
899
+ class SealedReplayThenLiveStructuredRunner(Generic[OutputT]):
900
+ """Consume an exact accepted prefix, then delegate subsequent calls live."""
901
+
902
+ def __init__(
903
+ self,
904
+ *,
905
+ source: SealedAcceptedOutputReplaySource,
906
+ requested_model: str,
907
+ live_runner: LowLevelStructuredRunner,
908
+ decision_receipt_sink: ReplayDecisionReceiptSink,
909
+ ) -> None:
910
+ if type(source) is not SealedAcceptedOutputReplaySource:
911
+ raise TypeError("source must be a SealedAcceptedOutputReplaySource")
912
+ model = _validate_requested_model(requested_model)
913
+ if not callable(live_runner):
914
+ raise TypeError("live_runner must be callable")
915
+ if not callable(decision_receipt_sink):
916
+ raise TypeError("decision_receipt_sink must be callable")
917
+ foreign_models = tuple(
918
+ source_model
919
+ for source_model in source.requested_models
920
+ if source_model != model
921
+ )
922
+ if foreign_models:
923
+ raise ValueError("sealed replay source contains a foreign requested model")
924
+ self.source = source
925
+ self.requested_model = model
926
+ self._live_runner = live_runner
927
+ self._decision_receipt_sink = decision_receipt_sink
928
+ self._remaining = {
929
+ entry.request_identity_sha256: entry for entry in source._entries
930
+ }
931
+ self._decision_lock = asyncio.Lock()
932
+ self._close_lock = asyncio.Lock()
933
+ self._closed = False
934
+
935
+ @property
936
+ def remaining_entry_count(self) -> int:
937
+ return len(self._remaining)
938
+
939
+ async def __call__(
940
+ self,
941
+ request: StructuredGenerationRequest[OutputT],
942
+ ) -> AttemptedStructuredGenerationResponse[OutputT] | StructuredGenerationResponse[OutputT]:
943
+ return await self.generate(request)
944
+
945
+ async def generate(
946
+ self,
947
+ request: StructuredGenerationRequest[OutputT],
948
+ ) -> AttemptedStructuredGenerationResponse[OutputT] | StructuredGenerationResponse[OutputT]:
949
+ if type(request) is not StructuredGenerationRequest:
950
+ raise TypeError("request must be an exact StructuredGenerationRequest")
951
+ StructuredGenerationRequest.__post_init__(request)
952
+ if self._closed:
953
+ raise SealedAcceptedOutputReplayError("sealed replay runner is closed")
954
+ identity = structured_replay_request_identity_sha256(
955
+ request,
956
+ requested_model=self.requested_model,
957
+ )
958
+ async with self._decision_lock:
959
+ entry = self._remaining.get(identity)
960
+ if entry is not None:
961
+ replayed = _materialize_replayed_response(entry, request)
962
+ receipt = _decision_receipt(
963
+ decision=SealedReplayDecision.REPLAYED,
964
+ current_call_id=request.call_id.value,
965
+ request_identity_sha256=identity,
966
+ requested_model=self.requested_model,
967
+ source=self.source,
968
+ remaining_entry_count=len(self._remaining) - 1,
969
+ entry=entry,
970
+ )
971
+ self._publish_receipt(receipt)
972
+ del self._remaining[identity]
973
+ return replayed
974
+
975
+ if self._remaining:
976
+ receipt = _decision_receipt(
977
+ decision=SealedReplayDecision.REQUEST_DRIFT,
978
+ current_call_id=request.call_id.value,
979
+ request_identity_sha256=identity,
980
+ requested_model=self.requested_model,
981
+ source=self.source,
982
+ remaining_entry_count=len(self._remaining),
983
+ entry=None,
984
+ )
985
+ self._publish_receipt(receipt)
986
+ raise SealedReplayRequestDriftError(
987
+ "structured request drifted before sealed replay prefix exhaustion"
988
+ )
989
+
990
+ receipt = _decision_receipt(
991
+ decision=SealedReplayDecision.LIVE_AFTER_PREFIX,
992
+ current_call_id=request.call_id.value,
993
+ request_identity_sha256=identity,
994
+ requested_model=self.requested_model,
995
+ source=self.source,
996
+ remaining_entry_count=0,
997
+ entry=None,
998
+ )
999
+ self._publish_receipt(receipt)
1000
+
1001
+ result = await self._live_runner(request)
1002
+ if type(result) is StructuredGenerationResponse:
1003
+ StructuredGenerationResponse.__post_init__(result)
1004
+ if type(result.value) is not request.output_type:
1005
+ raise TypeError("live runner response violates the requested output type")
1006
+ return cast(StructuredGenerationResponse[OutputT], result)
1007
+ if type(result) is AttemptedStructuredGenerationResponse:
1008
+ AttemptedStructuredGenerationResponse.__post_init__(result)
1009
+ if type(result.response.value) is not request.output_type:
1010
+ raise TypeError("live runner response violates the requested output type")
1011
+ return cast(AttemptedStructuredGenerationResponse[OutputT], result)
1012
+ raise TypeError("live runner returned an unsupported structured response")
1013
+
1014
+ def _publish_receipt(self, receipt: dict[str, object]) -> None:
1015
+ try:
1016
+ validated = validate_sealed_replay_decision_receipt(receipt)
1017
+ self._decision_receipt_sink(validated)
1018
+ except Exception:
1019
+ raise SealedReplayReceiptPublicationError(
1020
+ "required sealed replay decision receipt publication failed"
1021
+ ) from None
1022
+
1023
+ async def snapshot(self) -> object:
1024
+ snapshot = getattr(self._live_runner, "snapshot", None)
1025
+ if not callable(snapshot):
1026
+ raise AttributeError("live runner does not expose snapshot")
1027
+ return await snapshot()
1028
+
1029
+ async def aclose(self) -> None:
1030
+ async with self._close_lock:
1031
+ if self._closed:
1032
+ return
1033
+ self._closed = True
1034
+ close = getattr(self._live_runner, "aclose", None)
1035
+ if callable(close):
1036
+ await close()
1037
+
1038
+ async def __aenter__(self) -> "SealedReplayThenLiveStructuredRunner[OutputT]":
1039
+ if self._closed:
1040
+ raise SealedAcceptedOutputReplayError("sealed replay runner is closed")
1041
+ enter = getattr(self._live_runner, "__aenter__", None)
1042
+ if callable(enter):
1043
+ await enter()
1044
+ return self
1045
+
1046
+ async def __aexit__(self, *_: object) -> None:
1047
+ await self.aclose()
1048
+
1049
+
1050
+ __all__ = [
1051
+ "MAX_REPLAY_JSONL_BYTES",
1052
+ "MAX_REPLAY_JSONL_ROWS",
1053
+ "ReplayDecisionReceiptSink",
1054
+ "SEALED_ACCEPTED_OUTPUT_REPLAY_SCHEMA_VERSION",
1055
+ "SEALED_REPLAY_DECISION_RECEIPT_SCHEMA_VERSION",
1056
+ "SealedAcceptedOutputReplayError",
1057
+ "SealedAcceptedOutputReplaySource",
1058
+ "SealedReplayDecision",
1059
+ "SealedReplayJsonlFile",
1060
+ "SealedReplayReceiptPublicationError",
1061
+ "SealedReplayRequestDriftError",
1062
+ "SealedReplayThenLiveStructuredRunner",
1063
+ "SealedReplayTypedOutputError",
1064
+ "load_sealed_accepted_output_replay_jsonl",
1065
+ "structured_replay_request_identity_sha256",
1066
+ "validate_sealed_accepted_output_replay_source_receipt",
1067
+ "validate_sealed_replay_decision_receipt",
1068
+ ]