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,466 @@
1
+ """Provider-neutral contracts for prospective blinded treatment assignment.
2
+
3
+ The types in this module distinguish scientific treatments, their repeatable
4
+ occurrences, and provider-facing opaque slots. They authenticate exact input
5
+ order and both directions of the resulting bijection. The receipt's claim is
6
+ deliberately narrow: it establishes label/order assignment blinding, never
7
+ content blinding.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass
13
+ from enum import Enum
14
+ import hashlib
15
+ import json
16
+ import re
17
+
18
+ from agent_evolve.domain.patch import require_sha256
19
+
20
+
21
+ _IDENTIFIER = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
22
+ _SEED_MATERIAL = re.compile(r"^[a-z0-9][a-z0-9_.:-]{0,255}$")
23
+ _POLICY_BINDING_DOMAIN = b"agent-evolve:treatment-assignment-policy:v1\x00"
24
+ _INPUT_DOMAIN = b"agent-evolve:treatment-assignment-input:v1\x00"
25
+ _RECEIPT_DOMAIN = b"agent-evolve:treatment-assignment-receipt:v1\x00"
26
+
27
+
28
+ def _canonical_json(value: object) -> bytes:
29
+ return json.dumps(
30
+ value,
31
+ allow_nan=False,
32
+ ensure_ascii=True,
33
+ separators=(",", ":"),
34
+ sort_keys=True,
35
+ ).encode("ascii")
36
+
37
+
38
+ def _hash(domain: bytes, value: object) -> str:
39
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
40
+
41
+
42
+ def _require_identifier(value: object, name: str) -> str:
43
+ if type(value) is not str or _IDENTIFIER.fullmatch(value) is None:
44
+ raise ValueError(f"{name} must use the canonical lowercase identifier grammar")
45
+ return value
46
+
47
+
48
+ @dataclass(frozen=True, slots=True)
49
+ class TreatmentId:
50
+ """Nominal identifier for a scientific treatment; repeats are permitted."""
51
+
52
+ value: str
53
+
54
+ def __post_init__(self) -> None:
55
+ _require_identifier(self.value, "treatment_id")
56
+
57
+
58
+ @dataclass(frozen=True, slots=True)
59
+ class TreatmentOccurrenceId:
60
+ """Nominal identifier for one unique occurrence of a treatment."""
61
+
62
+ value: str
63
+
64
+ def __post_init__(self) -> None:
65
+ _require_identifier(self.value, "occurrence_id")
66
+
67
+
68
+ @dataclass(frozen=True, slots=True)
69
+ class OpaqueProviderSlotId:
70
+ """Nominal provider-facing slot identifier with no treatment semantics."""
71
+
72
+ value: str
73
+
74
+ def __post_init__(self) -> None:
75
+ _require_identifier(self.value, "opaque_provider_slot_id")
76
+
77
+
78
+ @dataclass(frozen=True, slots=True)
79
+ class TreatmentOccurrence:
80
+ """One canonical input occurrence, optionally bound to call/request identity."""
81
+
82
+ occurrence_id: TreatmentOccurrenceId
83
+ treatment_id: TreatmentId
84
+ call_identity: str | None = None
85
+ request_identity_sha256: str | None = None
86
+
87
+ def __post_init__(self) -> None:
88
+ if type(self.occurrence_id) is not TreatmentOccurrenceId:
89
+ raise TypeError("occurrence_id must be an exact TreatmentOccurrenceId")
90
+ if type(self.treatment_id) is not TreatmentId:
91
+ raise TypeError("treatment_id must be an exact TreatmentId")
92
+ self.occurrence_id.__post_init__()
93
+ self.treatment_id.__post_init__()
94
+ if self.call_identity is not None:
95
+ _require_identifier(self.call_identity, "call_identity")
96
+ if self.request_identity_sha256 is not None:
97
+ require_sha256(
98
+ self.request_identity_sha256,
99
+ "request_identity_sha256",
100
+ )
101
+
102
+ def to_record(self) -> dict[str, object]:
103
+ self.__post_init__()
104
+ return {
105
+ "schema_version": 1,
106
+ "occurrence_id": self.occurrence_id.value,
107
+ "treatment_id": self.treatment_id.value,
108
+ "call_identity": self.call_identity,
109
+ "request_identity_sha256": self.request_identity_sha256,
110
+ }
111
+
112
+
113
+ @dataclass(frozen=True, slots=True, eq=False)
114
+ class TreatmentAssignmentPolicyBinding:
115
+ """Identified public permutation policy and domain separation label."""
116
+
117
+ policy_id: str
118
+ policy_version: int
119
+ policy_definition_sha256: str
120
+ permutation_domain: str
121
+
122
+ def __post_init__(self) -> None:
123
+ _require_identifier(self.policy_id, "policy_id")
124
+ if type(self.policy_version) is not int or self.policy_version <= 0:
125
+ raise ValueError("policy_version must be a positive exact integer")
126
+ require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
127
+ _require_identifier(self.permutation_domain, "permutation_domain")
128
+
129
+ def _unsigned_record(self) -> dict[str, object]:
130
+ self.__post_init__()
131
+ return {
132
+ "schema_version": 1,
133
+ "policy_id": self.policy_id,
134
+ "policy_version": self.policy_version,
135
+ "policy_definition_sha256": self.policy_definition_sha256,
136
+ "permutation_domain": self.permutation_domain,
137
+ }
138
+
139
+ @property
140
+ def binding_sha256(self) -> str:
141
+ return _hash(_POLICY_BINDING_DOMAIN, self._unsigned_record())
142
+
143
+ def to_record(self) -> dict[str, object]:
144
+ return {**self._unsigned_record(), "binding_sha256": self.binding_sha256}
145
+
146
+ def __eq__(self, other: object) -> bool:
147
+ return (
148
+ type(other) is TreatmentAssignmentPolicyBinding
149
+ and self.binding_sha256 == other.binding_sha256
150
+ )
151
+
152
+ __hash__ = None
153
+
154
+
155
+ @dataclass(frozen=True, slots=True, eq=False)
156
+ class TreatmentAssignmentInput:
157
+ """Exact prospective input order and public seed material."""
158
+
159
+ experiment_commitment_sha256: str
160
+ public_seed_material: str
161
+ occurrences: tuple[TreatmentOccurrence, ...]
162
+ provider_slot_ids: tuple[OpaqueProviderSlotId, ...]
163
+
164
+ def __post_init__(self) -> None:
165
+ require_sha256(
166
+ self.experiment_commitment_sha256,
167
+ "experiment_commitment_sha256",
168
+ )
169
+ if (
170
+ type(self.public_seed_material) is not str
171
+ or _SEED_MATERIAL.fullmatch(self.public_seed_material) is None
172
+ ):
173
+ raise ValueError(
174
+ "public_seed_material must use the canonical public-seed grammar"
175
+ )
176
+ if type(self.occurrences) is not tuple or not self.occurrences or any(
177
+ type(value) is not TreatmentOccurrence for value in self.occurrences
178
+ ):
179
+ raise ValueError("occurrences must be a non-empty exact tuple")
180
+ if type(self.provider_slot_ids) is not tuple or any(
181
+ type(value) is not OpaqueProviderSlotId
182
+ for value in self.provider_slot_ids
183
+ ):
184
+ raise TypeError("provider_slot_ids must be an exact tuple")
185
+ if len(self.provider_slot_ids) != len(self.occurrences):
186
+ raise ValueError("provider slot and occurrence counts must match exactly")
187
+ for value in self.occurrences:
188
+ value.__post_init__()
189
+ for value in self.provider_slot_ids:
190
+ value.__post_init__()
191
+
192
+ occurrence_ids = tuple(value.occurrence_id.value for value in self.occurrences)
193
+ slot_ids = tuple(value.value for value in self.provider_slot_ids)
194
+ if len(set(occurrence_ids)) != len(occurrence_ids):
195
+ raise ValueError("occurrence IDs cannot repeat")
196
+ if len(set(slot_ids)) != len(slot_ids):
197
+ raise ValueError("opaque provider slot IDs cannot repeat")
198
+
199
+ treatment_ids = {value.treatment_id.value for value in self.occurrences}
200
+ occurrence_id_set = set(occurrence_ids)
201
+ slot_id_set = set(slot_ids)
202
+ if (
203
+ treatment_ids & occurrence_id_set
204
+ or treatment_ids & slot_id_set
205
+ or occurrence_id_set & slot_id_set
206
+ ):
207
+ raise ValueError(
208
+ "treatment, occurrence, and provider-slot identifier namespaces "
209
+ "must be disjoint"
210
+ )
211
+
212
+ def _unsigned_record(self) -> dict[str, object]:
213
+ self.__post_init__()
214
+ return {
215
+ "schema_version": 1,
216
+ "experiment_commitment_sha256": self.experiment_commitment_sha256,
217
+ "public_seed_material": self.public_seed_material,
218
+ "occurrence_input_order": [
219
+ value.to_record() for value in self.occurrences
220
+ ],
221
+ "provider_slot_input_order": [
222
+ value.value for value in self.provider_slot_ids
223
+ ],
224
+ }
225
+
226
+ @property
227
+ def input_sha256(self) -> str:
228
+ return _hash(_INPUT_DOMAIN, self._unsigned_record())
229
+
230
+ def to_record(self) -> dict[str, object]:
231
+ return {**self._unsigned_record(), "input_sha256": self.input_sha256}
232
+
233
+ def __eq__(self, other: object) -> bool:
234
+ return (
235
+ type(other) is TreatmentAssignmentInput
236
+ and self.input_sha256 == other.input_sha256
237
+ )
238
+
239
+ __hash__ = None
240
+
241
+
242
+ @dataclass(frozen=True, slots=True)
243
+ class TreatmentAssignment:
244
+ """One authenticated edge in the occurrence/provider-slot bijection."""
245
+
246
+ occurrence_id: TreatmentOccurrenceId
247
+ treatment_id: TreatmentId
248
+ opaque_provider_slot_id: OpaqueProviderSlotId
249
+ occurrence_input_index: int
250
+ provider_slot_input_index: int
251
+ call_identity: str | None = None
252
+ request_identity_sha256: str | None = None
253
+
254
+ def __post_init__(self) -> None:
255
+ if type(self.occurrence_id) is not TreatmentOccurrenceId:
256
+ raise TypeError("occurrence_id must be an exact TreatmentOccurrenceId")
257
+ if type(self.treatment_id) is not TreatmentId:
258
+ raise TypeError("treatment_id must be an exact TreatmentId")
259
+ if type(self.opaque_provider_slot_id) is not OpaqueProviderSlotId:
260
+ raise TypeError(
261
+ "opaque_provider_slot_id must be an exact OpaqueProviderSlotId"
262
+ )
263
+ self.occurrence_id.__post_init__()
264
+ self.treatment_id.__post_init__()
265
+ self.opaque_provider_slot_id.__post_init__()
266
+ for name in ("occurrence_input_index", "provider_slot_input_index"):
267
+ value = getattr(self, name)
268
+ if type(value) is not int or value < 0:
269
+ raise ValueError(f"{name} must be a non-negative exact integer")
270
+ if self.call_identity is not None:
271
+ _require_identifier(self.call_identity, "call_identity")
272
+ if self.request_identity_sha256 is not None:
273
+ require_sha256(
274
+ self.request_identity_sha256,
275
+ "request_identity_sha256",
276
+ )
277
+
278
+ def to_record(self) -> dict[str, object]:
279
+ self.__post_init__()
280
+ return {
281
+ "schema_version": 1,
282
+ "occurrence_id": self.occurrence_id.value,
283
+ "treatment_id": self.treatment_id.value,
284
+ "opaque_provider_slot_id": self.opaque_provider_slot_id.value,
285
+ "occurrence_input_index": self.occurrence_input_index,
286
+ "provider_slot_input_index": self.provider_slot_input_index,
287
+ "call_identity": self.call_identity,
288
+ "request_identity_sha256": self.request_identity_sha256,
289
+ }
290
+
291
+
292
+ class TreatmentAssignmentBlindingScope(str, Enum):
293
+ """The only blinding scope this receipt is capable of establishing."""
294
+
295
+ LABEL_AND_ORDER_ONLY = "label_and_order_only"
296
+
297
+
298
+ def _blinding_claim_record() -> dict[str, object]:
299
+ return {
300
+ "scope": TreatmentAssignmentBlindingScope.LABEL_AND_ORDER_ONLY.value,
301
+ "opaque_provider_slot_ids": True,
302
+ "content_blinding_claimed": False,
303
+ }
304
+
305
+
306
+ @dataclass(frozen=True, slots=True, eq=False)
307
+ class ProspectiveTreatmentAssignmentReceipt:
308
+ """Authenticated prospective assignment with explicit forward and inverse maps."""
309
+
310
+ policy: TreatmentAssignmentPolicyBinding
311
+ assignment_input_sha256: str
312
+ experiment_commitment_sha256: str
313
+ public_seed_material: str
314
+ occurrence_input_order: tuple[TreatmentOccurrence, ...]
315
+ provider_slot_input_order: tuple[OpaqueProviderSlotId, ...]
316
+ ordinal_permutation: tuple[int, ...]
317
+ inverse_ordinal_permutation: tuple[int, ...]
318
+ slot_to_occurrence: tuple[TreatmentAssignment, ...]
319
+ occurrence_to_slot: tuple[TreatmentAssignment, ...]
320
+
321
+ def __post_init__(self) -> None:
322
+ if type(self.policy) is not TreatmentAssignmentPolicyBinding:
323
+ raise TypeError("policy must be an exact TreatmentAssignmentPolicyBinding")
324
+ self.policy.__post_init__()
325
+ require_sha256(self.assignment_input_sha256, "assignment_input_sha256")
326
+ assignment_input = TreatmentAssignmentInput(
327
+ experiment_commitment_sha256=self.experiment_commitment_sha256,
328
+ public_seed_material=self.public_seed_material,
329
+ occurrences=self.occurrence_input_order,
330
+ provider_slot_ids=self.provider_slot_input_order,
331
+ )
332
+ if self.assignment_input_sha256 != assignment_input.input_sha256:
333
+ raise ValueError(
334
+ "assignment input commitment does not match receipt inputs"
335
+ )
336
+
337
+ count = len(self.occurrence_input_order)
338
+ for name in ("ordinal_permutation", "inverse_ordinal_permutation"):
339
+ value = getattr(self, name)
340
+ if type(value) is not tuple or any(
341
+ type(index) is not int for index in value
342
+ ):
343
+ raise TypeError(f"{name} must be an exact integer tuple")
344
+ if len(value) != count or tuple(sorted(value)) != tuple(range(count)):
345
+ raise ValueError(f"{name} must be a complete exact permutation")
346
+ for provider_index, occurrence_index in enumerate(self.ordinal_permutation):
347
+ if self.inverse_ordinal_permutation[occurrence_index] != provider_index:
348
+ raise ValueError("ordinal permutation and inverse disagree")
349
+
350
+ for name in ("slot_to_occurrence", "occurrence_to_slot"):
351
+ value = getattr(self, name)
352
+ if type(value) is not tuple or any(
353
+ type(item) is not TreatmentAssignment for item in value
354
+ ):
355
+ raise TypeError(f"{name} must be an exact assignment tuple")
356
+ if len(value) != count:
357
+ raise ValueError(f"{name} must cover every occurrence exactly once")
358
+ for item in value:
359
+ item.__post_init__()
360
+
361
+ expected_by_occurrence: list[TreatmentAssignment | None] = [None] * count
362
+ for provider_index, assignment in enumerate(self.slot_to_occurrence):
363
+ occurrence_index = self.ordinal_permutation[provider_index]
364
+ occurrence = self.occurrence_input_order[occurrence_index]
365
+ if (
366
+ assignment.provider_slot_input_index != provider_index
367
+ or assignment.opaque_provider_slot_id
368
+ != self.provider_slot_input_order[provider_index]
369
+ or assignment.occurrence_input_index != occurrence_index
370
+ or assignment.occurrence_id != occurrence.occurrence_id
371
+ or assignment.treatment_id != occurrence.treatment_id
372
+ or assignment.call_identity != occurrence.call_identity
373
+ or assignment.request_identity_sha256
374
+ != occurrence.request_identity_sha256
375
+ ):
376
+ raise ValueError("slot-to-occurrence mapping differs from bound inputs")
377
+ if expected_by_occurrence[occurrence_index] is not None:
378
+ raise ValueError("slot-to-occurrence mapping repeats an occurrence")
379
+ expected_by_occurrence[occurrence_index] = assignment
380
+
381
+ if any(value is None for value in expected_by_occurrence):
382
+ raise ValueError("slot-to-occurrence mapping is not a complete bijection")
383
+ for occurrence_index, assignment in enumerate(self.occurrence_to_slot):
384
+ if assignment is not expected_by_occurrence[occurrence_index]:
385
+ if assignment != expected_by_occurrence[occurrence_index]:
386
+ raise ValueError(
387
+ "occurrence-to-slot mapping is not the exact inverse"
388
+ )
389
+ if assignment.provider_slot_input_index != self.inverse_ordinal_permutation[
390
+ occurrence_index
391
+ ]:
392
+ raise ValueError("inverse mapping differs from inverse permutation")
393
+
394
+ if len(
395
+ {value.occurrence_id.value for value in self.slot_to_occurrence}
396
+ ) != count:
397
+ raise ValueError("assignment repeats an occurrence ID")
398
+ if len(
399
+ {
400
+ value.opaque_provider_slot_id.value
401
+ for value in self.slot_to_occurrence
402
+ }
403
+ ) != count:
404
+ raise ValueError("assignment repeats an opaque provider slot ID")
405
+
406
+ @property
407
+ def blinding_scope(self) -> TreatmentAssignmentBlindingScope:
408
+ return TreatmentAssignmentBlindingScope.LABEL_AND_ORDER_ONLY
409
+
410
+ @property
411
+ def content_blinding_claimed(self) -> bool:
412
+ return False
413
+
414
+ def _unsigned_record(self) -> dict[str, object]:
415
+ self.__post_init__()
416
+ return {
417
+ "schema_version": 1,
418
+ "prospective": True,
419
+ "policy": self.policy.to_record(),
420
+ "assignment_input_sha256": self.assignment_input_sha256,
421
+ "experiment_commitment_sha256": self.experiment_commitment_sha256,
422
+ "public_seed_material": self.public_seed_material,
423
+ "occurrence_input_order": [
424
+ value.to_record() for value in self.occurrence_input_order
425
+ ],
426
+ "provider_slot_input_order": [
427
+ value.value for value in self.provider_slot_input_order
428
+ ],
429
+ "ordinal_permutation": list(self.ordinal_permutation),
430
+ "inverse_ordinal_permutation": list(self.inverse_ordinal_permutation),
431
+ "slot_to_occurrence": [
432
+ value.to_record() for value in self.slot_to_occurrence
433
+ ],
434
+ "occurrence_to_slot": [
435
+ value.to_record() for value in self.occurrence_to_slot
436
+ ],
437
+ "blinding_claim": _blinding_claim_record(),
438
+ }
439
+
440
+ @property
441
+ def receipt_sha256(self) -> str:
442
+ return _hash(_RECEIPT_DOMAIN, self._unsigned_record())
443
+
444
+ def to_record(self) -> dict[str, object]:
445
+ return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
446
+
447
+ def __eq__(self, other: object) -> bool:
448
+ return (
449
+ type(other) is ProspectiveTreatmentAssignmentReceipt
450
+ and self.receipt_sha256 == other.receipt_sha256
451
+ )
452
+
453
+ __hash__ = None
454
+
455
+
456
+ __all__ = [
457
+ "OpaqueProviderSlotId",
458
+ "ProspectiveTreatmentAssignmentReceipt",
459
+ "TreatmentAssignment",
460
+ "TreatmentAssignmentBlindingScope",
461
+ "TreatmentAssignmentInput",
462
+ "TreatmentAssignmentPolicyBinding",
463
+ "TreatmentId",
464
+ "TreatmentOccurrence",
465
+ "TreatmentOccurrenceId",
466
+ ]
@@ -0,0 +1,76 @@
1
+ """Ports for deterministic finite, parent-relative variation catalogs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Protocol, runtime_checkable
6
+
7
+ from agent_evolve.domain.finite_variation import (
8
+ FiniteVariationContract,
9
+ FiniteVariationOption,
10
+ )
11
+ from agent_evolve.domain.typed_json import FrozenJsonObject, freeze_json
12
+ from agent_evolve.domain.variation_space import AtomicEditOption
13
+
14
+ if TYPE_CHECKING:
15
+ from agent_evolve.application.agentic_evolution import EvolutionCandidate
16
+
17
+
18
+ @runtime_checkable
19
+ class AtomicVariationCatalog(Protocol):
20
+ """Enumerate an immutable, deterministic option tuple for one parent."""
21
+
22
+ def options(
23
+ self,
24
+ parent: "EvolutionCandidate",
25
+ ) -> tuple[AtomicEditOption, ...]: ...
26
+
27
+
28
+ @runtime_checkable
29
+ class FiniteVariationCatalog(Protocol):
30
+ """Enumerate sealed full-child choices for one immutable parent.
31
+
32
+ The protocol intentionally receives configuration data rather than an
33
+ application-layer candidate. Benchmark adapters therefore need no import
34
+ from the evolutionary engine and may coordinate arbitrarily many fields in
35
+ one option.
36
+ """
37
+
38
+ catalog_id: str
39
+ catalog_version: int
40
+ definition_sha256: str
41
+
42
+ def options(
43
+ self,
44
+ parent_configuration: FrozenJsonObject,
45
+ ) -> tuple[FiniteVariationOption, ...]: ...
46
+
47
+
48
+ def bind_finite_variation_catalog(
49
+ catalog: FiniteVariationCatalog,
50
+ parent_configuration: FrozenJsonObject,
51
+ ) -> FiniteVariationContract:
52
+ """Seal one catalog result and its published semantics to one parent."""
53
+
54
+ if not isinstance(catalog, FiniteVariationCatalog):
55
+ raise TypeError("catalog must implement FiniteVariationCatalog")
56
+ if type(parent_configuration) is not FrozenJsonObject:
57
+ raise TypeError("parent_configuration must be an exact FrozenJsonObject")
58
+ if freeze_json(parent_configuration) is not parent_configuration:
59
+ raise TypeError("parent_configuration must already be frozen typed JSON")
60
+ options = catalog.options(parent_configuration)
61
+ if type(options) is not tuple:
62
+ raise TypeError("finite variation catalog must return an exact tuple")
63
+ return FiniteVariationContract(
64
+ catalog_id=catalog.catalog_id,
65
+ catalog_version=catalog.catalog_version,
66
+ catalog_definition_sha256=catalog.definition_sha256,
67
+ parent_configuration=parent_configuration,
68
+ options=options,
69
+ )
70
+
71
+
72
+ __all__ = [
73
+ "AtomicVariationCatalog",
74
+ "FiniteVariationCatalog",
75
+ "bind_finite_variation_catalog",
76
+ ]