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,567 @@
|
|
|
1
|
+
"""Exact scale-invariant fixed-reference hypervolume for three objectives.
|
|
2
|
+
|
|
3
|
+
This module is the three-dimensional counterpart of
|
|
4
|
+
``affine_hypervolume``. It is deliberately workload-neutral: a composition
|
|
5
|
+
root supplies three metric identifiers, their optimization senses, and a
|
|
6
|
+
prospectively fixed ideal/reference box. The implementation then exposes one
|
|
7
|
+
authenticated utility definition and replayable archive snapshots.
|
|
8
|
+
|
|
9
|
+
All axes are oriented to minimization and normalized so that the ideal is
|
|
10
|
+
zero and the reference is one. Hypervolume is computed exactly (up to IEEE
|
|
11
|
+
754 arithmetic) by sweeping the first axis and reusing the exact 2-D union
|
|
12
|
+
area on each slab. Duplicate, dominated, and out-of-reference points do not
|
|
13
|
+
change the measure.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import hashlib
|
|
19
|
+
import json
|
|
20
|
+
import math
|
|
21
|
+
from collections.abc import Mapping, Sequence
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
from numbers import Real
|
|
24
|
+
|
|
25
|
+
from agent_evolve.application.evolution_campaign import ArchiveUtilitySnapshot
|
|
26
|
+
from agent_evolve.domain.typed_json import (
|
|
27
|
+
FrozenJsonObject,
|
|
28
|
+
freeze_json,
|
|
29
|
+
thaw_json,
|
|
30
|
+
typed_json_sha256,
|
|
31
|
+
)
|
|
32
|
+
from agent_evolve.policies.reward.affine_hypervolume import (
|
|
33
|
+
AffineHypervolumeWaveRewardRecord,
|
|
34
|
+
AffineObjectiveAxis,
|
|
35
|
+
AffineWaveRewardCandidate,
|
|
36
|
+
)
|
|
37
|
+
from agent_evolve.policies.reward.frozen_archive import hypervolume_2d
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
_DEFINITION_DOMAIN = b"agent-evolve:affine-hypervolume-3d-definition:v1\x00"
|
|
41
|
+
_SNAPSHOT_DOMAIN = b"agent-evolve:affine-hypervolume-3d-snapshot:v1\x00"
|
|
42
|
+
_REFERENCE_ENVELOPE_DOMAIN = (
|
|
43
|
+
b"agent-evolve:affine-hypervolume-3d-reference-envelope:v1\x00"
|
|
44
|
+
)
|
|
45
|
+
_UTILITY_ID = "affine_fixed_reference_hypervolume_3d"
|
|
46
|
+
_UTILITY_VERSION = 1
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _canonical_json(value: object) -> bytes:
|
|
50
|
+
return json.dumps(
|
|
51
|
+
value,
|
|
52
|
+
ensure_ascii=True,
|
|
53
|
+
allow_nan=False,
|
|
54
|
+
separators=(",", ":"),
|
|
55
|
+
sort_keys=True,
|
|
56
|
+
).encode("ascii", errors="strict")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _finite(value: Real, *, name: str) -> float:
|
|
60
|
+
if isinstance(value, bool) or not isinstance(value, Real):
|
|
61
|
+
raise TypeError(f"{name} must be a real number")
|
|
62
|
+
result = float(value)
|
|
63
|
+
if not math.isfinite(result):
|
|
64
|
+
raise ValueError(f"{name} must be finite")
|
|
65
|
+
return result
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _object(value: dict[str, object]) -> FrozenJsonObject:
|
|
69
|
+
result = freeze_json(value)
|
|
70
|
+
if type(result) is not FrozenJsonObject: # pragma: no cover - closed root.
|
|
71
|
+
raise AssertionError("affine 3-D hypervolume record is not an object")
|
|
72
|
+
return result
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def hypervolume_3d(
|
|
76
|
+
points: Sequence[tuple[Real, Real, Real]],
|
|
77
|
+
reference_point: tuple[Real, Real, Real],
|
|
78
|
+
) -> float:
|
|
79
|
+
"""Return the union volume dominated by a minimization point set.
|
|
80
|
+
|
|
81
|
+
A point contributes only when it strictly improves every reference
|
|
82
|
+
coordinate. The first-axis sweep partitions the union into disjoint
|
|
83
|
+
slabs; within each slab :func:`hypervolume_2d` computes the active union
|
|
84
|
+
area. This is deterministic and exact for the small campaign archives
|
|
85
|
+
AgentEvolve uses.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
if type(reference_point) is not tuple or len(reference_point) != 3:
|
|
89
|
+
raise TypeError("reference_point must be an exact three-item tuple")
|
|
90
|
+
if isinstance(points, (str, bytes)) or not isinstance(points, Sequence):
|
|
91
|
+
raise TypeError("points must be a sequence of exact three-item tuples")
|
|
92
|
+
reference = tuple(
|
|
93
|
+
_finite(value, name=f"reference_point[{index}]")
|
|
94
|
+
for index, value in enumerate(reference_point)
|
|
95
|
+
)
|
|
96
|
+
canonical: list[tuple[float, float, float]] = []
|
|
97
|
+
for index, point in enumerate(points):
|
|
98
|
+
if type(point) is not tuple or len(point) != 3:
|
|
99
|
+
raise TypeError(f"points[{index}] must be an exact three-item tuple")
|
|
100
|
+
canonical.append(
|
|
101
|
+
tuple(
|
|
102
|
+
_finite(value, name=f"points[{index}][{axis}]")
|
|
103
|
+
for axis, value in enumerate(point)
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
eligible = tuple(
|
|
107
|
+
point
|
|
108
|
+
for point in sorted(set(canonical))
|
|
109
|
+
if all(point[index] < reference[index] for index in range(3))
|
|
110
|
+
)
|
|
111
|
+
if not eligible:
|
|
112
|
+
return 0.0
|
|
113
|
+
boundaries = (*sorted({point[0] for point in eligible}), reference[0])
|
|
114
|
+
volume = 0.0
|
|
115
|
+
for lower, upper in zip(boundaries, boundaries[1:]):
|
|
116
|
+
active = tuple(
|
|
117
|
+
(point[1], point[2]) for point in eligible if point[0] <= lower
|
|
118
|
+
)
|
|
119
|
+
volume += (upper - lower) * hypervolume_2d(
|
|
120
|
+
active,
|
|
121
|
+
(reference[1], reference[2]),
|
|
122
|
+
)
|
|
123
|
+
if volume < 0 or not math.isfinite(volume): # pragma: no cover - sweep guard.
|
|
124
|
+
raise RuntimeError("3-D hypervolume sweep produced an invalid volume")
|
|
125
|
+
return volume
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclass(frozen=True, slots=True)
|
|
129
|
+
class AffineHypervolume3DSpec:
|
|
130
|
+
"""Complete immutable definition of a dimensionless 3-D indicator."""
|
|
131
|
+
|
|
132
|
+
axes: tuple[AffineObjectiveAxis, AffineObjectiveAxis, AffineObjectiveAxis]
|
|
133
|
+
reference_provenance: str
|
|
134
|
+
|
|
135
|
+
def __post_init__(self) -> None:
|
|
136
|
+
if type(self.axes) is not tuple or len(self.axes) != 3 or any(
|
|
137
|
+
type(axis) is not AffineObjectiveAxis for axis in self.axes
|
|
138
|
+
):
|
|
139
|
+
raise TypeError("axes must contain exactly three AffineObjectiveAxis values")
|
|
140
|
+
for axis in self.axes:
|
|
141
|
+
AffineObjectiveAxis.__post_init__(axis)
|
|
142
|
+
if len({axis.metric_id for axis in self.axes}) != 3:
|
|
143
|
+
raise ValueError("affine hypervolume axes must name distinct metrics")
|
|
144
|
+
if (
|
|
145
|
+
type(self.reference_provenance) is not str
|
|
146
|
+
or not self.reference_provenance.strip()
|
|
147
|
+
or self.reference_provenance != self.reference_provenance.strip()
|
|
148
|
+
):
|
|
149
|
+
raise ValueError("reference_provenance must be canonical non-empty text")
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def metric_ids(self) -> tuple[str, str, str]:
|
|
153
|
+
return tuple(axis.metric_id for axis in self.axes) # type: ignore[return-value]
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def raw_volume_scale(self) -> float:
|
|
157
|
+
return math.prod(axis.span for axis in self.axes)
|
|
158
|
+
|
|
159
|
+
def to_record(self) -> dict[str, object]:
|
|
160
|
+
self.__post_init__()
|
|
161
|
+
return {
|
|
162
|
+
"schema_version": 1,
|
|
163
|
+
"indicator": "exact_affine_normalized_three_objective_hypervolume",
|
|
164
|
+
"axes": [axis.to_record() for axis in self.axes],
|
|
165
|
+
"normalized_reference": ["0x1.0000000000000p+0"] * 3,
|
|
166
|
+
"raw_volume_scale_hex": self.raw_volume_scale.hex(),
|
|
167
|
+
"reference_provenance": self.reference_provenance,
|
|
168
|
+
"out_of_reference_points": "zero_measure_clipped_by_hypervolume_sweep",
|
|
169
|
+
"algorithm": "first_axis_exact_slab_sweep_with_exact_2d_union",
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def definition_sha256(self) -> str:
|
|
174
|
+
return hashlib.sha256(
|
|
175
|
+
_DEFINITION_DOMAIN + _canonical_json(self.to_record())
|
|
176
|
+
).hexdigest()
|
|
177
|
+
|
|
178
|
+
def normalize(self, point: Mapping[str, Real]) -> tuple[float, float, float]:
|
|
179
|
+
if not isinstance(point, Mapping):
|
|
180
|
+
raise TypeError("objective point must be a mapping")
|
|
181
|
+
if set(point) != set(self.metric_ids):
|
|
182
|
+
raise ValueError("objective point differs from the affine metric set")
|
|
183
|
+
return tuple(
|
|
184
|
+
axis.normalize(point[axis.metric_id]) for axis in self.axes
|
|
185
|
+
) # type: ignore[return-value]
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def audit_affine_reference_envelope_3d(
|
|
189
|
+
*,
|
|
190
|
+
spec: AffineHypervolume3DSpec,
|
|
191
|
+
points: Sequence[Mapping[str, Real]],
|
|
192
|
+
evidence_identity_sha256: str,
|
|
193
|
+
) -> dict[str, object]:
|
|
194
|
+
"""Authenticate whether a fixed reference strictly contains evidence.
|
|
195
|
+
|
|
196
|
+
Filesystem provenance remains a workload-adapter responsibility. This
|
|
197
|
+
workload-neutral boundary binds the adapter's evidence identity to the
|
|
198
|
+
exact objective values, reports per-axis headroom, and makes a failed
|
|
199
|
+
containment gate explicit before an optimization campaign starts.
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
if type(spec) is not AffineHypervolume3DSpec:
|
|
203
|
+
raise TypeError("spec must be an exact AffineHypervolume3DSpec")
|
|
204
|
+
spec.__post_init__()
|
|
205
|
+
if isinstance(points, (str, bytes)) or not isinstance(points, Sequence):
|
|
206
|
+
raise TypeError("points must be a sequence of objective mappings")
|
|
207
|
+
if not points:
|
|
208
|
+
raise ValueError("reference-envelope evidence must not be empty")
|
|
209
|
+
if (
|
|
210
|
+
type(evidence_identity_sha256) is not str
|
|
211
|
+
or len(evidence_identity_sha256) != 64
|
|
212
|
+
or any(value not in "0123456789abcdef" for value in evidence_identity_sha256)
|
|
213
|
+
):
|
|
214
|
+
raise ValueError("evidence_identity_sha256 must be lowercase SHA-256")
|
|
215
|
+
|
|
216
|
+
normalized_points: list[tuple[float, float, float]] = []
|
|
217
|
+
raw_records: list[list[list[str]]] = []
|
|
218
|
+
violations: list[dict[str, object]] = []
|
|
219
|
+
for point_index, point in enumerate(points):
|
|
220
|
+
normalized = spec.normalize(point)
|
|
221
|
+
normalized_points.append(normalized)
|
|
222
|
+
raw_records.append(
|
|
223
|
+
[
|
|
224
|
+
[axis.metric_id, float(point[axis.metric_id]).hex()]
|
|
225
|
+
for axis in spec.axes
|
|
226
|
+
]
|
|
227
|
+
)
|
|
228
|
+
outside = [
|
|
229
|
+
{
|
|
230
|
+
"metric_id": axis.metric_id,
|
|
231
|
+
"raw_value_hex": float(point[axis.metric_id]).hex(),
|
|
232
|
+
"normalized_value_hex": normalized[axis_index].hex(),
|
|
233
|
+
}
|
|
234
|
+
for axis_index, axis in enumerate(spec.axes)
|
|
235
|
+
if normalized[axis_index] >= 1.0
|
|
236
|
+
]
|
|
237
|
+
if outside:
|
|
238
|
+
violations.append(
|
|
239
|
+
{
|
|
240
|
+
"point_index": point_index,
|
|
241
|
+
"outside_axes": outside,
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
componentwise = []
|
|
246
|
+
for axis_index, axis in enumerate(spec.axes):
|
|
247
|
+
worst_index = max(
|
|
248
|
+
range(len(normalized_points)),
|
|
249
|
+
key=lambda point_index: normalized_points[point_index][axis_index],
|
|
250
|
+
)
|
|
251
|
+
worst = normalized_points[worst_index][axis_index]
|
|
252
|
+
componentwise.append(
|
|
253
|
+
{
|
|
254
|
+
"metric_id": axis.metric_id,
|
|
255
|
+
"evidence_point_index": worst_index,
|
|
256
|
+
"raw_value_hex": float(points[worst_index][axis.metric_id]).hex(),
|
|
257
|
+
"normalized_value_hex": worst.hex(),
|
|
258
|
+
"normalized_margin_to_reference_hex": (1.0 - worst).hex(),
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
record: dict[str, object] = {
|
|
263
|
+
"schema_version": 1,
|
|
264
|
+
"evidence_identity_sha256": evidence_identity_sha256,
|
|
265
|
+
"utility_definition_sha256": spec.definition_sha256,
|
|
266
|
+
"point_count": len(points),
|
|
267
|
+
"metric_ids": list(spec.metric_ids),
|
|
268
|
+
"points": raw_records,
|
|
269
|
+
"componentwise_worst": componentwise,
|
|
270
|
+
"strictly_contains_all": not violations,
|
|
271
|
+
"violations": violations,
|
|
272
|
+
}
|
|
273
|
+
record["audit_sha256"] = hashlib.sha256(
|
|
274
|
+
_REFERENCE_ENVELOPE_DOMAIN + _canonical_json(record)
|
|
275
|
+
).hexdigest()
|
|
276
|
+
return record
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
RawObjectivePoint3D = tuple[
|
|
280
|
+
tuple[str, float], tuple[str, float], tuple[str, float]
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _raw_point(
|
|
285
|
+
spec: AffineHypervolume3DSpec,
|
|
286
|
+
value: Mapping[str, Real],
|
|
287
|
+
) -> RawObjectivePoint3D:
|
|
288
|
+
spec.normalize(value)
|
|
289
|
+
return tuple(
|
|
290
|
+
(axis.metric_id, float(value[axis.metric_id])) for axis in spec.axes
|
|
291
|
+
) # type: ignore[return-value]
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _point_record(point: RawObjectivePoint3D) -> list[list[str]]:
|
|
295
|
+
return [[metric_id, value.hex()] for metric_id, value in point]
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@dataclass(frozen=True, slots=True)
|
|
299
|
+
class AffineHypervolumeSnapshot3D:
|
|
300
|
+
"""One replayable archive cutoff in raw and normalized coordinates."""
|
|
301
|
+
|
|
302
|
+
spec: AffineHypervolume3DSpec
|
|
303
|
+
raw_archive_points: tuple[RawObjectivePoint3D, ...]
|
|
304
|
+
normalized_archive_points: tuple[tuple[float, float, float], ...] = field(
|
|
305
|
+
init=False
|
|
306
|
+
)
|
|
307
|
+
base_hypervolume: float = field(init=False)
|
|
308
|
+
raw_oriented_base_hypervolume: float = field(init=False)
|
|
309
|
+
snapshot_sha256: str = field(init=False)
|
|
310
|
+
|
|
311
|
+
def __post_init__(self) -> None:
|
|
312
|
+
if type(self.spec) is not AffineHypervolume3DSpec:
|
|
313
|
+
raise TypeError("spec must be an exact AffineHypervolume3DSpec")
|
|
314
|
+
self.spec.__post_init__()
|
|
315
|
+
if type(self.raw_archive_points) is not tuple:
|
|
316
|
+
raise TypeError("raw_archive_points must be an exact tuple")
|
|
317
|
+
expected_names = self.spec.metric_ids
|
|
318
|
+
for point in self.raw_archive_points:
|
|
319
|
+
if (
|
|
320
|
+
type(point) is not tuple
|
|
321
|
+
or len(point) != 3
|
|
322
|
+
or tuple(name for name, _ in point) != expected_names
|
|
323
|
+
):
|
|
324
|
+
raise ValueError("raw archive point differs from the affine axes")
|
|
325
|
+
for name, value in point:
|
|
326
|
+
_finite(value, name=f"archive point {name}")
|
|
327
|
+
canonical = tuple(
|
|
328
|
+
sorted(
|
|
329
|
+
set(self.raw_archive_points),
|
|
330
|
+
key=lambda point: tuple(value for _, value in point),
|
|
331
|
+
)
|
|
332
|
+
)
|
|
333
|
+
if self.raw_archive_points != canonical:
|
|
334
|
+
raise ValueError("raw archive points must be unique and canonical")
|
|
335
|
+
normalized = tuple(
|
|
336
|
+
self.spec.normalize(dict(point)) for point in self.raw_archive_points
|
|
337
|
+
)
|
|
338
|
+
base = hypervolume_3d(normalized, (1.0, 1.0, 1.0))
|
|
339
|
+
object.__setattr__(self, "normalized_archive_points", normalized)
|
|
340
|
+
object.__setattr__(self, "base_hypervolume", base)
|
|
341
|
+
object.__setattr__(
|
|
342
|
+
self,
|
|
343
|
+
"raw_oriented_base_hypervolume",
|
|
344
|
+
base * self.spec.raw_volume_scale,
|
|
345
|
+
)
|
|
346
|
+
object.__setattr__(
|
|
347
|
+
self,
|
|
348
|
+
"snapshot_sha256",
|
|
349
|
+
hashlib.sha256(
|
|
350
|
+
_SNAPSHOT_DOMAIN + _canonical_json(self._unsigned_record())
|
|
351
|
+
).hexdigest(),
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
@classmethod
|
|
355
|
+
def create(
|
|
356
|
+
cls,
|
|
357
|
+
*,
|
|
358
|
+
spec: AffineHypervolume3DSpec,
|
|
359
|
+
archive_points: Sequence[Mapping[str, Real]],
|
|
360
|
+
) -> "AffineHypervolumeSnapshot3D":
|
|
361
|
+
if isinstance(archive_points, (str, bytes)) or not isinstance(
|
|
362
|
+
archive_points, Sequence
|
|
363
|
+
):
|
|
364
|
+
raise TypeError("archive_points must be a sequence")
|
|
365
|
+
points = tuple(
|
|
366
|
+
sorted(
|
|
367
|
+
{_raw_point(spec, value) for value in archive_points},
|
|
368
|
+
key=lambda point: tuple(value for _, value in point),
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
return cls(spec=spec, raw_archive_points=points)
|
|
372
|
+
|
|
373
|
+
def augmented_hypervolume(
|
|
374
|
+
self,
|
|
375
|
+
points: Sequence[Mapping[str, Real]],
|
|
376
|
+
) -> float:
|
|
377
|
+
if isinstance(points, (str, bytes)) or not isinstance(points, Sequence):
|
|
378
|
+
raise TypeError("points must be a sequence")
|
|
379
|
+
normalized = tuple(self.spec.normalize(value) for value in points)
|
|
380
|
+
return hypervolume_3d(
|
|
381
|
+
(*self.normalized_archive_points, *normalized),
|
|
382
|
+
(1.0, 1.0, 1.0),
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
def joint_gain(self, points: Sequence[Mapping[str, Real]]) -> float:
|
|
386
|
+
return max(0.0, self.augmented_hypervolume(points) - self.base_hypervolume)
|
|
387
|
+
|
|
388
|
+
def marginal_gain(self, point: Mapping[str, Real]) -> float:
|
|
389
|
+
return self.joint_gain((point,))
|
|
390
|
+
|
|
391
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
392
|
+
return {
|
|
393
|
+
"schema_version": 1,
|
|
394
|
+
"definition_sha256": self.spec.definition_sha256,
|
|
395
|
+
"spec": self.spec.to_record(),
|
|
396
|
+
"raw_archive_points": [
|
|
397
|
+
_point_record(point) for point in self.raw_archive_points
|
|
398
|
+
],
|
|
399
|
+
"normalized_archive_points": [
|
|
400
|
+
[value.hex() for value in point]
|
|
401
|
+
for point in self.normalized_archive_points
|
|
402
|
+
],
|
|
403
|
+
"base_hypervolume_hex": self.base_hypervolume.hex(),
|
|
404
|
+
"raw_oriented_base_hypervolume_hex": (
|
|
405
|
+
self.raw_oriented_base_hypervolume.hex()
|
|
406
|
+
),
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
def to_record(self) -> dict[str, object]:
|
|
410
|
+
self.__post_init__()
|
|
411
|
+
return {**self._unsigned_record(), "snapshot_sha256": self.snapshot_sha256}
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@dataclass(frozen=True, slots=True)
|
|
415
|
+
class AffineFrozenArchiveJointWaveReward3D:
|
|
416
|
+
"""Dimensionless joint gain for one fixed-cardinality 3-D wave."""
|
|
417
|
+
|
|
418
|
+
snapshot: AffineHypervolumeSnapshot3D
|
|
419
|
+
|
|
420
|
+
def __post_init__(self) -> None:
|
|
421
|
+
if type(self.snapshot) is not AffineHypervolumeSnapshot3D:
|
|
422
|
+
raise TypeError("snapshot must be exact AffineHypervolumeSnapshot3D")
|
|
423
|
+
self.snapshot.__post_init__()
|
|
424
|
+
|
|
425
|
+
@property
|
|
426
|
+
def definition_hash(self) -> str:
|
|
427
|
+
return self.snapshot.spec.definition_sha256
|
|
428
|
+
|
|
429
|
+
def record(
|
|
430
|
+
self,
|
|
431
|
+
children: Sequence[AffineWaveRewardCandidate | None],
|
|
432
|
+
) -> AffineHypervolumeWaveRewardRecord:
|
|
433
|
+
self.__post_init__()
|
|
434
|
+
if isinstance(children, (str, bytes)) or not isinstance(children, Sequence):
|
|
435
|
+
raise TypeError("children must be a sequence")
|
|
436
|
+
if not children:
|
|
437
|
+
raise ValueError("wave reward requires at least one planned member")
|
|
438
|
+
admitted = tuple(
|
|
439
|
+
child.objective_map
|
|
440
|
+
for child in children
|
|
441
|
+
if child is not None
|
|
442
|
+
and child.valid
|
|
443
|
+
and child.operator_compliant
|
|
444
|
+
and child.evidence_compliant
|
|
445
|
+
)
|
|
446
|
+
augmented = self.snapshot.augmented_hypervolume(admitted)
|
|
447
|
+
gain = max(0.0, augmented - self.snapshot.base_hypervolume)
|
|
448
|
+
return AffineHypervolumeWaveRewardRecord(
|
|
449
|
+
reward=gain,
|
|
450
|
+
raw_oriented_gain=gain * self.snapshot.spec.raw_volume_scale,
|
|
451
|
+
base_hypervolume=self.snapshot.base_hypervolume,
|
|
452
|
+
augmented_hypervolume=augmented,
|
|
453
|
+
member_count=len(children),
|
|
454
|
+
admitted_count=len(admitted),
|
|
455
|
+
snapshot_sha256=self.snapshot.snapshot_sha256,
|
|
456
|
+
definition_sha256=self.definition_hash,
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
def __call__(self, children: Sequence[AffineWaveRewardCandidate | None]) -> float:
|
|
460
|
+
return self.record(children).reward
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
@dataclass(frozen=True, slots=True)
|
|
464
|
+
class AffineHypervolumeArchiveUtility3D:
|
|
465
|
+
"""Campaign archive-utility port for one affine 3-D indicator."""
|
|
466
|
+
|
|
467
|
+
spec: AffineHypervolume3DSpec
|
|
468
|
+
utility_id: str = field(init=False, default=_UTILITY_ID)
|
|
469
|
+
utility_version: int = field(init=False, default=_UTILITY_VERSION)
|
|
470
|
+
|
|
471
|
+
@property
|
|
472
|
+
def definition_sha256(self) -> str:
|
|
473
|
+
return self.spec.definition_sha256
|
|
474
|
+
|
|
475
|
+
@staticmethod
|
|
476
|
+
def _archive_points(archive: FrozenJsonObject) -> tuple[dict[str, float], ...]:
|
|
477
|
+
value = thaw_json(archive)
|
|
478
|
+
front = value.get("front_candidates")
|
|
479
|
+
if type(front) is not list:
|
|
480
|
+
raise ValueError("campaign archive omitted front_candidates")
|
|
481
|
+
points: list[dict[str, float]] = []
|
|
482
|
+
for candidate in front:
|
|
483
|
+
if type(candidate) is not dict or type(candidate.get("objectives")) is not list:
|
|
484
|
+
raise ValueError("campaign archive candidate omitted objectives")
|
|
485
|
+
point: dict[str, float] = {}
|
|
486
|
+
for row in candidate["objectives"]:
|
|
487
|
+
if (
|
|
488
|
+
type(row) is not dict
|
|
489
|
+
or type(row.get("metric_id")) is not str
|
|
490
|
+
or type(row.get("value_hex")) is not str
|
|
491
|
+
):
|
|
492
|
+
raise ValueError("campaign archive objective row is invalid")
|
|
493
|
+
point[row["metric_id"]] = float.fromhex(row["value_hex"])
|
|
494
|
+
points.append(point)
|
|
495
|
+
return tuple(points)
|
|
496
|
+
|
|
497
|
+
def freeze(
|
|
498
|
+
self,
|
|
499
|
+
*,
|
|
500
|
+
benchmark: FrozenJsonObject,
|
|
501
|
+
generation: int,
|
|
502
|
+
archive: FrozenJsonObject,
|
|
503
|
+
) -> ArchiveUtilitySnapshot:
|
|
504
|
+
snapshot = AffineHypervolumeSnapshot3D.create(
|
|
505
|
+
spec=self.spec,
|
|
506
|
+
archive_points=self._archive_points(archive),
|
|
507
|
+
)
|
|
508
|
+
return ArchiveUtilitySnapshot(
|
|
509
|
+
utility_id=self.utility_id,
|
|
510
|
+
utility_version=self.utility_version,
|
|
511
|
+
definition_sha256=self.definition_sha256,
|
|
512
|
+
generation=generation,
|
|
513
|
+
benchmark_sha256=typed_json_sha256(benchmark),
|
|
514
|
+
archive_sha256=typed_json_sha256(archive),
|
|
515
|
+
snapshot_receipt=_object(snapshot.to_record()),
|
|
516
|
+
scalar_utility_hex=snapshot.base_hypervolume.hex(),
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
def require_snapshot(
|
|
520
|
+
self,
|
|
521
|
+
value: ArchiveUtilitySnapshot,
|
|
522
|
+
) -> AffineHypervolumeSnapshot3D:
|
|
523
|
+
if type(value) is not ArchiveUtilitySnapshot:
|
|
524
|
+
raise TypeError("value must be an exact ArchiveUtilitySnapshot")
|
|
525
|
+
value.__post_init__()
|
|
526
|
+
if (
|
|
527
|
+
value.utility_id != self.utility_id
|
|
528
|
+
or value.utility_version != self.utility_version
|
|
529
|
+
or value.definition_sha256 != self.definition_sha256
|
|
530
|
+
):
|
|
531
|
+
raise ValueError("archive utility snapshot uses a foreign affine spec")
|
|
532
|
+
record = thaw_json(value.snapshot_receipt)
|
|
533
|
+
raw = record.get("raw_archive_points")
|
|
534
|
+
if type(raw) is not list:
|
|
535
|
+
raise ValueError("affine snapshot omitted raw archive points")
|
|
536
|
+
points: list[dict[str, float]] = []
|
|
537
|
+
for item in raw:
|
|
538
|
+
if type(item) is not list:
|
|
539
|
+
raise ValueError("affine raw point is not a list")
|
|
540
|
+
point: dict[str, float] = {}
|
|
541
|
+
for pair in item:
|
|
542
|
+
if (
|
|
543
|
+
type(pair) is not list
|
|
544
|
+
or len(pair) != 2
|
|
545
|
+
or type(pair[0]) is not str
|
|
546
|
+
or type(pair[1]) is not str
|
|
547
|
+
):
|
|
548
|
+
raise ValueError("affine raw point item is invalid")
|
|
549
|
+
point[pair[0]] = float.fromhex(pair[1])
|
|
550
|
+
points.append(point)
|
|
551
|
+
replayed = AffineHypervolumeSnapshot3D.create(
|
|
552
|
+
spec=self.spec,
|
|
553
|
+
archive_points=tuple(points),
|
|
554
|
+
)
|
|
555
|
+
if replayed.to_record() != record:
|
|
556
|
+
raise ValueError("affine snapshot receipt does not replay exactly")
|
|
557
|
+
return replayed
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
__all__ = [
|
|
561
|
+
"AffineFrozenArchiveJointWaveReward3D",
|
|
562
|
+
"AffineHypervolume3DSpec",
|
|
563
|
+
"AffineHypervolumeArchiveUtility3D",
|
|
564
|
+
"AffineHypervolumeSnapshot3D",
|
|
565
|
+
"audit_affine_reference_envelope_3d",
|
|
566
|
+
"hypervolume_3d",
|
|
567
|
+
]
|