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.
- agent_evolve/__init__.py +722 -0
- agent_evolve/agentic.py +2800 -0
- agent_evolve/api.py +767 -0
- agent_evolve/application/__init__.py +1580 -0
- agent_evolve/application/action_allocation.py +744 -0
- agent_evolve/application/action_allocation_frame.py +347 -0
- agent_evolve/application/action_allocation_frame_commit.py +185 -0
- agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
- agent_evolve/application/action_allocation_frame_v3.py +338 -0
- agent_evolve/application/action_archive_value.py +497 -0
- agent_evolve/application/action_evidence_consistency.py +455 -0
- agent_evolve/application/action_forecast_partitioning.py +1471 -0
- agent_evolve/application/action_metric_projection.py +211 -0
- agent_evolve/application/action_role_value.py +680 -0
- agent_evolve/application/action_score_authorities.py +363 -0
- agent_evolve/application/action_structural_signature.py +116 -0
- agent_evolve/application/action_target_realization.py +402 -0
- agent_evolve/application/agentic_evolution.py +7734 -0
- agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
- agent_evolve/application/anchor_residual_identification.py +463 -0
- agent_evolve/application/archive_conditioned_action_target.py +208 -0
- agent_evolve/application/artifact_journal.py +246 -0
- agent_evolve/application/artifact_replay.py +347 -0
- agent_evolve/application/budgeted_optimizer.py +1828 -0
- agent_evolve/application/calibrated_campaign.py +485 -0
- agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
- agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
- agent_evolve/application/campaign_capacity_recourse.py +254 -0
- agent_evolve/application/campaign_contextual_outcomes.py +119 -0
- agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
- agent_evolve/application/campaign_evidence_registry.py +262 -0
- agent_evolve/application/campaign_execution.py +2537 -0
- agent_evolve/application/campaign_generation_audit.py +942 -0
- agent_evolve/application/campaign_learning.py +1812 -0
- agent_evolve/application/campaign_learning_runtime.py +1977 -0
- agent_evolve/application/campaign_search_phase.py +227 -0
- agent_evolve/application/campaign_selector_context_extension.py +220 -0
- agent_evolve/application/campaign_variation_envelope.py +649 -0
- agent_evolve/application/campaign_variation_trace.py +451 -0
- agent_evolve/application/candidate_archive_consequence.py +128 -0
- agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
- agent_evolve/application/composite_outcome_updater.py +145 -0
- agent_evolve/application/composition_portfolio_selection.py +363 -0
- agent_evolve/application/concurrent_stage.py +144 -0
- agent_evolve/application/contextual_action_allocation.py +181 -0
- agent_evolve/application/contextual_campaign_outcomes.py +267 -0
- agent_evolve/application/contextual_campaign_planning.py +1366 -0
- agent_evolve/application/contextual_delayed_credit.py +651 -0
- agent_evolve/application/contextual_search_controller.py +2374 -0
- agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
- agent_evolve/application/decision_metric_projection.py +112 -0
- agent_evolve/application/derived_action_semantics.py +129 -0
- agent_evolve/application/detailed_evaluation.py +449 -0
- agent_evolve/application/earned_lineage.py +1011 -0
- agent_evolve/application/effective_choice_audit.py +484 -0
- agent_evolve/application/empirical_consequence_calibration.py +908 -0
- agent_evolve/application/evaluation_accounting.py +325 -0
- agent_evolve/application/evaluation_cache.py +199 -0
- agent_evolve/application/evaluation_escrow.py +547 -0
- agent_evolve/application/evaluation_recourse.py +253 -0
- agent_evolve/application/event_recorder.py +151 -0
- agent_evolve/application/evolution_campaign.py +1840 -0
- agent_evolve/application/executable_hypothesis.py +323 -0
- agent_evolve/application/factorial_branch_pilot.py +772 -0
- agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
- agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
- agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
- agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
- agent_evolve/application/finite_action_selection.py +188 -0
- agent_evolve/application/finite_action_set.py +306 -0
- agent_evolve/application/finite_action_transition.py +537 -0
- agent_evolve/application/finite_variation_eligibility.py +296 -0
- agent_evolve/application/forecast_geometry_portfolio.py +799 -0
- agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
- agent_evolve/application/front_proximity_admission.py +311 -0
- agent_evolve/application/front_proximity_parent_basis.py +458 -0
- agent_evolve/application/frozen_hurdle_score.py +659 -0
- agent_evolve/application/g3_causal_screen.py +2257 -0
- agent_evolve/application/g3_causal_validation.py +1046 -0
- agent_evolve/application/g3_postseal_curation.py +818 -0
- agent_evolve/application/gated_agentic_generator.py +205 -0
- agent_evolve/application/generation_feedback.py +293 -0
- agent_evolve/application/generative_proposal_journal.py +185 -0
- agent_evolve/application/geometry_conditional_elasticity.py +453 -0
- agent_evolve/application/global_wave_action_allocation.py +1151 -0
- agent_evolve/application/head_mass_conditional_seat.py +268 -0
- agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
- agent_evolve/application/identifiable_reflection_learning.py +395 -0
- agent_evolve/application/identifiable_reflection_request.py +364 -0
- agent_evolve/application/in_memory_residual_archive.py +341 -0
- agent_evolve/application/insight_memory.py +1804 -0
- agent_evolve/application/live_runtime_manifest.py +758 -0
- agent_evolve/application/llm_task_queue.py +769 -0
- agent_evolve/application/matched_finite_action_block.py +409 -0
- agent_evolve/application/materialized_action_broker.py +2328 -0
- agent_evolve/application/materialized_action_constraints.py +83 -0
- agent_evolve/application/materialized_variation.py +211 -0
- agent_evolve/application/multi_option_evolution.py +1536 -0
- agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
- agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
- agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
- agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
- agent_evolve/application/outcome_relation.py +193 -0
- agent_evolve/application/paired_allocation_comparison.py +241 -0
- agent_evolve/application/paired_block_schedule.py +127 -0
- agent_evolve/application/parent_measurement.py +226 -0
- agent_evolve/application/pareto_archive.py +811 -0
- agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
- agent_evolve/application/portfolio_evolution.py +2950 -0
- agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
- agent_evolve/application/portfolio_memory_attribution.py +581 -0
- agent_evolve/application/portfolio_memory_dose.py +788 -0
- agent_evolve/application/portfolio_memory_matched_control.py +938 -0
- agent_evolve/application/portfolio_memory_transfer.py +297 -0
- agent_evolve/application/portfolio_optimization_memory.py +363 -0
- agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
- agent_evolve/application/portfolio_projection.py +335 -0
- agent_evolve/application/portfolio_recombination.py +2032 -0
- agent_evolve/application/post_evolution_reflection.py +834 -0
- agent_evolve/application/postcommit_rank_authority.py +245 -0
- agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
- agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
- agent_evolve/application/prequential_residual_exploration.py +343 -0
- agent_evolve/application/prequential_score_portfolio.py +954 -0
- agent_evolve/application/projections.py +292 -0
- agent_evolve/application/protected_action_committee.py +1027 -0
- agent_evolve/application/protected_branch_pilot.py +376 -0
- agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
- agent_evolve/application/provider_replay.py +910 -0
- agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
- agent_evolve/application/recombination_residual_expert.py +403 -0
- agent_evolve/application/reflection_workflow.py +571 -0
- agent_evolve/application/region_conditional_credit.py +911 -0
- agent_evolve/application/residual_campaign_runtime.py +531 -0
- agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
- agent_evolve/application/residual_headroom_ledger.py +1544 -0
- agent_evolve/application/residual_learning_transaction.py +396 -0
- agent_evolve/application/residual_portfolio_evolution.py +1228 -0
- agent_evolve/application/residual_reachability.py +749 -0
- agent_evolve/application/residual_stage_credit.py +499 -0
- agent_evolve/application/same_prefix_paired_audit.py +1580 -0
- agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
- agent_evolve/application/sequential_lineage_allocation.py +1017 -0
- agent_evolve/application/sequential_market_replay.py +1395 -0
- agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
- agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
- agent_evolve/application/single_score_action_allocation.py +299 -0
- agent_evolve/application/source_exposure_allocation.py +906 -0
- agent_evolve/application/staged_memory.py +210 -0
- agent_evolve/application/stratified_cold_start_allocation.py +732 -0
- agent_evolve/application/support_guarded_hurdle_score.py +549 -0
- agent_evolve/application/target_conditioned_action_forecast.py +595 -0
- agent_evolve/application/target_conditioned_campaign.py +566 -0
- agent_evolve/application/treatment_assignment.py +201 -0
- agent_evolve/application/trusted_objective_evidence.py +217 -0
- agent_evolve/application/two_stage_action_evolution.py +1131 -0
- agent_evolve/application/v8lite_allocation_policy.py +1083 -0
- agent_evolve/application/v9_candidate_policy.py +1303 -0
- agent_evolve/bootstrap.py +108 -0
- agent_evolve/campaign_presets.py +517 -0
- agent_evolve/campaign_profiles.py +452 -0
- agent_evolve/campaign_variation_topology.py +288 -0
- agent_evolve/campaign_workload.py +950 -0
- agent_evolve/cli.py +797 -0
- agent_evolve/contract.py +241 -0
- agent_evolve/core/__init__.py +91 -0
- agent_evolve/core/action_semantics.py +411 -0
- agent_evolve/core/authored.py +105 -0
- agent_evolve/core/formatting.py +286 -0
- agent_evolve/core/optimization_semantics.py +324 -0
- agent_evolve/core/problem.py +167 -0
- agent_evolve/core/results.py +323 -0
- agent_evolve/core/stats.py +70 -0
- agent_evolve/core/telemetry.py +100 -0
- agent_evolve/domain/__init__.py +89 -0
- agent_evolve/domain/artifact.py +162 -0
- agent_evolve/domain/durable_text.py +68 -0
- agent_evolve/domain/event.py +1454 -0
- agent_evolve/domain/finite_action_set.py +426 -0
- agent_evolve/domain/finite_variation.py +526 -0
- agent_evolve/domain/generative_emission.py +559 -0
- agent_evolve/domain/ids.py +163 -0
- agent_evolve/domain/inline_text.py +106 -0
- agent_evolve/domain/insight.py +27 -0
- agent_evolve/domain/lineage.py +737 -0
- agent_evolve/domain/llm_task_queue.py +960 -0
- agent_evolve/domain/outcome.py +96 -0
- agent_evolve/domain/patch.py +854 -0
- agent_evolve/domain/typed_json.py +542 -0
- agent_evolve/domain/variation_space.py +158 -0
- agent_evolve/driver.py +1014 -0
- agent_evolve/harness/__init__.py +29 -0
- agent_evolve/harness/base.py +242 -0
- agent_evolve/harness/directives.py +163 -0
- agent_evolve/harness/generative_seal.py +479 -0
- agent_evolve/harness/registry.py +41 -0
- agent_evolve/infrastructure/__init__.py +39 -0
- agent_evolve/infrastructure/artifacts/__init__.py +6 -0
- agent_evolve/infrastructure/artifacts/_verification.py +67 -0
- agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
- agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
- agent_evolve/infrastructure/asyncio_runtime.py +109 -0
- agent_evolve/infrastructure/authored_runtime.py +188 -0
- agent_evolve/infrastructure/authored_worker.py +171 -0
- agent_evolve/infrastructure/clock.py +53 -0
- agent_evolve/infrastructure/events/__init__.py +6 -0
- agent_evolve/infrastructure/events/_validation.py +89 -0
- agent_evolve/infrastructure/events/in_memory.py +56 -0
- agent_evolve/infrastructure/events/jsonl.py +193 -0
- agent_evolve/infrastructure/exception_provenance.py +215 -0
- agent_evolve/infrastructure/ids.py +118 -0
- agent_evolve/infrastructure/lineage_codec.py +1836 -0
- agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
- agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
- agent_evolve/infrastructure/resource_lease.py +370 -0
- agent_evolve/infrastructure/sanitization/__init__.py +8 -0
- agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
- agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
- agent_evolve/infrastructure/stream_liveness.py +383 -0
- agent_evolve/infrastructure/subprocess_boundary.py +136 -0
- agent_evolve/integrations/__init__.py +1 -0
- agent_evolve/integrations/botorch/__init__.py +28 -0
- agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
- agent_evolve/integrations/completion.py +242 -0
- agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
- agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
- agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
- agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
- agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
- agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
- agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
- agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
- agent_evolve/integrations/pydantic_ai/harness.py +159 -0
- agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
- agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
- agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
- agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
- agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
- agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
- agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
- agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
- agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
- agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
- agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
- agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
- agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
- agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
- agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
- agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
- agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
- agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
- agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
- agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
- agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
- agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
- agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
- agent_evolve/integrations/pymoo_adapter.py +242 -0
- agent_evolve/policies/__init__.py +17 -0
- agent_evolve/policies/check.py +469 -0
- agent_evolve/policies/emit_scaffold.py +451 -0
- agent_evolve/policies/feedback/__init__.py +37 -0
- agent_evolve/policies/feedback/held_out_asn.py +1325 -0
- agent_evolve/policies/genetic.py +607 -0
- agent_evolve/policies/llm_backoff.py +183 -0
- agent_evolve/policies/llm_chooser.py +226 -0
- agent_evolve/policies/llm_generator.py +1760 -0
- agent_evolve/policies/llm_init.py +267 -0
- agent_evolve/policies/llm_operator.py +109 -0
- agent_evolve/policies/llm_prior.py +194 -0
- agent_evolve/policies/llm_surrogate.py +334 -0
- agent_evolve/policies/measurement_evidence.py +704 -0
- agent_evolve/policies/memory/__init__.py +223 -0
- agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
- agent_evolve/policies/memory/compatibility_matching.py +593 -0
- agent_evolve/policies/memory/global_falsification.py +1841 -0
- agent_evolve/policies/memory/prompt_shape.py +503 -0
- agent_evolve/policies/memory/randomized_subset.py +714 -0
- agent_evolve/policies/memory/staged_causal.py +1270 -0
- agent_evolve/policies/memory/treatment_compliance.py +759 -0
- agent_evolve/policies/objective_resolution/__init__.py +17 -0
- agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
- agent_evolve/policies/operator_portfolio.py +407 -0
- agent_evolve/policies/reguidance.py +1133 -0
- agent_evolve/policies/reward/__init__.py +83 -0
- agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
- agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
- agent_evolve/policies/reward/affine_hypervolume.py +490 -0
- agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
- agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
- agent_evolve/policies/reward/frozen_archive.py +360 -0
- agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
- agent_evolve/policies/search_state.py +208 -0
- agent_evolve/policies/selection/__init__.py +345 -0
- agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
- agent_evolve/policies/selection/affine_frontier_context.py +330 -0
- agent_evolve/policies/selection/affine_frontier_target.py +473 -0
- agent_evolve/policies/selection/archive_elite.py +1346 -0
- agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
- agent_evolve/policies/selection/calibrated_slate.py +1394 -0
- agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
- agent_evolve/policies/selection/common_candidate_pool.py +685 -0
- agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
- agent_evolve/policies/selection/disjoint_pairs.py +479 -0
- agent_evolve/policies/selection/elite_explorer.py +719 -0
- agent_evolve/policies/selection/finite_action.py +187 -0
- agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
- agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
- agent_evolve/policies/selection/forecast_calibration.py +922 -0
- agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
- agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
- agent_evolve/policies/selection/full_support_slate.py +91 -0
- agent_evolve/policies/selection/meaningful_direction.py +240 -0
- agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
- agent_evolve/policies/selection/model_anchored_slate.py +826 -0
- agent_evolve/policies/selection/phenotype_recourse.py +979 -0
- agent_evolve/policies/selection/proposal_support.py +368 -0
- agent_evolve/policies/selection/random_portfolio.py +254 -0
- agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
- agent_evolve/policies/selection/residual_frontier.py +463 -0
- agent_evolve/policies/selection/residual_frontier_target.py +605 -0
- agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
- agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
- agent_evolve/policies/selection/target_conditioned_features.py +812 -0
- agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
- agent_evolve/policies/selection/task_keyed_palette.py +906 -0
- agent_evolve/policies/semantics.py +147 -0
- agent_evolve/policies/structure.py +362 -0
- agent_evolve/policies/structured_output_budget.py +62 -0
- agent_evolve/policies/surrogate.py +696 -0
- agent_evolve/policies/variation/__init__.py +1 -0
- agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
- agent_evolve/policies/variation/crossover_inheritance.py +575 -0
- agent_evolve/policies/variation/disjoint_recombination.py +611 -0
- agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
- agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
- agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
- agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
- agent_evolve/policies/variation/typed_patch.py +1981 -0
- agent_evolve/policies/weighted_prior.py +394 -0
- agent_evolve/ports/__init__.py +383 -0
- agent_evolve/ports/action_allocation.py +733 -0
- agent_evolve/ports/action_allocation_frame.py +1153 -0
- agent_evolve/ports/action_allocation_frame_commit.py +294 -0
- agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
- agent_evolve/ports/action_allocation_frame_v3.py +995 -0
- agent_evolve/ports/action_forecast.py +1568 -0
- agent_evolve/ports/action_metric_projection.py +165 -0
- agent_evolve/ports/agentic_generator.py +1561 -0
- agent_evolve/ports/archive_context.py +136 -0
- agent_evolve/ports/artifact_sanitizer.py +44 -0
- agent_evolve/ports/artifact_store.py +225 -0
- agent_evolve/ports/clock.py +13 -0
- agent_evolve/ports/contextual_search_allocation.py +827 -0
- agent_evolve/ports/decision_metric_projection.py +258 -0
- agent_evolve/ports/event_store.py +55 -0
- agent_evolve/ports/executable_hypothesis.py +557 -0
- agent_evolve/ports/finite_acquisition.py +377 -0
- agent_evolve/ports/finite_acquisition_batch.py +296 -0
- agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
- agent_evolve/ports/finite_acquisition_json.py +247 -0
- agent_evolve/ports/finite_acquisition_space.py +168 -0
- agent_evolve/ports/finite_action_selection.py +348 -0
- agent_evolve/ports/finite_action_set.py +256 -0
- agent_evolve/ports/frontier_target.py +396 -0
- agent_evolve/ports/generation_failure.py +43 -0
- agent_evolve/ports/hard_feasibility.py +233 -0
- agent_evolve/ports/id_factory.py +34 -0
- agent_evolve/ports/llm_task_queue.py +93 -0
- agent_evolve/ports/objective_resolution.py +419 -0
- agent_evolve/ports/paired_allocation_comparison.py +401 -0
- agent_evolve/ports/paired_block_schedule.py +475 -0
- agent_evolve/ports/parent_measurement.py +336 -0
- agent_evolve/ports/portfolio_memory_dose.py +643 -0
- agent_evolve/ports/portfolio_selection.py +3169 -0
- agent_evolve/ports/postcommit_rank_authority.py +467 -0
- agent_evolve/ports/presented_action_evidence.py +794 -0
- agent_evolve/ports/resource_lease.py +162 -0
- agent_evolve/ports/structured_generator.py +734 -0
- agent_evolve/ports/structured_output_budget.py +120 -0
- agent_evolve/ports/subprocess_boundary.py +138 -0
- agent_evolve/ports/treatment_assignment.py +466 -0
- agent_evolve/ports/variation_catalog.py +76 -0
- agent_evolve/ports/variation_source.py +226 -0
- agent_evolve/proposal_mode.py +157 -0
- agent_evolve/proposers/__init__.py +10 -0
- agent_evolve/proposers/random_proposer.py +188 -0
- agent_evolve/provider_accounting.py +163 -0
- agent_evolve/py.typed +0 -0
- agent_evolve/reference_method.py +1570 -0
- agent_evolve/session/__init__.py +11 -0
- agent_evolve/session/authorship.py +864 -0
- agent_evolve/session/evaluate.py +236 -0
- agent_evolve/session/fidelity.py +237 -0
- agent_evolve/session/genetic_loop.py +742 -0
- agent_evolve/session/loop.py +803 -0
- agent_evolve/session/screening.py +671 -0
- agent_evolve/settings.py +376 -0
- agent_evolve/workload_kit.py +368 -0
- agent_evolve/workload_prompt.py +398 -0
- agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
- agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
- agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
- agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
- agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
- agentevolve_optimizer-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
"""Residual-hypervolume frontier cells for workload-neutral search planning.
|
|
2
|
+
|
|
3
|
+
The policy treats the already evaluated Pareto archive as a staircase with
|
|
4
|
+
potentially missing cells. It constructs outcome-blind aspiration points at
|
|
5
|
+
pairwise midpoints, then measures the exact fixed-reference hypervolume that
|
|
6
|
+
would be added if an aspiration were attained. A positive value identifies a
|
|
7
|
+
frontier gap; a zero value identifies a midpoint already dominated by the
|
|
8
|
+
archive.
|
|
9
|
+
|
|
10
|
+
Only an authenticated affine archive snapshot and already evaluated candidate
|
|
11
|
+
objectives enter this module. Candidate fields, workload names, model/provider
|
|
12
|
+
metadata, prompts, and unevaluated outcomes are deliberately outside the API.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import hashlib
|
|
18
|
+
import json
|
|
19
|
+
import math
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from itertools import combinations
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
from agent_evolve.domain.patch import require_sha256
|
|
25
|
+
from agent_evolve.domain.typed_json import thaw_json
|
|
26
|
+
from agent_evolve.policies.reward.affine_hypervolume_3d import hypervolume_3d
|
|
27
|
+
from agent_evolve.policies.reward.frozen_archive import hypervolume_2d
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
31
|
+
from agent_evolve.application.evolution_campaign import ArchiveUtilitySnapshot
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
RESIDUAL_FRONTIER_POLICY_ID = "residual_hypervolume_frontier_cells"
|
|
35
|
+
RESIDUAL_FRONTIER_POLICY_VERSION = 1
|
|
36
|
+
RESIDUAL_FRONTIER_POLICY_DEFINITION_SHA256 = hashlib.sha256(
|
|
37
|
+
b"agent-evolve:residual-hypervolume-frontier-cells:v1;"
|
|
38
|
+
b"input=authenticated-affine-prior-archive;dimensions=2-or-3;"
|
|
39
|
+
b"aspirations=pairwise-normalized-midpoints;"
|
|
40
|
+
b"score=exact-fixed-reference-hypervolume-marginal;"
|
|
41
|
+
b"zero-or-roundoff-residuals=excluded;"
|
|
42
|
+
b"ordering=descending-residual-then-canonical-cell-identity;"
|
|
43
|
+
b"candidate-binding=objective-vector-only;"
|
|
44
|
+
b"current-future-outcomes=false;workload-model-provider-fields=false"
|
|
45
|
+
).hexdigest()
|
|
46
|
+
_CELL_DOMAIN = b"agent-evolve:residual-hypervolume-frontier-cell:v1\x00"
|
|
47
|
+
_GEOMETRY_DOMAIN = b"agent-evolve:residual-hypervolume-frontier-geometry:v1\x00"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _canonical_json(value: object) -> bytes:
|
|
51
|
+
return json.dumps(
|
|
52
|
+
value,
|
|
53
|
+
allow_nan=False,
|
|
54
|
+
ensure_ascii=True,
|
|
55
|
+
separators=(",", ":"),
|
|
56
|
+
sort_keys=True,
|
|
57
|
+
).encode("ascii", errors="strict")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _decimal(value: float) -> str:
|
|
61
|
+
if type(value) is not float or not math.isfinite(value):
|
|
62
|
+
raise TypeError("residual-frontier values must be finite exact floats")
|
|
63
|
+
return format(0.0 if value == 0.0 else value, ".17g")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _finite_hex(value: object, *, name: str) -> float:
|
|
67
|
+
if type(value) is not str:
|
|
68
|
+
raise TypeError(f"{name} must be canonical binary64 hex text")
|
|
69
|
+
try:
|
|
70
|
+
result = float.fromhex(value)
|
|
71
|
+
except ValueError as error:
|
|
72
|
+
raise ValueError(f"{name} must be canonical binary64 hex text") from error
|
|
73
|
+
if not math.isfinite(result) or result.hex() != value:
|
|
74
|
+
raise ValueError(f"{name} must be a canonical finite binary64 value")
|
|
75
|
+
return result
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _hypervolume(points: tuple[tuple[float, ...], ...]) -> float:
|
|
79
|
+
if not points:
|
|
80
|
+
return 0.0
|
|
81
|
+
dimension = len(points[0])
|
|
82
|
+
if dimension == 2:
|
|
83
|
+
return hypervolume_2d(points, (1.0, 1.0)) # type: ignore[arg-type]
|
|
84
|
+
if dimension == 3:
|
|
85
|
+
return hypervolume_3d(points, (1.0, 1.0, 1.0)) # type: ignore[arg-type]
|
|
86
|
+
raise ValueError("residual-frontier hypervolume supports only 2-D or 3-D")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@dataclass(frozen=True, slots=True)
|
|
90
|
+
class ResidualFrontierAxis:
|
|
91
|
+
metric_id: str
|
|
92
|
+
goal: str
|
|
93
|
+
ideal: float
|
|
94
|
+
reference: float
|
|
95
|
+
|
|
96
|
+
def __post_init__(self) -> None:
|
|
97
|
+
if type(self.metric_id) is not str or not self.metric_id:
|
|
98
|
+
raise ValueError("residual-frontier metric_id must be non-empty")
|
|
99
|
+
if self.goal not in {"min", "max"}:
|
|
100
|
+
raise ValueError("residual-frontier goal must be min or max")
|
|
101
|
+
for name in ("ideal", "reference"):
|
|
102
|
+
value = getattr(self, name)
|
|
103
|
+
if type(value) is not float or not math.isfinite(value):
|
|
104
|
+
raise TypeError(f"{name} must be a finite exact float")
|
|
105
|
+
if self.goal == "min" and not self.reference > self.ideal:
|
|
106
|
+
raise ValueError("minimization reference must exceed ideal")
|
|
107
|
+
if self.goal == "max" and not self.ideal > self.reference:
|
|
108
|
+
raise ValueError("maximization ideal must exceed reference")
|
|
109
|
+
|
|
110
|
+
def normalize(self, value: float) -> float:
|
|
111
|
+
self.__post_init__()
|
|
112
|
+
if type(value) is not float or not math.isfinite(value):
|
|
113
|
+
raise TypeError("objective value must be a finite exact float")
|
|
114
|
+
if self.goal == "min":
|
|
115
|
+
return (value - self.ideal) / (self.reference - self.ideal)
|
|
116
|
+
return (self.ideal - value) / (self.ideal - self.reference)
|
|
117
|
+
|
|
118
|
+
def denormalize(self, value: float) -> float:
|
|
119
|
+
"""Map lower-is-better affine coordinates back to metric space.
|
|
120
|
+
|
|
121
|
+
This is the exact inverse of :meth:`normalize` for both minimization
|
|
122
|
+
and maximization axes. Keeping the inverse on the authenticated axis
|
|
123
|
+
prevents target allocators and prompt adapters from reimplementing
|
|
124
|
+
orientation-sensitive arithmetic.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
self.__post_init__()
|
|
128
|
+
if type(value) is not float or not math.isfinite(value):
|
|
129
|
+
raise TypeError("normalized objective must be a finite exact float")
|
|
130
|
+
return self.ideal + value * (self.reference - self.ideal)
|
|
131
|
+
|
|
132
|
+
def to_record(self) -> dict[str, str]:
|
|
133
|
+
self.__post_init__()
|
|
134
|
+
return {
|
|
135
|
+
"metric_id": self.metric_id,
|
|
136
|
+
"goal": self.goal,
|
|
137
|
+
"ideal_hex": self.ideal.hex(),
|
|
138
|
+
"reference_hex": self.reference.hex(),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass(frozen=True, slots=True)
|
|
143
|
+
class ResidualFrontierCell:
|
|
144
|
+
anchor_points: tuple[tuple[float, ...], tuple[float, ...]]
|
|
145
|
+
aspiration_point: tuple[float, ...]
|
|
146
|
+
potential_hypervolume_gain: float
|
|
147
|
+
cell_sha256: str = field(init=False)
|
|
148
|
+
|
|
149
|
+
def __post_init__(self) -> None:
|
|
150
|
+
if type(self.anchor_points) is not tuple or len(self.anchor_points) != 2:
|
|
151
|
+
raise TypeError("residual cell requires exactly two anchor points")
|
|
152
|
+
dimension = len(self.anchor_points[0])
|
|
153
|
+
if dimension not in (2, 3):
|
|
154
|
+
raise ValueError("residual cell supports only 2-D or 3-D")
|
|
155
|
+
if self.anchor_points != tuple(sorted(set(self.anchor_points))):
|
|
156
|
+
raise ValueError("residual cell anchors must be unique and canonical")
|
|
157
|
+
for point in (*self.anchor_points, self.aspiration_point):
|
|
158
|
+
if type(point) is not tuple or len(point) != dimension:
|
|
159
|
+
raise TypeError("residual cell points must share one dimension")
|
|
160
|
+
if any(type(value) is not float or not math.isfinite(value) for value in point):
|
|
161
|
+
raise TypeError("residual cell points must contain finite exact floats")
|
|
162
|
+
expected = tuple(
|
|
163
|
+
(left + right) / 2.0
|
|
164
|
+
for left, right in zip(*self.anchor_points, strict=True)
|
|
165
|
+
)
|
|
166
|
+
if self.aspiration_point != expected:
|
|
167
|
+
raise ValueError("residual aspiration must be the exact anchor midpoint")
|
|
168
|
+
if (
|
|
169
|
+
type(self.potential_hypervolume_gain) is not float
|
|
170
|
+
or not math.isfinite(self.potential_hypervolume_gain)
|
|
171
|
+
or self.potential_hypervolume_gain <= 0.0
|
|
172
|
+
):
|
|
173
|
+
raise ValueError("residual cell must carry positive finite opportunity")
|
|
174
|
+
object.__setattr__(
|
|
175
|
+
self,
|
|
176
|
+
"cell_sha256",
|
|
177
|
+
hashlib.sha256(_CELL_DOMAIN + _canonical_json(self._unsigned_record())).hexdigest(),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
181
|
+
return {
|
|
182
|
+
"schema_version": 1,
|
|
183
|
+
"anchor_points_hex": [
|
|
184
|
+
[value.hex() for value in point] for point in self.anchor_points
|
|
185
|
+
],
|
|
186
|
+
"aspiration_point_hex": [value.hex() for value in self.aspiration_point],
|
|
187
|
+
"potential_hypervolume_gain_hex": self.potential_hypervolume_gain.hex(),
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
def to_record(self) -> dict[str, object]:
|
|
191
|
+
self.__post_init__()
|
|
192
|
+
return {**self._unsigned_record(), "cell_sha256": self.cell_sha256}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@dataclass(frozen=True, slots=True)
|
|
196
|
+
class ResidualFrontierGeometry:
|
|
197
|
+
archive_utility_snapshot_sha256: str
|
|
198
|
+
axes: tuple[ResidualFrontierAxis, ...]
|
|
199
|
+
normalized_archive_points: tuple[tuple[float, ...], ...]
|
|
200
|
+
base_hypervolume: float
|
|
201
|
+
cells: tuple[ResidualFrontierCell, ...]
|
|
202
|
+
geometry_sha256: str = field(init=False)
|
|
203
|
+
|
|
204
|
+
def __post_init__(self) -> None:
|
|
205
|
+
require_sha256(
|
|
206
|
+
self.archive_utility_snapshot_sha256,
|
|
207
|
+
"archive_utility_snapshot_sha256",
|
|
208
|
+
)
|
|
209
|
+
if type(self.axes) is not tuple or len(self.axes) not in (2, 3):
|
|
210
|
+
raise TypeError("residual geometry requires two or three axes")
|
|
211
|
+
for axis in self.axes:
|
|
212
|
+
if type(axis) is not ResidualFrontierAxis:
|
|
213
|
+
raise TypeError("residual geometry axes must be exact")
|
|
214
|
+
axis.__post_init__()
|
|
215
|
+
if len({axis.metric_id for axis in self.axes}) != len(self.axes):
|
|
216
|
+
raise ValueError("residual geometry axes must be unique")
|
|
217
|
+
dimension = len(self.axes)
|
|
218
|
+
if (
|
|
219
|
+
type(self.normalized_archive_points) is not tuple
|
|
220
|
+
or not self.normalized_archive_points
|
|
221
|
+
or self.normalized_archive_points
|
|
222
|
+
!= tuple(sorted(set(self.normalized_archive_points)))
|
|
223
|
+
):
|
|
224
|
+
raise ValueError("normalized archive points must be non-empty and canonical")
|
|
225
|
+
for point in self.normalized_archive_points:
|
|
226
|
+
if type(point) is not tuple or len(point) != dimension:
|
|
227
|
+
raise TypeError("normalized archive point dimension differs")
|
|
228
|
+
if any(type(value) is not float or not math.isfinite(value) for value in point):
|
|
229
|
+
raise TypeError("normalized archive points must be finite")
|
|
230
|
+
if (
|
|
231
|
+
type(self.base_hypervolume) is not float
|
|
232
|
+
or not math.isfinite(self.base_hypervolume)
|
|
233
|
+
or self.base_hypervolume < 0.0
|
|
234
|
+
):
|
|
235
|
+
raise ValueError("base_hypervolume must be finite and non-negative")
|
|
236
|
+
if not math.isclose(
|
|
237
|
+
self.base_hypervolume,
|
|
238
|
+
_hypervolume(self.normalized_archive_points),
|
|
239
|
+
rel_tol=0.0,
|
|
240
|
+
abs_tol=64.0 * math.ulp(max(1.0, self.base_hypervolume)),
|
|
241
|
+
):
|
|
242
|
+
raise ValueError("residual geometry base hypervolume is inconsistent")
|
|
243
|
+
if type(self.cells) is not tuple:
|
|
244
|
+
raise TypeError("residual cells must be an exact tuple")
|
|
245
|
+
for cell in self.cells:
|
|
246
|
+
if type(cell) is not ResidualFrontierCell:
|
|
247
|
+
raise TypeError("residual cells must contain exact values")
|
|
248
|
+
cell.__post_init__()
|
|
249
|
+
expected_cells = tuple(
|
|
250
|
+
sorted(
|
|
251
|
+
self.cells,
|
|
252
|
+
key=lambda value: (
|
|
253
|
+
-value.potential_hypervolume_gain,
|
|
254
|
+
value.cell_sha256,
|
|
255
|
+
),
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
if self.cells != expected_cells or len({cell.cell_sha256 for cell in self.cells}) != len(self.cells):
|
|
259
|
+
raise ValueError("residual cells must be unique and opportunity ordered")
|
|
260
|
+
object.__setattr__(
|
|
261
|
+
self,
|
|
262
|
+
"geometry_sha256",
|
|
263
|
+
hashlib.sha256(
|
|
264
|
+
_GEOMETRY_DOMAIN + _canonical_json(self._unsigned_record())
|
|
265
|
+
).hexdigest(),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
269
|
+
return {
|
|
270
|
+
"schema_version": 1,
|
|
271
|
+
"policy": {
|
|
272
|
+
"policy_id": RESIDUAL_FRONTIER_POLICY_ID,
|
|
273
|
+
"policy_version": RESIDUAL_FRONTIER_POLICY_VERSION,
|
|
274
|
+
"definition_sha256": RESIDUAL_FRONTIER_POLICY_DEFINITION_SHA256,
|
|
275
|
+
},
|
|
276
|
+
"archive_utility_snapshot_sha256": self.archive_utility_snapshot_sha256,
|
|
277
|
+
"axes": [axis.to_record() for axis in self.axes],
|
|
278
|
+
"normalized_archive_points_hex": [
|
|
279
|
+
[value.hex() for value in point]
|
|
280
|
+
for point in self.normalized_archive_points
|
|
281
|
+
],
|
|
282
|
+
"base_hypervolume_hex": self.base_hypervolume.hex(),
|
|
283
|
+
"cells": [cell.to_record() for cell in self.cells],
|
|
284
|
+
"current_or_future_candidate_outcomes_consulted": False,
|
|
285
|
+
"workload_model_provider_fields_consulted": False,
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
def to_record(self) -> dict[str, object]:
|
|
289
|
+
self.__post_init__()
|
|
290
|
+
return {**self._unsigned_record(), "geometry_sha256": self.geometry_sha256}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def residual_frontier_geometry(
|
|
294
|
+
archive_utility: ArchiveUtilitySnapshot,
|
|
295
|
+
) -> ResidualFrontierGeometry:
|
|
296
|
+
"""Project exact positive midpoint residuals from one prior archive."""
|
|
297
|
+
|
|
298
|
+
from agent_evolve.application.evolution_campaign import ArchiveUtilitySnapshot
|
|
299
|
+
|
|
300
|
+
if type(archive_utility) is not ArchiveUtilitySnapshot:
|
|
301
|
+
raise TypeError("archive_utility must be an exact snapshot")
|
|
302
|
+
archive_utility.__post_init__()
|
|
303
|
+
snapshot = thaw_json(archive_utility.snapshot_receipt)
|
|
304
|
+
if type(snapshot) is not dict:
|
|
305
|
+
raise TypeError("affine archive snapshot must thaw to an object")
|
|
306
|
+
if snapshot.get("definition_sha256") != archive_utility.definition_sha256:
|
|
307
|
+
raise ValueError("affine snapshot definition differs from outer utility")
|
|
308
|
+
spec = snapshot.get("spec")
|
|
309
|
+
raw_axes = spec.get("axes") if type(spec) is dict else None
|
|
310
|
+
raw_points = snapshot.get("normalized_archive_points")
|
|
311
|
+
if type(raw_axes) is not list or len(raw_axes) not in (2, 3):
|
|
312
|
+
raise ValueError("residual-frontier utility requires affine 2-D or 3-D axes")
|
|
313
|
+
if type(raw_points) is not list or not raw_points:
|
|
314
|
+
raise ValueError("residual-frontier utility requires archive points")
|
|
315
|
+
axes: list[ResidualFrontierAxis] = []
|
|
316
|
+
for index, raw in enumerate(raw_axes):
|
|
317
|
+
if type(raw) is not dict:
|
|
318
|
+
raise TypeError(f"axis[{index}] must be an object")
|
|
319
|
+
metric_id = raw.get("metric_id")
|
|
320
|
+
goal = raw.get("goal")
|
|
321
|
+
if type(metric_id) is not str or goal not in {"min", "max"}:
|
|
322
|
+
raise ValueError(f"axis[{index}] is malformed")
|
|
323
|
+
axes.append(
|
|
324
|
+
ResidualFrontierAxis(
|
|
325
|
+
metric_id=metric_id,
|
|
326
|
+
goal=goal,
|
|
327
|
+
ideal=_finite_hex(raw.get("ideal_hex"), name=f"axis[{index}].ideal"),
|
|
328
|
+
reference=_finite_hex(
|
|
329
|
+
raw.get("reference_hex"),
|
|
330
|
+
name=f"axis[{index}].reference",
|
|
331
|
+
),
|
|
332
|
+
)
|
|
333
|
+
)
|
|
334
|
+
dimension = len(axes)
|
|
335
|
+
points = tuple(
|
|
336
|
+
sorted(
|
|
337
|
+
{
|
|
338
|
+
tuple(
|
|
339
|
+
_finite_hex(value, name=f"point[{row_index}][{axis_index}]")
|
|
340
|
+
for axis_index, value in enumerate(row)
|
|
341
|
+
)
|
|
342
|
+
for row_index, row in enumerate(raw_points)
|
|
343
|
+
if type(row) is list and len(row) == dimension
|
|
344
|
+
}
|
|
345
|
+
)
|
|
346
|
+
)
|
|
347
|
+
if len(points) != len(raw_points):
|
|
348
|
+
raise ValueError("normalized archive points are malformed or duplicated")
|
|
349
|
+
base = _hypervolume(points)
|
|
350
|
+
recorded_base = _finite_hex(
|
|
351
|
+
snapshot.get("base_hypervolume_hex"),
|
|
352
|
+
name="base_hypervolume",
|
|
353
|
+
)
|
|
354
|
+
tolerance = 64.0 * math.ulp(max(1.0, base, recorded_base))
|
|
355
|
+
if not math.isclose(base, recorded_base, rel_tol=0.0, abs_tol=tolerance):
|
|
356
|
+
raise ValueError("recorded affine hypervolume differs from exact projection")
|
|
357
|
+
cells: list[ResidualFrontierCell] = []
|
|
358
|
+
for left, right in combinations(points, 2):
|
|
359
|
+
aspiration = tuple(
|
|
360
|
+
(first + second) / 2.0
|
|
361
|
+
for first, second in zip(left, right, strict=True)
|
|
362
|
+
)
|
|
363
|
+
gain = max(0.0, _hypervolume((*points, aspiration)) - base)
|
|
364
|
+
if gain <= tolerance:
|
|
365
|
+
continue
|
|
366
|
+
cells.append(
|
|
367
|
+
ResidualFrontierCell(
|
|
368
|
+
anchor_points=(left, right),
|
|
369
|
+
aspiration_point=aspiration,
|
|
370
|
+
potential_hypervolume_gain=float(gain),
|
|
371
|
+
)
|
|
372
|
+
)
|
|
373
|
+
return ResidualFrontierGeometry(
|
|
374
|
+
archive_utility_snapshot_sha256=archive_utility.snapshot_sha256,
|
|
375
|
+
axes=tuple(axes),
|
|
376
|
+
normalized_archive_points=points,
|
|
377
|
+
base_hypervolume=float(base),
|
|
378
|
+
cells=tuple(
|
|
379
|
+
sorted(
|
|
380
|
+
cells,
|
|
381
|
+
key=lambda value: (
|
|
382
|
+
-value.potential_hypervolume_gain,
|
|
383
|
+
value.cell_sha256,
|
|
384
|
+
),
|
|
385
|
+
)
|
|
386
|
+
),
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def normalized_candidate_point(
|
|
391
|
+
geometry: ResidualFrontierGeometry,
|
|
392
|
+
candidate: EvolutionCandidate,
|
|
393
|
+
) -> tuple[float, ...]:
|
|
394
|
+
"""Bind an evaluated candidate to the same normalized affine frame."""
|
|
395
|
+
|
|
396
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
397
|
+
|
|
398
|
+
if type(geometry) is not ResidualFrontierGeometry:
|
|
399
|
+
raise TypeError("geometry must be exact ResidualFrontierGeometry")
|
|
400
|
+
geometry.__post_init__()
|
|
401
|
+
if type(candidate) is not EvolutionCandidate:
|
|
402
|
+
raise TypeError("candidate must be an exact EvolutionCandidate")
|
|
403
|
+
candidate.__post_init__()
|
|
404
|
+
objectives = candidate.objective_map
|
|
405
|
+
metric_ids = tuple(axis.metric_id for axis in geometry.axes)
|
|
406
|
+
if set(objectives) != set(metric_ids):
|
|
407
|
+
raise ValueError("candidate objectives differ from residual-frontier axes")
|
|
408
|
+
return tuple(
|
|
409
|
+
axis.normalize(float(objectives[axis.metric_id])) for axis in geometry.axes
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def residual_anchor_parents(
|
|
414
|
+
*,
|
|
415
|
+
geometry: ResidualFrontierGeometry,
|
|
416
|
+
candidates: tuple[EvolutionCandidate, ...],
|
|
417
|
+
) -> tuple[EvolutionCandidate, EvolutionCandidate] | None:
|
|
418
|
+
"""Return distinct evaluated parents nearest the best residual anchors."""
|
|
419
|
+
|
|
420
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
421
|
+
|
|
422
|
+
if type(geometry) is not ResidualFrontierGeometry:
|
|
423
|
+
raise TypeError("geometry must be exact ResidualFrontierGeometry")
|
|
424
|
+
geometry.__post_init__()
|
|
425
|
+
if type(candidates) is not tuple or any(
|
|
426
|
+
type(value) is not EvolutionCandidate for value in candidates
|
|
427
|
+
):
|
|
428
|
+
raise TypeError("candidates must contain exact EvolutionCandidate values")
|
|
429
|
+
if len(candidates) < 2:
|
|
430
|
+
return None
|
|
431
|
+
if not geometry.cells:
|
|
432
|
+
return None
|
|
433
|
+
rows = tuple((candidate, normalized_candidate_point(geometry, candidate)) for candidate in candidates)
|
|
434
|
+
anchors = geometry.cells[0].anchor_points
|
|
435
|
+
best: tuple[float, tuple[str, str], tuple[EvolutionCandidate, EvolutionCandidate]] | None = None
|
|
436
|
+
for left, right in combinations(rows, 2):
|
|
437
|
+
for ordered in ((left, right), (right, left)):
|
|
438
|
+
distance = sum(
|
|
439
|
+
abs(value - target)
|
|
440
|
+
for (_, point), anchor in zip(ordered, anchors, strict=True)
|
|
441
|
+
for value, target in zip(point, anchor, strict=True)
|
|
442
|
+
)
|
|
443
|
+
parents = (ordered[0][0], ordered[1][0])
|
|
444
|
+
identities = tuple(parent.occurrence.configuration_hash for parent in parents)
|
|
445
|
+
proposal = (distance, identities, parents)
|
|
446
|
+
if best is None or proposal[:2] < best[:2]:
|
|
447
|
+
best = proposal
|
|
448
|
+
if best is None: # pragma: no cover - combinations guarantee a value.
|
|
449
|
+
return None
|
|
450
|
+
return best[2]
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
__all__ = [
|
|
454
|
+
"RESIDUAL_FRONTIER_POLICY_DEFINITION_SHA256",
|
|
455
|
+
"RESIDUAL_FRONTIER_POLICY_ID",
|
|
456
|
+
"RESIDUAL_FRONTIER_POLICY_VERSION",
|
|
457
|
+
"ResidualFrontierAxis",
|
|
458
|
+
"ResidualFrontierCell",
|
|
459
|
+
"ResidualFrontierGeometry",
|
|
460
|
+
"normalized_candidate_point",
|
|
461
|
+
"residual_anchor_parents",
|
|
462
|
+
"residual_frontier_geometry",
|
|
463
|
+
]
|