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,575 @@
1
+ """Portable pre-evaluation consequence features for residual actions.
2
+
3
+ The feature ABI is expressed only in generic campaign quantities: prior
4
+ broker evidence, native rank, mutation radius/arity, calibrated LLM forecasts,
5
+ parent archive opportunity, and remaining-horizon phase. Workload objective
6
+ geometry is delegated to an authenticated scalar archive-utility port.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ from collections import Counter
13
+ from dataclasses import dataclass, field
14
+ import hashlib
15
+ import json
16
+ import math
17
+ import statistics
18
+
19
+ from agent_evolve.application.agentic_evolution import EvolutionCandidate
20
+ from agent_evolve.application.candidate_archive_consequence import (
21
+ CandidateArchiveConsequenceUtilityPort,
22
+ candidate_archive_utility,
23
+ validate_candidate_archive_consequence_utility,
24
+ )
25
+ from agent_evolve.application.contextual_search_controller import SearchPhase
26
+ from agent_evolve.application.frozen_hurdle_score import (
27
+ MaterializedActionFeatureBatch,
28
+ MaterializedActionFeatureVector,
29
+ )
30
+ from agent_evolve.application.materialized_action_broker import (
31
+ BrokerEvidenceChannel,
32
+ RegretBrokeredMaterializedActionPolicy,
33
+ )
34
+ from agent_evolve.application.residual_portfolio_evolution import (
35
+ MaterializedActionProposalBatch,
36
+ ResidualPortfolioDecisionRequest,
37
+ )
38
+ from agent_evolve.domain.ids import CandidateId
39
+ from agent_evolve.domain.typed_json import freeze_json
40
+
41
+ from .materialized_hierarchical_residual_expert import (
42
+ MaterializedHierarchicalResidualActionEvidence,
43
+ MaterializedHierarchicalResidualActionEvidencePort,
44
+ )
45
+
46
+
47
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_NAMES = (
48
+ "broker_mean",
49
+ "broker_standard_deviation",
50
+ "broker_upper_bound",
51
+ "opportunity_scaled_index",
52
+ "gain_global_mean",
53
+ "gain_global_count_log1p",
54
+ "gain_local_mean",
55
+ "gain_local_count_log1p",
56
+ "positive_global_mean",
57
+ "positive_global_count_log1p",
58
+ "native_rank_reciprocal",
59
+ "native_rank_percentile",
60
+ "reference_action",
61
+ "radius_normalized",
62
+ "component_count_normalized",
63
+ "probability_valid",
64
+ "forecast_available",
65
+ "forecast_minimum_confidence",
66
+ "forecast_mean_confidence",
67
+ "predicted_p10_complement",
68
+ "predicted_p50_complement",
69
+ "predicted_p90_complement",
70
+ "predicted_complement_spread",
71
+ "parent_available",
72
+ "parent_leave_one_out_contribution",
73
+ "parent_leave_one_out_fraction_of_opportunity",
74
+ "parent_generated_in_live_run",
75
+ "phase_composition",
76
+ "phase_terminal_conversion",
77
+ )
78
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_ID = (
79
+ "portable_residual_consequence_features"
80
+ )
81
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_VERSION = 1
82
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_GROUPS = (
83
+ (
84
+ "empirical_history",
85
+ (
86
+ "broker_mean",
87
+ "broker_standard_deviation",
88
+ "broker_upper_bound",
89
+ "opportunity_scaled_index",
90
+ "gain_global_mean",
91
+ "gain_global_count_log1p",
92
+ "gain_local_mean",
93
+ "gain_local_count_log1p",
94
+ "positive_global_mean",
95
+ "positive_global_count_log1p",
96
+ ),
97
+ ),
98
+ (
99
+ "forecast",
100
+ (
101
+ "forecast_available",
102
+ "forecast_minimum_confidence",
103
+ "forecast_mean_confidence",
104
+ "predicted_p10_complement",
105
+ "predicted_p50_complement",
106
+ "predicted_p90_complement",
107
+ "predicted_complement_spread",
108
+ ),
109
+ ),
110
+ (
111
+ "parent",
112
+ (
113
+ "parent_available",
114
+ "parent_leave_one_out_contribution",
115
+ "parent_leave_one_out_fraction_of_opportunity",
116
+ "parent_generated_in_live_run",
117
+ ),
118
+ ),
119
+ (
120
+ "phase",
121
+ (
122
+ "phase_composition",
123
+ "phase_terminal_conversion",
124
+ ),
125
+ ),
126
+ (
127
+ "proposal_structure",
128
+ (
129
+ "native_rank_reciprocal",
130
+ "native_rank_percentile",
131
+ "reference_action",
132
+ "radius_normalized",
133
+ "component_count_normalized",
134
+ "probability_valid",
135
+ ),
136
+ ),
137
+ )
138
+ _DEFINITION_DOMAIN = (
139
+ b"agent-evolve:portable-residual-consequence-features:v1\x00"
140
+ )
141
+
142
+
143
+ def _canonical_json(value: object) -> bytes:
144
+ return json.dumps(
145
+ value,
146
+ allow_nan=False,
147
+ ensure_ascii=True,
148
+ separators=(",", ":"),
149
+ sort_keys=True,
150
+ ).encode("ascii", errors="strict")
151
+
152
+
153
+ def _feature_abi_sha256() -> str:
154
+ return hashlib.sha256(
155
+ b"agent-evolve:portable-residual-consequence-feature-abi:v1\x00"
156
+ + _canonical_json(PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_NAMES)
157
+ ).hexdigest()
158
+
159
+
160
+ @dataclass(slots=True)
161
+ class PortableResidualConsequenceFeatureProjection:
162
+ """Project a sealed action population using one authenticated prior cutoff."""
163
+
164
+ prior_candidates: tuple[EvolutionCandidate, ...]
165
+ initial_candidate_ids: tuple[CandidateId, ...]
166
+ evidence_sources: tuple[
167
+ MaterializedHierarchicalResidualActionEvidencePort,
168
+ ...,
169
+ ] = field(repr=False, compare=False)
170
+ broker: RegretBrokeredMaterializedActionPolicy = field(
171
+ repr=False,
172
+ compare=False,
173
+ )
174
+ archive_utility: CandidateArchiveConsequenceUtilityPort = field(
175
+ repr=False,
176
+ compare=False,
177
+ )
178
+ projection_id: str = (
179
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_ID
180
+ )
181
+ projection_version: int = (
182
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_VERSION
183
+ )
184
+ feature_names: tuple[str, ...] = (
185
+ PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_NAMES
186
+ )
187
+ definition_sha256: str = field(init=False)
188
+ _cache: dict[str, MaterializedActionFeatureBatch] = field(
189
+ init=False,
190
+ default_factory=dict,
191
+ repr=False,
192
+ )
193
+ _lock: asyncio.Lock = field(
194
+ init=False,
195
+ default_factory=asyncio.Lock,
196
+ repr=False,
197
+ )
198
+
199
+ def __post_init__(self) -> None:
200
+ if (
201
+ type(self.prior_candidates) is not tuple
202
+ or not self.prior_candidates
203
+ or any(
204
+ type(candidate) is not EvolutionCandidate
205
+ for candidate in self.prior_candidates
206
+ )
207
+ ):
208
+ raise TypeError(
209
+ "prior_candidates must contain exact non-empty candidates"
210
+ )
211
+ for candidate in self.prior_candidates:
212
+ candidate.__post_init__()
213
+ candidate_ids = tuple(
214
+ candidate.candidate_id for candidate in self.prior_candidates
215
+ )
216
+ if len(candidate_ids) != len(set(candidate_ids)):
217
+ raise ValueError("prior candidate IDs must be unique")
218
+ if (
219
+ type(self.initial_candidate_ids) is not tuple
220
+ or self.initial_candidate_ids
221
+ != tuple(
222
+ sorted(
223
+ set(self.initial_candidate_ids),
224
+ key=lambda value: value.value,
225
+ )
226
+ )
227
+ ):
228
+ raise ValueError(
229
+ "initial_candidate_ids must be unique and canonical"
230
+ )
231
+ if any(
232
+ type(value) is not CandidateId
233
+ for value in self.initial_candidate_ids
234
+ ):
235
+ raise TypeError("initial candidate IDs must be exact")
236
+ if not set(self.initial_candidate_ids).issubset(set(candidate_ids)):
237
+ raise ValueError("initial candidates are absent from the prior")
238
+ if (
239
+ type(self.evidence_sources) is not tuple
240
+ or not self.evidence_sources
241
+ or any(
242
+ not isinstance(
243
+ value,
244
+ MaterializedHierarchicalResidualActionEvidencePort,
245
+ )
246
+ for value in self.evidence_sources
247
+ )
248
+ ):
249
+ raise TypeError(
250
+ "evidence_sources must implement their runtime port"
251
+ )
252
+ expert_ids = tuple(
253
+ value.expert_id for value in self.evidence_sources
254
+ )
255
+ if expert_ids != tuple(sorted(set(expert_ids))):
256
+ raise ValueError("evidence sources must be unique and canonical")
257
+ if type(self.broker) is not RegretBrokeredMaterializedActionPolicy:
258
+ raise TypeError("broker must be exact")
259
+ self.broker.__post_init__()
260
+ utility_identity = (
261
+ validate_candidate_archive_consequence_utility(
262
+ self.archive_utility
263
+ )
264
+ )
265
+ if (
266
+ self.projection_id
267
+ != PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_ID
268
+ or self.projection_version
269
+ != PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_VERSION
270
+ or self.feature_names
271
+ != PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_NAMES
272
+ ):
273
+ raise ValueError("portable feature projection identity is immutable")
274
+ self.definition_sha256 = hashlib.sha256(
275
+ _DEFINITION_DOMAIN
276
+ + _canonical_json(
277
+ {
278
+ "schema_version": 1,
279
+ "feature_abi_sha256": _feature_abi_sha256(),
280
+ "archive_utility": {
281
+ "utility_id": utility_identity[0],
282
+ "utility_version": utility_identity[1],
283
+ "definition_sha256": utility_identity[2],
284
+ },
285
+ "prior_only": True,
286
+ "current_candidate_outcomes": False,
287
+ "objective_names_in_core": False,
288
+ "workload_model_provider_branches": False,
289
+ }
290
+ )
291
+ ).hexdigest()
292
+
293
+ def _evidence(
294
+ self,
295
+ action_sha256: str,
296
+ ) -> MaterializedHierarchicalResidualActionEvidence:
297
+ matches = tuple(
298
+ value
299
+ for source in self.evidence_sources
300
+ if (value := source.evidence_for(action_sha256)) is not None
301
+ )
302
+ if len(matches) != 1:
303
+ raise ValueError(
304
+ "one sealed action must have exactly one semantic evidence row"
305
+ )
306
+ return matches[0]
307
+
308
+ def _utility(self, candidates: tuple[EvolutionCandidate, ...]) -> float:
309
+ return candidate_archive_utility(self.archive_utility, candidates)
310
+
311
+ def _marginal(
312
+ self,
313
+ objective_point: dict[str, float],
314
+ ) -> float:
315
+ result = self.archive_utility.marginal_utility(
316
+ self.prior_candidates,
317
+ objective_point,
318
+ )
319
+ if type(result) is not float or not math.isfinite(result) or result < 0.0:
320
+ raise ValueError(
321
+ "archive marginal utility must be finite and non-negative"
322
+ )
323
+ return result
324
+
325
+ def _predicted_complements(
326
+ self,
327
+ evidence: MaterializedHierarchicalResidualActionEvidence,
328
+ parent: EvolutionCandidate | None,
329
+ ) -> tuple[float, float, float]:
330
+ if parent is None:
331
+ return (0.0, 0.0, 0.0)
332
+ parent_objectives = parent.objective_map
333
+ forecasts = {
334
+ value.metric_id: value
335
+ for value in evidence.effect_predictions
336
+ }
337
+ if set(forecasts) != set(parent_objectives):
338
+ raise ValueError(
339
+ "forecast metrics differ from the parent objective vector"
340
+ )
341
+ result: list[float] = []
342
+ for field_name in ("p10_delta", "p50_delta", "p90_delta"):
343
+ point = {
344
+ metric_id: parent_objectives[metric_id]
345
+ + float(getattr(forecasts[metric_id], field_name))
346
+ for metric_id in parent_objectives
347
+ }
348
+ result.append(self._marginal(point))
349
+ return tuple(result) # type: ignore[return-value]
350
+
351
+ async def project(
352
+ self,
353
+ request: ResidualPortfolioDecisionRequest,
354
+ proposals: tuple[MaterializedActionProposalBatch, ...],
355
+ ) -> MaterializedActionFeatureBatch:
356
+ self.__post_init__()
357
+ if type(request) is not ResidualPortfolioDecisionRequest:
358
+ raise TypeError("request must be exact")
359
+ request.__post_init__()
360
+ if any(
361
+ candidate.generation >= request.decision_index
362
+ for candidate in self.prior_candidates
363
+ ):
364
+ raise ValueError("prior candidates cross the current decision cutoff")
365
+ if type(proposals) is not tuple or not proposals:
366
+ raise ValueError("proposals must be a non-empty exact tuple")
367
+ async with self._lock:
368
+ cached = self._cache.get(request.request_sha256)
369
+ if cached is not None:
370
+ expected = tuple(
371
+ sorted(value.proposal_sha256 for value in proposals)
372
+ )
373
+ if cached.proposal_sha256s != expected:
374
+ raise ValueError(
375
+ "one request identity cannot name two proposal universes"
376
+ )
377
+ return cached
378
+
379
+ actions = tuple(
380
+ action
381
+ for proposal in proposals
382
+ for action in proposal.actions
383
+ )
384
+ action_by_sha256 = {
385
+ value.action_sha256: value for value in actions
386
+ }
387
+ if len(action_by_sha256) != len(actions):
388
+ raise ValueError("proposal union repeats an action identity")
389
+ evidence_by_action = {
390
+ action_sha256: self._evidence(action_sha256)
391
+ for action_sha256 in action_by_sha256
392
+ }
393
+ expert_counts = Counter(
394
+ value.action.expert_id
395
+ for value in evidence_by_action.values()
396
+ )
397
+ maximum_radius = max(
398
+ value.plan.radius for value in evidence_by_action.values()
399
+ )
400
+ maximum_components = max(
401
+ len(value.plan.component_option_ids)
402
+ for value in evidence_by_action.values()
403
+ )
404
+ prior_by_id = {
405
+ value.candidate_id: value
406
+ for value in self.prior_candidates
407
+ }
408
+ full_utility = self._utility(self.prior_candidates)
409
+ parent_contributions: dict[CandidateId, float] = {}
410
+ for index, candidate in enumerate(self.prior_candidates):
411
+ reduced = (
412
+ self.prior_candidates[:index]
413
+ + self.prior_candidates[index + 1 :]
414
+ )
415
+ parent_contributions[candidate.candidate_id] = max(
416
+ 0.0,
417
+ full_utility - self._utility(reduced),
418
+ )
419
+ opportunity = max(parent_contributions.values(), default=0.0)
420
+ initial_ids = set(self.initial_candidate_ids)
421
+ rows: list[MaterializedActionFeatureVector] = []
422
+ row_evidence: list[dict[str, object]] = []
423
+ for action_sha256 in sorted(action_by_sha256):
424
+ action = action_by_sha256[action_sha256]
425
+ evidence = evidence_by_action[action_sha256]
426
+ score = self.broker.score(action)
427
+ estimates = {
428
+ value.channel: value for value in score.estimates
429
+ }
430
+ gain = estimates[BrokerEvidenceChannel.GAIN]
431
+ positive = estimates[BrokerEvidenceChannel.POSITIVE]
432
+ parent_id = evidence.plan.parent_candidate_id
433
+ parent = prior_by_id.get(parent_id)
434
+ parent_contribution = parent_contributions.get(
435
+ parent_id,
436
+ 0.0,
437
+ )
438
+ predicted = self._predicted_complements(
439
+ evidence,
440
+ parent,
441
+ )
442
+ confidences = tuple(
443
+ value.confidence for value in evidence.effect_predictions
444
+ )
445
+ expert_count = expert_counts[action.expert_id]
446
+ native_rank = evidence.provider_rank
447
+ broker_mean = score.return_estimate.mean
448
+ broker_sd = score.return_estimate.standard_deviation
449
+ broker_upper = score.upper_confidence_bound
450
+ opportunity_scaled_index = (
451
+ broker_mean
452
+ if request.phase is SearchPhase.TERMINAL_CONVERSION
453
+ else broker_mean
454
+ + min(
455
+ max(0.0, broker_upper - broker_mean),
456
+ max(opportunity, broker_mean),
457
+ )
458
+ )
459
+ values = (
460
+ broker_mean,
461
+ broker_sd,
462
+ broker_upper,
463
+ opportunity_scaled_index,
464
+ gain.global_mean,
465
+ math.log1p(gain.global_count),
466
+ gain.local_mean,
467
+ math.log1p(gain.local_count),
468
+ positive.global_mean,
469
+ math.log1p(positive.global_count),
470
+ 1.0 / native_rank,
471
+ (
472
+ 1.0
473
+ if expert_count <= 1
474
+ else 1.0
475
+ - ((native_rank - 1.0) / (expert_count - 1.0))
476
+ ),
477
+ 1.0 if action.reference_action else 0.0,
478
+ evidence.plan.radius / max(1, maximum_radius),
479
+ len(evidence.plan.component_option_ids)
480
+ / max(1, maximum_components),
481
+ evidence.probability_valid,
482
+ 1.0 if evidence.effect_predictions else 0.0,
483
+ min(confidences, default=0.0),
484
+ (
485
+ statistics.fmean(confidences)
486
+ if confidences
487
+ else 0.0
488
+ ),
489
+ predicted[0],
490
+ predicted[1],
491
+ predicted[2],
492
+ max(predicted) - min(predicted),
493
+ 1.0 if parent is not None else 0.0,
494
+ parent_contribution,
495
+ (
496
+ parent_contribution / opportunity
497
+ if opportunity > 0.0
498
+ else 0.0
499
+ ),
500
+ (
501
+ 1.0
502
+ if parent is not None and parent_id not in initial_ids
503
+ else 0.0
504
+ ),
505
+ (
506
+ 1.0
507
+ if request.phase is SearchPhase.COMPOSITION
508
+ else 0.0
509
+ ),
510
+ (
511
+ 1.0
512
+ if request.phase is SearchPhase.TERMINAL_CONVERSION
513
+ else 0.0
514
+ ),
515
+ )
516
+ if len(values) != len(self.feature_names):
517
+ raise AssertionError("portable feature ABI drifted")
518
+ rows.append(
519
+ MaterializedActionFeatureVector(
520
+ action_sha256=action_sha256,
521
+ values=tuple(float(value) for value in values),
522
+ )
523
+ )
524
+ row_evidence.append(
525
+ {
526
+ "action_sha256": action_sha256,
527
+ "semantic_evidence": evidence.to_record(),
528
+ "broker_score": score.to_record(),
529
+ "features_hex": [
530
+ float(value).hex() for value in values
531
+ ],
532
+ }
533
+ )
534
+ frozen_evidence = freeze_json(
535
+ {
536
+ "schema_version": 1,
537
+ "feature_abi_sha256": _feature_abi_sha256(),
538
+ "prior_candidate_ids": [
539
+ value.candidate_id.value
540
+ for value in self.prior_candidates
541
+ ],
542
+ "prior_configuration_sha256s": [
543
+ value.occurrence.configuration_hash
544
+ for value in self.prior_candidates
545
+ ],
546
+ "prior_utility_hex": full_utility.hex(),
547
+ "opportunity_hex": opportunity.hex(),
548
+ "rows": row_evidence,
549
+ "candidate_outcomes_observed": False,
550
+ }
551
+ )
552
+ batch = MaterializedActionFeatureBatch(
553
+ projection_id=self.projection_id,
554
+ projection_version=self.projection_version,
555
+ projection_definition_sha256=self.definition_sha256,
556
+ residual_request_sha256=request.request_sha256,
557
+ proposal_sha256s=tuple(
558
+ sorted(value.proposal_sha256 for value in proposals)
559
+ ),
560
+ feature_names=self.feature_names,
561
+ vectors=tuple(rows),
562
+ candidate_outcomes_observed=False,
563
+ evidence=frozen_evidence,
564
+ )
565
+ self._cache[request.request_sha256] = batch
566
+ return batch
567
+
568
+
569
+ __all__ = [
570
+ "PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_GROUPS",
571
+ "PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_NAMES",
572
+ "PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_ID",
573
+ "PORTABLE_RESIDUAL_CONSEQUENCE_FEATURE_PROJECTION_VERSION",
574
+ "PortableResidualConsequenceFeatureProjection",
575
+ ]