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,479 @@
1
+ """Record and replay a generative proposer, so its evidence is checkable.
2
+
3
+ The catalogue path is auditable because the model's whole output is one token
4
+ from a sealed list. Generative proposal gives that up on purpose -- the model
5
+ authors configurations -- so the audit has to move with it. This wrapper is
6
+ where it moves to.
7
+
8
+ ``SealedGenerativeHarness`` sits between the loop and any :class:`Harness` and
9
+ does one of two things:
10
+
11
+ ``record`` call the delegate, hash the exact instruction, seal what came back
12
+ (configurations verbatim, guidance text verbatim) into a chained
13
+ journal, and hand the loop the delegate's answer unchanged.
14
+ ``replay`` serve the sealed answer, after checking that the question matches.
15
+ No provider, no network, no credential. A prompt that has drifted
16
+ from the sealed one is an error, never a live call.
17
+
18
+ The prompt is hashed rather than stored because it is a *derived* quantity: the
19
+ loop composes it from the problem's directives and the campaign's own state, so
20
+ a replay that reaches a different hash has already diverged somewhere it can
21
+ still be diagnosed. Storing the text as well would make the journal larger and
22
+ prove nothing extra.
23
+
24
+ **Why replay is exact at all.** Nothing here makes a stochastic loop
25
+ deterministic. Replay reproduces a run only when everything outside the
26
+ provider is already reproducible -- a deterministic evaluator, a fixed seed, and
27
+ the same code. That is the standing condition on this project's benchmarks, and
28
+ when it does not hold the drift check fails loudly instead of quietly serving
29
+ the wrong answer.
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ from typing import Any, Callable, Dict, List, Optional, Sequence
35
+
36
+ from agent_evolve.core.problem import ValidationOutcome
37
+ from agent_evolve.domain.generative_emission import (
38
+ GENESIS_CALL_SHA256,
39
+ GenerativeEmission,
40
+ GenerativeProposalCall,
41
+ SealedGuidanceCall,
42
+ SealedRunHeader,
43
+ generative_prompt_sha256,
44
+ )
45
+ from agent_evolve.domain.typed_json import freeze_json, thaw_json
46
+ from agent_evolve.harness.base import (
47
+ Harness,
48
+ HarnessBase,
49
+ HarnessContext,
50
+ HarnessOutputError,
51
+ LLMConfig,
52
+ )
53
+
54
+ __all__ = [
55
+ "SealedGenerativeHarness",
56
+ "SealedReplayDriftError",
57
+ "CANDIDATE_OPS",
58
+ "GUIDANCE_OPS",
59
+ ]
60
+
61
+ #: Operations whose output is a configuration the model authored. These are the
62
+ #: operator under test.
63
+ CANDIDATE_OPS = (
64
+ "generate_initial",
65
+ "regenerate",
66
+ "generate_offspring",
67
+ "regenerate_offspring",
68
+ )
69
+
70
+ #: Operations whose output is text that re-enters a later prompt.
71
+ GUIDANCE_OPS = (
72
+ "failure_insights",
73
+ "constraint_instruction",
74
+ "performance_insights",
75
+ )
76
+
77
+
78
+ class SealedReplayDriftError(RuntimeError):
79
+ """A replayed call is not the call that was sealed.
80
+
81
+ Raised rather than falling back to a live call. A silent fallback would let
82
+ a run that claims to be provider-free contact a provider, which is exactly
83
+ the property the seal exists to prove.
84
+ """
85
+
86
+
87
+ def _as_outcome(value: Any) -> ValidationOutcome:
88
+ if isinstance(value, ValidationOutcome):
89
+ return value
90
+ if value is True or value is None:
91
+ return ValidationOutcome(True)
92
+ if value is False:
93
+ return ValidationOutcome(False, "validation", "validate() returned False")
94
+ raise TypeError("validate() must return a ValidationOutcome or a bool")
95
+
96
+
97
+ def _verdict(
98
+ validator: Optional[Callable[[Dict[str, Any]], Any]],
99
+ config: Dict[str, Any],
100
+ ) -> tuple[bool, str]:
101
+ """Run the problem's own feasibility check, and never let it abort the run."""
102
+
103
+ if validator is None:
104
+ return True, ""
105
+ try:
106
+ outcome = _as_outcome(validator(config))
107
+ except ValueError as exc:
108
+ return False, f"ValueError: {exc}" or "ValueError"
109
+ except TypeError as exc:
110
+ return False, f"TypeError: {exc}" or "TypeError"
111
+ if outcome.ok:
112
+ return True, ""
113
+ return False, (outcome.message or outcome.failure_phase or "rejected by validate()")
114
+
115
+
116
+ class SealedGenerativeHarness(HarnessBase):
117
+ """Seal a generative proposer's decisions by content, not by menu index.
118
+
119
+ *delegate* is the proposer actually being audited; in ``replay`` mode it is
120
+ never called and may be omitted entirely.
121
+
122
+ *validator* should be the problem's ``validate``. Its verdict is sealed
123
+ alongside each emission so the journal records what the loop was told, and a
124
+ replay re-runs it and requires agreement -- feasibility certification
125
+ survives the loss of the catalogue.
126
+
127
+ *candidate_schema_sha256* pins the support the emission was drawn from. It
128
+ is the field that makes a matched null checkable: a null sampling a
129
+ different schema is a support mismatch, and this is where that becomes
130
+ visible rather than assumed.
131
+ """
132
+
133
+ id = "sealed_generative"
134
+
135
+ def __init__(
136
+ self,
137
+ delegate: Optional[Harness] = None,
138
+ *,
139
+ candidate_schema_sha256: str,
140
+ mode: str = "record",
141
+ validator: Optional[Callable[[Dict[str, Any]], Any]] = None,
142
+ sealed_calls: Sequence[Any] = (),
143
+ on_seal: Optional[Callable[[Dict[str, Any]], None]] = None,
144
+ ) -> None:
145
+ super().__init__()
146
+ if mode not in ("record", "replay"):
147
+ raise ValueError("mode must be 'record' or 'replay'")
148
+ if mode == "record" and delegate is None:
149
+ raise ValueError("recording requires a delegate proposer to record")
150
+ self._delegate = delegate
151
+ self._mode = mode
152
+ self._validator = validator
153
+ self._schema_sha256 = candidate_schema_sha256
154
+ self._on_seal = on_seal
155
+ self._sealed: List[Any] = list(sealed_calls)
156
+ self._calls: List[Any] = []
157
+ self._previous = GENESIS_CALL_SHA256
158
+ self._cursor = 0
159
+
160
+ # -- lifecycle --------------------------------------------------------
161
+
162
+ def _on_bind(self, ctx: HarnessContext, cfg: LLMConfig) -> None:
163
+ if self._delegate is not None:
164
+ self._delegate.bind(ctx, cfg)
165
+ if self._mode == "record" and not self._calls:
166
+ # The header opens the chain, before any question is asked, because
167
+ # it declares which questions this proposer will be asked at all.
168
+ self._append(
169
+ SealedRunHeader(
170
+ proposer_id=str(getattr(self._delegate, "id", "unknown")),
171
+ requested_model=cfg.model,
172
+ candidate_schema_sha256=self._schema_sha256,
173
+ provides_insights=bool(
174
+ getattr(self._delegate, "provides_insights", True)
175
+ ),
176
+ )
177
+ )
178
+ elif self._mode == "replay":
179
+ if not self._sealed or type(self._sealed[0]) is not SealedRunHeader:
180
+ raise SealedReplayDriftError(
181
+ "the sealed journal has no run header, so the recorded "
182
+ "proposer's declarations cannot be recovered"
183
+ )
184
+ header = self._sealed[0]
185
+ if header.candidate_schema_sha256 != self._schema_sha256:
186
+ raise SealedReplayDriftError(
187
+ "the sealed run was recorded against a different candidate "
188
+ "schema than the one now bound"
189
+ )
190
+ self._cursor = 1
191
+ self._append(header)
192
+
193
+ def set_call_observer(self, observer) -> None: # noqa: ANN001 - port signature
194
+ super().set_call_observer(observer)
195
+ setter = getattr(self._delegate, "set_call_observer", None)
196
+ if setter is not None:
197
+ setter(observer)
198
+
199
+ @property
200
+ def calls(self) -> tuple:
201
+ """The chained journal this run produced, in issue order."""
202
+
203
+ return tuple(self._calls)
204
+
205
+ @property
206
+ def terminal_sha256(self) -> str:
207
+ """The digest that closes the chain. Publishing it dates the evidence."""
208
+
209
+ return self._previous
210
+
211
+ @property
212
+ def provides_insights(self) -> bool:
213
+ """Whether the loop should ask this proposer for guidance at all.
214
+
215
+ In replay the answer is *read from the sealed run header*, not guessed
216
+ and not inferred. The loop skips guidance calls for a proposer that
217
+ declares it makes none -- an uninformed baseline is exactly that case --
218
+ so a replay that assumed ``True`` because the delegate is absent issues a
219
+ call the recording never made, and then reports a drift it invented
220
+ itself. Inferring it from which guidance calls appear does not work
221
+ either: a proposer that declines *failure* insights is still asked for
222
+ the constraint guide, so the journal holds guidance calls in both cases.
223
+ """
224
+
225
+ if self._mode == "replay":
226
+ return bool(self._sealed[0].provides_insights)
227
+ return bool(getattr(self._delegate, "provides_insights", True))
228
+
229
+ # -- the seven operations ---------------------------------------------
230
+
231
+ def generate_initial(self, n: int) -> List[Dict[str, Any]]:
232
+ return self._candidates(
233
+ "generate_initial",
234
+ self.directives.compose_initial(self.context, n),
235
+ lambda: self._delegate.generate_initial(n),
236
+ )
237
+
238
+ def regenerate(
239
+ self,
240
+ failed_str: str,
241
+ n: int,
242
+ constraint_instruction: str,
243
+ performance_insights: str,
244
+ ) -> List[Dict[str, Any]]:
245
+ return self._candidates(
246
+ "regenerate",
247
+ self.directives.compose_regenerate(
248
+ self.context, failed_str, n, constraint_instruction, performance_insights
249
+ ),
250
+ lambda: self._delegate.regenerate(
251
+ failed_str, n, constraint_instruction, performance_insights
252
+ ),
253
+ )
254
+
255
+ def generate_offspring(
256
+ self,
257
+ pareto_str: str,
258
+ n: int,
259
+ constraint_instruction: str,
260
+ performance_insights: str,
261
+ ) -> List[Dict[str, Any]]:
262
+ return self._candidates(
263
+ "generate_offspring",
264
+ self.directives.compose_offspring(
265
+ self.context, pareto_str, n, constraint_instruction, performance_insights
266
+ ),
267
+ lambda: self._delegate.generate_offspring(
268
+ pareto_str, n, constraint_instruction, performance_insights
269
+ ),
270
+ )
271
+
272
+ def regenerate_offspring(
273
+ self,
274
+ failed_str: str,
275
+ pareto_str: str,
276
+ n: int,
277
+ constraint_instruction: str,
278
+ performance_insights: str,
279
+ ) -> List[Dict[str, Any]]:
280
+ return self._candidates(
281
+ "regenerate_offspring",
282
+ self.directives.compose_regenerate_offspring(
283
+ self.context,
284
+ failed_str,
285
+ pareto_str,
286
+ n,
287
+ constraint_instruction,
288
+ performance_insights,
289
+ ),
290
+ lambda: self._delegate.regenerate_offspring(
291
+ failed_str, pareto_str, n, constraint_instruction, performance_insights
292
+ ),
293
+ )
294
+
295
+ def failure_insights(self, failed_str: str, n_failed: int) -> List[str]:
296
+ outputs = self._guidance(
297
+ "failure_insights",
298
+ self.directives.compose_failure_insights(self.context, failed_str, n_failed),
299
+ lambda: self._delegate.failure_insights(failed_str, n_failed),
300
+ )
301
+ return list(outputs)
302
+
303
+ def constraint_instruction(
304
+ self, failed_str: str, previous: Optional[str] = None
305
+ ) -> str:
306
+ outputs = self._guidance(
307
+ "constraint_instruction",
308
+ self.directives.compose_constraint_instruction(
309
+ self.context, failed_str, previous or ""
310
+ ),
311
+ lambda: self._delegate.constraint_instruction(failed_str, previous),
312
+ )
313
+ return outputs[0] if outputs else ""
314
+
315
+ def performance_insights(
316
+ self, stats_str: str, pareto_str: str, previous: Optional[str] = None
317
+ ) -> str:
318
+ outputs = self._guidance(
319
+ "performance_insights",
320
+ self.directives.compose_performance_insights(
321
+ self.context, stats_str, pareto_str, previous or ""
322
+ ),
323
+ lambda: self._delegate.performance_insights(stats_str, pareto_str, previous),
324
+ )
325
+ return outputs[0] if outputs else ""
326
+
327
+ # -- sealing ----------------------------------------------------------
328
+
329
+ def _next_sealed(self, op: str, prompt_sha256: str, expected: type) -> Any:
330
+ if self._cursor >= len(self._sealed):
331
+ raise SealedReplayDriftError(
332
+ f"{op}: the sealed journal is exhausted at call "
333
+ f"{self._cursor}. The replayed run asked more of the proposer "
334
+ "than the recorded one did, so it is a different run."
335
+ )
336
+ call = self._sealed[self._cursor]
337
+ self._cursor += 1
338
+ if type(call) is not expected:
339
+ raise SealedReplayDriftError(
340
+ f"call {call.call_ordinal}: sealed as {type(call).__name__}, "
341
+ f"replayed as {expected.__name__}"
342
+ )
343
+ if call.op != op:
344
+ raise SealedReplayDriftError(
345
+ f"call {call.call_ordinal}: sealed op {call.op!r}, replayed op {op!r}"
346
+ )
347
+ if call.prompt_sha256 != prompt_sha256:
348
+ raise SealedReplayDriftError(
349
+ f"call {call.call_ordinal} ({op}): the prompt is not the sealed "
350
+ "prompt. Replay reconstructs the question before it trusts the "
351
+ "answer, and this question differs."
352
+ )
353
+ return call
354
+
355
+ def _append(self, call: Any) -> None:
356
+ self._calls.append(call)
357
+ self._previous = call.identity_sha256
358
+ if self._on_seal is not None:
359
+ self._on_seal(call.to_record())
360
+
361
+ def _candidates(
362
+ self,
363
+ op: str,
364
+ instruction: str,
365
+ live: Callable[[], List[Dict[str, Any]]],
366
+ ) -> List[Dict[str, Any]]:
367
+ prompt_sha256 = generative_prompt_sha256(instruction)
368
+ ordinal = len(self._calls)
369
+
370
+ if self._mode == "replay":
371
+ sealed = self._next_sealed(op, prompt_sha256, GenerativeProposalCall)
372
+ if sealed.candidate_schema_sha256 != self._schema_sha256:
373
+ raise SealedReplayDriftError(
374
+ f"call {sealed.call_ordinal}: the emission was drawn from a "
375
+ "different candidate schema than the one now bound. The "
376
+ "support moved, so the decision is not the same decision."
377
+ )
378
+ configs = [thaw_json(c) for c in (e.configuration for e in sealed.emissions)]
379
+ self._recheck(sealed, configs)
380
+ call = GenerativeProposalCall(
381
+ call_ordinal=ordinal,
382
+ op=op,
383
+ requested_model=sealed.requested_model,
384
+ prompt_sha256=prompt_sha256,
385
+ candidate_schema_sha256=self._schema_sha256,
386
+ emissions=sealed.emissions,
387
+ previous_call_sha256=self._previous,
388
+ )
389
+ self._append(call)
390
+ return [dict(c) for c in configs]
391
+
392
+ configs = live()
393
+ if not isinstance(configs, list) or not configs:
394
+ # An empty answer is a failed call, and the loop already retries it.
395
+ # Sealing it as a success would put a call in the record that
396
+ # produced nothing, which is the shape of fabricated telemetry.
397
+ raise HarnessOutputError(f"{op}: proposer returned no candidates")
398
+ emissions = []
399
+ for config in configs:
400
+ accepted, reason = _verdict(self._validator, config)
401
+ emissions.append(
402
+ GenerativeEmission(
403
+ configuration=freeze_json(dict(config)),
404
+ accepted=accepted,
405
+ rejection_reason=reason,
406
+ )
407
+ )
408
+ call = GenerativeProposalCall(
409
+ call_ordinal=ordinal,
410
+ op=op,
411
+ requested_model=self.cfg.model,
412
+ prompt_sha256=prompt_sha256,
413
+ candidate_schema_sha256=self._schema_sha256,
414
+ emissions=tuple(emissions),
415
+ previous_call_sha256=self._previous,
416
+ )
417
+ self._append(call)
418
+ return configs
419
+
420
+ def _recheck(self, sealed: GenerativeProposalCall, configs: List[Any]) -> None:
421
+ """Re-run the feasibility check and require the sealed verdict back.
422
+
423
+ This is what replaces the catalogue's enumeration guarantee. The
424
+ catalogue could promise every option was constructible because it built
425
+ them; a generative seal promises only that the emission still earns the
426
+ verdict the run acted on -- and it proves that by asking again.
427
+ """
428
+
429
+ if self._validator is None:
430
+ return
431
+ for emission, config in zip(sealed.emissions, configs):
432
+ accepted, reason = _verdict(self._validator, config)
433
+ if accepted != emission.accepted:
434
+ raise SealedReplayDriftError(
435
+ f"call {sealed.call_ordinal}: a sealed emission validated as "
436
+ f"{'valid' if emission.accepted else 'invalid'} and now "
437
+ f"validates as {'valid' if accepted else 'invalid'}. The "
438
+ "problem's feasibility rule changed under the seal."
439
+ )
440
+ if not accepted and reason != emission.rejection_reason:
441
+ raise SealedReplayDriftError(
442
+ f"call {sealed.call_ordinal}: the rejection the proposer was "
443
+ "shown is not the rejection it would be shown now."
444
+ )
445
+
446
+ def _guidance(
447
+ self,
448
+ op: str,
449
+ instruction: str,
450
+ live: Callable[[], Any],
451
+ ) -> tuple:
452
+ prompt_sha256 = generative_prompt_sha256(instruction)
453
+ ordinal = len(self._calls)
454
+
455
+ if self._mode == "replay":
456
+ sealed = self._next_sealed(op, prompt_sha256, SealedGuidanceCall)
457
+ call = SealedGuidanceCall(
458
+ call_ordinal=ordinal,
459
+ op=op,
460
+ requested_model=sealed.requested_model,
461
+ prompt_sha256=prompt_sha256,
462
+ outputs=sealed.outputs,
463
+ previous_call_sha256=self._previous,
464
+ )
465
+ self._append(call)
466
+ return sealed.outputs
467
+
468
+ raw = live()
469
+ outputs = tuple(str(x) for x in raw) if isinstance(raw, (list, tuple)) else (str(raw),)
470
+ call = SealedGuidanceCall(
471
+ call_ordinal=ordinal,
472
+ op=op,
473
+ requested_model=self.cfg.model,
474
+ prompt_sha256=prompt_sha256,
475
+ outputs=outputs,
476
+ previous_call_sha256=self._previous,
477
+ )
478
+ self._append(call)
479
+ return outputs
@@ -0,0 +1,41 @@
1
+ """Harness registry: register adapters by string id, create them by id."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Callable, Dict, List
6
+
7
+ from agent_evolve.harness.base import Harness
8
+
9
+ HarnessFactory = Callable[[], Harness]
10
+
11
+
12
+ class HarnessRegistry:
13
+ """Process-wide registry of harness adapters keyed by string id."""
14
+
15
+ def __init__(self) -> None:
16
+ self._factories: Dict[str, HarnessFactory] = {}
17
+
18
+ def register(self, harness_id: str, factory: HarnessFactory) -> None:
19
+ self._factories[harness_id] = factory
20
+
21
+ def create(self, harness_id: str, **kwargs: Any) -> Harness:
22
+ if harness_id not in self._factories:
23
+ raise KeyError(
24
+ f"Unknown harness '{harness_id}'. Registered: {sorted(self._factories)}"
25
+ )
26
+ factory = self._factories[harness_id]
27
+ try:
28
+ return factory(**kwargs) if kwargs else factory()
29
+ except TypeError:
30
+ # A factory that does not take the requested options still builds;
31
+ # the option was advisory (a seed, say), not part of the contract.
32
+ return factory()
33
+
34
+ def ids(self) -> List[str]:
35
+ return sorted(self._factories)
36
+
37
+ def clear(self) -> None:
38
+ self._factories.clear()
39
+
40
+
41
+ harness_registry = HarnessRegistry()
@@ -0,0 +1,39 @@
1
+ """Infrastructure adapters for AgentEvolve ports."""
2
+
3
+ from agent_evolve.infrastructure.outcome_adaptive_phase_journal import (
4
+ DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_DEFINITION_SHA256,
5
+ DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_ID,
6
+ DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_VERSION,
7
+ DurableJsonlOutcomeAdaptivePhaseCommitter,
8
+ )
9
+ from agent_evolve.infrastructure.sequential_phase_journal import (
10
+ DURABLE_SEQUENTIAL_PHASE_JOURNAL_DEFINITION_SHA256,
11
+ DURABLE_SEQUENTIAL_PHASE_JOURNAL_ID,
12
+ DURABLE_SEQUENTIAL_PHASE_JOURNAL_VERSION,
13
+ DurableJsonlSequentialPhaseCommitter,
14
+ )
15
+ from agent_evolve.infrastructure.residual_headroom_journal import (
16
+ DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_DEFINITION_SHA256,
17
+ DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_ID,
18
+ DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_VERSION,
19
+ DurableJsonlResidualHeadroomStore,
20
+ )
21
+ from agent_evolve.infrastructure.subprocess_boundary import (
22
+ ExplicitEnvironmentSubprocessBoundary,
23
+ )
24
+
25
+ __all__ = [
26
+ "DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_DEFINITION_SHA256",
27
+ "DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_ID",
28
+ "DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_VERSION",
29
+ "DURABLE_SEQUENTIAL_PHASE_JOURNAL_DEFINITION_SHA256",
30
+ "DURABLE_SEQUENTIAL_PHASE_JOURNAL_ID",
31
+ "DURABLE_SEQUENTIAL_PHASE_JOURNAL_VERSION",
32
+ "DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_DEFINITION_SHA256",
33
+ "DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_ID",
34
+ "DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_VERSION",
35
+ "DurableJsonlResidualHeadroomStore",
36
+ "DurableJsonlOutcomeAdaptivePhaseCommitter",
37
+ "DurableJsonlSequentialPhaseCommitter",
38
+ "ExplicitEnvironmentSubprocessBoundary",
39
+ ]
@@ -0,0 +1,6 @@
1
+ """Content-addressed artifact-store implementations."""
2
+
3
+ from agent_evolve.infrastructure.artifacts.filesystem import FileSystemArtifactStore
4
+ from agent_evolve.infrastructure.artifacts.in_memory import InMemoryArtifactStore
5
+
6
+ __all__ = ["FileSystemArtifactStore", "InMemoryArtifactStore"]
@@ -0,0 +1,67 @@
1
+ """Shared verification for artifact-store adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import agent_evolve.domain.artifact as artifact_domain
6
+ from agent_evolve.domain.artifact import ArtifactRef, validate_media_type
7
+ from agent_evolve.domain.ids import ArtifactId
8
+ from agent_evolve.ports.artifact_store import ArtifactTypeError, CorruptArtifactError
9
+
10
+
11
+ def require_artifact_id(value: ArtifactId) -> None:
12
+ if not isinstance(value, ArtifactId):
13
+ raise ArtifactTypeError("artifact_id must be an ArtifactId")
14
+
15
+
16
+ def require_content_and_media_type(content: bytes, media_type: str) -> None:
17
+ if not isinstance(content, bytes):
18
+ raise ArtifactTypeError("artifact content must be immutable bytes")
19
+ try:
20
+ validate_media_type(media_type)
21
+ except (TypeError, ValueError) as exc:
22
+ raise ArtifactTypeError(f"Invalid artifact media type: {exc}") from exc
23
+
24
+
25
+ def require_expected_media_type(expected_media_type: str | None) -> None:
26
+ if expected_media_type is None:
27
+ return
28
+ try:
29
+ validate_media_type(expected_media_type)
30
+ except (TypeError, ValueError) as exc:
31
+ raise ArtifactTypeError(f"Invalid expected media type: {exc}") from exc
32
+
33
+
34
+ def verify_content(ref: ArtifactRef, content: bytes) -> None:
35
+ if not isinstance(ref, ArtifactRef):
36
+ raise CorruptArtifactError("Stored artifact metadata is not an ArtifactRef")
37
+ if not isinstance(content, bytes):
38
+ raise CorruptArtifactError("Stored artifact content is not immutable bytes")
39
+ if len(content) != ref.size_bytes:
40
+ raise CorruptArtifactError(
41
+ f"Artifact {ref.artifact_id} size does not match its metadata"
42
+ )
43
+ payload_digest = artifact_domain.content_sha256(content)
44
+ if payload_digest != ref.sha256_hex:
45
+ raise CorruptArtifactError(
46
+ f"Artifact {ref.artifact_id} payload does not match its SHA-256 digest"
47
+ )
48
+ identity_digest = artifact_domain.artifact_identity_sha256(
49
+ content,
50
+ media_type=ref.media_type,
51
+ )
52
+ if ref.artifact_id != ArtifactId(f"artifact_{identity_digest}"):
53
+ raise CorruptArtifactError(
54
+ f"Artifact {ref.artifact_id} ID does not match its typed payload"
55
+ )
56
+
57
+
58
+ def verify_expected_media_type(
59
+ ref: ArtifactRef,
60
+ expected_media_type: str | None,
61
+ ) -> None:
62
+ require_expected_media_type(expected_media_type)
63
+ if expected_media_type is not None and ref.media_type != expected_media_type:
64
+ raise ArtifactTypeError(
65
+ f"Artifact {ref.artifact_id} has media type {ref.media_type!r}, "
66
+ f"not {expected_media_type!r}"
67
+ )