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,236 @@
1
+ """Black-box candidate evaluation against a Problem.
2
+
3
+ Runs the three per-candidate obligations in order: ``validate`` rejects cheaply
4
+ and explains itself, ``materialize`` builds the artifact, ``evaluate`` measures
5
+ it. Expected infeasibility surfaces as a failed :class:`CandidateResult`
6
+ carrying a ``failure_phase`` and message; the message is forwarded to the LLM
7
+ as feedback.
8
+
9
+ Evaluation is cached on the identity of the *materialized artifact*, not the
10
+ configuration. Distinct configurations that build the same artifact are
11
+ therefore measured once. Keying on the configuration -- which is what this did
12
+ before -- paid twice for the redundancy the union-over-sum analysis measured as
13
+ the dominant loss.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any, Dict, List, MutableMapping, Optional, Sequence, Tuple
19
+
20
+ from agent_evolve.contract import artifact_key, as_evaluator
21
+ from agent_evolve.core.formatting import CandidateResult
22
+ from agent_evolve.core.problem import (
23
+ ObjectiveSpec,
24
+ ValidationOutcome,
25
+ normalize_objective_values,
26
+ )
27
+
28
+ INVALID_PENALTY: float = 1e18
29
+
30
+ _VALIDATION_FALSE_HINT = (
31
+ "validate() returned False without a reason. Raise ValueError('...') from "
32
+ "validate() describing what is wrong and how to fix it (unknown keys, wrong "
33
+ "types, out-of-range values, invalid combinations)."
34
+ )
35
+
36
+
37
+ def format_optimizer_error(exc: BaseException) -> str:
38
+ """Format an exception for regeneration prompts with a concrete fix hint."""
39
+ name = type(exc).__name__
40
+ msg = str(exc).strip()
41
+ if msg:
42
+ return f"{name}: {msg}"
43
+ return (
44
+ f"{name} was raised with no message. Raise ValueError('clear explanation of "
45
+ "what failed and valid alternatives') instead."
46
+ )
47
+
48
+
49
+ def _penalty_objectives(objectives: Sequence[ObjectiveSpec]) -> Dict[str, float]:
50
+ return {s.name: (0.0 if s.goal == "max" else INVALID_PENALTY) for s in objectives}
51
+
52
+
53
+ def _failure(
54
+ config: Dict[str, Any],
55
+ objectives: Sequence[ObjectiveSpec],
56
+ message: str,
57
+ phase: str,
58
+ *,
59
+ evaluation_attempted: bool = False,
60
+ ) -> CandidateResult:
61
+ return CandidateResult(
62
+ configuration=config,
63
+ objectives=_penalty_objectives(objectives),
64
+ is_valid=False,
65
+ error_message=message,
66
+ failure_phase=phase,
67
+ evaluation_attempted=evaluation_attempted,
68
+ )
69
+
70
+
71
+ class EvaluationCache(dict):
72
+ """Artifact identity -> objective vector, plus what it saved.
73
+
74
+ ``hits`` is the number of evaluations not paid for. It is reported rather
75
+ than inferred, so a problem whose ``materialize`` collapses nothing can see
76
+ that immediately instead of assuming a saving it never got.
77
+
78
+ ``misses`` is what the budget actually counts: distinct artifacts measured.
79
+
80
+ A REFUSAL is a measurement too. An artifact whose ``evaluate`` raised was
81
+ charged -- it ran the evaluator, it took the wall-clock -- so its outcome
82
+ is recorded exactly like a successful one, and a re-proposed refusal is
83
+ served from memory instead of being charged again. On a venue that
84
+ refuses over half of what is proposed (the EDA case: 53%), forgetting
85
+ refusals meant a config could be billed every time the sampler re-drew
86
+ it. ``refusal_hits`` counts those replays, apart from ``hits``, because
87
+ "we did not pay for a success again" and "we did not pay for a failure
88
+ again" are different savings and a campaign should see both.
89
+ """
90
+
91
+ def __init__(self, *args, **kwargs) -> None:
92
+ super().__init__(*args, **kwargs)
93
+ self.hits = 0
94
+ self.misses = 0
95
+ self.refusal_hits = 0
96
+ #: artifact key -> (message, failure phase) of the charged refusal.
97
+ self._refusals: Dict[str, Tuple[str, str]] = {}
98
+
99
+ def record_refusal(self, key: str, message: str, phase: str) -> None:
100
+ self._refusals[key] = (str(message), str(phase))
101
+
102
+ def refusal(self, key: str) -> Optional[Tuple[str, str]]:
103
+ return self._refusals.get(key)
104
+
105
+ #: Hard ceiling on ``misses``. Once reached, no further artifact is
106
+ #: measured; a budget that is only checked between generations is not a
107
+ #: budget, and a caller who said 40 must not be billed for 48.
108
+ budget: Optional[int] = None
109
+
110
+ def exhausted(self) -> bool:
111
+ return self.budget is not None and self.misses >= self.budget
112
+
113
+
114
+ def evaluate_batch(
115
+ problem: Any,
116
+ candidates: List[Dict[str, Any]],
117
+ objectives: Sequence[ObjectiveSpec],
118
+ cache: Optional[MutableMapping[str, Dict[str, float]]] = None,
119
+ ) -> Tuple[List[CandidateResult], List[CandidateResult], List[CandidateResult]]:
120
+ """Evaluate *candidates* against *problem*.
121
+
122
+ Returns ``(valid, failed, ordered)`` where *ordered* has one
123
+ :class:`CandidateResult` per input candidate in input order. When *cache*
124
+ is supplied, artifacts already measured are not measured again.
125
+ """
126
+ bound = as_evaluator(problem)
127
+ valid: List[CandidateResult] = []
128
+ failed: List[CandidateResult] = []
129
+ ordered: List[CandidateResult] = []
130
+
131
+ def _record(cr: CandidateResult, bucket: List[CandidateResult]) -> None:
132
+ bucket.append(cr)
133
+ ordered.append(cr)
134
+
135
+ for config in candidates:
136
+ try:
137
+ outcome = bound.validate(config)
138
+ except ValueError as exc:
139
+ outcome = ValidationOutcome(False, "validation", format_optimizer_error(exc))
140
+ if not outcome.ok:
141
+ _record(
142
+ _failure(
143
+ config,
144
+ objectives,
145
+ outcome.message or "invalid configuration",
146
+ outcome.failure_phase or "validation",
147
+ ),
148
+ failed,
149
+ )
150
+ continue
151
+
152
+ try:
153
+ artifact = bound.materialize(config)
154
+ except ValueError as exc:
155
+ _record(
156
+ _failure(config, objectives, format_optimizer_error(exc), "materialization"),
157
+ failed,
158
+ )
159
+ continue
160
+
161
+ key = artifact_key(artifact) if cache is not None else None
162
+ if key is not None and isinstance(cache, EvaluationCache):
163
+ remembered = cache.refusal(key)
164
+ if remembered is not None:
165
+ # This artifact was already measured and REFUSED, and that
166
+ # refusal was charged once. Replay the recorded outcome --
167
+ # same message, same phase, so the feedback upstream is
168
+ # identical -- without running the evaluator or charging the
169
+ # budget again (evaluation_attempted stays False: no
170
+ # evaluation happened HERE).
171
+ message, phase = remembered
172
+ cache.refusal_hits += 1
173
+ _record(_failure(config, objectives, message, phase), failed)
174
+ continue
175
+ if key is not None and key in cache:
176
+ normalized = dict(cache[key])
177
+ if isinstance(cache, EvaluationCache):
178
+ cache.hits += 1
179
+ elif isinstance(cache, EvaluationCache) and cache.exhausted():
180
+ # The budget is spent. Report it as a refusal rather than quietly
181
+ # measuring one more, so the number the caller gave is the number
182
+ # they are billed for.
183
+ _record(
184
+ _failure(
185
+ config,
186
+ objectives,
187
+ f"evaluation budget of {cache.budget} exhausted",
188
+ "budget",
189
+ ),
190
+ failed,
191
+ )
192
+ continue
193
+ else:
194
+ try:
195
+ obj = bound.evaluate(artifact)
196
+ except ValueError as exc:
197
+ # A measurement that failed was still a measurement. It ran the
198
+ # simulator, it took the wall-clock, and on a timeout it took
199
+ # the *most* wall-clock of anything in the batch. Not charging
200
+ # it let a run keep going until it had 40 successes, however
201
+ # many artifacts that took, and report the budget as honoured.
202
+ if isinstance(cache, EvaluationCache):
203
+ cache.misses += 1
204
+ if key is not None:
205
+ # Remember the refusal under the artifact's identity,
206
+ # so re-proposing it is a replay, never a second bill.
207
+ cache.record_refusal(
208
+ key, format_optimizer_error(exc), "evaluation")
209
+ _record(
210
+ _failure(
211
+ config,
212
+ objectives,
213
+ format_optimizer_error(exc),
214
+ "evaluation",
215
+ evaluation_attempted=True,
216
+ ),
217
+ failed,
218
+ )
219
+ continue
220
+ normalized = normalize_objective_values(obj, objectives)
221
+ if key is not None:
222
+ cache[key] = dict(normalized)
223
+ if isinstance(cache, EvaluationCache):
224
+ cache.misses += 1
225
+
226
+ _record(
227
+ CandidateResult(
228
+ configuration=config,
229
+ objectives=normalized,
230
+ is_valid=True,
231
+ evaluation_attempted=True,
232
+ ),
233
+ valid,
234
+ )
235
+
236
+ return valid, failed, ordered
@@ -0,0 +1,237 @@
1
+ """A problem's optional CHEAPER evaluation fidelity, and its separate ledger.
2
+
3
+ Some evaluators expose a knob that buys a correlated answer for a fraction of
4
+ the cost -- fewer mapper iterations, a coarser mesh, a shorter simulation, a
5
+ subsample of the workload. A campaign whose budget is denominated in REAL
6
+ evaluations can spend that cheaper mode on evidence the surrogate needs and
7
+ still be honest about what it paid, but only if the two are never added up.
8
+
9
+ This module is the seam, and its whole design is the separation:
10
+
11
+ * :class:`ProxySource` holds the problem's ``evaluate_proxy`` bound method and
12
+ a key function, **and nothing else**. It has no reference to the problem,
13
+ the evaluation cache, or the budget, so "a proxy evaluation cannot become a
14
+ charged evaluation" is a property of the object graph rather than a promise
15
+ in a docstring -- the same construction that makes the screen unable to
16
+ spend budget (see :mod:`agent_evolve.session.screening`).
17
+ * Every proxy call is counted in :class:`ProxyLedger`, reported beside the
18
+ charged count and never folded into it.
19
+ * A hard ``ceiling`` bounds what a run may spend at the cheap fidelity, so a
20
+ consumer that asks for a proxy value in a loop degrades to "no proxy" rather
21
+ than to an unbounded bill.
22
+
23
+ A problem opts in by defining::
24
+
25
+ def evaluate_proxy(self, config) -> Mapping[str, float]: ...
26
+
27
+ returning EXACTLY the declared objectives, at a cheaper and correlated
28
+ fidelity. Optionally it may describe that fidelity for the record::
29
+
30
+ proxy_fidelity_name: str # e.g. "timeloop@50-mappings"
31
+ proxy_cost_ratio: float # measured seconds(proxy)/seconds(real)
32
+
33
+ Nothing here decides whether a proxy is GOOD. That is the gate's job: a proxy
34
+ enters the screen as evidence or as a candidate ordering and is
35
+ cross-validated against the run's own REAL measurements like anything else.
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ import json
41
+ from dataclasses import dataclass, field
42
+ from typing import Any, Callable, Dict, Mapping, Optional, Sequence
43
+
44
+ from agent_evolve.core.problem import ObjectiveSpec, normalize_objective_values
45
+
46
+ __all__ = ["ProxyLedger", "ProxySource", "proxy_fidelity_builder"]
47
+
48
+ Config = Dict[str, Any]
49
+
50
+
51
+ def _canonical_key(config: Mapping[str, Any]) -> str:
52
+ return json.dumps(config, sort_keys=True, default=str)
53
+
54
+
55
+ @dataclass
56
+ class ProxyLedger:
57
+ """What the cheap fidelity was asked for, and what it cost. Never charged.
58
+
59
+ ``evaluations`` counts calls that actually ran the cheap evaluator;
60
+ ``cache_hits`` counts repeats served from memory, because a consumer that
61
+ re-asks for the same candidate must not be reported as having spent
62
+ anything twice. ``refused_ceiling`` is the count of requests declined
63
+ because the run had spent its proxy allowance.
64
+ """
65
+
66
+ evaluations: int = 0
67
+ cache_hits: int = 0
68
+ failures: int = 0
69
+ refused_ceiling: int = 0
70
+ rows_offered: int = 0
71
+ rows_used: int = 0
72
+
73
+ def as_dict(self) -> Dict[str, int]:
74
+ return {
75
+ "proxy_evaluations": self.evaluations,
76
+ "proxy_cache_hits": self.cache_hits,
77
+ "proxy_failures": self.failures,
78
+ "proxy_refused_ceiling": self.refused_ceiling,
79
+ "proxy_rows_offered": self.rows_offered,
80
+ "proxy_rows_used": self.rows_used,
81
+ }
82
+
83
+
84
+ class ProxySource:
85
+ """The cheap fidelity, memoized, counted, and bounded.
86
+
87
+ Construct with :meth:`for_problem`, which returns ``None`` when the
88
+ problem exposes no cheaper fidelity -- so every consumer's "off" path is
89
+ the absence of an object rather than a flag it might forget to read.
90
+ """
91
+
92
+ def __init__(
93
+ self,
94
+ evaluate: Callable[[Config], Mapping[str, float]],
95
+ objectives: Sequence[ObjectiveSpec],
96
+ *,
97
+ key: Callable[[Config], str] = _canonical_key,
98
+ name: str = "proxy",
99
+ cost_ratio: Optional[float] = None,
100
+ ceiling: Optional[int] = None,
101
+ ) -> None:
102
+ if not callable(evaluate):
103
+ raise TypeError("evaluate must be callable")
104
+ if ceiling is not None and ceiling < 0:
105
+ raise ValueError(f"ceiling must not be negative, got {ceiling}")
106
+ # DELIBERATELY only these: a bound method, a key function, the
107
+ # objective specs, and counters. No problem, no cache, no budget.
108
+ self._evaluate = evaluate
109
+ self._key = key
110
+ self._specs = list(objectives)
111
+ self.name = str(name)
112
+ self.cost_ratio = None if cost_ratio is None else float(cost_ratio)
113
+ self.ceiling = ceiling
114
+ self.ledger = ProxyLedger()
115
+ self._memo: Dict[str, Optional[Dict[str, float]]] = {}
116
+ #: the harvest contract (`core.telemetry`), so the cheap fidelity's
117
+ #: ledger reaches the SearchResult like any other mechanism's counters
118
+ self.telemetry = self.ledger
119
+ self.mechanism = "proxy_fidelity"
120
+ self.authored_by = "none"
121
+
122
+ # -- construction ------------------------------------------------------
123
+ @classmethod
124
+ def for_problem(cls, problem: Any, *, ceiling: Optional[int] = None
125
+ ) -> Optional["ProxySource"]:
126
+ """The problem's cheap fidelity, or ``None`` if it does not have one."""
127
+
128
+ evaluate = getattr(problem, "evaluate_proxy", None)
129
+ if not callable(evaluate):
130
+ return None
131
+ key = getattr(problem, "candidate_key", None)
132
+ return cls(
133
+ evaluate,
134
+ list(problem.objectives),
135
+ key=key if callable(key) else _canonical_key,
136
+ name=str(getattr(problem, "proxy_fidelity_name", "proxy")),
137
+ cost_ratio=getattr(problem, "proxy_cost_ratio", None),
138
+ ceiling=ceiling,
139
+ )
140
+
141
+ # -- use ---------------------------------------------------------------
142
+ def key(self, config: Config) -> str:
143
+ return self._key(config)
144
+
145
+ def evaluate(self, config: Config) -> Optional[Dict[str, float]]:
146
+ """The cheap objectives for *config*, or ``None``.
147
+
148
+ ``None`` means "this run has no cheap answer for this candidate" --
149
+ the evaluator refused, returned something the objective contract does
150
+ not accept, or the proxy allowance is spent. Every consumer treats
151
+ that as "no proxy", never as a value.
152
+ """
153
+
154
+ token = self._key(config)
155
+ if token in self._memo:
156
+ self.ledger.cache_hits += 1
157
+ return self._memo[token]
158
+ if self.ceiling is not None and self.ledger.evaluations >= self.ceiling:
159
+ self.ledger.refused_ceiling += 1
160
+ return None
161
+ self.ledger.evaluations += 1
162
+ try:
163
+ values = normalize_objective_values(self._evaluate(config), self._specs)
164
+ except Exception:
165
+ self.ledger.failures += 1
166
+ self._memo[token] = None
167
+ return None
168
+ self._memo[token] = values
169
+ return values
170
+
171
+ def rows(
172
+ self, candidates: Sequence[Config], *, exclude: Sequence[str] = ()
173
+ ) -> list[tuple[Config, Dict[str, float]]]:
174
+ """``(config, cheap objectives)`` for each candidate that yields one.
175
+
176
+ ``exclude`` names candidate keys that already have a REAL measurement.
177
+ A real row always supersedes a cheap one: the point of the seam is to
178
+ add evidence where there is none, never to dilute evidence there is.
179
+ """
180
+
181
+ skip = set(exclude)
182
+ out = []
183
+ for candidate in candidates:
184
+ if self._key(candidate) in skip:
185
+ continue
186
+ self.ledger.rows_offered += 1
187
+ values = self.evaluate(candidate)
188
+ if values is not None:
189
+ out.append((dict(candidate), values))
190
+ return out
191
+
192
+
193
+ def proxy_fidelity_builder(source: ProxySource) -> Callable[..., Any]:
194
+ """The cheap fidelity itself, as a :data:`SurrogateBuilder`.
195
+
196
+ A surrogate is anything that ORDERS candidates without charging the
197
+ budget, and a correlated cheap evaluation is exactly that. Presenting it
198
+ as a builder means it earns its place the same way an authored artifact
199
+ does: the screen's gate cross-validates it against the run's own REAL
200
+ measurements, per objective, and admits it only if it ranks them. Nothing
201
+ about this asserts that a cheap fidelity ranks well -- it makes the claim
202
+ checkable in the loop that would rely on it.
203
+
204
+ The builder ignores the training rows because there is nothing to fit.
205
+ """
206
+
207
+ def build(rows: Any, specs: Any) -> Callable[[Sequence[Config]], Any]:
208
+ names = [spec.name for spec in specs]
209
+ goals = {spec.name: spec.goal for spec in specs}
210
+
211
+ def predict(configs: Sequence[Config]) -> Any:
212
+ out: list[Optional[Dict[str, float]]] = []
213
+ for config in configs:
214
+ out.append(source.evaluate(config))
215
+ got = [row for row in out if row is not None]
216
+ if not got:
217
+ return None # no cheap answer at all -> screen nothing
218
+ if len(got) == len(out):
219
+ return out
220
+ # A candidate the cheap fidelity REFUSES is ranked last, not
221
+ # dropped: refusing one member of a pool must not blind the screen
222
+ # to the other n-1. This mirrors what the expensive evaluator
223
+ # already does with an infeasible candidate -- it returns a
224
+ # penalty vector rather than nothing -- and it keeps the returned
225
+ # sequence aligned with the pool the caller passed in.
226
+ worst: Dict[str, float] = {}
227
+ for name in names:
228
+ values = [row[name] for row in got]
229
+ span = max(values) - min(values)
230
+ pad = abs(span) * 0.1 + (abs(max(values, key=abs)) * 1e-9) + 1e-12
231
+ worst[name] = (max(values) + pad if goals.get(name) == "min"
232
+ else min(values) - pad)
233
+ return [dict(worst) if row is None else row for row in out]
234
+
235
+ return predict
236
+
237
+ return build