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,812 @@
1
+ """Authenticated portable feature projection for T-RAP profile v1.
2
+
3
+ The projector converts typed, prior-only engine facts into the exact 70-column
4
+ development schema. It is intentionally separate from the acquisition model:
5
+ workload adapters materialize configurations and archive snapshots, while this
6
+ module owns generic normalization, transition differencing, target alignment,
7
+ feature order, and cryptographic receipts.
8
+
9
+ Profile v1 is scale-qualified for an eight-member proposal slate, two parent
10
+ lanes, and proposal generations 1/3/5. Those are explicit validation limits,
11
+ not hidden assumptions of the generic acquisition core.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import hashlib
17
+ import json
18
+ import math
19
+ from dataclasses import dataclass
20
+ from statistics import fmean
21
+ from typing import ClassVar, Sequence
22
+
23
+ from agent_evolve.domain.patch import require_sha256
24
+ from agent_evolve.domain.typed_json import (
25
+ FrozenJsonValue,
26
+ thaw_json,
27
+ typed_json_sha256,
28
+ )
29
+ from agent_evolve.policies.selection.calibrated_slate import SlateAllocationRequest
30
+ from agent_evolve.policies.selection.forecast_calibration import ForecastConfidenceBin
31
+ from agent_evolve.policies.selection.structural_posterior_slate import (
32
+ StructuralPosteriorMemberScoreRow,
33
+ )
34
+ from agent_evolve.policies.selection.target_conditioned_prequential import (
35
+ TargetConditionedMemberFeatures,
36
+ )
37
+ from agent_evolve.ports.archive_context import (
38
+ CampaignPortfolioArchiveContextProjection,
39
+ )
40
+ from agent_evolve.ports.frontier_target import CampaignPortfolioFrontierTarget
41
+
42
+
43
+ PROJECTOR_ID = "trap_portable_features_v1"
44
+ PROJECTOR_VERSION = 1
45
+ PROJECTOR_DEFINITION_SHA256 = hashlib.sha256(
46
+ b"agent-evolve:trap-portable-features:v1;"
47
+ b"schema=70-exact-columns;inputs=sealed-k8,prior-structural-score-rows,"
48
+ b"typed-parent-child-configurations,authenticated-affine-archive-context,"
49
+ b"authenticated-frontier-target,generation,lane-slot,remaining-horizon;"
50
+ b"scale=k8,two-lanes,generations-1-3-5,horizon-2;"
51
+ b"missing-extra-nonfinite=fail-closed;"
52
+ b"workload-model-provider-option-name-current-outcome-features=false"
53
+ ).hexdigest()
54
+
55
+ PORTABLE_FEATURES = (
56
+ "bias",
57
+ *tuple(f"rank_{value}" for value in range(1, 9)),
58
+ "generation_1",
59
+ "generation_3",
60
+ "generation_5",
61
+ "parent_slot_0",
62
+ "parent_slot_1",
63
+ "role_proposal_exploit",
64
+ "role_proposal_falsify",
65
+ "role_proposal_coverage",
66
+ "family_frequency",
67
+ "family_rarity",
68
+ "supporting_card_count",
69
+ "archive_novelty",
70
+ "structural_coverage_raw",
71
+ "calibrated_exploitation_score",
72
+ "calibrated_frontier_score",
73
+ "raw_epistemic_score",
74
+ "structural_coverage_score",
75
+ "epistemic_structural_score",
76
+ "confidence_low_fraction",
77
+ "confidence_medium_fraction",
78
+ "confidence_high_fraction",
79
+ "favorable_fraction",
80
+ "adverse_fraction",
81
+ "abstention_fraction",
82
+ "posterior_correctness_mean",
83
+ "calibration_observation_count_log",
84
+ "transition_change_count",
85
+ "transition_numeric_fraction",
86
+ "transition_categorical_fraction",
87
+ "transition_relative_numeric_delta_log",
88
+ "transition_numeric_sign",
89
+ "transition_path_depth",
90
+ "parent_desirability_mean",
91
+ "parent_desirability_min",
92
+ "parent_desirability_max",
93
+ "archive_base_hypervolume",
94
+ "archive_point_count_log",
95
+ )
96
+ TARGET_FEATURES = (
97
+ "target_favorable_fraction",
98
+ "target_adverse_fraction",
99
+ "target_abstention_fraction",
100
+ "off_target_favorable_fraction",
101
+ "off_target_adverse_fraction",
102
+ "off_target_abstention_fraction",
103
+ "target_declared_confidence",
104
+ "target_posterior_correctness",
105
+ "target_signed_evidence",
106
+ "target_reliability_adjusted_evidence",
107
+ "target_opportunity_from_ideal",
108
+ "target_parent_achievement",
109
+ "target_parent_regret",
110
+ "target_active_axis_fraction",
111
+ "target_zero_axis_fraction",
112
+ *tuple(f"target_opportunity_rank_{value}" for value in range(1, 8)),
113
+ "remaining_proposal_horizon",
114
+ "remaining_proposal_horizon_fraction",
115
+ )
116
+ FEATURE_NAMES = (*PORTABLE_FEATURES, *TARGET_FEATURES)
117
+
118
+ _TRANSITION_DOMAIN = b"agent-evolve:trap-portable-transition:v1\x00"
119
+ _PROJECTION_REQUEST_DOMAIN = b"agent-evolve:trap-feature-request:v1\x00"
120
+ _CONFIDENCE_VALUE = {
121
+ ForecastConfidenceBin.UNKNOWN: 0.0,
122
+ ForecastConfidenceBin.LOW: 1.0 / 3.0,
123
+ ForecastConfidenceBin.MEDIUM: 2.0 / 3.0,
124
+ ForecastConfidenceBin.HIGH: 1.0,
125
+ }
126
+
127
+
128
+ def _canonical_json(value: object) -> bytes:
129
+ return json.dumps(
130
+ value,
131
+ allow_nan=False,
132
+ ensure_ascii=True,
133
+ separators=(",", ":"),
134
+ sort_keys=True,
135
+ ).encode("ascii", errors="strict")
136
+
137
+
138
+ def _hash(domain: bytes, value: object) -> str:
139
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
140
+
141
+
142
+ def _finite(value: float, *, name: str) -> None:
143
+ if type(value) is not float or not math.isfinite(value):
144
+ raise TypeError(f"{name} must be an exact finite float")
145
+
146
+
147
+ def _decimal(value: object, *, name: str) -> float:
148
+ if type(value) is not str:
149
+ raise TypeError(f"{name} must be finite decimal text")
150
+ try:
151
+ result = float(value)
152
+ except ValueError as error:
153
+ raise ValueError(f"{name} is not finite decimal text") from error
154
+ _finite(result, name=name)
155
+ return result
156
+
157
+
158
+ def _flatten(value: object, path: str = "$") -> dict[str, object]:
159
+ if type(value) is dict:
160
+ result: dict[str, object] = {}
161
+ for key in sorted(value):
162
+ result.update(_flatten(value[key], f"{path}.{key}"))
163
+ return result
164
+ if type(value) is list:
165
+ result = {}
166
+ for index, item in enumerate(value):
167
+ result.update(_flatten(item, f"{path}[{index}]"))
168
+ return result
169
+ return {path: value}
170
+
171
+
172
+ @dataclass(frozen=True, slots=True, eq=False)
173
+ class PortableTransitionReceipt:
174
+ """Generic structural delta between one parent and proposed child."""
175
+
176
+ option_id: str
177
+ option_identity_sha256: str
178
+ parent_configuration_sha256: str
179
+ child_configuration_sha256: str
180
+ changed_paths: tuple[str, ...]
181
+ change_count: float
182
+ numeric_fraction: float
183
+ categorical_fraction: float
184
+ relative_numeric_delta_log: float
185
+ numeric_sign: float
186
+ path_depth: float
187
+
188
+ def __post_init__(self) -> None:
189
+ if type(self.option_id) is not str or not self.option_id:
190
+ raise ValueError("option_id must be non-empty")
191
+ for name in (
192
+ "option_identity_sha256",
193
+ "parent_configuration_sha256",
194
+ "child_configuration_sha256",
195
+ ):
196
+ require_sha256(getattr(self, name), name)
197
+ if type(self.changed_paths) is not tuple or any(
198
+ type(value) is not str or not value for value in self.changed_paths
199
+ ):
200
+ raise TypeError("changed_paths must be an exact string tuple")
201
+ if self.changed_paths != tuple(sorted(set(self.changed_paths))):
202
+ raise ValueError("changed_paths must be unique and canonical")
203
+ for name in (
204
+ "change_count",
205
+ "numeric_fraction",
206
+ "categorical_fraction",
207
+ "relative_numeric_delta_log",
208
+ "numeric_sign",
209
+ "path_depth",
210
+ ):
211
+ _finite(getattr(self, name), name=name)
212
+ if self.change_count != float(len(self.changed_paths)):
213
+ raise ValueError("change_count differs from changed_paths")
214
+ for name in ("numeric_fraction", "categorical_fraction"):
215
+ if not 0.0 <= getattr(self, name) <= 1.0:
216
+ raise ValueError(f"{name} must lie in [0, 1]")
217
+ if not -1.0 <= self.numeric_sign <= 1.0:
218
+ raise ValueError("numeric_sign must lie in [-1, 1]")
219
+ if self.relative_numeric_delta_log < 0.0 or self.path_depth < 0.0:
220
+ raise ValueError("transition magnitudes must be non-negative")
221
+
222
+ def _unsigned_record(self) -> dict[str, object]:
223
+ self.__post_init__()
224
+ return {
225
+ "schema_version": 1,
226
+ "option_id": self.option_id,
227
+ "option_identity_sha256": self.option_identity_sha256,
228
+ "parent_configuration_sha256": self.parent_configuration_sha256,
229
+ "child_configuration_sha256": self.child_configuration_sha256,
230
+ "changed_paths": list(self.changed_paths),
231
+ "features_hex": {
232
+ "transition_change_count": self.change_count.hex(),
233
+ "transition_numeric_fraction": self.numeric_fraction.hex(),
234
+ "transition_categorical_fraction": self.categorical_fraction.hex(),
235
+ "transition_relative_numeric_delta_log": (
236
+ self.relative_numeric_delta_log.hex()
237
+ ),
238
+ "transition_numeric_sign": self.numeric_sign.hex(),
239
+ "transition_path_depth": self.path_depth.hex(),
240
+ },
241
+ }
242
+
243
+ @property
244
+ def transition_sha256(self) -> str:
245
+ return _hash(_TRANSITION_DOMAIN, self._unsigned_record())
246
+
247
+ def to_record(self) -> dict[str, object]:
248
+ return {
249
+ **self._unsigned_record(),
250
+ "transition_sha256": self.transition_sha256,
251
+ }
252
+
253
+ def feature_map(self) -> dict[str, float]:
254
+ self.__post_init__()
255
+ return {
256
+ "transition_change_count": self.change_count,
257
+ "transition_numeric_fraction": self.numeric_fraction,
258
+ "transition_categorical_fraction": self.categorical_fraction,
259
+ "transition_relative_numeric_delta_log": (
260
+ self.relative_numeric_delta_log
261
+ ),
262
+ "transition_numeric_sign": self.numeric_sign,
263
+ "transition_path_depth": self.path_depth,
264
+ }
265
+
266
+ def __eq__(self, other: object) -> bool:
267
+ return (
268
+ type(other) is PortableTransitionReceipt
269
+ and self.transition_sha256 == other.transition_sha256
270
+ )
271
+
272
+ __hash__ = None
273
+
274
+
275
+ def project_portable_transition(
276
+ *,
277
+ option_id: str,
278
+ option_identity_sha256: str,
279
+ parent_configuration: FrozenJsonValue,
280
+ child_configuration: FrozenJsonValue,
281
+ ) -> PortableTransitionReceipt:
282
+ """Compute the profile-v1 configuration delta without domain knowledge."""
283
+
284
+ parent_sha256 = typed_json_sha256(parent_configuration)
285
+ child_sha256 = typed_json_sha256(child_configuration)
286
+ parent = _flatten(thaw_json(parent_configuration))
287
+ child = _flatten(thaw_json(child_configuration))
288
+ paths = sorted(set(parent) | set(child))
289
+ changed = tuple(path for path in paths if parent.get(path) != child.get(path))
290
+ numeric_relative: list[float] = []
291
+ numeric_signs: list[float] = []
292
+ categorical = 0
293
+ for path in changed:
294
+ old = parent.get(path)
295
+ new = child.get(path)
296
+ if (
297
+ type(old) in {int, float}
298
+ and type(new) in {int, float}
299
+ and type(old) is not bool
300
+ and type(new) is not bool
301
+ ):
302
+ delta = float(new) - float(old)
303
+ numeric_relative.append(abs(delta) / max(abs(float(old)), 1e-12))
304
+ numeric_signs.append(
305
+ 0.0 if delta == 0.0 else math.copysign(1.0, delta)
306
+ )
307
+ else:
308
+ categorical += 1
309
+ denominator = max(1, len(changed))
310
+ depths = [path.count(".") + path.count("[") for path in changed]
311
+ return PortableTransitionReceipt(
312
+ option_id=option_id,
313
+ option_identity_sha256=option_identity_sha256,
314
+ parent_configuration_sha256=parent_sha256,
315
+ child_configuration_sha256=child_sha256,
316
+ changed_paths=changed,
317
+ change_count=float(len(changed)),
318
+ numeric_fraction=len(numeric_relative) / denominator,
319
+ categorical_fraction=categorical / denominator,
320
+ relative_numeric_delta_log=(
321
+ 0.0
322
+ if not numeric_relative
323
+ else fmean(math.log1p(value) for value in numeric_relative)
324
+ ),
325
+ numeric_sign=0.0 if not numeric_signs else fmean(numeric_signs),
326
+ path_depth=0.0 if not depths else fmean(depths),
327
+ )
328
+
329
+
330
+ @dataclass(frozen=True, slots=True, eq=False)
331
+ class TargetConditionedFeatureProjectionRequest:
332
+ allocation_request: SlateAllocationRequest
333
+ structural_score_rows: tuple[StructuralPosteriorMemberScoreRow, ...]
334
+ transition_receipts: tuple[PortableTransitionReceipt, ...]
335
+ archive_context: CampaignPortfolioArchiveContextProjection
336
+ frontier_target: CampaignPortfolioFrontierTarget
337
+ campaign_generation: int
338
+ lane_slot: int
339
+ remaining_proposal_horizon: int
340
+
341
+ def __post_init__(self) -> None:
342
+ if type(self.allocation_request) is not SlateAllocationRequest:
343
+ raise TypeError("allocation_request must be exact")
344
+ self.allocation_request.revalidate()
345
+ if type(self.structural_score_rows) is not tuple or any(
346
+ type(value) is not StructuralPosteriorMemberScoreRow
347
+ for value in self.structural_score_rows
348
+ ):
349
+ raise TypeError("structural_score_rows must contain exact rows")
350
+ if type(self.transition_receipts) is not tuple or any(
351
+ type(value) is not PortableTransitionReceipt
352
+ for value in self.transition_receipts
353
+ ):
354
+ raise TypeError("transition_receipts must contain exact rows")
355
+ for value in (*self.structural_score_rows, *self.transition_receipts):
356
+ value.__post_init__()
357
+ members = self.allocation_request.slate.members
358
+ member_ids = {value.option_id for value in members}
359
+ score_ids = tuple(value.option_id for value in self.structural_score_rows)
360
+ transition_ids = tuple(value.option_id for value in self.transition_receipts)
361
+ canonical = tuple(sorted(member_ids))
362
+ if score_ids != canonical or transition_ids != canonical:
363
+ raise ValueError("score and transition rows must exactly cover the slate")
364
+ member_by_id = {value.option_id: value for value in members}
365
+ for row in self.structural_score_rows:
366
+ if (
367
+ row.option_identity_sha256
368
+ != member_by_id[row.option_id].option_identity_sha256
369
+ ):
370
+ raise ValueError("structural row names a foreign option")
371
+ parent_sha256 = self.allocation_request.slate.parent_candidate_identity_sha256
372
+ for row in self.transition_receipts:
373
+ if (
374
+ row.option_identity_sha256
375
+ != member_by_id[row.option_id].option_identity_sha256
376
+ or row.parent_configuration_sha256 != parent_sha256
377
+ ):
378
+ raise ValueError("transition row names a foreign parent or option")
379
+ if type(self.archive_context) is not CampaignPortfolioArchiveContextProjection:
380
+ raise TypeError("archive_context must be exact")
381
+ self.archive_context.__post_init__()
382
+ if type(self.frontier_target) is not CampaignPortfolioFrontierTarget:
383
+ raise TypeError("frontier_target must be exact")
384
+ self.frontier_target.__post_init__()
385
+ if (
386
+ self.archive_context.archive_utility_snapshot_sha256
387
+ != self.frontier_target.archive_utility_snapshot_sha256
388
+ or self.archive_context.parent_configuration_sha256 != parent_sha256
389
+ or self.frontier_target.parent_configuration_sha256 != parent_sha256
390
+ ):
391
+ raise ValueError("archive context, target, and slate disagree")
392
+ if type(self.campaign_generation) is not int or self.campaign_generation not in {
393
+ 1,
394
+ 3,
395
+ 5,
396
+ }:
397
+ raise ValueError("profile v1 supports campaign generations 1, 3, and 5")
398
+ if type(self.lane_slot) is not int or self.lane_slot not in {0, 1}:
399
+ raise ValueError("profile v1 supports exactly lane slots 0 and 1")
400
+ expected_horizon = {1: 2, 3: 1, 5: 0}[self.campaign_generation]
401
+ if (
402
+ type(self.remaining_proposal_horizon) is not int
403
+ or self.remaining_proposal_horizon != expected_horizon
404
+ ):
405
+ raise ValueError("remaining horizon differs from profile-v1 generation")
406
+ if len(members) != 8:
407
+ raise ValueError("profile v1 requires an exact K8 proposal slate")
408
+
409
+ def _unsigned_record(self) -> dict[str, object]:
410
+ self.__post_init__()
411
+ return {
412
+ "schema_version": 1,
413
+ "allocation_request_sha256": self.allocation_request.request_sha256,
414
+ "structural_score_rows": [
415
+ value.to_record() for value in self.structural_score_rows
416
+ ],
417
+ "transition_receipts": [
418
+ value.to_record() for value in self.transition_receipts
419
+ ],
420
+ "archive_context": self.archive_context.to_record(),
421
+ "frontier_target": self.frontier_target.to_record(),
422
+ "campaign_generation": self.campaign_generation,
423
+ "lane_slot": self.lane_slot,
424
+ "remaining_proposal_horizon": self.remaining_proposal_horizon,
425
+ "current_or_future_outcomes_consulted": False,
426
+ }
427
+
428
+ @property
429
+ def request_sha256(self) -> str:
430
+ return _hash(_PROJECTION_REQUEST_DOMAIN, self._unsigned_record())
431
+
432
+ def to_record(self) -> dict[str, object]:
433
+ return {**self._unsigned_record(), "request_sha256": self.request_sha256}
434
+
435
+ def __eq__(self, other: object) -> bool:
436
+ return (
437
+ type(other) is TargetConditionedFeatureProjectionRequest
438
+ and self.request_sha256 == other.request_sha256
439
+ )
440
+
441
+ __hash__ = None
442
+
443
+
444
+ def _weighted(
445
+ rows: dict[str, object],
446
+ metric_ids: Sequence[str],
447
+ weights: Sequence[float],
448
+ value,
449
+ ) -> float:
450
+ denominator = sum(weights)
451
+ if denominator <= 0.0:
452
+ return 0.0
453
+ return sum(
454
+ weight * float(value(rows[metric_id]))
455
+ for metric_id, weight in zip(metric_ids, weights, strict=True)
456
+ ) / denominator
457
+
458
+
459
+ def _geometry(
460
+ request: TargetConditionedFeatureProjectionRequest,
461
+ ) -> tuple[
462
+ tuple[str, ...],
463
+ tuple[float, ...],
464
+ tuple[float, ...],
465
+ float,
466
+ float,
467
+ float,
468
+ tuple[float, ...],
469
+ float,
470
+ int,
471
+ ]:
472
+ archive = thaw_json(request.archive_context.payload)
473
+ target = thaw_json(request.frontier_target.payload)
474
+ if type(archive) is not dict or type(target) is not dict:
475
+ raise TypeError("affine archive and target payloads must be objects")
476
+ frame = archive.get("optimization_frame")
477
+ archive_rows = archive.get("archive")
478
+ parent = archive.get("parent")
479
+ target_direction = target.get("target_direction")
480
+ assigned_parent = target.get("assigned_parent")
481
+ if any(
482
+ type(value) is not dict
483
+ for value in (frame, archive_rows, parent, target_direction, assigned_parent)
484
+ ):
485
+ raise ValueError("affine archive or target payload is incomplete")
486
+ axes = frame.get("axes")
487
+ directions = frame.get("reference_directions")
488
+ points = archive_rows.get("normalized_points_decimal")
489
+ parent_point_raw = parent.get("normalized_point_decimal")
490
+ if (
491
+ type(axes) is not list
492
+ or len(axes) not in (2, 3)
493
+ or type(directions) is not list
494
+ or type(points) is not list
495
+ or not points
496
+ or type(parent_point_raw) is not list
497
+ or len(parent_point_raw) != len(axes)
498
+ ):
499
+ raise ValueError("affine geometry has an unsupported shape")
500
+ metric_ids = tuple(
501
+ axis.get("metric_id") if type(axis) is dict else None for axis in axes
502
+ )
503
+ if any(type(value) is not str for value in metric_ids) or len(
504
+ set(metric_ids)
505
+ ) != len(metric_ids):
506
+ raise ValueError("affine axes must use unique metric IDs")
507
+ direction = next(
508
+ (
509
+ value
510
+ for value in directions
511
+ if type(value) is dict
512
+ and value.get("direction_id") == request.frontier_target.direction_id
513
+ ),
514
+ None,
515
+ )
516
+ if type(direction) is not dict:
517
+ raise ValueError("frontier target direction is absent from archive context")
518
+ archive_weights_raw = direction.get("normalized_importance_decimal")
519
+ target_weights_raw = target_direction.get("normalized_weights_decimal")
520
+ if (
521
+ type(archive_weights_raw) is not list
522
+ or type(target_weights_raw) is not list
523
+ or len(archive_weights_raw) != len(metric_ids)
524
+ or len(target_weights_raw) != len(metric_ids)
525
+ ):
526
+ raise ValueError("frontier weights differ from affine dimension")
527
+ archive_weights = tuple(
528
+ _decimal(value, name="archive direction weight")
529
+ for value in archive_weights_raw
530
+ )
531
+ maximum = max(archive_weights)
532
+ if maximum <= 0.0 or any(value < 0.0 for value in archive_weights):
533
+ raise ValueError("affine direction weights must be non-negative")
534
+ expected_weights = tuple(value / maximum for value in archive_weights)
535
+ weights = tuple(
536
+ _decimal(value, name="target direction weight")
537
+ for value in target_weights_raw
538
+ )
539
+ if any(
540
+ not math.isclose(left, right, rel_tol=0.0, abs_tol=1e-12)
541
+ for left, right in zip(weights, expected_weights, strict=True)
542
+ ):
543
+ raise ValueError("frontier target weights disagree with archive context")
544
+ parent_point = tuple(
545
+ _decimal(value, name="archive parent point") for value in parent_point_raw
546
+ )
547
+ assigned_point_raw = assigned_parent.get("normalized_point_decimal")
548
+ if type(assigned_point_raw) is not list or len(assigned_point_raw) != len(
549
+ parent_point
550
+ ):
551
+ raise ValueError("frontier target parent point is malformed")
552
+ assigned_point = tuple(
553
+ _decimal(value, name="target parent point") for value in assigned_point_raw
554
+ )
555
+ if any(
556
+ not math.isclose(left, right, rel_tol=0.0, abs_tol=1e-12)
557
+ for left, right in zip(parent_point, assigned_point, strict=True)
558
+ ):
559
+ raise ValueError("frontier target parent differs from archive context")
560
+ opportunity = _decimal(
561
+ target_direction.get("opportunity_from_ideal_decimal"),
562
+ name="target opportunity",
563
+ )
564
+ parent_achievement = _decimal(
565
+ assigned_parent.get("achievement_decimal"), name="parent achievement"
566
+ )
567
+ parent_regret = _decimal(
568
+ assigned_parent.get("regret_above_archive_best_decimal"),
569
+ name="parent regret",
570
+ )
571
+ base_hypervolume = _decimal(
572
+ frame.get("base_hypervolume_decimal"), name="base hypervolume"
573
+ )
574
+ return (
575
+ metric_ids,
576
+ weights,
577
+ tuple(float(value == 0.0) for value in weights),
578
+ opportunity,
579
+ parent_achievement,
580
+ parent_regret,
581
+ parent_point,
582
+ base_hypervolume,
583
+ len(points),
584
+ )
585
+
586
+
587
+ @dataclass(frozen=True, slots=True)
588
+ class TargetConditionedPortableFeatureProjector:
589
+ projector_id: ClassVar[str] = PROJECTOR_ID
590
+ projector_version: ClassVar[int] = PROJECTOR_VERSION
591
+ definition_sha256: ClassVar[str] = PROJECTOR_DEFINITION_SHA256
592
+ feature_names: ClassVar[tuple[str, ...]] = FEATURE_NAMES
593
+
594
+ def project(
595
+ self, request: TargetConditionedFeatureProjectionRequest
596
+ ) -> tuple[TargetConditionedMemberFeatures, ...]:
597
+ if type(request) is not TargetConditionedFeatureProjectionRequest:
598
+ raise TypeError("request must be exact")
599
+ request.__post_init__()
600
+ (
601
+ metric_ids,
602
+ target_weights,
603
+ off_target_weights,
604
+ opportunity,
605
+ parent_achievement,
606
+ parent_regret,
607
+ parent_point,
608
+ base_hypervolume,
609
+ archive_point_count,
610
+ ) = _geometry(request)
611
+ members = {
612
+ value.option_id: value for value in request.allocation_request.slate.members
613
+ }
614
+ scores = {value.option_id: value for value in request.structural_score_rows}
615
+ transitions = {
616
+ value.option_id: value for value in request.transition_receipts
617
+ }
618
+ family_counts: dict[str, int] = {}
619
+ for member in members.values():
620
+ family_counts[member.family] = family_counts.get(member.family, 0) + 1
621
+ desirability = tuple(1.0 - value for value in parent_point)
622
+ rows = []
623
+ for option_id in sorted(members):
624
+ member = members[option_id]
625
+ score = scores[option_id]
626
+ metric_rows = {value.metric_id: value for value in score.metric_scores}
627
+ if set(metric_rows) != set(metric_ids):
628
+ raise ValueError("structural metrics differ from affine target axes")
629
+ count = float(len(metric_rows))
630
+
631
+ def weighted(weights: Sequence[float], value) -> float:
632
+ return _weighted(metric_rows, metric_ids, weights, value)
633
+
634
+ signed = lambda row: float(row.favorable_assertion) - float( # noqa: E731
635
+ row.adverse_assertion
636
+ )
637
+ features: dict[str, float] = {"bias": 1.0}
638
+ for rank in range(1, 9):
639
+ features[f"rank_{rank}"] = float(member.model_rank == rank)
640
+ for generation in (1, 3, 5):
641
+ features[f"generation_{generation}"] = float(
642
+ request.campaign_generation == generation
643
+ )
644
+ features["parent_slot_0"] = float(request.lane_slot == 0)
645
+ features["parent_slot_1"] = float(request.lane_slot == 1)
646
+ for role in ("exploit", "falsify", "coverage"):
647
+ features[f"role_proposal_{role}"] = float(
648
+ member.role_proposal.value == role
649
+ )
650
+ family_frequency = family_counts[member.family] / 8.0
651
+ features.update(
652
+ {
653
+ "family_frequency": family_frequency,
654
+ "family_rarity": 1.0 / max(1.0, 8.0 * family_frequency),
655
+ "supporting_card_count": float(len(member.supporting_card_keys)),
656
+ "archive_novelty": (
657
+ member.structural_evidence.archive_novelty_score
658
+ ),
659
+ "structural_coverage_raw": (
660
+ member.structural_evidence.structural_coverage_score
661
+ ),
662
+ "calibrated_exploitation_score": (
663
+ score.calibrated_exploitation_score
664
+ ),
665
+ "calibrated_frontier_score": score.calibrated_frontier_score,
666
+ "raw_epistemic_score": score.raw_epistemic_score,
667
+ "structural_coverage_score": score.structural_coverage_score,
668
+ "epistemic_structural_score": score.epistemic_structural_score,
669
+ "confidence_low_fraction": sum(
670
+ value.confidence is ForecastConfidenceBin.LOW
671
+ for value in metric_rows.values()
672
+ )
673
+ / count,
674
+ "confidence_medium_fraction": sum(
675
+ value.confidence is ForecastConfidenceBin.MEDIUM
676
+ for value in metric_rows.values()
677
+ )
678
+ / count,
679
+ "confidence_high_fraction": sum(
680
+ value.confidence is ForecastConfidenceBin.HIGH
681
+ for value in metric_rows.values()
682
+ )
683
+ / count,
684
+ "favorable_fraction": sum(
685
+ value.favorable_assertion for value in metric_rows.values()
686
+ )
687
+ / count,
688
+ "adverse_fraction": sum(
689
+ value.adverse_assertion for value in metric_rows.values()
690
+ )
691
+ / count,
692
+ "abstention_fraction": sum(
693
+ value.explicit_abstention for value in metric_rows.values()
694
+ )
695
+ / count,
696
+ "posterior_correctness_mean": fmean(
697
+ value.calibration_cell.posterior_correctness
698
+ for value in metric_rows.values()
699
+ ),
700
+ "calibration_observation_count_log": math.log1p(
701
+ sum(
702
+ value.calibration_cell.observation_count
703
+ for value in metric_rows.values()
704
+ )
705
+ ),
706
+ **transitions[option_id].feature_map(),
707
+ "parent_desirability_mean": fmean(desirability),
708
+ "parent_desirability_min": min(desirability),
709
+ "parent_desirability_max": max(desirability),
710
+ "archive_base_hypervolume": base_hypervolume,
711
+ "archive_point_count_log": math.log1p(archive_point_count),
712
+ "target_favorable_fraction": weighted(
713
+ target_weights, lambda row: row.favorable_assertion
714
+ ),
715
+ "target_adverse_fraction": weighted(
716
+ target_weights, lambda row: row.adverse_assertion
717
+ ),
718
+ "target_abstention_fraction": weighted(
719
+ target_weights, lambda row: row.explicit_abstention
720
+ ),
721
+ "off_target_favorable_fraction": weighted(
722
+ off_target_weights, lambda row: row.favorable_assertion
723
+ ),
724
+ "off_target_adverse_fraction": weighted(
725
+ off_target_weights, lambda row: row.adverse_assertion
726
+ ),
727
+ "off_target_abstention_fraction": weighted(
728
+ off_target_weights, lambda row: row.explicit_abstention
729
+ ),
730
+ "target_declared_confidence": weighted(
731
+ target_weights, lambda row: _CONFIDENCE_VALUE[row.confidence]
732
+ ),
733
+ "target_posterior_correctness": weighted(
734
+ target_weights,
735
+ lambda row: row.calibration_cell.posterior_correctness,
736
+ ),
737
+ "target_signed_evidence": weighted(target_weights, signed),
738
+ "target_reliability_adjusted_evidence": weighted(
739
+ target_weights,
740
+ lambda row: signed(row)
741
+ * (2.0 * row.calibration_cell.posterior_correctness - 1.0),
742
+ ),
743
+ "target_opportunity_from_ideal": opportunity,
744
+ "target_parent_achievement": parent_achievement,
745
+ "target_parent_regret": parent_regret,
746
+ "target_active_axis_fraction": sum(
747
+ value > 0.0 for value in target_weights
748
+ )
749
+ / len(target_weights),
750
+ "target_zero_axis_fraction": sum(
751
+ value == 0.0 for value in target_weights
752
+ )
753
+ / len(target_weights),
754
+ "remaining_proposal_horizon": float(
755
+ request.remaining_proposal_horizon
756
+ ),
757
+ "remaining_proposal_horizon_fraction": (
758
+ request.remaining_proposal_horizon / 2.0
759
+ ),
760
+ }
761
+ )
762
+ for rank in range(1, 8):
763
+ features[f"target_opportunity_rank_{rank}"] = float(
764
+ request.frontier_target.opportunity_rank == rank
765
+ )
766
+ if set(features) != set(self.feature_names):
767
+ raise RuntimeError("portable feature implementation drifted")
768
+ values = tuple(float(features[name]) for name in self.feature_names)
769
+ if any(not math.isfinite(value) for value in values):
770
+ raise ValueError("portable features must all be finite")
771
+ rows.append(
772
+ TargetConditionedMemberFeatures(
773
+ option_id=option_id,
774
+ option_identity_sha256=member.option_identity_sha256,
775
+ feature_names=self.feature_names,
776
+ values=values,
777
+ projector_id=self.projector_id,
778
+ projector_version=self.projector_version,
779
+ projector_definition_sha256=self.definition_sha256,
780
+ )
781
+ )
782
+ return tuple(rows)
783
+
784
+ def to_record(self) -> dict[str, object]:
785
+ return {
786
+ "projector_id": self.projector_id,
787
+ "projector_version": self.projector_version,
788
+ "definition_sha256": self.definition_sha256,
789
+ "feature_names": list(self.feature_names),
790
+ "scale_qualification": {
791
+ "proposal_slate_size": 8,
792
+ "lane_slots": 2,
793
+ "proposal_generations": [1, 3, 5],
794
+ "maximum_remaining_horizon": 2,
795
+ },
796
+ "workload_model_provider_option_name_features": False,
797
+ "current_or_future_outcomes_consulted": False,
798
+ }
799
+
800
+
801
+ __all__ = [
802
+ "FEATURE_NAMES",
803
+ "PORTABLE_FEATURES",
804
+ "PROJECTOR_DEFINITION_SHA256",
805
+ "PROJECTOR_ID",
806
+ "PROJECTOR_VERSION",
807
+ "PortableTransitionReceipt",
808
+ "TARGET_FEATURES",
809
+ "TargetConditionedFeatureProjectionRequest",
810
+ "TargetConditionedPortableFeatureProjector",
811
+ "project_portable_transition",
812
+ ]