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,1417 @@
1
+ """Constraint-by-construction residual proposals with semantic conservation.
2
+
3
+ Models are useful for proposing semantic preferences, but they should not own
4
+ executable validity. This adapter accepts structurally typed parent/option
5
+ preferences, then projects each member independently onto the exact finite
6
+ variation contract. One invalid member therefore cannot discard an otherwise
7
+ useful slate. When projection changes an action, the claims authored for the
8
+ rejected action are quarantined and a second identity-preserving call
9
+ re-grounds rationale and forecasts against the exact compiled action. No
10
+ workload-, model-, or provider-specific repair branch is required.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ import hashlib
17
+ import json
18
+ import math
19
+ import re
20
+ from typing import Annotated, Any, Callable, ClassVar, Literal, cast
21
+
22
+ from pydantic import (
23
+ BaseModel,
24
+ ConfigDict,
25
+ Field,
26
+ StringConstraints,
27
+ create_model,
28
+ model_validator,
29
+ )
30
+ from pydantic_core import PydanticCustomError
31
+
32
+ from agent_evolve.application.residual_reachability import (
33
+ CrossParentFiniteActionSchema,
34
+ HierarchicalResidualPlan,
35
+ ResidualProposalRole,
36
+ )
37
+ from agent_evolve.domain.finite_variation import FiniteVariationOption
38
+ from agent_evolve.domain.ids import LLMCallId
39
+ from agent_evolve.domain.llm_task_queue import ValidationIssueReasonCode
40
+ from agent_evolve.domain.typed_json import thaw_json
41
+ from agent_evolve.integrations.pydantic_ai.agentic_generator import (
42
+ AttemptedStructuredGenerationResponse,
43
+ LowLevelRunner,
44
+ )
45
+ from agent_evolve.integrations.pydantic_ai.residual_reachability import (
46
+ HIERARCHICAL_RESIDUAL_PROPOSAL_TOOL_NAME,
47
+ HierarchicalResidualMetricForecast,
48
+ HierarchicalResidualProposalRequest,
49
+ HierarchicalResidualProposalSelection,
50
+ render_hierarchical_residual_prompt,
51
+ )
52
+ from agent_evolve.ports.agentic_generator import AgenticCallTelemetry
53
+ from agent_evolve.ports.portfolio_selection import (
54
+ pairwise_disjoint_parent_patch_pairs,
55
+ )
56
+ from agent_evolve.ports.structured_generator import (
57
+ StructuredGenerationRequest,
58
+ StructuredGenerationResponse,
59
+ )
60
+
61
+
62
+ RECONCILED_RESIDUAL_PROPOSAL_POLICY_ID = (
63
+ "pydantic_ai_semantically_conserved_hierarchical_residual_proposal"
64
+ )
65
+ RECONCILED_RESIDUAL_PROPOSAL_POLICY_VERSION = 2
66
+ RECONCILED_RESIDUAL_PROPOSAL_POLICY_DEFINITION_SHA256 = hashlib.sha256(
67
+ b"agent-evolve:semantically-conserved-hierarchical-residual-proposal:v2;"
68
+ b"model-output=structurally-typed-parent-option-preferences;"
69
+ b"member-local-projection=exact-finite-contract;"
70
+ b"projection-distance=family-metadata-description;"
71
+ b"projected-claims=quarantined;"
72
+ b"postcompile-regrounding=identity-preserving-typed-call;"
73
+ b"regrounding-failure=explicit-uninformative-claims;"
74
+ b"quantile-canonicalization=stable-sort;"
75
+ b"whole-slate-retry-for-local-semantic-invalidity=false;"
76
+ b"workload-model-provider-branches=false"
77
+ ).hexdigest()
78
+
79
+ _STRICT = ConfigDict(
80
+ extra="forbid",
81
+ strict=True,
82
+ populate_by_name=True,
83
+ validate_default=True,
84
+ )
85
+ _Rationale = Annotated[
86
+ str,
87
+ StringConstraints(
88
+ strict=True,
89
+ strip_whitespace=True,
90
+ min_length=1,
91
+ max_length=16_384,
92
+ ),
93
+ ]
94
+ _DECISION_DOMAIN = b"agent-evolve:hierarchical-residual-proposal-decision:v2\x00"
95
+ _RECONCILIATION_DOMAIN = (
96
+ b"agent-evolve:residual-proposal-reconciliation:v2\x00"
97
+ )
98
+ _POSTCOMPILE_DECISION_DOMAIN = (
99
+ b"agent-evolve:postcompile-semantic-regrounding-decision:v1\x00"
100
+ )
101
+ _POSTCOMPILE_TOOL_NAME = "reground_compiled_residual_semantics"
102
+ _TOKEN = re.compile(r"[a-zA-Z0-9]+")
103
+
104
+
105
+ def _canonical_bytes(value: object) -> bytes:
106
+ return json.dumps(
107
+ value,
108
+ allow_nan=False,
109
+ ensure_ascii=True,
110
+ separators=(",", ":"),
111
+ sort_keys=True,
112
+ ).encode("ascii", errors="strict")
113
+
114
+
115
+ def _hash(domain: bytes, value: object) -> str:
116
+ return hashlib.sha256(domain + _canonical_bytes(value)).hexdigest()
117
+
118
+
119
+ class _PreferenceMetricPredictionBase(BaseModel):
120
+ model_config = _STRICT
121
+
122
+ @model_validator(mode="after")
123
+ def _finite(self) -> "_PreferenceMetricPredictionBase":
124
+ values = tuple(
125
+ cast(float, getattr(cast(Any, self), name))
126
+ for name in (
127
+ "p10_delta",
128
+ "p50_delta",
129
+ "p90_delta",
130
+ "confidence",
131
+ )
132
+ )
133
+ if not all(math.isfinite(value) for value in values):
134
+ raise ValueError("metric preference values must be finite")
135
+ return self
136
+
137
+
138
+ class _PreferenceMemberBase(BaseModel):
139
+ model_config = _STRICT
140
+
141
+ allowed_radii: ClassVar[frozenset[int]] = frozenset()
142
+ required_metric_ids: ClassVar[frozenset[str]] = frozenset()
143
+
144
+ @model_validator(mode="after")
145
+ def _structural_contract(self) -> "_PreferenceMemberBase":
146
+ option_ids = tuple(cast(Any, self).component_option_ids)
147
+ if len(option_ids) not in type(self).allowed_radii:
148
+ raise PydanticCustomError(
149
+ ValidationIssueReasonCode.RESIDUAL_RADIUS_CONTRACT_VIOLATION.value,
150
+ "component tuple has a forbidden radius",
151
+ )
152
+ metrics = tuple(
153
+ item.metric_id for item in cast(Any, self).effect_predictions
154
+ )
155
+ if (
156
+ len(set(metrics)) != len(metrics)
157
+ or set(metrics) != type(self).required_metric_ids
158
+ ):
159
+ raise PydanticCustomError(
160
+ ValidationIssueReasonCode.RESIDUAL_METRIC_CONTRACT_VIOLATION.value,
161
+ "effect predictions must cover each requested metric once",
162
+ )
163
+ return self
164
+
165
+
166
+ class _PreferenceOutputBase(BaseModel):
167
+ model_config = _STRICT
168
+
169
+ proposal_count: ClassVar[int] = 1
170
+ minimum_distinct_parents: ClassVar[int] = 1
171
+
172
+ @model_validator(mode="after")
173
+ def _slate_contract(self) -> "_PreferenceOutputBase":
174
+ members = tuple(cast(Any, self).members)
175
+ if len(members) != type(self).proposal_count:
176
+ raise ValueError("members must have the exact requested size")
177
+ if (
178
+ len({value.parent_candidate_id for value in members})
179
+ < type(self).minimum_distinct_parents
180
+ ):
181
+ raise PydanticCustomError(
182
+ ValidationIssueReasonCode.RESIDUAL_PLAN_DIVERSITY_VIOLATION.value,
183
+ "members do not cover enough distinct parents",
184
+ )
185
+ return self
186
+
187
+
188
+ class _PostCompilationMemberBase(BaseModel):
189
+ model_config = _STRICT
190
+
191
+ required_metric_ids: ClassVar[frozenset[str]] = frozenset()
192
+
193
+ @model_validator(mode="after")
194
+ def _metric_contract(self) -> "_PostCompilationMemberBase":
195
+ metrics = tuple(
196
+ item.metric_id for item in cast(Any, self).effect_predictions
197
+ )
198
+ if (
199
+ len(set(metrics)) != len(metrics)
200
+ or set(metrics) != type(self).required_metric_ids
201
+ ):
202
+ raise PydanticCustomError(
203
+ ValidationIssueReasonCode.RESIDUAL_METRIC_CONTRACT_VIOLATION.value,
204
+ "post-compilation forecasts must cover every metric once",
205
+ )
206
+ return self
207
+
208
+
209
+ class _PostCompilationOutputBase(BaseModel):
210
+ model_config = _STRICT
211
+
212
+ required_member_indices: ClassVar[tuple[int, ...]] = ()
213
+
214
+ @model_validator(mode="after")
215
+ def _member_contract(self) -> "_PostCompilationOutputBase":
216
+ indices = tuple(
217
+ int(member.member_index)
218
+ for member in cast(Any, self).members
219
+ )
220
+ if indices != type(self).required_member_indices:
221
+ raise ValueError(
222
+ "post-compilation members must preserve the exact requested "
223
+ "member order"
224
+ )
225
+ return self
226
+
227
+
228
+ def reconciled_residual_preference_output_type(
229
+ request: HierarchicalResidualProposalRequest,
230
+ ) -> type[BaseModel]:
231
+ """Build a structural DTO; trusted code owns cross-field feasibility."""
232
+
233
+ request.__post_init__()
234
+ parent_literal = Literal.__getitem__(
235
+ tuple(
236
+ value.parent_candidate_id.value
237
+ for value in request.action_schema.bindings
238
+ )
239
+ )
240
+ option_literal = Literal.__getitem__(request.action_schema.option_ids)
241
+ role_literal = Literal.__getitem__(
242
+ tuple(value.value for value in request.allowed_roles)
243
+ )
244
+ metric_literal = Literal.__getitem__(request.required_metric_ids)
245
+ prediction_type = create_model(
246
+ "ResidualMetricPreference",
247
+ __base__=_PreferenceMetricPredictionBase,
248
+ __module__=__name__,
249
+ metric_id=(metric_literal, ...),
250
+ p10_delta=(float, ...),
251
+ p50_delta=(float, ...),
252
+ p90_delta=(float, ...),
253
+ confidence=(float, Field(ge=0.0, le=1.0, strict=True)),
254
+ )
255
+ member_type = create_model(
256
+ "HierarchicalResidualPreferenceMember",
257
+ __base__=_PreferenceMemberBase,
258
+ __module__=__name__,
259
+ parent_candidate_id=(parent_literal, ...),
260
+ component_option_ids=(
261
+ list[option_literal],
262
+ Field(
263
+ min_length=min(request.allowed_radii),
264
+ max_length=max(request.allowed_radii),
265
+ ),
266
+ ),
267
+ role=(role_literal, ...),
268
+ probability_valid=(float, Field(ge=0.0, le=1.0, strict=True)),
269
+ effect_predictions=(
270
+ list[prediction_type],
271
+ Field(
272
+ min_length=len(request.required_metric_ids),
273
+ max_length=len(request.required_metric_ids),
274
+ ),
275
+ ),
276
+ interaction_rationale=(_Rationale, ...),
277
+ )
278
+ member_type.allowed_radii = frozenset(request.allowed_radii)
279
+ member_type.required_metric_ids = frozenset(
280
+ request.required_metric_ids
281
+ )
282
+ output_type = create_model(
283
+ "HierarchicalResidualPreferenceSlate",
284
+ __base__=_PreferenceOutputBase,
285
+ __module__=__name__,
286
+ members=(
287
+ list[member_type],
288
+ Field(
289
+ min_length=request.proposal_count,
290
+ max_length=request.proposal_count,
291
+ ),
292
+ ),
293
+ slate_rationale=(_Rationale, ...),
294
+ )
295
+ output_type.proposal_count = request.proposal_count
296
+ output_type.minimum_distinct_parents = (
297
+ request.minimum_distinct_parents
298
+ )
299
+ return output_type
300
+
301
+
302
+ def postcompile_semantic_regrounding_output_type(
303
+ *,
304
+ projected_member_indices: tuple[int, ...],
305
+ required_metric_ids: tuple[str, ...],
306
+ ) -> type[BaseModel]:
307
+ """Build a DTO that can annotate, but never alter, compiled identities."""
308
+
309
+ if (
310
+ type(projected_member_indices) is not tuple
311
+ or not projected_member_indices
312
+ or any(
313
+ type(value) is not int or value <= 0
314
+ for value in projected_member_indices
315
+ )
316
+ or projected_member_indices
317
+ != tuple(sorted(set(projected_member_indices)))
318
+ ):
319
+ raise ValueError(
320
+ "projected_member_indices must be a non-empty canonical tuple"
321
+ )
322
+ if (
323
+ type(required_metric_ids) is not tuple
324
+ or not required_metric_ids
325
+ or any(type(value) is not str or not value for value in required_metric_ids)
326
+ or required_metric_ids != tuple(sorted(set(required_metric_ids)))
327
+ ):
328
+ raise ValueError(
329
+ "required_metric_ids must be a non-empty canonical tuple"
330
+ )
331
+ member_literal = Literal.__getitem__(projected_member_indices)
332
+ metric_literal = Literal.__getitem__(required_metric_ids)
333
+ prediction_type = create_model(
334
+ "PostCompilationResidualMetricForecast",
335
+ __base__=_PreferenceMetricPredictionBase,
336
+ __module__=__name__,
337
+ metric_id=(metric_literal, ...),
338
+ p10_delta=(float, ...),
339
+ p50_delta=(float, ...),
340
+ p90_delta=(float, ...),
341
+ confidence=(float, Field(ge=0.0, le=1.0, strict=True)),
342
+ )
343
+ member_type = create_model(
344
+ "PostCompilationResidualSemanticClaims",
345
+ __base__=_PostCompilationMemberBase,
346
+ __module__=__name__,
347
+ member_index=(member_literal, ...),
348
+ semantic_fidelity_acknowledgement=(
349
+ Literal["exact_compiled_action"],
350
+ ...,
351
+ ),
352
+ probability_valid=(float, Field(ge=0.0, le=1.0, strict=True)),
353
+ effect_predictions=(
354
+ list[prediction_type],
355
+ Field(
356
+ min_length=len(required_metric_ids),
357
+ max_length=len(required_metric_ids),
358
+ ),
359
+ ),
360
+ interaction_rationale=(_Rationale, ...),
361
+ )
362
+ member_type.required_metric_ids = frozenset(required_metric_ids)
363
+ output_type = create_model(
364
+ "PostCompilationResidualSemanticSlate",
365
+ __base__=_PostCompilationOutputBase,
366
+ __module__=__name__,
367
+ members=(
368
+ list[member_type],
369
+ Field(
370
+ min_length=len(projected_member_indices),
371
+ max_length=len(projected_member_indices),
372
+ ),
373
+ ),
374
+ regrounding_rationale=(_Rationale, ...),
375
+ )
376
+ output_type.required_member_indices = projected_member_indices
377
+ return output_type
378
+
379
+
380
+ def _semantic_record(option: FiniteVariationOption) -> dict[str, object]:
381
+ prompt = option.prompt_record()
382
+ return {
383
+ "family": prompt["family"],
384
+ "description": prompt["description"],
385
+ "metadata": {
386
+ key: value
387
+ for key, value in cast(
388
+ dict[str, object],
389
+ prompt["metadata"],
390
+ ).items()
391
+ if not key.endswith("_sha256")
392
+ },
393
+ }
394
+
395
+
396
+ def _description_tokens(value: object) -> frozenset[str]:
397
+ if type(value) is not str:
398
+ return frozenset()
399
+ return frozenset(token.lower() for token in _TOKEN.findall(value))
400
+
401
+
402
+ def _semantic_distance(
403
+ source: dict[str, object],
404
+ target: dict[str, object],
405
+ target_option_id: str,
406
+ ) -> tuple[int, int, int, str]:
407
+ source_metadata = cast(dict[str, object], source["metadata"])
408
+ target_metadata = cast(dict[str, object], target["metadata"])
409
+ keys = set(source_metadata) | set(target_metadata)
410
+ metadata_disagreement = sum(
411
+ source_metadata.get(key) != target_metadata.get(key)
412
+ for key in keys
413
+ )
414
+ token_disagreement = len(
415
+ _description_tokens(source["description"])
416
+ ^ _description_tokens(target["description"])
417
+ )
418
+ return (
419
+ int(source["family"] != target["family"]),
420
+ metadata_disagreement,
421
+ token_disagreement,
422
+ target_option_id,
423
+ )
424
+
425
+
426
+ @dataclass(frozen=True, slots=True)
427
+ class ResidualMemberReconciliation:
428
+ parent_candidate_id: str
429
+ requested_component_option_ids: tuple[str, ...]
430
+ reconciled_component_option_ids: tuple[str, ...]
431
+ reason_codes: tuple[str, ...]
432
+ projection_score: tuple[int, ...] | None
433
+
434
+ def to_record(self) -> dict[str, object]:
435
+ unsigned: dict[str, object] = {
436
+ "schema_version": 1,
437
+ "parent_candidate_id": self.parent_candidate_id,
438
+ "requested_component_option_ids": list(
439
+ self.requested_component_option_ids
440
+ ),
441
+ "reconciled_component_option_ids": list(
442
+ self.reconciled_component_option_ids
443
+ ),
444
+ "reason_codes": list(self.reason_codes),
445
+ "projection_score": (
446
+ None
447
+ if self.projection_score is None
448
+ else list(self.projection_score)
449
+ ),
450
+ }
451
+ return {
452
+ **unsigned,
453
+ "reconciliation_sha256": _hash(
454
+ _RECONCILIATION_DOMAIN,
455
+ unsigned,
456
+ ),
457
+ }
458
+
459
+
460
+ def _nearest_available_option(
461
+ *,
462
+ requested_id: str,
463
+ available_by_id: dict[str, FiniteVariationOption],
464
+ union_semantics_by_id: dict[str, dict[str, object]],
465
+ ) -> tuple[str, tuple[int, int, int, str]]:
466
+ source = union_semantics_by_id[requested_id]
467
+ ranked = tuple(
468
+ (
469
+ _semantic_distance(
470
+ source,
471
+ _semantic_record(option),
472
+ option_id,
473
+ ),
474
+ option_id,
475
+ )
476
+ for option_id, option in available_by_id.items()
477
+ )
478
+ score, option_id = min(ranked)
479
+ return option_id, score
480
+
481
+
482
+ def reconcile_component_preferences(
483
+ *,
484
+ schema: CrossParentFiniteActionSchema,
485
+ parent_candidate_id: str,
486
+ requested_option_ids: tuple[str, ...],
487
+ ) -> ResidualMemberReconciliation:
488
+ """Project one member onto its exact parent-bound feasible action set."""
489
+
490
+ binding = next(
491
+ value
492
+ for value in schema.bindings
493
+ if value.parent_candidate_id.value == parent_candidate_id
494
+ )
495
+ available_by_id = {
496
+ value.option_id: value for value in binding.contract.options
497
+ }
498
+ union_semantics_by_id = {
499
+ cast(str, value["option_id"]): {
500
+ "family": value["family"],
501
+ "description": value["description"],
502
+ "metadata": {
503
+ key: item
504
+ for key, item in cast(
505
+ dict[str, object],
506
+ value["metadata"],
507
+ ).items()
508
+ if not key.endswith("_sha256")
509
+ },
510
+ }
511
+ for value in schema.action_prompt_records
512
+ }
513
+ current: list[str] = []
514
+ reason_codes: list[str] = []
515
+ component_scores: list[tuple[int, int, int, str]] = []
516
+ for requested_id in requested_option_ids:
517
+ if requested_id in available_by_id:
518
+ current.append(requested_id)
519
+ continue
520
+ replacement, score = _nearest_available_option(
521
+ requested_id=requested_id,
522
+ available_by_id=available_by_id,
523
+ union_semantics_by_id=union_semantics_by_id,
524
+ )
525
+ current.append(replacement)
526
+ component_scores.append(score)
527
+ reason_codes.append("parent_unavailable_option_projected")
528
+
529
+ if len(current) == 1:
530
+ final = tuple(current)
531
+ else:
532
+ compatible = pairwise_disjoint_parent_patch_pairs(
533
+ binding.contract,
534
+ tuple(available_by_id),
535
+ )
536
+ compatible_set = frozenset(compatible)
537
+ pair = tuple(sorted(current))
538
+ if len(set(pair)) == 2 and pair in compatible_set:
539
+ final = pair
540
+ else:
541
+ candidates: list[
542
+ tuple[
543
+ tuple[int, int, int, str, int],
544
+ tuple[str, str],
545
+ ]
546
+ ] = []
547
+ for keep_index, keep in enumerate(current):
548
+ rejected = current[1 - keep_index]
549
+ rejected_semantics = union_semantics_by_id[rejected]
550
+ for compatible_pair in compatible:
551
+ if keep not in compatible_pair:
552
+ continue
553
+ replacement = (
554
+ compatible_pair[0]
555
+ if compatible_pair[1] == keep
556
+ else compatible_pair[1]
557
+ )
558
+ distance = _semantic_distance(
559
+ rejected_semantics,
560
+ _semantic_record(available_by_id[replacement]),
561
+ replacement,
562
+ )
563
+ candidates.append(
564
+ ((*distance, keep_index), compatible_pair)
565
+ )
566
+ if not candidates:
567
+ raise ValueError(
568
+ "finite contract exposes no compatible reconciliation"
569
+ )
570
+ projection_score, final = min(candidates)
571
+ component_scores.append(projection_score[:4])
572
+ reason_codes.append("overlapping_component_projected")
573
+
574
+ integer_score = None
575
+ if component_scores:
576
+ integer_score = tuple(
577
+ sum(value[index] for value in component_scores)
578
+ for index in range(3)
579
+ )
580
+ return ResidualMemberReconciliation(
581
+ parent_candidate_id=parent_candidate_id,
582
+ requested_component_option_ids=requested_option_ids,
583
+ reconciled_component_option_ids=tuple(sorted(final)),
584
+ reason_codes=tuple(sorted(set(reason_codes))),
585
+ projection_score=integer_score,
586
+ )
587
+
588
+
589
+ def _telemetry(
590
+ response: StructuredGenerationResponse[Any],
591
+ attempt_count: int,
592
+ ) -> AgenticCallTelemetry:
593
+ return AgenticCallTelemetry(
594
+ requested_model=response.requested_model,
595
+ resolved_model=response.resolved_model,
596
+ resolved_provider=response.resolved_provider,
597
+ provider_response_id=response.provider_response_id,
598
+ finish_reason=response.finish_reason,
599
+ input_tokens=response.input_tokens,
600
+ output_tokens=response.output_tokens,
601
+ reasoning_tokens=response.reasoning_tokens,
602
+ cache_read_tokens=response.cache_read_tokens,
603
+ cache_write_tokens=response.cache_write_tokens,
604
+ cost_usd=response.cost_usd,
605
+ latency_ns=response.latency_ns,
606
+ attempt_count=attempt_count,
607
+ )
608
+
609
+
610
+ def _canonical_forecasts(
611
+ predictions: object,
612
+ ) -> tuple[HierarchicalResidualMetricForecast, ...]:
613
+ return tuple(
614
+ sorted(
615
+ (
616
+ HierarchicalResidualMetricForecast(
617
+ metric_id=prediction.metric_id,
618
+ p10_delta=sorted(
619
+ (
620
+ float(prediction.p10_delta),
621
+ float(prediction.p50_delta),
622
+ float(prediction.p90_delta),
623
+ )
624
+ )[0],
625
+ p50_delta=sorted(
626
+ (
627
+ float(prediction.p10_delta),
628
+ float(prediction.p50_delta),
629
+ float(prediction.p90_delta),
630
+ )
631
+ )[1],
632
+ p90_delta=sorted(
633
+ (
634
+ float(prediction.p10_delta),
635
+ float(prediction.p50_delta),
636
+ float(prediction.p90_delta),
637
+ )
638
+ )[2],
639
+ confidence=float(prediction.confidence),
640
+ )
641
+ for prediction in cast(Any, predictions)
642
+ ),
643
+ key=lambda item: item.metric_id,
644
+ )
645
+ )
646
+
647
+
648
+ def _neutral_forecasts(
649
+ metric_ids: tuple[str, ...],
650
+ ) -> tuple[HierarchicalResidualMetricForecast, ...]:
651
+ return tuple(
652
+ HierarchicalResidualMetricForecast(
653
+ metric_id=metric_id,
654
+ p10_delta=0.0,
655
+ p50_delta=0.0,
656
+ p90_delta=0.0,
657
+ confidence=0.0,
658
+ )
659
+ for metric_id in metric_ids
660
+ )
661
+
662
+
663
+ def _claims_record(
664
+ *,
665
+ probability_valid: float,
666
+ forecasts: tuple[HierarchicalResidualMetricForecast, ...],
667
+ rationale: str,
668
+ ) -> dict[str, object]:
669
+ return {
670
+ "probability_valid_hex": probability_valid.hex(),
671
+ "effect_predictions": [
672
+ {
673
+ "metric_id": prediction.metric_id,
674
+ "p10_delta_hex": prediction.p10_delta.hex(),
675
+ "p50_delta_hex": prediction.p50_delta.hex(),
676
+ "p90_delta_hex": prediction.p90_delta.hex(),
677
+ "confidence_hex": prediction.confidence.hex(),
678
+ }
679
+ for prediction in forecasts
680
+ ],
681
+ "interaction_rationale": rationale,
682
+ }
683
+
684
+
685
+ def _response_telemetry_record(
686
+ response: StructuredGenerationResponse[Any],
687
+ attempt_count: int,
688
+ ) -> dict[str, object]:
689
+ return {
690
+ "requested_model": response.requested_model,
691
+ "resolved_model": response.resolved_model,
692
+ "resolved_provider": response.resolved_provider,
693
+ "provider_response_id": response.provider_response_id,
694
+ "finish_reason": response.finish_reason,
695
+ "input_tokens": response.input_tokens,
696
+ "output_tokens": response.output_tokens,
697
+ "reasoning_tokens": response.reasoning_tokens,
698
+ "cache_read_tokens": response.cache_read_tokens,
699
+ "cache_write_tokens": response.cache_write_tokens,
700
+ "cost_usd": (
701
+ None if response.cost_usd is None else str(response.cost_usd)
702
+ ),
703
+ "latency_ns": response.latency_ns,
704
+ "attempt_count": attempt_count,
705
+ }
706
+
707
+
708
+ def _derived_regrounding_call_id(call_id: LLMCallId) -> LLMCallId:
709
+ candidate = f"{call_id.value}_reground"
710
+ if len(candidate) <= 128:
711
+ return LLMCallId(candidate)
712
+ digest = hashlib.sha256(
713
+ call_id.value.encode("ascii", errors="strict")
714
+ ).hexdigest()[:24]
715
+ return LLMCallId(f"call_reground_{digest}")
716
+
717
+
718
+ def _option_record_for_parent(
719
+ request: HierarchicalResidualProposalRequest,
720
+ *,
721
+ parent_candidate_id: str,
722
+ option_id: str,
723
+ ) -> dict[str, object]:
724
+ binding = next(
725
+ value
726
+ for value in request.action_schema.bindings
727
+ if value.parent_candidate_id.value == parent_candidate_id
728
+ )
729
+ option = next(
730
+ value
731
+ for value in binding.contract.options
732
+ if value.option_id == option_id
733
+ )
734
+ return option.prompt_record()
735
+
736
+
737
+ def _postcompile_regrounding_prompt(
738
+ *,
739
+ request: HierarchicalResidualProposalRequest,
740
+ members: object,
741
+ reconciliations: tuple[ResidualMemberReconciliation, ...],
742
+ canonical_predictions: tuple[
743
+ tuple[HierarchicalResidualMetricForecast, ...],
744
+ ...,
745
+ ],
746
+ ) -> tuple[str, tuple[int, ...]]:
747
+ projected_indices = tuple(
748
+ index
749
+ for index, reconciliation in enumerate(reconciliations, start=1)
750
+ if reconciliation.reason_codes
751
+ )
752
+ if not projected_indices:
753
+ raise ValueError("post-compilation prompt requires projected members")
754
+ source_members = tuple(cast(Any, members))
755
+ payload_members: list[dict[str, object]] = []
756
+ for member_index in projected_indices:
757
+ member = source_members[member_index - 1]
758
+ reconciliation = reconciliations[member_index - 1]
759
+ original_claims = _claims_record(
760
+ probability_valid=float(member.probability_valid),
761
+ forecasts=canonical_predictions[member_index - 1],
762
+ rationale=str(member.interaction_rationale),
763
+ )
764
+ payload_members.append(
765
+ {
766
+ "member_index": member_index,
767
+ "parent_candidate_id": member.parent_candidate_id,
768
+ "requested_component_option_ids": list(
769
+ reconciliation.requested_component_option_ids
770
+ ),
771
+ "exact_compiled_component_option_ids": list(
772
+ reconciliation.reconciled_component_option_ids
773
+ ),
774
+ "projection_reason_codes": list(
775
+ reconciliation.reason_codes
776
+ ),
777
+ "exact_compiled_option_records": [
778
+ _option_record_for_parent(
779
+ request,
780
+ parent_candidate_id=member.parent_candidate_id,
781
+ option_id=option_id,
782
+ )
783
+ for option_id in (
784
+ reconciliation.reconciled_component_option_ids
785
+ )
786
+ ],
787
+ "quarantined_original_claims": original_claims,
788
+ }
789
+ )
790
+ contract = {
791
+ "schema_version": 1,
792
+ "source_request_sha256": request.request_sha256,
793
+ "source_instruction": request.instruction,
794
+ "strictly_prior_context": thaw_json(request.context),
795
+ "required_metric_ids": list(request.required_metric_ids),
796
+ "projected_members": payload_members,
797
+ "authority": {
798
+ "exact_compiled_parent_and_actions_are_immutable": True,
799
+ "may_change_configuration_or_action_identity": False,
800
+ "may_restore_quarantined_claims_without_new_justification": False,
801
+ "current_candidate_outcomes_observed": False,
802
+ "task": (
803
+ "author fresh probability, raw-metric effect forecasts, and "
804
+ "mechanistic rationale for each exact compiled action"
805
+ ),
806
+ },
807
+ "forecast_contract": {
808
+ "deltas_are_parent_relative_in_raw_metric_units": True,
809
+ "ordered_quantiles_required": True,
810
+ "confidence_and_probability_valid_range": [0.0, 1.0],
811
+ },
812
+ }
813
+ prompt = "\n".join(
814
+ (
815
+ "You are a post-compilation semantic verifier inside a generic "
816
+ "evolutionary optimizer. Trusted code changed one or more proposed "
817
+ "actions to satisfy an exact finite contract. Claims written for "
818
+ "the rejected actions have no authority. Re-ground every listed "
819
+ "member against only its exact compiled parent/action records and "
820
+ "the strictly-prior evidence. You cannot select, replace, reorder, "
821
+ "or edit an executable action.",
822
+ "",
823
+ "POST-COMPILATION SEMANTIC REGROUNDING CONTRACT",
824
+ json.dumps(
825
+ contract,
826
+ allow_nan=False,
827
+ ensure_ascii=True,
828
+ separators=(",", ":"),
829
+ sort_keys=True,
830
+ ),
831
+ )
832
+ )
833
+ return prompt, projected_indices
834
+
835
+
836
+ @dataclass(frozen=True, slots=True)
837
+ class PostCompilationSemanticRegrounding:
838
+ status: str
839
+ call_id: LLMCallId | None
840
+ decision_sha256: str
841
+ claims_by_member_index: tuple[
842
+ tuple[
843
+ int,
844
+ float,
845
+ tuple[HierarchicalResidualMetricForecast, ...],
846
+ str,
847
+ ],
848
+ ...,
849
+ ]
850
+ telemetry: dict[str, object] | None
851
+ regrounding_rationale: str | None
852
+ failure_kind: str | None
853
+ unordered_forecast_count: int
854
+
855
+ def __post_init__(self) -> None:
856
+ if (
857
+ type(self.unordered_forecast_count) is not int
858
+ or self.unordered_forecast_count < 0
859
+ ):
860
+ raise ValueError(
861
+ "unordered_forecast_count must be a non-negative integer"
862
+ )
863
+ if self.status not in {
864
+ "not_required",
865
+ "regrounded",
866
+ "quarantined_fallback",
867
+ }:
868
+ raise ValueError("unknown post-compilation regrounding status")
869
+ if self.status == "not_required":
870
+ if (
871
+ self.call_id is not None
872
+ or self.claims_by_member_index
873
+ or self.telemetry is not None
874
+ or self.regrounding_rationale is not None
875
+ or self.failure_kind is not None
876
+ ):
877
+ raise ValueError("not-required regrounding cannot carry a call")
878
+ else:
879
+ if type(self.call_id) is not LLMCallId:
880
+ raise TypeError("attempted regrounding requires a call ID")
881
+ LLMCallId.__post_init__(cast(LLMCallId, self.call_id))
882
+ if not self.claims_by_member_index:
883
+ raise ValueError("attempted regrounding requires final claims")
884
+ if self.status == "regrounded":
885
+ if self.telemetry is None or self.regrounding_rationale is None:
886
+ raise ValueError("successful regrounding requires evidence")
887
+ if self.failure_kind is not None:
888
+ raise ValueError("successful regrounding cannot have a failure")
889
+ if self.status == "quarantined_fallback":
890
+ if (
891
+ self.telemetry is not None
892
+ or self.regrounding_rationale is not None
893
+ or self.failure_kind is None
894
+ ):
895
+ raise ValueError("fallback regrounding evidence is inconsistent")
896
+
897
+
898
+ @dataclass(slots=True)
899
+ class PydanticAIReconciledHierarchicalResidualProposalPolicy:
900
+ generate_once: LowLevelRunner
901
+ reconciliation_sink: Callable[[dict[str, object]], None] | None = None
902
+
903
+ def __post_init__(self) -> None:
904
+ if not callable(self.generate_once):
905
+ raise TypeError("generate_once must be callable")
906
+ if self.reconciliation_sink is not None and not callable(
907
+ self.reconciliation_sink
908
+ ):
909
+ raise TypeError("reconciliation_sink must be callable or None")
910
+
911
+ async def _reground_projected_members(
912
+ self,
913
+ *,
914
+ request: HierarchicalResidualProposalRequest,
915
+ members: object,
916
+ reconciliations: tuple[ResidualMemberReconciliation, ...],
917
+ canonical_predictions: tuple[
918
+ tuple[HierarchicalResidualMetricForecast, ...],
919
+ ...,
920
+ ],
921
+ ) -> PostCompilationSemanticRegrounding:
922
+ projected_indices = tuple(
923
+ index
924
+ for index, reconciliation in enumerate(
925
+ reconciliations,
926
+ start=1,
927
+ )
928
+ if reconciliation.reason_codes
929
+ )
930
+ if not projected_indices:
931
+ result = PostCompilationSemanticRegrounding(
932
+ status="not_required",
933
+ call_id=None,
934
+ decision_sha256=_hash(
935
+ _POSTCOMPILE_DECISION_DOMAIN,
936
+ {
937
+ "schema_version": 1,
938
+ "source_request_sha256": request.request_sha256,
939
+ "status": "not_required",
940
+ },
941
+ ),
942
+ claims_by_member_index=(),
943
+ telemetry=None,
944
+ regrounding_rationale=None,
945
+ failure_kind=None,
946
+ unordered_forecast_count=0,
947
+ )
948
+ result.__post_init__()
949
+ return result
950
+
951
+ prompt, rendered_indices = _postcompile_regrounding_prompt(
952
+ request=request,
953
+ members=members,
954
+ reconciliations=reconciliations,
955
+ canonical_predictions=canonical_predictions,
956
+ )
957
+ if rendered_indices != projected_indices:
958
+ raise RuntimeError("post-compilation prompt lost projected members")
959
+ output_type = postcompile_semantic_regrounding_output_type(
960
+ projected_member_indices=projected_indices,
961
+ required_metric_ids=request.required_metric_ids,
962
+ )
963
+ call_id = _derived_regrounding_call_id(request.call_id)
964
+ try:
965
+ raw = await self.generate_once(
966
+ StructuredGenerationRequest(
967
+ call_id=call_id,
968
+ operation="postcompile_semantic_regrounding",
969
+ prompt=prompt,
970
+ output_type=output_type,
971
+ output_tool_name=_POSTCOMPILE_TOOL_NAME,
972
+ max_output_tokens=request.max_output_tokens,
973
+ temperature=request.temperature,
974
+ )
975
+ )
976
+ if type(raw) is AttemptedStructuredGenerationResponse:
977
+ response = raw.response
978
+ attempt_count = raw.attempt_count
979
+ elif type(raw) is StructuredGenerationResponse:
980
+ response = raw
981
+ attempt_count = 1
982
+ else:
983
+ raise TypeError("low-level runner returned a foreign response")
984
+ StructuredGenerationResponse.__post_init__(response)
985
+ if type(response.value) is not output_type:
986
+ raise TypeError(
987
+ "post-compilation response differs from requested type"
988
+ )
989
+ value = cast(Any, response.value)
990
+ claims = tuple(
991
+ (
992
+ int(member.member_index),
993
+ float(member.probability_valid),
994
+ _canonical_forecasts(member.effect_predictions),
995
+ (
996
+ "Post-compilation semantic re-grounding for the exact "
997
+ f"compiled action: {member.interaction_rationale}"
998
+ ),
999
+ )
1000
+ for member in value.members
1001
+ )
1002
+ unordered_forecast_count = sum(
1003
+ (
1004
+ float(prediction.p10_delta),
1005
+ float(prediction.p50_delta),
1006
+ float(prediction.p90_delta),
1007
+ )
1008
+ != tuple(
1009
+ sorted(
1010
+ (
1011
+ float(prediction.p10_delta),
1012
+ float(prediction.p50_delta),
1013
+ float(prediction.p90_delta),
1014
+ )
1015
+ )
1016
+ )
1017
+ for member in value.members
1018
+ for prediction in member.effect_predictions
1019
+ )
1020
+ regrounding_rationale = (
1021
+ "Post-compilation semantic re-grounding for exact compiled "
1022
+ f"actions: {value.regrounding_rationale}"
1023
+ )
1024
+ decision_record = {
1025
+ "schema_version": 1,
1026
+ "source_request_sha256": request.request_sha256,
1027
+ "call_id": call_id.value,
1028
+ "status": "regrounded",
1029
+ "claims": [
1030
+ {
1031
+ "member_index": index,
1032
+ **_claims_record(
1033
+ probability_valid=probability_valid,
1034
+ forecasts=forecasts,
1035
+ rationale=rationale,
1036
+ ),
1037
+ }
1038
+ for index, probability_valid, forecasts, rationale in claims
1039
+ ],
1040
+ "regrounding_rationale": regrounding_rationale,
1041
+ }
1042
+ result = PostCompilationSemanticRegrounding(
1043
+ status="regrounded",
1044
+ call_id=call_id,
1045
+ decision_sha256=_hash(
1046
+ _POSTCOMPILE_DECISION_DOMAIN,
1047
+ decision_record,
1048
+ ),
1049
+ claims_by_member_index=claims,
1050
+ telemetry=_response_telemetry_record(
1051
+ response,
1052
+ attempt_count,
1053
+ ),
1054
+ regrounding_rationale=regrounding_rationale,
1055
+ failure_kind=None,
1056
+ unordered_forecast_count=unordered_forecast_count,
1057
+ )
1058
+ result.__post_init__()
1059
+ return result
1060
+ except Exception as error:
1061
+ fallback_rationale = (
1062
+ "The trusted compiler changed this executable action. The "
1063
+ "original semantic claims are quarantined and post-compilation "
1064
+ "re-grounding did not complete; reason only from the exact "
1065
+ "compiled action and strictly-prior evidence."
1066
+ )
1067
+ neutral = _neutral_forecasts(request.required_metric_ids)
1068
+ claims = tuple(
1069
+ (index, 0.5, neutral, fallback_rationale)
1070
+ for index in projected_indices
1071
+ )
1072
+ failure_kind = type(error).__name__
1073
+ decision_record = {
1074
+ "schema_version": 1,
1075
+ "source_request_sha256": request.request_sha256,
1076
+ "call_id": call_id.value,
1077
+ "status": "quarantined_fallback",
1078
+ "failure_kind": failure_kind,
1079
+ "claims": [
1080
+ {
1081
+ "member_index": index,
1082
+ **_claims_record(
1083
+ probability_valid=probability_valid,
1084
+ forecasts=forecasts,
1085
+ rationale=rationale,
1086
+ ),
1087
+ }
1088
+ for index, probability_valid, forecasts, rationale in claims
1089
+ ],
1090
+ }
1091
+ result = PostCompilationSemanticRegrounding(
1092
+ status="quarantined_fallback",
1093
+ call_id=call_id,
1094
+ decision_sha256=_hash(
1095
+ _POSTCOMPILE_DECISION_DOMAIN,
1096
+ decision_record,
1097
+ ),
1098
+ claims_by_member_index=claims,
1099
+ telemetry=None,
1100
+ regrounding_rationale=None,
1101
+ failure_kind=failure_kind,
1102
+ unordered_forecast_count=0,
1103
+ )
1104
+ result.__post_init__()
1105
+ return result
1106
+
1107
+ async def select(
1108
+ self,
1109
+ request: HierarchicalResidualProposalRequest,
1110
+ ) -> HierarchicalResidualProposalSelection:
1111
+ request.__post_init__()
1112
+ output_type = reconciled_residual_preference_output_type(request)
1113
+ prompt = "\n".join(
1114
+ (
1115
+ render_hierarchical_residual_prompt(request),
1116
+ "",
1117
+ "VALIDITY OWNERSHIP",
1118
+ "Express the best semantic parent/action preferences. Select "
1119
+ "distinct parent-relative patch loci whenever the radius is "
1120
+ "two. Trusted engine code independently projects any locally "
1121
+ "incompatible member onto the nearest exact finite-contract "
1122
+ "action; one local mistake will not discard the full slate.",
1123
+ )
1124
+ )
1125
+ raw = await self.generate_once(
1126
+ StructuredGenerationRequest(
1127
+ call_id=request.call_id,
1128
+ operation=request.operation,
1129
+ prompt=prompt,
1130
+ output_type=output_type,
1131
+ output_tool_name=HIERARCHICAL_RESIDUAL_PROPOSAL_TOOL_NAME,
1132
+ max_output_tokens=request.max_output_tokens,
1133
+ temperature=request.temperature,
1134
+ )
1135
+ )
1136
+ if type(raw) is AttemptedStructuredGenerationResponse:
1137
+ response = raw.response
1138
+ attempt_count = raw.attempt_count
1139
+ elif type(raw) is StructuredGenerationResponse:
1140
+ response = raw
1141
+ attempt_count = 1
1142
+ else:
1143
+ raise TypeError("low-level runner returned a foreign response")
1144
+ StructuredGenerationResponse.__post_init__(response)
1145
+ if type(response.value) is not output_type:
1146
+ raise TypeError("response value differs from requested output type")
1147
+ value = cast(Any, response.value)
1148
+ reconciliations = tuple(
1149
+ reconcile_component_preferences(
1150
+ schema=request.action_schema,
1151
+ parent_candidate_id=member.parent_candidate_id,
1152
+ requested_option_ids=tuple(member.component_option_ids),
1153
+ )
1154
+ for member in value.members
1155
+ )
1156
+ canonical_predictions = tuple(
1157
+ _canonical_forecasts(member.effect_predictions)
1158
+ for member in value.members
1159
+ )
1160
+ regrounding = await self._reground_projected_members(
1161
+ request=request,
1162
+ members=value.members,
1163
+ reconciliations=reconciliations,
1164
+ canonical_predictions=canonical_predictions,
1165
+ )
1166
+ final_probabilities = [
1167
+ float(member.probability_valid) for member in value.members
1168
+ ]
1169
+ final_predictions = list(canonical_predictions)
1170
+ final_rationales = [
1171
+ str(member.interaction_rationale) for member in value.members
1172
+ ]
1173
+ for (
1174
+ member_index,
1175
+ probability_valid,
1176
+ predictions,
1177
+ rationale,
1178
+ ) in regrounding.claims_by_member_index:
1179
+ final_probabilities[member_index - 1] = probability_valid
1180
+ final_predictions[member_index - 1] = predictions
1181
+ final_rationales[member_index - 1] = rationale
1182
+ if regrounding.status == "regrounded":
1183
+ final_slate_rationale = cast(
1184
+ str,
1185
+ regrounding.regrounding_rationale,
1186
+ )
1187
+ elif regrounding.status == "quarantined_fallback":
1188
+ final_slate_rationale = (
1189
+ "One or more actions were changed by trusted compilation. "
1190
+ "Their original slate-level semantic claims are quarantined; "
1191
+ "reason only from exact compiled actions and strictly-prior "
1192
+ "evidence."
1193
+ )
1194
+ else:
1195
+ final_slate_rationale = str(value.slate_rationale)
1196
+ final_members = [
1197
+ {
1198
+ "parent_candidate_id": member.parent_candidate_id,
1199
+ "component_option_ids": list(
1200
+ reconciliation.reconciled_component_option_ids
1201
+ ),
1202
+ "role": member.role,
1203
+ "probability_valid": probability_valid,
1204
+ "effect_predictions": [
1205
+ {
1206
+ "metric_id": prediction.metric_id,
1207
+ "p10_delta": prediction.p10_delta,
1208
+ "p50_delta": prediction.p50_delta,
1209
+ "p90_delta": prediction.p90_delta,
1210
+ "confidence": prediction.confidence,
1211
+ }
1212
+ for prediction in predictions
1213
+ ],
1214
+ "interaction_rationale": rationale,
1215
+ }
1216
+ for (
1217
+ member,
1218
+ reconciliation,
1219
+ probability_valid,
1220
+ predictions,
1221
+ rationale,
1222
+ ) in zip(
1223
+ value.members,
1224
+ reconciliations,
1225
+ final_probabilities,
1226
+ final_predictions,
1227
+ final_rationales,
1228
+ strict=True,
1229
+ )
1230
+ ]
1231
+ decision_sha256 = _hash(
1232
+ _DECISION_DOMAIN,
1233
+ {
1234
+ "schema_version": 2,
1235
+ "request_sha256": request.request_sha256,
1236
+ "postcompile_decision_sha256": (
1237
+ regrounding.decision_sha256
1238
+ ),
1239
+ "members": final_members,
1240
+ "slate_rationale": final_slate_rationale,
1241
+ },
1242
+ )
1243
+ plans = tuple(
1244
+ HierarchicalResidualPlan(
1245
+ parent_candidate_id=next(
1246
+ binding.parent_candidate_id
1247
+ for binding in request.action_schema.bindings
1248
+ if binding.parent_candidate_id.value
1249
+ == member.parent_candidate_id
1250
+ ),
1251
+ parent_contract_sha256=request.action_schema.contract_for(
1252
+ next(
1253
+ binding.parent_candidate_id
1254
+ for binding in request.action_schema.bindings
1255
+ if binding.parent_candidate_id.value
1256
+ == member.parent_candidate_id
1257
+ )
1258
+ ).identity_sha256,
1259
+ action_schema_sha256=request.action_schema.schema_sha256,
1260
+ component_option_ids=(
1261
+ reconciliation.reconciled_component_option_ids
1262
+ ),
1263
+ role=ResidualProposalRole(member.role),
1264
+ expert_id=request.expert_id,
1265
+ expert_definition_sha256=request.expert_definition_sha256,
1266
+ native_rank=rank,
1267
+ decision_receipt_sha256=decision_sha256,
1268
+ )
1269
+ for rank, (member, reconciliation) in enumerate(
1270
+ zip(value.members, reconciliations, strict=True),
1271
+ start=1,
1272
+ )
1273
+ )
1274
+ result = HierarchicalResidualProposalSelection(
1275
+ request_sha256=request.request_sha256,
1276
+ decision_sha256=decision_sha256,
1277
+ plans=plans,
1278
+ rationales=tuple(final_rationales),
1279
+ probability_valid=tuple(final_probabilities),
1280
+ effect_predictions=tuple(final_predictions),
1281
+ slate_rationale=final_slate_rationale,
1282
+ telemetry=_telemetry(response, attempt_count),
1283
+ )
1284
+ result.__post_init__()
1285
+ if self.reconciliation_sink is not None:
1286
+ unordered_forecast_count = sum(
1287
+ (
1288
+ float(prediction.p10_delta),
1289
+ float(prediction.p50_delta),
1290
+ float(prediction.p90_delta),
1291
+ )
1292
+ != tuple(
1293
+ sorted(
1294
+ (
1295
+ float(prediction.p10_delta),
1296
+ float(prediction.p50_delta),
1297
+ float(prediction.p90_delta),
1298
+ )
1299
+ )
1300
+ )
1301
+ for member in value.members
1302
+ for prediction in member.effect_predictions
1303
+ )
1304
+ member_records: list[dict[str, object]] = []
1305
+ for member_index, (
1306
+ member,
1307
+ reconciliation,
1308
+ original_predictions,
1309
+ final_probability,
1310
+ allocation_predictions,
1311
+ allocation_rationale,
1312
+ ) in enumerate(
1313
+ zip(
1314
+ value.members,
1315
+ reconciliations,
1316
+ canonical_predictions,
1317
+ final_probabilities,
1318
+ final_predictions,
1319
+ final_rationales,
1320
+ strict=True,
1321
+ ),
1322
+ start=1,
1323
+ ):
1324
+ original_claims = _claims_record(
1325
+ probability_valid=float(member.probability_valid),
1326
+ forecasts=original_predictions,
1327
+ rationale=str(member.interaction_rationale),
1328
+ )
1329
+ allocation_claims = _claims_record(
1330
+ probability_valid=final_probability,
1331
+ forecasts=allocation_predictions,
1332
+ rationale=allocation_rationale,
1333
+ )
1334
+ member_records.append(
1335
+ {
1336
+ **reconciliation.to_record(),
1337
+ "member_index": member_index,
1338
+ "semantic_fidelity": (
1339
+ "exact_claims_preserved"
1340
+ if not reconciliation.reason_codes
1341
+ else (
1342
+ "projected_claims_regrounded"
1343
+ if regrounding.status == "regrounded"
1344
+ else "projected_claims_quarantined_fallback"
1345
+ )
1346
+ ),
1347
+ "original_claims": original_claims,
1348
+ "original_claims_sha256": _hash(
1349
+ _POSTCOMPILE_DECISION_DOMAIN,
1350
+ original_claims,
1351
+ ),
1352
+ "allocation_claims": allocation_claims,
1353
+ "allocation_claims_sha256": _hash(
1354
+ _POSTCOMPILE_DECISION_DOMAIN,
1355
+ allocation_claims,
1356
+ ),
1357
+ }
1358
+ )
1359
+ record: dict[str, object] = {
1360
+ "schema_version": 2,
1361
+ "policy_id": RECONCILED_RESIDUAL_PROPOSAL_POLICY_ID,
1362
+ "policy_version": (
1363
+ RECONCILED_RESIDUAL_PROPOSAL_POLICY_VERSION
1364
+ ),
1365
+ "policy_definition_sha256": (
1366
+ RECONCILED_RESIDUAL_PROPOSAL_POLICY_DEFINITION_SHA256
1367
+ ),
1368
+ "call_id": request.call_id.value,
1369
+ "request_sha256": request.request_sha256,
1370
+ "decision_sha256": decision_sha256,
1371
+ "members": member_records,
1372
+ "projected_member_count": sum(
1373
+ bool(value.reason_codes)
1374
+ for value in reconciliations
1375
+ ),
1376
+ "unordered_forecast_count": unordered_forecast_count,
1377
+ "postcompile_regrounding": {
1378
+ "status": regrounding.status,
1379
+ "call_id": (
1380
+ None
1381
+ if regrounding.call_id is None
1382
+ else regrounding.call_id.value
1383
+ ),
1384
+ "decision_sha256": regrounding.decision_sha256,
1385
+ "telemetry": regrounding.telemetry,
1386
+ "failure_kind": regrounding.failure_kind,
1387
+ "unordered_forecast_count": (
1388
+ regrounding.unordered_forecast_count
1389
+ ),
1390
+ },
1391
+ "original_slate_rationale": str(value.slate_rationale),
1392
+ "allocation_slate_rationale": final_slate_rationale,
1393
+ "whole_slate_retry_avoided": any(
1394
+ value.reason_codes for value in reconciliations
1395
+ )
1396
+ or unordered_forecast_count > 0
1397
+ or regrounding.unordered_forecast_count > 0,
1398
+ }
1399
+ record["receipt_sha256"] = _hash(
1400
+ _RECONCILIATION_DOMAIN,
1401
+ record,
1402
+ )
1403
+ self.reconciliation_sink(record)
1404
+ return result
1405
+
1406
+
1407
+ __all__ = [
1408
+ "PydanticAIReconciledHierarchicalResidualProposalPolicy",
1409
+ "PostCompilationSemanticRegrounding",
1410
+ "RECONCILED_RESIDUAL_PROPOSAL_POLICY_DEFINITION_SHA256",
1411
+ "RECONCILED_RESIDUAL_PROPOSAL_POLICY_ID",
1412
+ "RECONCILED_RESIDUAL_PROPOSAL_POLICY_VERSION",
1413
+ "ResidualMemberReconciliation",
1414
+ "reconcile_component_preferences",
1415
+ "postcompile_semantic_regrounding_output_type",
1416
+ "reconciled_residual_preference_output_type",
1417
+ ]