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,490 @@
|
|
|
1
|
+
"""Scale-invariant fixed-reference hypervolume for two-objective campaigns.
|
|
2
|
+
|
|
3
|
+
The policy freezes an affine, dimensionless objective transform before a
|
|
4
|
+
generation. Workloads inject only metric identifiers, optimization goals,
|
|
5
|
+
and fixed ideal/reference values; archive credit, portfolio credit, and pair
|
|
6
|
+
utility all reuse the resulting authenticated snapshot.
|
|
7
|
+
|
|
8
|
+
For a minimization axis ``u=(x-ideal)/(reference-ideal)``. For a
|
|
9
|
+
maximization axis ``u=(ideal-x)/(ideal-reference)``. In both cases the ideal
|
|
10
|
+
maps to zero, the fixed reference maps to one, and ordinary two-dimensional
|
|
11
|
+
minimization hypervolume is measured against ``(1, 1)``. This makes the
|
|
12
|
+
utility invariant to positive changes of units when the injected bounds are
|
|
13
|
+
transformed with the observations.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import hashlib
|
|
19
|
+
import json
|
|
20
|
+
import math
|
|
21
|
+
import re
|
|
22
|
+
from collections.abc import Mapping, Sequence
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from numbers import Real
|
|
25
|
+
from typing import Protocol
|
|
26
|
+
|
|
27
|
+
from agent_evolve.application.evolution_campaign import ArchiveUtilitySnapshot
|
|
28
|
+
from agent_evolve.domain.typed_json import (
|
|
29
|
+
FrozenJsonObject,
|
|
30
|
+
freeze_json,
|
|
31
|
+
thaw_json,
|
|
32
|
+
typed_json_sha256,
|
|
33
|
+
)
|
|
34
|
+
from agent_evolve.policies.reward.frozen_archive import hypervolume_2d
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
38
|
+
_DEFINITION_DOMAIN = b"agent-evolve:affine-hypervolume-2d-definition:v1\x00"
|
|
39
|
+
_SNAPSHOT_DOMAIN = b"agent-evolve:affine-hypervolume-2d-snapshot:v1\x00"
|
|
40
|
+
_UTILITY_ID = "affine_fixed_reference_hypervolume_2d"
|
|
41
|
+
_UTILITY_VERSION = 1
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _canonical_json(value: object) -> bytes:
|
|
45
|
+
return json.dumps(
|
|
46
|
+
value,
|
|
47
|
+
ensure_ascii=True,
|
|
48
|
+
allow_nan=False,
|
|
49
|
+
separators=(",", ":"),
|
|
50
|
+
sort_keys=True,
|
|
51
|
+
).encode("ascii", errors="strict")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _finite(value: Real, *, name: str) -> float:
|
|
55
|
+
if isinstance(value, bool) or not isinstance(value, Real):
|
|
56
|
+
raise TypeError(f"{name} must be a real number")
|
|
57
|
+
result = float(value)
|
|
58
|
+
if not math.isfinite(result):
|
|
59
|
+
raise ValueError(f"{name} must be finite")
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _object(value: dict[str, object]) -> FrozenJsonObject:
|
|
64
|
+
result = freeze_json(value)
|
|
65
|
+
if type(result) is not FrozenJsonObject: # pragma: no cover - closed input.
|
|
66
|
+
raise AssertionError("affine hypervolume record did not freeze as an object")
|
|
67
|
+
return result
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass(frozen=True, slots=True)
|
|
71
|
+
class AffineObjectiveAxis:
|
|
72
|
+
"""One objective's fixed affine orientation and scale."""
|
|
73
|
+
|
|
74
|
+
metric_id: str
|
|
75
|
+
goal: str
|
|
76
|
+
ideal: float
|
|
77
|
+
reference: float
|
|
78
|
+
|
|
79
|
+
def __post_init__(self) -> None:
|
|
80
|
+
if type(self.metric_id) is not str or _TOKEN.fullmatch(self.metric_id) is None:
|
|
81
|
+
raise ValueError("metric_id must use the closed token grammar")
|
|
82
|
+
if self.goal not in {"min", "max"}:
|
|
83
|
+
raise ValueError("goal must be 'min' or 'max'")
|
|
84
|
+
ideal = _finite(self.ideal, name="ideal")
|
|
85
|
+
reference = _finite(self.reference, name="reference")
|
|
86
|
+
if self.goal == "min" and not reference > ideal:
|
|
87
|
+
raise ValueError("a minimization reference must exceed its ideal")
|
|
88
|
+
if self.goal == "max" and not ideal > reference:
|
|
89
|
+
raise ValueError("a maximization ideal must exceed its reference")
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def span(self) -> float:
|
|
93
|
+
self.__post_init__()
|
|
94
|
+
return float(abs(self.reference - self.ideal))
|
|
95
|
+
|
|
96
|
+
def normalize(self, value: Real) -> float:
|
|
97
|
+
number = _finite(value, name=f"objective {self.metric_id}")
|
|
98
|
+
if self.goal == "min":
|
|
99
|
+
return (number - self.ideal) / (self.reference - self.ideal)
|
|
100
|
+
return (self.ideal - number) / (self.ideal - self.reference)
|
|
101
|
+
|
|
102
|
+
def to_record(self) -> dict[str, str]:
|
|
103
|
+
self.__post_init__()
|
|
104
|
+
return {
|
|
105
|
+
"metric_id": self.metric_id,
|
|
106
|
+
"goal": self.goal,
|
|
107
|
+
"ideal_hex": float(self.ideal).hex(),
|
|
108
|
+
"reference_hex": float(self.reference).hex(),
|
|
109
|
+
"span_hex": self.span.hex(),
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True, slots=True)
|
|
114
|
+
class AffineHypervolume2DSpec:
|
|
115
|
+
"""Complete immutable definition of a dimensionless 2-D indicator."""
|
|
116
|
+
|
|
117
|
+
axes: tuple[AffineObjectiveAxis, AffineObjectiveAxis]
|
|
118
|
+
reference_provenance: str
|
|
119
|
+
|
|
120
|
+
def __post_init__(self) -> None:
|
|
121
|
+
if type(self.axes) is not tuple or len(self.axes) != 2 or any(
|
|
122
|
+
type(axis) is not AffineObjectiveAxis for axis in self.axes
|
|
123
|
+
):
|
|
124
|
+
raise TypeError("axes must contain exactly two AffineObjectiveAxis values")
|
|
125
|
+
for axis in self.axes:
|
|
126
|
+
AffineObjectiveAxis.__post_init__(axis)
|
|
127
|
+
if self.axes[0].metric_id == self.axes[1].metric_id:
|
|
128
|
+
raise ValueError("affine hypervolume axes must name distinct metrics")
|
|
129
|
+
if (
|
|
130
|
+
type(self.reference_provenance) is not str
|
|
131
|
+
or not self.reference_provenance.strip()
|
|
132
|
+
or self.reference_provenance != self.reference_provenance.strip()
|
|
133
|
+
):
|
|
134
|
+
raise ValueError("reference_provenance must be canonical non-empty text")
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def metric_ids(self) -> tuple[str, str]:
|
|
138
|
+
return (self.axes[0].metric_id, self.axes[1].metric_id)
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def raw_area_scale(self) -> float:
|
|
142
|
+
return self.axes[0].span * self.axes[1].span
|
|
143
|
+
|
|
144
|
+
def to_record(self) -> dict[str, object]:
|
|
145
|
+
self.__post_init__()
|
|
146
|
+
return {
|
|
147
|
+
"schema_version": 1,
|
|
148
|
+
"indicator": "exact_affine_normalized_two_objective_hypervolume",
|
|
149
|
+
"axes": [axis.to_record() for axis in self.axes],
|
|
150
|
+
"normalized_reference": ["0x1.0000000000000p+0"] * 2,
|
|
151
|
+
"raw_area_scale_hex": self.raw_area_scale.hex(),
|
|
152
|
+
"reference_provenance": self.reference_provenance,
|
|
153
|
+
"out_of_reference_points": "zero_measure_clipped_by_hypervolume_sweep",
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def definition_sha256(self) -> str:
|
|
158
|
+
return hashlib.sha256(
|
|
159
|
+
_DEFINITION_DOMAIN + _canonical_json(self.to_record())
|
|
160
|
+
).hexdigest()
|
|
161
|
+
|
|
162
|
+
def normalize(self, point: Mapping[str, Real]) -> tuple[float, float]:
|
|
163
|
+
if not isinstance(point, Mapping):
|
|
164
|
+
raise TypeError("objective point must be a mapping")
|
|
165
|
+
if set(point) != set(self.metric_ids):
|
|
166
|
+
raise ValueError("objective point differs from the affine metric set")
|
|
167
|
+
return (
|
|
168
|
+
self.axes[0].normalize(point[self.axes[0].metric_id]),
|
|
169
|
+
self.axes[1].normalize(point[self.axes[1].metric_id]),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
RawObjectivePoint = tuple[tuple[str, float], tuple[str, float]]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _raw_point(
|
|
177
|
+
spec: AffineHypervolume2DSpec,
|
|
178
|
+
value: Mapping[str, Real],
|
|
179
|
+
) -> RawObjectivePoint:
|
|
180
|
+
spec.normalize(value)
|
|
181
|
+
return (
|
|
182
|
+
(spec.axes[0].metric_id, float(value[spec.axes[0].metric_id])),
|
|
183
|
+
(spec.axes[1].metric_id, float(value[spec.axes[1].metric_id])),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _point_record(point: RawObjectivePoint) -> list[list[str]]:
|
|
188
|
+
return [[metric_id, value.hex()] for metric_id, value in point]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@dataclass(frozen=True, slots=True)
|
|
192
|
+
class AffineHypervolumeSnapshot2D:
|
|
193
|
+
"""One frozen archive cutoff in raw and normalized coordinates."""
|
|
194
|
+
|
|
195
|
+
spec: AffineHypervolume2DSpec
|
|
196
|
+
raw_archive_points: tuple[RawObjectivePoint, ...]
|
|
197
|
+
normalized_archive_points: tuple[tuple[float, float], ...] = field(init=False)
|
|
198
|
+
base_hypervolume: float = field(init=False)
|
|
199
|
+
raw_oriented_base_hypervolume: float = field(init=False)
|
|
200
|
+
snapshot_sha256: str = field(init=False)
|
|
201
|
+
|
|
202
|
+
def __post_init__(self) -> None:
|
|
203
|
+
if type(self.spec) is not AffineHypervolume2DSpec:
|
|
204
|
+
raise TypeError("spec must be an exact AffineHypervolume2DSpec")
|
|
205
|
+
self.spec.__post_init__()
|
|
206
|
+
if type(self.raw_archive_points) is not tuple:
|
|
207
|
+
raise TypeError("raw_archive_points must be an exact tuple")
|
|
208
|
+
expected_names = self.spec.metric_ids
|
|
209
|
+
for point in self.raw_archive_points:
|
|
210
|
+
if (
|
|
211
|
+
type(point) is not tuple
|
|
212
|
+
or len(point) != 2
|
|
213
|
+
or tuple(name for name, _ in point) != expected_names
|
|
214
|
+
):
|
|
215
|
+
raise ValueError("raw archive point differs from the affine axes")
|
|
216
|
+
for name, value in point:
|
|
217
|
+
_finite(value, name=f"archive point {name}")
|
|
218
|
+
canonical = tuple(
|
|
219
|
+
sorted(
|
|
220
|
+
set(self.raw_archive_points),
|
|
221
|
+
key=lambda point: tuple(value for _, value in point),
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
if self.raw_archive_points != canonical:
|
|
225
|
+
raise ValueError("raw archive points must be unique and canonical")
|
|
226
|
+
normalized = tuple(
|
|
227
|
+
self.spec.normalize(dict(point)) for point in self.raw_archive_points
|
|
228
|
+
)
|
|
229
|
+
base = hypervolume_2d(normalized, (1.0, 1.0))
|
|
230
|
+
object.__setattr__(self, "normalized_archive_points", normalized)
|
|
231
|
+
object.__setattr__(self, "base_hypervolume", base)
|
|
232
|
+
object.__setattr__(
|
|
233
|
+
self,
|
|
234
|
+
"raw_oriented_base_hypervolume",
|
|
235
|
+
base * self.spec.raw_area_scale,
|
|
236
|
+
)
|
|
237
|
+
object.__setattr__(
|
|
238
|
+
self,
|
|
239
|
+
"snapshot_sha256",
|
|
240
|
+
hashlib.sha256(
|
|
241
|
+
_SNAPSHOT_DOMAIN + _canonical_json(self._unsigned_record())
|
|
242
|
+
).hexdigest(),
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
def create(
|
|
247
|
+
cls,
|
|
248
|
+
*,
|
|
249
|
+
spec: AffineHypervolume2DSpec,
|
|
250
|
+
archive_points: Sequence[Mapping[str, Real]],
|
|
251
|
+
) -> "AffineHypervolumeSnapshot2D":
|
|
252
|
+
if isinstance(archive_points, (str, bytes)) or not isinstance(
|
|
253
|
+
archive_points, Sequence
|
|
254
|
+
):
|
|
255
|
+
raise TypeError("archive_points must be a sequence")
|
|
256
|
+
points = tuple(
|
|
257
|
+
sorted(
|
|
258
|
+
{
|
|
259
|
+
_raw_point(spec, value)
|
|
260
|
+
for value in archive_points
|
|
261
|
+
},
|
|
262
|
+
key=lambda point: tuple(value for _, value in point),
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
return cls(spec=spec, raw_archive_points=points)
|
|
266
|
+
|
|
267
|
+
def augmented_hypervolume(
|
|
268
|
+
self,
|
|
269
|
+
points: Sequence[Mapping[str, Real]],
|
|
270
|
+
) -> float:
|
|
271
|
+
if isinstance(points, (str, bytes)) or not isinstance(points, Sequence):
|
|
272
|
+
raise TypeError("points must be a sequence")
|
|
273
|
+
normalized = tuple(self.spec.normalize(value) for value in points)
|
|
274
|
+
return hypervolume_2d(
|
|
275
|
+
(*self.normalized_archive_points, *normalized),
|
|
276
|
+
(1.0, 1.0),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
def joint_gain(self, points: Sequence[Mapping[str, Real]]) -> float:
|
|
280
|
+
return max(0.0, self.augmented_hypervolume(points) - self.base_hypervolume)
|
|
281
|
+
|
|
282
|
+
def marginal_gain(self, point: Mapping[str, Real]) -> float:
|
|
283
|
+
return self.joint_gain((point,))
|
|
284
|
+
|
|
285
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
286
|
+
return {
|
|
287
|
+
"schema_version": 1,
|
|
288
|
+
"definition_sha256": self.spec.definition_sha256,
|
|
289
|
+
"spec": self.spec.to_record(),
|
|
290
|
+
"raw_archive_points": [
|
|
291
|
+
_point_record(point) for point in self.raw_archive_points
|
|
292
|
+
],
|
|
293
|
+
"normalized_archive_points": [
|
|
294
|
+
[first.hex(), second.hex()]
|
|
295
|
+
for first, second in self.normalized_archive_points
|
|
296
|
+
],
|
|
297
|
+
"base_hypervolume_hex": self.base_hypervolume.hex(),
|
|
298
|
+
"raw_oriented_base_hypervolume_hex": (
|
|
299
|
+
self.raw_oriented_base_hypervolume.hex()
|
|
300
|
+
),
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
def to_record(self) -> dict[str, object]:
|
|
304
|
+
self.__post_init__()
|
|
305
|
+
return {**self._unsigned_record(), "snapshot_sha256": self.snapshot_sha256}
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class AffineWaveRewardCandidate(Protocol):
|
|
309
|
+
valid: bool
|
|
310
|
+
operator_compliant: bool
|
|
311
|
+
evidence_compliant: bool
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def objective_map(self) -> dict[str, float]: ...
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
@dataclass(frozen=True, slots=True)
|
|
318
|
+
class AffineHypervolumeWaveRewardRecord:
|
|
319
|
+
reward: float
|
|
320
|
+
raw_oriented_gain: float
|
|
321
|
+
base_hypervolume: float
|
|
322
|
+
augmented_hypervolume: float
|
|
323
|
+
member_count: int
|
|
324
|
+
admitted_count: int
|
|
325
|
+
snapshot_sha256: str
|
|
326
|
+
definition_sha256: str
|
|
327
|
+
|
|
328
|
+
def to_record(self) -> dict[str, object]:
|
|
329
|
+
return {
|
|
330
|
+
"reward_hex": self.reward.hex(),
|
|
331
|
+
"raw_oriented_gain_hex": self.raw_oriented_gain.hex(),
|
|
332
|
+
"base_hypervolume_hex": self.base_hypervolume.hex(),
|
|
333
|
+
"augmented_hypervolume_hex": self.augmented_hypervolume.hex(),
|
|
334
|
+
"member_count": self.member_count,
|
|
335
|
+
"admitted_count": self.admitted_count,
|
|
336
|
+
"snapshot_sha256": self.snapshot_sha256,
|
|
337
|
+
"definition_sha256": self.definition_sha256,
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@dataclass(frozen=True, slots=True)
|
|
342
|
+
class AffineFrozenArchiveJointWaveReward:
|
|
343
|
+
"""Dimensionless joint gain for one fixed-cardinality candidate wave."""
|
|
344
|
+
|
|
345
|
+
snapshot: AffineHypervolumeSnapshot2D
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
def definition_hash(self) -> str:
|
|
349
|
+
return self.snapshot.spec.definition_sha256
|
|
350
|
+
|
|
351
|
+
def record(
|
|
352
|
+
self,
|
|
353
|
+
children: Sequence[AffineWaveRewardCandidate | None],
|
|
354
|
+
) -> AffineHypervolumeWaveRewardRecord:
|
|
355
|
+
if isinstance(children, (str, bytes)) or not isinstance(children, Sequence):
|
|
356
|
+
raise TypeError("children must be a sequence")
|
|
357
|
+
if not children:
|
|
358
|
+
raise ValueError("wave reward requires at least one planned member")
|
|
359
|
+
admitted = tuple(
|
|
360
|
+
child.objective_map
|
|
361
|
+
for child in children
|
|
362
|
+
if child is not None
|
|
363
|
+
and child.valid
|
|
364
|
+
and child.operator_compliant
|
|
365
|
+
and child.evidence_compliant
|
|
366
|
+
)
|
|
367
|
+
augmented = self.snapshot.augmented_hypervolume(admitted)
|
|
368
|
+
gain = max(0.0, augmented - self.snapshot.base_hypervolume)
|
|
369
|
+
return AffineHypervolumeWaveRewardRecord(
|
|
370
|
+
reward=gain,
|
|
371
|
+
raw_oriented_gain=gain * self.snapshot.spec.raw_area_scale,
|
|
372
|
+
base_hypervolume=self.snapshot.base_hypervolume,
|
|
373
|
+
augmented_hypervolume=augmented,
|
|
374
|
+
member_count=len(children),
|
|
375
|
+
admitted_count=len(admitted),
|
|
376
|
+
snapshot_sha256=self.snapshot.snapshot_sha256,
|
|
377
|
+
definition_sha256=self.definition_hash,
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
def __call__(self, children: Sequence[AffineWaveRewardCandidate | None]) -> float:
|
|
381
|
+
return self.record(children).reward
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
@dataclass(frozen=True, slots=True)
|
|
385
|
+
class AffineHypervolumeArchiveUtility:
|
|
386
|
+
"""Campaign archive-utility port for the affine indicator."""
|
|
387
|
+
|
|
388
|
+
spec: AffineHypervolume2DSpec
|
|
389
|
+
utility_id: str = field(init=False, default=_UTILITY_ID)
|
|
390
|
+
utility_version: int = field(init=False, default=_UTILITY_VERSION)
|
|
391
|
+
|
|
392
|
+
@property
|
|
393
|
+
def definition_sha256(self) -> str:
|
|
394
|
+
return self.spec.definition_sha256
|
|
395
|
+
|
|
396
|
+
@staticmethod
|
|
397
|
+
def _archive_points(archive: FrozenJsonObject) -> tuple[dict[str, float], ...]:
|
|
398
|
+
value = thaw_json(archive)
|
|
399
|
+
front = value.get("front_candidates")
|
|
400
|
+
if type(front) is not list:
|
|
401
|
+
raise ValueError("campaign archive omitted front_candidates")
|
|
402
|
+
points: list[dict[str, float]] = []
|
|
403
|
+
for candidate in front:
|
|
404
|
+
if type(candidate) is not dict or type(candidate.get("objectives")) is not list:
|
|
405
|
+
raise ValueError("campaign archive candidate omitted objectives")
|
|
406
|
+
point: dict[str, float] = {}
|
|
407
|
+
for row in candidate["objectives"]:
|
|
408
|
+
if (
|
|
409
|
+
type(row) is not dict
|
|
410
|
+
or type(row.get("metric_id")) is not str
|
|
411
|
+
or type(row.get("value_hex")) is not str
|
|
412
|
+
):
|
|
413
|
+
raise ValueError("campaign archive objective row is invalid")
|
|
414
|
+
point[row["metric_id"]] = float.fromhex(row["value_hex"])
|
|
415
|
+
points.append(point)
|
|
416
|
+
return tuple(points)
|
|
417
|
+
|
|
418
|
+
def freeze(
|
|
419
|
+
self,
|
|
420
|
+
*,
|
|
421
|
+
benchmark: FrozenJsonObject,
|
|
422
|
+
generation: int,
|
|
423
|
+
archive: FrozenJsonObject,
|
|
424
|
+
) -> ArchiveUtilitySnapshot:
|
|
425
|
+
self.spec.__post_init__()
|
|
426
|
+
snapshot = AffineHypervolumeSnapshot2D.create(
|
|
427
|
+
spec=self.spec,
|
|
428
|
+
archive_points=self._archive_points(archive),
|
|
429
|
+
)
|
|
430
|
+
return ArchiveUtilitySnapshot(
|
|
431
|
+
utility_id=self.utility_id,
|
|
432
|
+
utility_version=self.utility_version,
|
|
433
|
+
definition_sha256=self.definition_sha256,
|
|
434
|
+
generation=generation,
|
|
435
|
+
benchmark_sha256=typed_json_sha256(benchmark),
|
|
436
|
+
archive_sha256=typed_json_sha256(archive),
|
|
437
|
+
snapshot_receipt=_object(snapshot.to_record()),
|
|
438
|
+
scalar_utility_hex=snapshot.base_hypervolume.hex(),
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
def require_snapshot(
|
|
442
|
+
self,
|
|
443
|
+
value: ArchiveUtilitySnapshot,
|
|
444
|
+
) -> AffineHypervolumeSnapshot2D:
|
|
445
|
+
if type(value) is not ArchiveUtilitySnapshot:
|
|
446
|
+
raise TypeError("value must be an exact ArchiveUtilitySnapshot")
|
|
447
|
+
value.__post_init__()
|
|
448
|
+
if (
|
|
449
|
+
value.utility_id != self.utility_id
|
|
450
|
+
or value.utility_version != self.utility_version
|
|
451
|
+
or value.definition_sha256 != self.definition_sha256
|
|
452
|
+
):
|
|
453
|
+
raise ValueError("archive utility snapshot uses a foreign affine spec")
|
|
454
|
+
record = thaw_json(value.snapshot_receipt)
|
|
455
|
+
raw = record.get("raw_archive_points")
|
|
456
|
+
if type(raw) is not list:
|
|
457
|
+
raise ValueError("affine snapshot omitted raw archive points")
|
|
458
|
+
points: list[dict[str, float]] = []
|
|
459
|
+
for item in raw:
|
|
460
|
+
if type(item) is not list:
|
|
461
|
+
raise ValueError("affine raw point is not a list")
|
|
462
|
+
point: dict[str, float] = {}
|
|
463
|
+
for pair in item:
|
|
464
|
+
if (
|
|
465
|
+
type(pair) is not list
|
|
466
|
+
or len(pair) != 2
|
|
467
|
+
or type(pair[0]) is not str
|
|
468
|
+
or type(pair[1]) is not str
|
|
469
|
+
):
|
|
470
|
+
raise ValueError("affine raw point item is invalid")
|
|
471
|
+
point[pair[0]] = float.fromhex(pair[1])
|
|
472
|
+
points.append(point)
|
|
473
|
+
replayed = AffineHypervolumeSnapshot2D.create(
|
|
474
|
+
spec=self.spec,
|
|
475
|
+
archive_points=tuple(points),
|
|
476
|
+
)
|
|
477
|
+
if replayed.to_record() != record:
|
|
478
|
+
raise ValueError("affine snapshot receipt does not replay exactly")
|
|
479
|
+
return replayed
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
__all__ = [
|
|
483
|
+
"AffineFrozenArchiveJointWaveReward",
|
|
484
|
+
"AffineHypervolume2DSpec",
|
|
485
|
+
"AffineHypervolumeArchiveUtility",
|
|
486
|
+
"AffineHypervolumeSnapshot2D",
|
|
487
|
+
"AffineHypervolumeWaveRewardRecord",
|
|
488
|
+
"AffineObjectiveAxis",
|
|
489
|
+
"AffineWaveRewardCandidate",
|
|
490
|
+
]
|