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,835 @@
1
+ """Agentic ranked-portfolio adapter for the residual action market.
2
+
3
+ The adapter reuses the established LLM portfolio selector and exact finite
4
+ option materializer, but stops before real evaluation. Its sealed candidates
5
+ can therefore compete with acquisition, restart, or recombination experts
6
+ under the workload/model/provider-blind materialized-action broker.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import hashlib
13
+ import json
14
+ from dataclasses import dataclass, field
15
+
16
+ from agent_evolve.application.agentic_evolution import (
17
+ EvolutionCandidate,
18
+ RewardPolicyBinding,
19
+ )
20
+ from agent_evolve.application.materialized_action_broker import (
21
+ MaterializedActionContext,
22
+ MaterializedActionDescriptor,
23
+ )
24
+ from agent_evolve.application.portfolio_evolution import (
25
+ EvaluatedPreparedPortfolioMember,
26
+ PortfolioEvolution,
27
+ PortfolioVariationWaveRequest,
28
+ PreparedPortfolioVariationWave,
29
+ )
30
+ from agent_evolve.application.residual_portfolio_evolution import (
31
+ DISJOINT_ACTION_EVALUATION_WAVES_V1,
32
+ DisjointActionEvaluationLedger,
33
+ MaterializedActionEvaluation,
34
+ MaterializedActionEvaluationBatch,
35
+ MaterializedActionProposalBatch,
36
+ ResidualPortfolioDecisionRequest,
37
+ )
38
+ from agent_evolve.domain.patch import require_sha256
39
+ from agent_evolve.domain.typed_json import freeze_json
40
+ from agent_evolve.policies.selection.phenotype_recourse import PhenotypeIdentity
41
+
42
+
43
+ AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_ID = "agentic_portfolio"
44
+ AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_VERSION = 2
45
+ AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_DEFINITION_SHA256 = hashlib.sha256(
46
+ b"agent-evolve:agentic-portfolio-residual-expert:v2;"
47
+ b"proposal=one-existing-ranked-finite-portfolio-call;"
48
+ b"materialization=engine-owned-exact-sealed-finite-options;"
49
+ b"evaluation=none-before-downstream-broker;"
50
+ b"phenotype=engine-configured-benchmark-facing-identity-port;"
51
+ b"context=generic-conservative-action-cells;"
52
+ b"operator-arm=finite-option-family;"
53
+ b"memory=selector-visible-cards-with-action-attribution;"
54
+ b"legacy-aggregate-memory-self-credit=forbidden;"
55
+ b"matched-memory-control=forbidden;"
56
+ b"selected-subset-waves=real-concurrent-engine-evaluation;"
57
+ b"exactly-once-boundary=materialized-action;"
58
+ b"reservation=fail-closed-before-authoritative-evaluator-await;"
59
+ b"workload-model-provider-branches=false"
60
+ ).hexdigest()
61
+ AGENTIC_PORTFOLIO_CONTEXT_PROJECTION_DEFINITION_SHA256 = hashlib.sha256(
62
+ b"agent-evolve:agentic-portfolio-residual-context:v1;"
63
+ b"residual-frontier=unknown-before-evaluation;"
64
+ b"parent-position=selected-valid-parent;"
65
+ b"archive-relation=unknown-before-evaluation;"
66
+ b"structural-signature=phenotype-identity;"
67
+ b"patch-compatibility=exact-parent-relative-materialization;"
68
+ b"forecast-calibration=unidentified;"
69
+ b"source-distance=zero-until-identified;"
70
+ b"memory-dose=number-of-cited-cards-clipped-to-15;"
71
+ b"workload-model-provider-fields=false"
72
+ ).hexdigest()
73
+
74
+ _EVALUATOR_RECEIPT_DOMAIN = (
75
+ b"agent-evolve:agentic-portfolio-residual-evaluation:v1\x00"
76
+ )
77
+
78
+
79
+ def _canonical_json(value: object) -> bytes:
80
+ return json.dumps(
81
+ value,
82
+ allow_nan=False,
83
+ ensure_ascii=True,
84
+ separators=(",", ":"),
85
+ sort_keys=True,
86
+ ).encode("ascii", errors="strict")
87
+
88
+
89
+ def _phenotype_identity(
90
+ service: PortfolioEvolution,
91
+ configuration: object,
92
+ ) -> PhenotypeIdentity:
93
+ identify = getattr(service.engine, "identify_phenotype", None)
94
+ if not callable(identify):
95
+ raise TypeError(
96
+ "agentic residual expert requires the portfolio engine's "
97
+ "benchmark-facing phenotype identity boundary"
98
+ )
99
+ identity = identify(configuration)
100
+ if type(identity) is not PhenotypeIdentity:
101
+ raise TypeError("portfolio engine must return an exact PhenotypeIdentity")
102
+ PhenotypeIdentity.__post_init__(identity)
103
+ return identity
104
+
105
+
106
+ def _context(
107
+ request: ResidualPortfolioDecisionRequest,
108
+ *,
109
+ phenotype_identity_sha256: str,
110
+ supporting_card_count: int,
111
+ ) -> MaterializedActionContext:
112
+ require_sha256(
113
+ phenotype_identity_sha256,
114
+ "phenotype_identity_sha256",
115
+ )
116
+ if type(supporting_card_count) is not int or supporting_card_count < 0:
117
+ raise ValueError("supporting_card_count must be non-negative")
118
+ return MaterializedActionContext(
119
+ campaign_scope_sha256=request.campaign_scope_sha256,
120
+ decision_index=request.decision_index,
121
+ phase=request.phase,
122
+ remaining_decisions=request.remaining_decisions,
123
+ remaining_evaluations=request.remaining_evaluations,
124
+ residual_frontier_cell="unknown_before_evaluation",
125
+ parent_position_cell="selected_valid_parent",
126
+ archive_relation_cell="unknown_before_evaluation",
127
+ structural_signature_sha256=phenotype_identity_sha256,
128
+ patch_compatibility_cell="exact_parent_relative_materialization",
129
+ forecast_calibration_cell="unidentified",
130
+ source_distance_bin=0,
131
+ memory_dose_bin=min(supporting_card_count, 15),
132
+ )
133
+
134
+
135
+ def _evaluation_receipt_sha256(
136
+ *,
137
+ prepared: PreparedPortfolioVariationWave,
138
+ evaluated: EvaluatedPreparedPortfolioMember,
139
+ action: MaterializedActionDescriptor,
140
+ ) -> str:
141
+ if type(prepared) is not PreparedPortfolioVariationWave:
142
+ raise TypeError("prepared must be exact")
143
+ prepared.__post_init__()
144
+ if type(evaluated) is not EvaluatedPreparedPortfolioMember:
145
+ raise TypeError("evaluated must be exact")
146
+ evaluated.__post_init__()
147
+ if type(action) is not MaterializedActionDescriptor:
148
+ raise TypeError("action must be exact")
149
+ action.__post_init__()
150
+ candidate = evaluated.outcome.candidate
151
+ if (
152
+ candidate is None
153
+ or candidate.candidate_id != action.target_candidate_id
154
+ or candidate.occurrence.configuration_hash != action.configuration_sha256
155
+ ):
156
+ raise ValueError("evaluated member differs from residual action")
157
+ detailed = candidate.detailed_evaluation
158
+ return hashlib.sha256(
159
+ _EVALUATOR_RECEIPT_DOMAIN
160
+ + _canonical_json(
161
+ {
162
+ "schema_version": 1,
163
+ "prepared_portfolio_sha256": prepared.preparation_sha256,
164
+ "action_sha256": action.action_sha256,
165
+ "materialization_receipt_sha256": (
166
+ evaluated.materialization.receipt_sha256
167
+ ),
168
+ "portfolio_outcome_sha256": evaluated.receipt.outcome_sha256,
169
+ "candidate_id": candidate.candidate_id.value,
170
+ "configuration_sha256": (
171
+ candidate.occurrence.configuration_hash
172
+ ),
173
+ "valid": candidate.valid,
174
+ "detailed_evaluation_sha256": (
175
+ None if detailed is None else detailed.evidence_sha256
176
+ ),
177
+ }
178
+ )
179
+ ).hexdigest()
180
+
181
+
182
+ @dataclass(slots=True)
183
+ class AgenticPortfolioResidualExpert:
184
+ """Expose one existing agentic portfolio wave as unevaluated proposals.
185
+
186
+ The injected ``prior_state_sha256`` is the common campaign cutoff shared
187
+ with every competing expert. The distinct portfolio-selection request
188
+ hash still binds this expert's finite action catalog, cards, parent,
189
+ selector context, and LLM-call identity in proposal evidence.
190
+ """
191
+
192
+ portfolio: PortfolioEvolution
193
+ wave: PortfolioVariationWaveRequest
194
+ campaign_scope_sha256: str
195
+ prior_state_sha256: str
196
+ reward_binding: RewardPolicyBinding | None = None
197
+ expert_id: str = field(
198
+ init=False,
199
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_ID,
200
+ )
201
+ expert_version: int = field(
202
+ init=False,
203
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_VERSION,
204
+ )
205
+ definition_sha256: str = field(
206
+ init=False,
207
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_DEFINITION_SHA256,
208
+ )
209
+ _prepared_by_proposal: dict[str, PreparedPortfolioVariationWave] = field(
210
+ init=False,
211
+ default_factory=dict,
212
+ )
213
+ evaluation_wave_semantics: str = field(
214
+ init=False,
215
+ default=DISJOINT_ACTION_EVALUATION_WAVES_V1,
216
+ )
217
+ _evaluation_ledger: DisjointActionEvaluationLedger = field(
218
+ init=False,
219
+ default_factory=DisjointActionEvaluationLedger,
220
+ )
221
+
222
+ def __post_init__(self) -> None:
223
+ if type(self.portfolio) is not PortfolioEvolution:
224
+ raise TypeError("portfolio must be an exact PortfolioEvolution")
225
+ self.portfolio.__post_init__()
226
+ if type(self.wave) is not PortfolioVariationWaveRequest:
227
+ raise TypeError("wave must be an exact PortfolioVariationWaveRequest")
228
+ PortfolioVariationWaveRequest.__post_init__(self.wave)
229
+ require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
230
+ require_sha256(self.prior_state_sha256, "prior_state_sha256")
231
+ if (
232
+ self.wave.memory_credit is not None
233
+ or self.wave.matched_memory_control is not None
234
+ ):
235
+ raise ValueError(
236
+ "residual brokerage forbids legacy wave-level memory credit; "
237
+ "credit selected actions downstream"
238
+ )
239
+ if self.reward_binding is not None:
240
+ if type(self.reward_binding) is not RewardPolicyBinding:
241
+ raise TypeError("reward_binding must be exact or None")
242
+ RewardPolicyBinding.__post_init__(self.reward_binding)
243
+ # Fail during composition, not after one paid selector call.
244
+ _phenotype_identity(self.portfolio, self.wave.parent.configuration)
245
+
246
+ def _validate_request(
247
+ self,
248
+ request: ResidualPortfolioDecisionRequest,
249
+ ) -> int:
250
+ if type(request) is not ResidualPortfolioDecisionRequest:
251
+ raise TypeError("request must be an exact residual request")
252
+ request.__post_init__()
253
+ expected_slots = request.proposal_slots_for(self.expert_id)
254
+ if request.campaign_scope_sha256 != self.campaign_scope_sha256:
255
+ raise ValueError("residual request crosses campaign scopes")
256
+ if request.prior_state_sha256 != self.prior_state_sha256:
257
+ raise ValueError(
258
+ "residual prior-state identity differs from the common cutoff"
259
+ )
260
+ if expected_slots != self.wave.selection_request.portfolio_size:
261
+ raise ValueError(
262
+ "residual proposal capacity differs from ranked portfolio size"
263
+ )
264
+ return expected_slots
265
+
266
+ async def propose(
267
+ self,
268
+ request: ResidualPortfolioDecisionRequest,
269
+ ) -> MaterializedActionProposalBatch:
270
+ expected_slots = self._validate_request(request)
271
+ prepared = await self.portfolio.prepare(self.wave)
272
+ if len(prepared.invocations) != expected_slots:
273
+ raise RuntimeError("agentic portfolio did not fill proposal capacity")
274
+ actions: list[MaterializedActionDescriptor] = []
275
+ member_evidence: list[dict[str, object]] = []
276
+ for selected, invocation in zip(
277
+ prepared.selection.decision.members,
278
+ prepared.invocations,
279
+ strict=True,
280
+ ):
281
+ identity = _phenotype_identity(
282
+ self.portfolio,
283
+ invocation.draft.configuration,
284
+ )
285
+ action = MaterializedActionDescriptor(
286
+ context=_context(
287
+ request,
288
+ phenotype_identity_sha256=identity.identity_sha256,
289
+ supporting_card_count=len(selected.supporting_card_keys),
290
+ ),
291
+ configuration=freeze_json(invocation.draft.configuration),
292
+ phenotype_identity_sha256=identity.identity_sha256,
293
+ expert_id=self.expert_id,
294
+ native_rank=selected.rank,
295
+ parent_ids=tuple(
296
+ value.candidate_id for value in invocation.plan.parents
297
+ ),
298
+ operator_id=selected.family,
299
+ target_candidate_id=invocation.candidate_id,
300
+ role_id="llm_ranked_challenger",
301
+ normalized_evaluation_cost=1.0,
302
+ reference_action=False,
303
+ )
304
+ actions.append(action)
305
+ member_evidence.append(
306
+ {
307
+ "action_sha256": action.action_sha256,
308
+ "rank": selected.rank,
309
+ "option_id": selected.option_id,
310
+ "option_identity_sha256": (
311
+ selected.option_identity_sha256
312
+ ),
313
+ "family": selected.family,
314
+ "supporting_card_keys": list(
315
+ selected.supporting_card_keys
316
+ ),
317
+ "effect_predictions": [
318
+ {
319
+ "metric_id": value.metric_id,
320
+ "direction": value.direction.value,
321
+ }
322
+ for value in selected.effect_predictions
323
+ ],
324
+ "design_rationale_sha256": hashlib.sha256(
325
+ selected.design_rationale.encode(
326
+ "utf-8",
327
+ errors="strict",
328
+ )
329
+ ).hexdigest(),
330
+ }
331
+ )
332
+ supplemental = prepared.selection.supplemental_audit
333
+ evidence = freeze_json(
334
+ {
335
+ "schema_version": 1,
336
+ "prepared_portfolio_sha256": prepared.preparation_sha256,
337
+ "source_request_sha256": (
338
+ self.wave.selection_request.request_sha256
339
+ ),
340
+ "common_prior_state_sha256": self.prior_state_sha256,
341
+ "source_decision_sha256": (
342
+ prepared.selection.decision.decision_sha256
343
+ ),
344
+ "source_selection_policy": {
345
+ "policy_id": prepared.selection.decision.policy_id,
346
+ "policy_version": (
347
+ prepared.selection.decision.policy_version
348
+ ),
349
+ "definition_sha256": (
350
+ prepared.selection.decision.policy_definition_sha256
351
+ ),
352
+ },
353
+ "selection_telemetry_sha256": (
354
+ prepared.selection_telemetry_sha256
355
+ ),
356
+ "supplemental_audit_sha256": (
357
+ None if supplemental is None else supplemental.audit_sha256
358
+ ),
359
+ "context_projection_definition_sha256": (
360
+ AGENTIC_PORTFOLIO_CONTEXT_PROJECTION_DEFINITION_SHA256
361
+ ),
362
+ "members": member_evidence,
363
+ "strictly_prior_outcomes_only": True,
364
+ "evaluation_deferred": True,
365
+ "legacy_memory_self_credit": False,
366
+ }
367
+ )
368
+ batch = MaterializedActionProposalBatch(
369
+ request_sha256=request.request_sha256,
370
+ expert_id=self.expert_id,
371
+ expert_version=self.expert_version,
372
+ expert_definition_sha256=self.definition_sha256,
373
+ actions=tuple(actions),
374
+ evidence=evidence,
375
+ )
376
+ if batch.proposal_sha256 in self._prepared_by_proposal:
377
+ raise RuntimeError("agentic residual proposal was repeated")
378
+ self._prepared_by_proposal[batch.proposal_sha256] = prepared
379
+ return batch
380
+
381
+ async def evaluate(
382
+ self,
383
+ proposal: MaterializedActionProposalBatch,
384
+ selected_action_sha256s: tuple[str, ...],
385
+ ) -> MaterializedActionEvaluationBatch:
386
+ if type(proposal) is not MaterializedActionProposalBatch:
387
+ raise TypeError("proposal must be exact")
388
+ proposal.__post_init__()
389
+ if (
390
+ proposal.expert_id,
391
+ proposal.expert_version,
392
+ proposal.expert_definition_sha256,
393
+ ) != (self.expert_id, self.expert_version, self.definition_sha256):
394
+ raise ValueError("proposal is bound to another expert")
395
+ try:
396
+ prepared = self._prepared_by_proposal[proposal.proposal_sha256]
397
+ except KeyError as error:
398
+ raise ValueError("proposal was not issued by this live expert") from error
399
+ if (
400
+ type(selected_action_sha256s) is not tuple
401
+ or not selected_action_sha256s
402
+ or selected_action_sha256s
403
+ != tuple(sorted(set(selected_action_sha256s)))
404
+ ):
405
+ raise ValueError("selected action hashes must be non-empty and canonical")
406
+ action_by_sha256 = {
407
+ value.action_sha256: value for value in proposal.actions
408
+ }
409
+ try:
410
+ selected_actions = tuple(
411
+ action_by_sha256[value] for value in selected_action_sha256s
412
+ )
413
+ except KeyError as error:
414
+ raise ValueError(
415
+ "broker selected outside the agentic proposal"
416
+ ) from error
417
+ wave = self._evaluation_ledger.reserve(
418
+ proposal,
419
+ selected_action_sha256s,
420
+ )
421
+ evaluated = await self.portfolio.evaluate_prepared_members(
422
+ prepared,
423
+ tuple(value.target_candidate_id for value in selected_actions),
424
+ reward_binding=self.reward_binding,
425
+ )
426
+ evaluations: list[MaterializedActionEvaluation] = []
427
+ for action, member in zip(
428
+ selected_actions,
429
+ evaluated,
430
+ strict=True,
431
+ ):
432
+ candidate = member.outcome.candidate
433
+ if type(candidate) is not EvolutionCandidate:
434
+ raise ValueError("agentic portfolio evaluation omitted its candidate")
435
+ evaluations.append(
436
+ MaterializedActionEvaluation(
437
+ action=action,
438
+ candidate=candidate,
439
+ evaluator_receipt_sha256=_evaluation_receipt_sha256(
440
+ prepared=prepared,
441
+ evaluated=member,
442
+ action=action,
443
+ ),
444
+ )
445
+ )
446
+ evidence = freeze_json(
447
+ {
448
+ "schema_version": 1,
449
+ "prepared_portfolio_sha256": prepared.preparation_sha256,
450
+ "selected_native_ranks": [
451
+ value.native_rank for value in selected_actions
452
+ ],
453
+ "selected_candidate_ids": [
454
+ value.target_candidate_id.value
455
+ for value in selected_actions
456
+ ],
457
+ "real_evaluation_count": len(evaluations),
458
+ "broker_selected_subset_only": True,
459
+ "downstream_archive_credit_pending": True,
460
+ "evaluation_wave": wave.to_record(),
461
+ }
462
+ )
463
+ batch = MaterializedActionEvaluationBatch(
464
+ proposal_sha256=proposal.proposal_sha256,
465
+ expert_id=self.expert_id,
466
+ expert_version=self.expert_version,
467
+ expert_definition_sha256=self.definition_sha256,
468
+ selected_action_sha256s=selected_action_sha256s,
469
+ evaluations=tuple(evaluations),
470
+ evidence=evidence,
471
+ )
472
+ return batch
473
+
474
+
475
+ @dataclass(slots=True)
476
+ class AgenticPortfolioBatchResidualExpert:
477
+ """Aggregate concurrent parent-lane portfolios into one proposal expert.
478
+
479
+ A campaign commonly owns several parent lanes but the broker should learn
480
+ one transferable ``agentic_portfolio`` arm, not one arm per lane. This
481
+ adapter prepares every lane concurrently, assigns one contiguous expert
482
+ rank over their union, and later evaluates only the broker-selected
483
+ occurrences grouped by source lane.
484
+ """
485
+
486
+ portfolio: PortfolioEvolution
487
+ waves: tuple[PortfolioVariationWaveRequest, ...]
488
+ campaign_scope_sha256: str
489
+ prior_state_sha256: str
490
+ reward_binding: RewardPolicyBinding | None = None
491
+ expert_id: str = field(
492
+ init=False,
493
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_ID,
494
+ )
495
+ expert_version: int = field(
496
+ init=False,
497
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_VERSION,
498
+ )
499
+ definition_sha256: str = field(
500
+ init=False,
501
+ default=AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_DEFINITION_SHA256,
502
+ )
503
+ _prepared_by_proposal: dict[
504
+ str,
505
+ tuple[PreparedPortfolioVariationWave, ...],
506
+ ] = field(init=False, default_factory=dict)
507
+ evaluation_wave_semantics: str = field(
508
+ init=False,
509
+ default=DISJOINT_ACTION_EVALUATION_WAVES_V1,
510
+ )
511
+ _evaluation_ledger: DisjointActionEvaluationLedger = field(
512
+ init=False,
513
+ default_factory=DisjointActionEvaluationLedger,
514
+ )
515
+
516
+ def __post_init__(self) -> None:
517
+ if type(self.portfolio) is not PortfolioEvolution:
518
+ raise TypeError("portfolio must be an exact PortfolioEvolution")
519
+ self.portfolio.__post_init__()
520
+ if type(self.waves) is not tuple or not self.waves:
521
+ raise ValueError("waves must be a non-empty exact tuple")
522
+ for wave in self.waves:
523
+ if type(wave) is not PortfolioVariationWaveRequest:
524
+ raise TypeError("waves must contain exact portfolio requests")
525
+ PortfolioVariationWaveRequest.__post_init__(wave)
526
+ if (
527
+ wave.memory_credit is not None
528
+ or wave.matched_memory_control is not None
529
+ ):
530
+ raise ValueError(
531
+ "residual brokerage forbids legacy wave-level memory credit"
532
+ )
533
+ request_ids = tuple(
534
+ value.selection_request.request_sha256 for value in self.waves
535
+ )
536
+ parent_ids = tuple(value.parent.candidate_id for value in self.waves)
537
+ if (
538
+ len(set(request_ids)) != len(request_ids)
539
+ or len(set(parent_ids)) != len(parent_ids)
540
+ ):
541
+ raise ValueError("batch waves must have unique requests and parents")
542
+ require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
543
+ require_sha256(self.prior_state_sha256, "prior_state_sha256")
544
+ if self.reward_binding is not None:
545
+ if type(self.reward_binding) is not RewardPolicyBinding:
546
+ raise TypeError("reward_binding must be exact or None")
547
+ RewardPolicyBinding.__post_init__(self.reward_binding)
548
+ _phenotype_identity(self.portfolio, self.waves[0].parent.configuration)
549
+
550
+ @property
551
+ def proposal_capacity(self) -> int:
552
+ return sum(
553
+ value.selection_request.portfolio_size for value in self.waves
554
+ )
555
+
556
+ def _validate_request(
557
+ self,
558
+ request: ResidualPortfolioDecisionRequest,
559
+ ) -> None:
560
+ if type(request) is not ResidualPortfolioDecisionRequest:
561
+ raise TypeError("request must be an exact residual request")
562
+ request.__post_init__()
563
+ if request.campaign_scope_sha256 != self.campaign_scope_sha256:
564
+ raise ValueError("residual request crosses campaign scopes")
565
+ if request.prior_state_sha256 != self.prior_state_sha256:
566
+ raise ValueError(
567
+ "residual prior-state identity differs from the common cutoff"
568
+ )
569
+ if request.proposal_slots_for(self.expert_id) != self.proposal_capacity:
570
+ raise ValueError(
571
+ "residual proposal capacity differs from batched portfolio size"
572
+ )
573
+
574
+ async def propose(
575
+ self,
576
+ request: ResidualPortfolioDecisionRequest,
577
+ ) -> MaterializedActionProposalBatch:
578
+ self._validate_request(request)
579
+ raw_prepared = await asyncio.gather(
580
+ *(self.portfolio.prepare(value) for value in self.waves)
581
+ )
582
+ prepared = tuple(raw_prepared)
583
+ if sum(len(value.invocations) for value in prepared) != self.proposal_capacity:
584
+ raise RuntimeError("agentic portfolio batch did not fill capacity")
585
+ actions: list[MaterializedActionDescriptor] = []
586
+ wave_evidence: list[dict[str, object]] = []
587
+ global_rank = 0
588
+ for lane_index, value in enumerate(prepared, start=1):
589
+ lane_members: list[dict[str, object]] = []
590
+ for selected, invocation in zip(
591
+ value.selection.decision.members,
592
+ value.invocations,
593
+ strict=True,
594
+ ):
595
+ global_rank += 1
596
+ identity = _phenotype_identity(
597
+ self.portfolio,
598
+ invocation.draft.configuration,
599
+ )
600
+ action = MaterializedActionDescriptor(
601
+ context=_context(
602
+ request,
603
+ phenotype_identity_sha256=identity.identity_sha256,
604
+ supporting_card_count=len(
605
+ selected.supporting_card_keys
606
+ ),
607
+ ),
608
+ configuration=freeze_json(invocation.draft.configuration),
609
+ phenotype_identity_sha256=identity.identity_sha256,
610
+ expert_id=self.expert_id,
611
+ native_rank=global_rank,
612
+ parent_ids=tuple(
613
+ parent.candidate_id
614
+ for parent in invocation.plan.parents
615
+ ),
616
+ operator_id=selected.family,
617
+ target_candidate_id=invocation.candidate_id,
618
+ role_id="llm_ranked_challenger",
619
+ normalized_evaluation_cost=1.0,
620
+ reference_action=False,
621
+ )
622
+ actions.append(action)
623
+ lane_members.append(
624
+ {
625
+ "action_sha256": action.action_sha256,
626
+ "expert_native_rank": global_rank,
627
+ "lane_native_rank": selected.rank,
628
+ "option_id": selected.option_id,
629
+ "option_identity_sha256": (
630
+ selected.option_identity_sha256
631
+ ),
632
+ "family": selected.family,
633
+ "supporting_card_keys": list(
634
+ selected.supporting_card_keys
635
+ ),
636
+ "effect_predictions": [
637
+ {
638
+ "metric_id": prediction.metric_id,
639
+ "direction": prediction.direction.value,
640
+ }
641
+ for prediction in selected.effect_predictions
642
+ ],
643
+ "design_rationale_sha256": hashlib.sha256(
644
+ selected.design_rationale.encode(
645
+ "utf-8",
646
+ errors="strict",
647
+ )
648
+ ).hexdigest(),
649
+ }
650
+ )
651
+ supplemental = value.selection.supplemental_audit
652
+ wave_evidence.append(
653
+ {
654
+ "lane_index": lane_index,
655
+ "parent_candidate_id": value.wave.parent.candidate_id.value,
656
+ "source_request_sha256": (
657
+ value.wave.selection_request.request_sha256
658
+ ),
659
+ "source_decision_sha256": (
660
+ value.selection.decision.decision_sha256
661
+ ),
662
+ "prepared_portfolio_sha256": value.preparation_sha256,
663
+ "selection_telemetry_sha256": (
664
+ value.selection_telemetry_sha256
665
+ ),
666
+ "supplemental_audit_sha256": (
667
+ None
668
+ if supplemental is None
669
+ else supplemental.audit_sha256
670
+ ),
671
+ "members": lane_members,
672
+ }
673
+ )
674
+ evidence = freeze_json(
675
+ {
676
+ "schema_version": 1,
677
+ "common_prior_state_sha256": self.prior_state_sha256,
678
+ "context_projection_definition_sha256": (
679
+ AGENTIC_PORTFOLIO_CONTEXT_PROJECTION_DEFINITION_SHA256
680
+ ),
681
+ "source_waves": wave_evidence,
682
+ "concurrent_parent_lane_preparation": True,
683
+ "strictly_prior_outcomes_only": True,
684
+ "evaluation_deferred": True,
685
+ "legacy_memory_self_credit": False,
686
+ }
687
+ )
688
+ batch = MaterializedActionProposalBatch(
689
+ request_sha256=request.request_sha256,
690
+ expert_id=self.expert_id,
691
+ expert_version=self.expert_version,
692
+ expert_definition_sha256=self.definition_sha256,
693
+ actions=tuple(actions),
694
+ evidence=evidence,
695
+ )
696
+ if batch.proposal_sha256 in self._prepared_by_proposal:
697
+ raise RuntimeError("agentic residual batch proposal was repeated")
698
+ self._prepared_by_proposal[batch.proposal_sha256] = prepared
699
+ return batch
700
+
701
+ async def evaluate(
702
+ self,
703
+ proposal: MaterializedActionProposalBatch,
704
+ selected_action_sha256s: tuple[str, ...],
705
+ ) -> MaterializedActionEvaluationBatch:
706
+ if type(proposal) is not MaterializedActionProposalBatch:
707
+ raise TypeError("proposal must be exact")
708
+ proposal.__post_init__()
709
+ if (
710
+ proposal.expert_id,
711
+ proposal.expert_version,
712
+ proposal.expert_definition_sha256,
713
+ ) != (self.expert_id, self.expert_version, self.definition_sha256):
714
+ raise ValueError("proposal is bound to another expert")
715
+ try:
716
+ prepared = self._prepared_by_proposal[proposal.proposal_sha256]
717
+ except KeyError as error:
718
+ raise ValueError("proposal was not issued by this live expert") from error
719
+ if (
720
+ type(selected_action_sha256s) is not tuple
721
+ or not selected_action_sha256s
722
+ or selected_action_sha256s
723
+ != tuple(sorted(set(selected_action_sha256s)))
724
+ ):
725
+ raise ValueError("selected action hashes must be non-empty and canonical")
726
+ action_by_sha256 = {
727
+ value.action_sha256: value for value in proposal.actions
728
+ }
729
+ try:
730
+ selected_actions = tuple(
731
+ action_by_sha256[value] for value in selected_action_sha256s
732
+ )
733
+ except KeyError as error:
734
+ raise ValueError(
735
+ "broker selected outside the agentic batch proposal"
736
+ ) from error
737
+ wave = self._evaluation_ledger.reserve(
738
+ proposal,
739
+ selected_action_sha256s,
740
+ )
741
+
742
+ prepared_by_candidate = {
743
+ invocation.candidate_id: (lane_index, value)
744
+ for lane_index, value in enumerate(prepared)
745
+ for invocation in value.invocations
746
+ }
747
+ lane_actions: dict[int, list[MaterializedActionDescriptor]] = {}
748
+ for action in selected_actions:
749
+ try:
750
+ lane_index, _ = prepared_by_candidate[action.target_candidate_id]
751
+ except KeyError as error:
752
+ raise ValueError(
753
+ "selected action lost its prepared source lane"
754
+ ) from error
755
+ lane_actions.setdefault(lane_index, []).append(action)
756
+ lane_indices = tuple(sorted(lane_actions))
757
+ raw_evaluated = await asyncio.gather(
758
+ *(
759
+ self.portfolio.evaluate_prepared_members(
760
+ prepared[lane_index],
761
+ tuple(
762
+ value.target_candidate_id
763
+ for value in lane_actions[lane_index]
764
+ ),
765
+ reward_binding=self.reward_binding,
766
+ )
767
+ for lane_index in lane_indices
768
+ )
769
+ )
770
+ evaluated_by_candidate = {
771
+ value.materialization.candidate_id: value
772
+ for lane_result in raw_evaluated
773
+ for value in lane_result
774
+ }
775
+ evaluations: list[MaterializedActionEvaluation] = []
776
+ for action in selected_actions:
777
+ try:
778
+ member = evaluated_by_candidate[action.target_candidate_id]
779
+ except KeyError as error:
780
+ raise RuntimeError(
781
+ "selected agentic action was not evaluated"
782
+ ) from error
783
+ candidate = member.outcome.candidate
784
+ if type(candidate) is not EvolutionCandidate:
785
+ raise ValueError("agentic batch evaluation omitted its candidate")
786
+ _, source_prepared = prepared_by_candidate[
787
+ action.target_candidate_id
788
+ ]
789
+ evaluations.append(
790
+ MaterializedActionEvaluation(
791
+ action=action,
792
+ candidate=candidate,
793
+ evaluator_receipt_sha256=_evaluation_receipt_sha256(
794
+ prepared=source_prepared,
795
+ evaluated=member,
796
+ action=action,
797
+ ),
798
+ )
799
+ )
800
+ evidence = freeze_json(
801
+ {
802
+ "schema_version": 1,
803
+ "source_preparation_sha256s": [
804
+ value.preparation_sha256 for value in prepared
805
+ ],
806
+ "selected_native_ranks": [
807
+ value.native_rank for value in selected_actions
808
+ ],
809
+ "selected_parent_lane_count": len(lane_indices),
810
+ "real_evaluation_count": len(evaluations),
811
+ "broker_selected_subset_only": True,
812
+ "downstream_archive_credit_pending": True,
813
+ "evaluation_wave": wave.to_record(),
814
+ }
815
+ )
816
+ batch = MaterializedActionEvaluationBatch(
817
+ proposal_sha256=proposal.proposal_sha256,
818
+ expert_id=self.expert_id,
819
+ expert_version=self.expert_version,
820
+ expert_definition_sha256=self.definition_sha256,
821
+ selected_action_sha256s=selected_action_sha256s,
822
+ evaluations=tuple(evaluations),
823
+ evidence=evidence,
824
+ )
825
+ return batch
826
+
827
+
828
+ __all__ = [
829
+ "AGENTIC_PORTFOLIO_CONTEXT_PROJECTION_DEFINITION_SHA256",
830
+ "AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_DEFINITION_SHA256",
831
+ "AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_ID",
832
+ "AGENTIC_PORTFOLIO_RESIDUAL_EXPERT_VERSION",
833
+ "AgenticPortfolioBatchResidualExpert",
834
+ "AgenticPortfolioResidualExpert",
835
+ ]