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,684 @@
|
|
|
1
|
+
"""Acquisition-certified residual allocation over a model-proposed slate.
|
|
2
|
+
|
|
3
|
+
An upstream numerical expert contributes a reference slate while the language
|
|
4
|
+
model contributes residual alternatives. This policy enumerates every hard-
|
|
5
|
+
feasible evaluation subset of the authenticated proposal, scores all subsets
|
|
6
|
+
under one strictly-prior acquisition realization, and retains the reference on
|
|
7
|
+
ties. The selected slate therefore cannot have lower *measured acquisition*
|
|
8
|
+
than the best feasible reference-preserving slate. This is deliberately not a
|
|
9
|
+
claim about unseen evaluator outcomes; those remain the experiment endpoint.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import hashlib
|
|
15
|
+
import json
|
|
16
|
+
import math
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
from itertools import combinations
|
|
19
|
+
from typing import Protocol, runtime_checkable
|
|
20
|
+
|
|
21
|
+
from agent_evolve.domain.patch import require_sha256
|
|
22
|
+
from agent_evolve.policies.selection.calibrated_slate import (
|
|
23
|
+
AllocatedSlateMember,
|
|
24
|
+
SlateAllocationRequest,
|
|
25
|
+
SlateAllocationRole,
|
|
26
|
+
assess_allocated_slate_memory_dose,
|
|
27
|
+
)
|
|
28
|
+
from agent_evolve.ports.finite_acquisition import (
|
|
29
|
+
FiniteAcquisitionCandidate,
|
|
30
|
+
FiniteAcquisitionObjective,
|
|
31
|
+
FiniteAcquisitionObservation,
|
|
32
|
+
)
|
|
33
|
+
from agent_evolve.ports.finite_acquisition_batch import (
|
|
34
|
+
FiniteAcquisitionBatchScoreDecision,
|
|
35
|
+
FiniteAcquisitionBatchScorePolicy,
|
|
36
|
+
FiniteAcquisitionBatchScoreRequest,
|
|
37
|
+
FiniteAcquisitionSlate,
|
|
38
|
+
validate_finite_acquisition_batch_score_decision,
|
|
39
|
+
)
|
|
40
|
+
from agent_evolve.ports.portfolio_memory_dose import PortfolioMemoryDoseAssessment
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
POLICY_ID = "acquisition_certified_residual_slate"
|
|
44
|
+
POLICY_VERSION = 1
|
|
45
|
+
_CONTEXT_DOMAIN = b"agent-evolve:acquisition-certified-slate-context:v1\x00"
|
|
46
|
+
_DECISION_DOMAIN = b"agent-evolve:acquisition-certified-slate-decision:v1\x00"
|
|
47
|
+
_POLICY_DOMAIN = b"agent-evolve:acquisition-certified-slate-policy:v1\x00"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _canonical_json(value: object) -> bytes:
|
|
51
|
+
return json.dumps(
|
|
52
|
+
value,
|
|
53
|
+
allow_nan=False,
|
|
54
|
+
ensure_ascii=True,
|
|
55
|
+
separators=(",", ":"),
|
|
56
|
+
sort_keys=True,
|
|
57
|
+
).encode("ascii", errors="strict")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def finite_acquisition_policy_identity(
|
|
61
|
+
policy: FiniteAcquisitionBatchScorePolicy,
|
|
62
|
+
) -> tuple[str, int, str]:
|
|
63
|
+
if not isinstance(policy, FiniteAcquisitionBatchScorePolicy):
|
|
64
|
+
raise TypeError("scorer must implement FiniteAcquisitionBatchScorePolicy")
|
|
65
|
+
values = (
|
|
66
|
+
getattr(policy, "policy_id", None),
|
|
67
|
+
getattr(policy, "policy_version", None),
|
|
68
|
+
getattr(policy, "definition_sha256", None),
|
|
69
|
+
)
|
|
70
|
+
if type(values[0]) is not str or not values[0]:
|
|
71
|
+
raise ValueError("scorer policy_id must be non-empty")
|
|
72
|
+
if type(values[1]) is not int or values[1] <= 0:
|
|
73
|
+
raise ValueError("scorer policy_version must be positive")
|
|
74
|
+
require_sha256(values[2], "scorer definition_sha256")
|
|
75
|
+
return values # type: ignore[return-value]
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
79
|
+
class AcquisitionCertifiedSlateContext:
|
|
80
|
+
"""Strictly-prior numerical context registered for one finite contract."""
|
|
81
|
+
|
|
82
|
+
campaign_scope_sha256: str
|
|
83
|
+
finite_contract_sha256: str
|
|
84
|
+
cutoff_index: int
|
|
85
|
+
seed: int
|
|
86
|
+
objectives: tuple[FiniteAcquisitionObjective, ...]
|
|
87
|
+
observations: tuple[FiniteAcquisitionObservation, ...]
|
|
88
|
+
candidates: tuple[FiniteAcquisitionCandidate, ...]
|
|
89
|
+
reference_option_ids: tuple[str, ...]
|
|
90
|
+
context_sha256: str = field(init=False, default="")
|
|
91
|
+
|
|
92
|
+
def __post_init__(self) -> None:
|
|
93
|
+
require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
|
|
94
|
+
require_sha256(self.finite_contract_sha256, "finite_contract_sha256")
|
|
95
|
+
if type(self.cutoff_index) is not int or self.cutoff_index < 1:
|
|
96
|
+
raise ValueError("cutoff_index must be positive")
|
|
97
|
+
if type(self.seed) is not int or self.seed < 0:
|
|
98
|
+
raise ValueError("seed must be non-negative")
|
|
99
|
+
# A one-slate request exercises the complete shared acquisition input
|
|
100
|
+
# law without introducing a second validator in this module.
|
|
101
|
+
if type(self.reference_option_ids) is not tuple or not (
|
|
102
|
+
self.reference_option_ids
|
|
103
|
+
):
|
|
104
|
+
raise ValueError("reference_option_ids must be a non-empty tuple")
|
|
105
|
+
if self.reference_option_ids != tuple(sorted(set(self.reference_option_ids))):
|
|
106
|
+
raise ValueError("reference option IDs must be unique and canonical")
|
|
107
|
+
available = {value.candidate_id for value in self.candidates}
|
|
108
|
+
if not set(self.reference_option_ids) <= available:
|
|
109
|
+
raise ValueError("reference options escape the numerical candidate set")
|
|
110
|
+
FiniteAcquisitionBatchScoreRequest(
|
|
111
|
+
campaign_scope_sha256=self.campaign_scope_sha256,
|
|
112
|
+
cutoff_index=self.cutoff_index,
|
|
113
|
+
seed=self.seed,
|
|
114
|
+
objectives=self.objectives,
|
|
115
|
+
observations=self.observations,
|
|
116
|
+
candidates=self.candidates,
|
|
117
|
+
slates=(FiniteAcquisitionSlate(self.reference_option_ids),),
|
|
118
|
+
)
|
|
119
|
+
computed = hashlib.sha256(
|
|
120
|
+
_CONTEXT_DOMAIN + _canonical_json(self._unsigned_record())
|
|
121
|
+
).hexdigest()
|
|
122
|
+
if self.context_sha256 not in ("", computed):
|
|
123
|
+
raise ValueError("context_sha256 does not authenticate the context")
|
|
124
|
+
object.__setattr__(self, "context_sha256", computed)
|
|
125
|
+
|
|
126
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
127
|
+
return {
|
|
128
|
+
"schema_version": 1,
|
|
129
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
130
|
+
"finite_contract_sha256": self.finite_contract_sha256,
|
|
131
|
+
"cutoff_index": self.cutoff_index,
|
|
132
|
+
"seed": self.seed,
|
|
133
|
+
"objectives": [value.to_record() for value in self.objectives],
|
|
134
|
+
"observations": [value.to_record() for value in self.observations],
|
|
135
|
+
"candidates": [value.to_record() for value in self.candidates],
|
|
136
|
+
"reference_option_ids": list(self.reference_option_ids),
|
|
137
|
+
"current_or_future_outcomes_consulted": False,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
def to_record(self) -> dict[str, object]:
|
|
141
|
+
self.__post_init__()
|
|
142
|
+
return {**self._unsigned_record(), "context_sha256": self.context_sha256}
|
|
143
|
+
|
|
144
|
+
def __eq__(self, other: object) -> bool:
|
|
145
|
+
return (
|
|
146
|
+
type(other) is AcquisitionCertifiedSlateContext
|
|
147
|
+
and self.context_sha256 == other.context_sha256
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
__hash__ = None
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@runtime_checkable
|
|
154
|
+
class AcquisitionCertifiedSlateContextProvider(Protocol):
|
|
155
|
+
provider_id: str
|
|
156
|
+
provider_version: int
|
|
157
|
+
definition_sha256: str
|
|
158
|
+
|
|
159
|
+
def context_for(
|
|
160
|
+
self,
|
|
161
|
+
finite_contract_sha256: str,
|
|
162
|
+
) -> AcquisitionCertifiedSlateContext: ...
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@runtime_checkable
|
|
166
|
+
class AcquisitionCertifiedSlateContextSink(Protocol):
|
|
167
|
+
provider_id: str
|
|
168
|
+
provider_version: int
|
|
169
|
+
definition_sha256: str
|
|
170
|
+
|
|
171
|
+
def register_many(
|
|
172
|
+
self,
|
|
173
|
+
contexts: tuple[AcquisitionCertifiedSlateContext, ...],
|
|
174
|
+
) -> None: ...
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass(slots=True)
|
|
178
|
+
class AcquisitionCertifiedSlateContextRegistry:
|
|
179
|
+
"""Append-only, replay-idempotent bridge from envelope to allocator.
|
|
180
|
+
|
|
181
|
+
Preparation and audit paths may deterministically reconstruct an already
|
|
182
|
+
registered context. Re-registering the exact authenticated value is a
|
|
183
|
+
no-op; attempting to bind the same finite contract to a different context
|
|
184
|
+
remains a hard error. The conflict check is performed before any write so
|
|
185
|
+
that a mixed batch cannot partially mutate the registry.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
provider_id: str = "append_only_acquisition_certification_context"
|
|
189
|
+
provider_version: int = 2
|
|
190
|
+
definition_sha256: str = hashlib.sha256(
|
|
191
|
+
b"agent-evolve:append-only-acquisition-certification-context:v2;"
|
|
192
|
+
b"key=finite-contract-sha256;identical-replay=idempotent;"
|
|
193
|
+
b"conflicting-replacement=false;batch-write=atomic;strictly-prior=true"
|
|
194
|
+
).hexdigest()
|
|
195
|
+
_contexts: dict[str, AcquisitionCertifiedSlateContext] = field(
|
|
196
|
+
init=False,
|
|
197
|
+
default_factory=dict,
|
|
198
|
+
repr=False,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def register(self, context: AcquisitionCertifiedSlateContext) -> None:
|
|
202
|
+
self.register_many((context,))
|
|
203
|
+
|
|
204
|
+
def register_many(
|
|
205
|
+
self,
|
|
206
|
+
contexts: tuple[AcquisitionCertifiedSlateContext, ...],
|
|
207
|
+
) -> None:
|
|
208
|
+
if type(contexts) is not tuple or not contexts:
|
|
209
|
+
raise ValueError("contexts must be a non-empty exact tuple")
|
|
210
|
+
incoming: dict[str, AcquisitionCertifiedSlateContext] = {}
|
|
211
|
+
for context in contexts:
|
|
212
|
+
if type(context) is not AcquisitionCertifiedSlateContext:
|
|
213
|
+
raise TypeError("contexts must contain exact contexts")
|
|
214
|
+
context.__post_init__()
|
|
215
|
+
prior = incoming.get(context.finite_contract_sha256)
|
|
216
|
+
if prior is not None:
|
|
217
|
+
if prior.context_sha256 != context.context_sha256:
|
|
218
|
+
raise ValueError(
|
|
219
|
+
"context batch binds one finite contract to conflicting "
|
|
220
|
+
"contexts"
|
|
221
|
+
)
|
|
222
|
+
continue
|
|
223
|
+
incoming[context.finite_contract_sha256] = context
|
|
224
|
+
conflicts = tuple(
|
|
225
|
+
sorted(
|
|
226
|
+
finite_contract_sha256
|
|
227
|
+
for finite_contract_sha256, context in incoming.items()
|
|
228
|
+
if finite_contract_sha256 in self._contexts
|
|
229
|
+
and self._contexts[finite_contract_sha256].context_sha256
|
|
230
|
+
!= context.context_sha256
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
if conflicts:
|
|
234
|
+
raise ValueError(
|
|
235
|
+
"acquisition certification context is append-only; conflicting "
|
|
236
|
+
f"contracts={conflicts!r}"
|
|
237
|
+
)
|
|
238
|
+
self._contexts.update(
|
|
239
|
+
{
|
|
240
|
+
finite_contract_sha256: context
|
|
241
|
+
for finite_contract_sha256, context in incoming.items()
|
|
242
|
+
if finite_contract_sha256 not in self._contexts
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def context_for(
|
|
247
|
+
self,
|
|
248
|
+
finite_contract_sha256: str,
|
|
249
|
+
) -> AcquisitionCertifiedSlateContext:
|
|
250
|
+
require_sha256(finite_contract_sha256, "finite_contract_sha256")
|
|
251
|
+
try:
|
|
252
|
+
return self._contexts[finite_contract_sha256]
|
|
253
|
+
except KeyError as error:
|
|
254
|
+
raise KeyError(
|
|
255
|
+
"no acquisition certification context was registered for contract"
|
|
256
|
+
) from error
|
|
257
|
+
|
|
258
|
+
def to_record(self) -> dict[str, object]:
|
|
259
|
+
return {
|
|
260
|
+
"provider_id": self.provider_id,
|
|
261
|
+
"provider_version": self.provider_version,
|
|
262
|
+
"definition_sha256": self.definition_sha256,
|
|
263
|
+
"registered_context_count": len(self._contexts),
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def feasible_slate_option_id_subsets(
|
|
268
|
+
request: SlateAllocationRequest,
|
|
269
|
+
) -> tuple[tuple[str, ...], ...]:
|
|
270
|
+
member_by_id = {value.option_id: value for value in request.slate.members}
|
|
271
|
+
compatible = (
|
|
272
|
+
None
|
|
273
|
+
if request.pairwise_disjoint_option_id_pairs is None
|
|
274
|
+
else {frozenset(value) for value in request.pairwise_disjoint_option_id_pairs}
|
|
275
|
+
)
|
|
276
|
+
feasible: list[tuple[str, ...]] = []
|
|
277
|
+
for subset in combinations(sorted(member_by_id), request.portfolio_size):
|
|
278
|
+
if not set(request.required_option_ids) <= set(subset):
|
|
279
|
+
continue
|
|
280
|
+
if compatible is not None and any(
|
|
281
|
+
frozenset((left, right)) not in compatible
|
|
282
|
+
for index, left in enumerate(subset)
|
|
283
|
+
for right in subset[index + 1 :]
|
|
284
|
+
):
|
|
285
|
+
continue
|
|
286
|
+
members = tuple(member_by_id[value] for value in subset)
|
|
287
|
+
if request.min_distinct_families is not None and len(
|
|
288
|
+
{value.family for value in members}
|
|
289
|
+
) < request.min_distinct_families:
|
|
290
|
+
continue
|
|
291
|
+
if request.memory_dose_contract is not None:
|
|
292
|
+
assessment = assess_allocated_slate_memory_dose(request, members)
|
|
293
|
+
if assessment is None or not assessment.passed:
|
|
294
|
+
continue
|
|
295
|
+
feasible.append(subset)
|
|
296
|
+
return tuple(feasible)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
300
|
+
class AcquisitionCertifiedSlateDecision:
|
|
301
|
+
request: SlateAllocationRequest
|
|
302
|
+
selected: tuple[AllocatedSlateMember, ...]
|
|
303
|
+
reference_option_ids: tuple[str, ...]
|
|
304
|
+
selected_option_ids: tuple[str, ...]
|
|
305
|
+
reference_log_acquisition_value: float
|
|
306
|
+
selected_log_acquisition_value: float
|
|
307
|
+
certificate_margin: float
|
|
308
|
+
reference_member_count: int
|
|
309
|
+
feasible_slate_count: int
|
|
310
|
+
score_request: FiniteAcquisitionBatchScoreRequest
|
|
311
|
+
score_decision: FiniteAcquisitionBatchScoreDecision
|
|
312
|
+
memory_dose_assessment: PortfolioMemoryDoseAssessment | None
|
|
313
|
+
policy_definition_sha256: str
|
|
314
|
+
decision_sha256: str = field(init=False, default="")
|
|
315
|
+
|
|
316
|
+
policy_id = POLICY_ID
|
|
317
|
+
policy_version = POLICY_VERSION
|
|
318
|
+
|
|
319
|
+
def __post_init__(self) -> None:
|
|
320
|
+
if type(self.request) is not SlateAllocationRequest:
|
|
321
|
+
raise TypeError("request must be exact")
|
|
322
|
+
self.request.revalidate()
|
|
323
|
+
if type(self.selected) is not tuple or len(self.selected) != (
|
|
324
|
+
self.request.portfolio_size
|
|
325
|
+
):
|
|
326
|
+
raise ValueError("selected must fill the evaluation portfolio")
|
|
327
|
+
for value in self.selected:
|
|
328
|
+
if type(value) is not AllocatedSlateMember:
|
|
329
|
+
raise TypeError("selected must contain exact allocated members")
|
|
330
|
+
value.__post_init__()
|
|
331
|
+
if value.role is not SlateAllocationRole.ACQUISITION_CERTIFIED:
|
|
332
|
+
raise ValueError("selected member has a foreign acquisition role")
|
|
333
|
+
for name in ("reference_option_ids", "selected_option_ids"):
|
|
334
|
+
values = getattr(self, name)
|
|
335
|
+
if values != tuple(sorted(set(values))) or len(values) != (
|
|
336
|
+
self.request.portfolio_size
|
|
337
|
+
):
|
|
338
|
+
raise ValueError(f"{name} must be a canonical complete slate")
|
|
339
|
+
if tuple(sorted(value.option_id for value in self.selected)) != (
|
|
340
|
+
self.selected_option_ids
|
|
341
|
+
):
|
|
342
|
+
raise ValueError("selected member identities differ from selected slate")
|
|
343
|
+
for name in (
|
|
344
|
+
"reference_log_acquisition_value",
|
|
345
|
+
"selected_log_acquisition_value",
|
|
346
|
+
"certificate_margin",
|
|
347
|
+
):
|
|
348
|
+
value = getattr(self, name)
|
|
349
|
+
if type(value) is not float or not math.isfinite(value):
|
|
350
|
+
raise TypeError(f"{name} must be finite")
|
|
351
|
+
if not math.isclose(
|
|
352
|
+
self.selected_log_acquisition_value
|
|
353
|
+
- self.reference_log_acquisition_value,
|
|
354
|
+
self.certificate_margin,
|
|
355
|
+
rel_tol=0.0,
|
|
356
|
+
abs_tol=1e-12,
|
|
357
|
+
):
|
|
358
|
+
raise ValueError("certificate margin does not close")
|
|
359
|
+
if self.certificate_margin < -1e-12:
|
|
360
|
+
raise ValueError("selected acquisition is below its retained reference")
|
|
361
|
+
if (
|
|
362
|
+
type(self.reference_member_count) is not int
|
|
363
|
+
or not 0 <= self.reference_member_count <= self.request.portfolio_size
|
|
364
|
+
):
|
|
365
|
+
raise ValueError("reference_member_count is outside the portfolio")
|
|
366
|
+
if self.reference_member_count != len(
|
|
367
|
+
set(self.selected_option_ids).intersection(self.reference_option_ids)
|
|
368
|
+
):
|
|
369
|
+
raise ValueError(
|
|
370
|
+
"reference_member_count must equal selected/reference overlap"
|
|
371
|
+
)
|
|
372
|
+
if type(self.feasible_slate_count) is not int or self.feasible_slate_count < 1:
|
|
373
|
+
raise ValueError("feasible_slate_count must be positive")
|
|
374
|
+
if type(self.score_request) is not FiniteAcquisitionBatchScoreRequest:
|
|
375
|
+
raise TypeError("score_request must be exact")
|
|
376
|
+
if type(self.score_decision) is not FiniteAcquisitionBatchScoreDecision:
|
|
377
|
+
raise TypeError("score_decision must be exact")
|
|
378
|
+
validate_finite_acquisition_batch_score_decision(
|
|
379
|
+
self.score_request,
|
|
380
|
+
self.score_decision,
|
|
381
|
+
)
|
|
382
|
+
if self.feasible_slate_count != len(self.score_request.slates):
|
|
383
|
+
raise ValueError("feasible slate count differs from score request")
|
|
384
|
+
score_by_ids = {
|
|
385
|
+
value.slate.candidate_ids: value.log_acquisition_value
|
|
386
|
+
for value in self.score_decision.scores
|
|
387
|
+
}
|
|
388
|
+
if score_by_ids.get(self.reference_option_ids) != (
|
|
389
|
+
self.reference_log_acquisition_value
|
|
390
|
+
) or score_by_ids.get(self.selected_option_ids) != (
|
|
391
|
+
self.selected_log_acquisition_value
|
|
392
|
+
):
|
|
393
|
+
raise ValueError("certificate values differ from numerical scores")
|
|
394
|
+
if self.memory_dose_assessment is not None:
|
|
395
|
+
if type(self.memory_dose_assessment) is not PortfolioMemoryDoseAssessment:
|
|
396
|
+
raise TypeError("memory_dose_assessment must be exact or None")
|
|
397
|
+
self.memory_dose_assessment.__post_init__()
|
|
398
|
+
if not self.memory_dose_assessment.passed:
|
|
399
|
+
raise ValueError("selected acquisition slate violates memory dose")
|
|
400
|
+
require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
|
|
401
|
+
computed = hashlib.sha256(
|
|
402
|
+
_DECISION_DOMAIN + _canonical_json(self._unsigned_record())
|
|
403
|
+
).hexdigest()
|
|
404
|
+
if self.decision_sha256 not in ("", computed):
|
|
405
|
+
raise ValueError("decision_sha256 does not authenticate the decision")
|
|
406
|
+
object.__setattr__(self, "decision_sha256", computed)
|
|
407
|
+
|
|
408
|
+
def revalidate(self) -> None:
|
|
409
|
+
if type(self) is not AcquisitionCertifiedSlateDecision:
|
|
410
|
+
raise TypeError("decision must be exact")
|
|
411
|
+
self.__post_init__()
|
|
412
|
+
|
|
413
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
414
|
+
return {
|
|
415
|
+
"schema_version": 1,
|
|
416
|
+
"event_type": "acquisition_certified_residual_slate_allocated",
|
|
417
|
+
"policy_id": self.policy_id,
|
|
418
|
+
"policy_version": self.policy_version,
|
|
419
|
+
"policy_definition_sha256": self.policy_definition_sha256,
|
|
420
|
+
"request": self.request.to_record(),
|
|
421
|
+
"request_sha256": self.request.request_sha256,
|
|
422
|
+
"selected": [value.to_record() for value in self.selected],
|
|
423
|
+
"reference_option_ids": list(self.reference_option_ids),
|
|
424
|
+
"selected_option_ids": list(self.selected_option_ids),
|
|
425
|
+
"reference_log_acquisition_value_hex": (
|
|
426
|
+
self.reference_log_acquisition_value.hex()
|
|
427
|
+
),
|
|
428
|
+
"selected_log_acquisition_value_hex": (
|
|
429
|
+
self.selected_log_acquisition_value.hex()
|
|
430
|
+
),
|
|
431
|
+
"certificate_margin_hex": self.certificate_margin.hex(),
|
|
432
|
+
"reference_member_count": self.reference_member_count,
|
|
433
|
+
"feasible_slate_count": self.feasible_slate_count,
|
|
434
|
+
"score_request": self.score_request.to_record(),
|
|
435
|
+
"score_decision": self.score_decision.to_record(),
|
|
436
|
+
"memory_dose_assessment": (
|
|
437
|
+
None
|
|
438
|
+
if self.memory_dose_assessment is None
|
|
439
|
+
else self.memory_dose_assessment.to_record()
|
|
440
|
+
),
|
|
441
|
+
"certificate_scope": (
|
|
442
|
+
"frozen_strictly_prior_acquisition_not_unseen_outcome"
|
|
443
|
+
),
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
def to_record(self) -> dict[str, object]:
|
|
447
|
+
self.revalidate()
|
|
448
|
+
return {**self._unsigned_record(), "decision_sha256": self.decision_sha256}
|
|
449
|
+
|
|
450
|
+
def __eq__(self, other: object) -> bool:
|
|
451
|
+
return (
|
|
452
|
+
type(other) is AcquisitionCertifiedSlateDecision
|
|
453
|
+
and self.decision_sha256 == other.decision_sha256
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
__hash__ = None
|
|
457
|
+
|
|
458
|
+
@property
|
|
459
|
+
def prior_only(self) -> bool:
|
|
460
|
+
return True
|
|
461
|
+
|
|
462
|
+
@property
|
|
463
|
+
def administered_card_keys(self) -> tuple[str, ...]:
|
|
464
|
+
selected_ids = {value.option_id for value in self.selected}
|
|
465
|
+
return tuple(
|
|
466
|
+
sorted(
|
|
467
|
+
{
|
|
468
|
+
card_key
|
|
469
|
+
for member in self.request.slate.members
|
|
470
|
+
if member.option_id in selected_ids
|
|
471
|
+
for card_key in member.supporting_card_keys
|
|
472
|
+
if card_key in self.request.assigned_card_keys
|
|
473
|
+
}
|
|
474
|
+
)
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
@dataclass(frozen=True, slots=True)
|
|
479
|
+
class AcquisitionCertifiedSlatePolicy:
|
|
480
|
+
"""Choose the highest acquired feasible slate while retaining an anchor."""
|
|
481
|
+
|
|
482
|
+
context_provider: AcquisitionCertifiedSlateContextProvider
|
|
483
|
+
scorer: FiniteAcquisitionBatchScorePolicy
|
|
484
|
+
exact_combination_limit: int = 250_000
|
|
485
|
+
tie_tolerance: float = 1e-12
|
|
486
|
+
policy_id: str = field(init=False, default=POLICY_ID)
|
|
487
|
+
policy_version: int = field(init=False, default=POLICY_VERSION)
|
|
488
|
+
definition_sha256: str = field(init=False, default="")
|
|
489
|
+
|
|
490
|
+
def __post_init__(self) -> None:
|
|
491
|
+
if not isinstance(
|
|
492
|
+
self.context_provider,
|
|
493
|
+
AcquisitionCertifiedSlateContextProvider,
|
|
494
|
+
):
|
|
495
|
+
raise TypeError("context_provider must implement its exact port")
|
|
496
|
+
scorer_identity = finite_acquisition_policy_identity(self.scorer)
|
|
497
|
+
if type(self.exact_combination_limit) is not int or (
|
|
498
|
+
self.exact_combination_limit < 1
|
|
499
|
+
):
|
|
500
|
+
raise ValueError("exact_combination_limit must be positive")
|
|
501
|
+
if (
|
|
502
|
+
type(self.tie_tolerance) is not float
|
|
503
|
+
or not math.isfinite(self.tie_tolerance)
|
|
504
|
+
or self.tie_tolerance < 0.0
|
|
505
|
+
):
|
|
506
|
+
raise ValueError("tie_tolerance must be finite and non-negative")
|
|
507
|
+
record = {
|
|
508
|
+
"schema_version": 1,
|
|
509
|
+
"policy_id": POLICY_ID,
|
|
510
|
+
"policy_version": POLICY_VERSION,
|
|
511
|
+
"context_provider": {
|
|
512
|
+
"provider_id": self.context_provider.provider_id,
|
|
513
|
+
"provider_version": self.context_provider.provider_version,
|
|
514
|
+
"definition_sha256": self.context_provider.definition_sha256,
|
|
515
|
+
},
|
|
516
|
+
"scorer": {
|
|
517
|
+
"policy_id": scorer_identity[0],
|
|
518
|
+
"policy_version": scorer_identity[1],
|
|
519
|
+
"definition_sha256": scorer_identity[2],
|
|
520
|
+
},
|
|
521
|
+
"exact_combination_limit": self.exact_combination_limit,
|
|
522
|
+
"tie_tolerance_hex": self.tie_tolerance.hex(),
|
|
523
|
+
"reference": "maximum-anchor-count-feasible-slate",
|
|
524
|
+
"reference_member_count": "selected_reference_intersection",
|
|
525
|
+
"tie_break": "retain-reference-then-canonical-option-ids",
|
|
526
|
+
"outcome_access": "strictly-prior-only",
|
|
527
|
+
}
|
|
528
|
+
object.__setattr__(
|
|
529
|
+
self,
|
|
530
|
+
"definition_sha256",
|
|
531
|
+
hashlib.sha256(_POLICY_DOMAIN + _canonical_json(record)).hexdigest(),
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
def select(
|
|
535
|
+
self,
|
|
536
|
+
request: SlateAllocationRequest,
|
|
537
|
+
) -> AcquisitionCertifiedSlateDecision:
|
|
538
|
+
self.__post_init__()
|
|
539
|
+
if type(request) is not SlateAllocationRequest:
|
|
540
|
+
raise TypeError("request must be exact")
|
|
541
|
+
request.revalidate()
|
|
542
|
+
context = self.context_provider.context_for(
|
|
543
|
+
request.slate.finite_contract_sha256
|
|
544
|
+
)
|
|
545
|
+
if type(context) is not AcquisitionCertifiedSlateContext:
|
|
546
|
+
raise TypeError("context provider returned a foreign context")
|
|
547
|
+
context.__post_init__()
|
|
548
|
+
if context.finite_contract_sha256 != request.slate.finite_contract_sha256:
|
|
549
|
+
raise ValueError("acquisition context names a foreign finite contract")
|
|
550
|
+
if len(context.reference_option_ids) != request.portfolio_size:
|
|
551
|
+
raise ValueError(
|
|
552
|
+
"acquisition reference must exactly fill the evaluation portfolio"
|
|
553
|
+
)
|
|
554
|
+
feasible = feasible_slate_option_id_subsets(request)
|
|
555
|
+
if not feasible:
|
|
556
|
+
raise ValueError("proposal contains no hard-feasible evaluation slate")
|
|
557
|
+
if len(feasible) > self.exact_combination_limit:
|
|
558
|
+
raise ValueError("feasible slate count exceeds the exact certificate limit")
|
|
559
|
+
slate_ids = {value.option_id for value in request.slate.members}
|
|
560
|
+
candidate_by_id = {value.candidate_id: value for value in context.candidates}
|
|
561
|
+
if not slate_ids <= set(candidate_by_id):
|
|
562
|
+
raise ValueError("numerical context does not cover the proposal slate")
|
|
563
|
+
reference_set = set(context.reference_option_ids)
|
|
564
|
+
maximum_reference_count = max(
|
|
565
|
+
len(set(value).intersection(reference_set)) for value in feasible
|
|
566
|
+
)
|
|
567
|
+
if maximum_reference_count != request.portfolio_size:
|
|
568
|
+
raise ValueError(
|
|
569
|
+
"complete numerical reference is not hard-feasible in the proposal"
|
|
570
|
+
)
|
|
571
|
+
reference = min(
|
|
572
|
+
value
|
|
573
|
+
for value in feasible
|
|
574
|
+
if len(set(value).intersection(reference_set)) == maximum_reference_count
|
|
575
|
+
)
|
|
576
|
+
score_request = FiniteAcquisitionBatchScoreRequest(
|
|
577
|
+
campaign_scope_sha256=context.campaign_scope_sha256,
|
|
578
|
+
cutoff_index=context.cutoff_index,
|
|
579
|
+
seed=context.seed,
|
|
580
|
+
objectives=context.objectives,
|
|
581
|
+
observations=context.observations,
|
|
582
|
+
candidates=tuple(candidate_by_id[value] for value in sorted(slate_ids)),
|
|
583
|
+
slates=tuple(FiniteAcquisitionSlate(value) for value in feasible),
|
|
584
|
+
)
|
|
585
|
+
score_decision = self.scorer.score(score_request)
|
|
586
|
+
validate_finite_acquisition_batch_score_decision(
|
|
587
|
+
score_request,
|
|
588
|
+
score_decision,
|
|
589
|
+
)
|
|
590
|
+
expected_scorer = finite_acquisition_policy_identity(self.scorer)
|
|
591
|
+
if (
|
|
592
|
+
score_decision.policy_id,
|
|
593
|
+
score_decision.policy_version,
|
|
594
|
+
score_decision.policy_definition_sha256,
|
|
595
|
+
) != expected_scorer:
|
|
596
|
+
raise ValueError("batch scorer returned a foreign policy identity")
|
|
597
|
+
score_by_ids = {
|
|
598
|
+
value.slate.candidate_ids: value.log_acquisition_value
|
|
599
|
+
for value in score_decision.scores
|
|
600
|
+
}
|
|
601
|
+
best_value = max(score_by_ids.values())
|
|
602
|
+
if score_by_ids[reference] >= best_value - self.tie_tolerance:
|
|
603
|
+
selected_ids = reference
|
|
604
|
+
else:
|
|
605
|
+
selected_ids = min(
|
|
606
|
+
value
|
|
607
|
+
for value in feasible
|
|
608
|
+
if score_by_ids[value] >= best_value - self.tie_tolerance
|
|
609
|
+
)
|
|
610
|
+
member_by_id = {value.option_id: value for value in request.slate.members}
|
|
611
|
+
selected_members = tuple(
|
|
612
|
+
sorted(
|
|
613
|
+
(member_by_id[value] for value in selected_ids),
|
|
614
|
+
key=lambda value: value.model_rank,
|
|
615
|
+
)
|
|
616
|
+
)
|
|
617
|
+
selected_value = score_by_ids[selected_ids]
|
|
618
|
+
reference_value = score_by_ids[reference]
|
|
619
|
+
memory_dose_assessment = (
|
|
620
|
+
None
|
|
621
|
+
if request.memory_dose_contract is None
|
|
622
|
+
else assess_allocated_slate_memory_dose(request, selected_members)
|
|
623
|
+
)
|
|
624
|
+
if memory_dose_assessment is not None and not memory_dose_assessment.passed:
|
|
625
|
+
raise AssertionError("certified winner violated enumerated memory dose")
|
|
626
|
+
return AcquisitionCertifiedSlateDecision(
|
|
627
|
+
request=request,
|
|
628
|
+
selected=tuple(
|
|
629
|
+
AllocatedSlateMember(
|
|
630
|
+
role=SlateAllocationRole.ACQUISITION_CERTIFIED,
|
|
631
|
+
option_id=value.option_id,
|
|
632
|
+
option_identity_sha256=value.option_identity_sha256,
|
|
633
|
+
model_rank=value.model_rank,
|
|
634
|
+
role_score=float(selected_value),
|
|
635
|
+
)
|
|
636
|
+
for value in selected_members
|
|
637
|
+
),
|
|
638
|
+
reference_option_ids=reference,
|
|
639
|
+
selected_option_ids=selected_ids,
|
|
640
|
+
reference_log_acquisition_value=float(reference_value),
|
|
641
|
+
selected_log_acquisition_value=float(selected_value),
|
|
642
|
+
certificate_margin=float(selected_value - reference_value),
|
|
643
|
+
reference_member_count=len(set(selected_ids).intersection(reference_set)),
|
|
644
|
+
feasible_slate_count=len(feasible),
|
|
645
|
+
score_request=score_request,
|
|
646
|
+
score_decision=score_decision,
|
|
647
|
+
memory_dose_assessment=memory_dose_assessment,
|
|
648
|
+
policy_definition_sha256=self.definition_sha256,
|
|
649
|
+
)
|
|
650
|
+
|
|
651
|
+
def to_record(self) -> dict[str, object]:
|
|
652
|
+
self.__post_init__()
|
|
653
|
+
scorer = finite_acquisition_policy_identity(self.scorer)
|
|
654
|
+
return {
|
|
655
|
+
"policy_id": self.policy_id,
|
|
656
|
+
"policy_version": self.policy_version,
|
|
657
|
+
"definition_sha256": self.definition_sha256,
|
|
658
|
+
"context_provider": {
|
|
659
|
+
"provider_id": self.context_provider.provider_id,
|
|
660
|
+
"provider_version": self.context_provider.provider_version,
|
|
661
|
+
"definition_sha256": self.context_provider.definition_sha256,
|
|
662
|
+
},
|
|
663
|
+
"scorer": {
|
|
664
|
+
"policy_id": scorer[0],
|
|
665
|
+
"policy_version": scorer[1],
|
|
666
|
+
"definition_sha256": scorer[2],
|
|
667
|
+
},
|
|
668
|
+
"exact_combination_limit": self.exact_combination_limit,
|
|
669
|
+
"tie_tolerance_hex": self.tie_tolerance.hex(),
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
__all__ = [
|
|
674
|
+
"AcquisitionCertifiedSlateContext",
|
|
675
|
+
"AcquisitionCertifiedSlateContextProvider",
|
|
676
|
+
"AcquisitionCertifiedSlateContextRegistry",
|
|
677
|
+
"AcquisitionCertifiedSlateContextSink",
|
|
678
|
+
"AcquisitionCertifiedSlateDecision",
|
|
679
|
+
"AcquisitionCertifiedSlatePolicy",
|
|
680
|
+
"POLICY_ID",
|
|
681
|
+
"POLICY_VERSION",
|
|
682
|
+
"feasible_slate_option_id_subsets",
|
|
683
|
+
"finite_acquisition_policy_identity",
|
|
684
|
+
]
|