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,566 @@
|
|
|
1
|
+
"""Selected-only campaign lifecycle for target-conditioned acquisition."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import math
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from typing import Protocol
|
|
10
|
+
|
|
11
|
+
from agent_evolve.application.campaign_execution import CampaignStageRequest
|
|
12
|
+
from agent_evolve.application.evolution_campaign import CampaignGenerationKind
|
|
13
|
+
from agent_evolve.application.portfolio_campaign_runtime import (
|
|
14
|
+
CampaignPortfolioOutcomePreparation,
|
|
15
|
+
CampaignPortfolioWaveContext,
|
|
16
|
+
)
|
|
17
|
+
from agent_evolve.application.portfolio_evolution import (
|
|
18
|
+
PortfolioMemberDisposition,
|
|
19
|
+
PortfolioVariationWaveRequest,
|
|
20
|
+
PortfolioVariationWaveResult,
|
|
21
|
+
)
|
|
22
|
+
from agent_evolve.domain.typed_json import (
|
|
23
|
+
FrozenJsonObject,
|
|
24
|
+
freeze_json,
|
|
25
|
+
thaw_json,
|
|
26
|
+
typed_json_sha256,
|
|
27
|
+
)
|
|
28
|
+
from agent_evolve.policies.selection.target_conditioned_allocator import (
|
|
29
|
+
RegisteredTargetConditionedAllocationContextProvider,
|
|
30
|
+
TargetConditionedAllocationContext,
|
|
31
|
+
TargetConditionedAllocationContextProvider,
|
|
32
|
+
TargetConditionedSlateAllocatorAdapter,
|
|
33
|
+
)
|
|
34
|
+
from agent_evolve.policies.selection.target_conditioned_prequential import (
|
|
35
|
+
TargetConditionedAcquisitionState,
|
|
36
|
+
TargetConditionedAcquisitionProfile,
|
|
37
|
+
TargetConditionedMetaPrior,
|
|
38
|
+
TargetConditionedSelectedObservation,
|
|
39
|
+
TargetConditionedSlateDecision,
|
|
40
|
+
TargetConditionedStateUpdateReceipt,
|
|
41
|
+
update_target_conditioned_state,
|
|
42
|
+
)
|
|
43
|
+
from agent_evolve.ports.portfolio_selection import PortfolioSelectionRequest
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
_CUTOFF_DOMAIN = b"agent-evolve:target-conditioned-campaign-cutoff:v1\x00"
|
|
47
|
+
_SPECIFICATION_DOMAIN = (
|
|
48
|
+
b"agent-evolve:target-conditioned-campaign-specification:v1\x00"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _object(value: dict[str, object]) -> FrozenJsonObject:
|
|
53
|
+
result = freeze_json(value)
|
|
54
|
+
if type(result) is not FrozenJsonObject: # pragma: no cover - closed root.
|
|
55
|
+
raise AssertionError("target-conditioned evidence did not freeze to an object")
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _canonical_json(value: object) -> bytes:
|
|
60
|
+
return json.dumps(
|
|
61
|
+
value,
|
|
62
|
+
allow_nan=False,
|
|
63
|
+
ensure_ascii=True,
|
|
64
|
+
separators=(",", ":"),
|
|
65
|
+
sort_keys=True,
|
|
66
|
+
).encode("ascii", errors="strict")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _decimal(value: object, *, name: str) -> float:
|
|
70
|
+
if type(value) is not str:
|
|
71
|
+
raise TypeError(f"{name} must be decimal text")
|
|
72
|
+
result = float(value)
|
|
73
|
+
if not math.isfinite(result):
|
|
74
|
+
raise ValueError(f"{name} must be finite")
|
|
75
|
+
return result
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _achievement(point: tuple[float, ...], weights: tuple[float, ...]) -> float:
|
|
79
|
+
active = tuple(
|
|
80
|
+
(value, weight)
|
|
81
|
+
for value, weight in zip(point, weights, strict=True)
|
|
82
|
+
if weight > 0.0
|
|
83
|
+
)
|
|
84
|
+
if not active:
|
|
85
|
+
raise ValueError("target direction must activate at least one axis")
|
|
86
|
+
maximum = max(weight * value for value, weight in active)
|
|
87
|
+
weighted_mean = sum(weight * value for value, weight in active) / sum(
|
|
88
|
+
weight for _value, weight in active
|
|
89
|
+
)
|
|
90
|
+
return maximum + 0.05 * weighted_mean
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class SelectedTargetConditionedDecisionProvider(Protocol):
|
|
94
|
+
def __call__(
|
|
95
|
+
self,
|
|
96
|
+
wave: PortfolioVariationWaveRequest,
|
|
97
|
+
result: PortfolioVariationWaveResult,
|
|
98
|
+
) -> TargetConditionedSlateDecision: ...
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class SelectedTargetConditionedContextProvider(Protocol):
|
|
102
|
+
def __call__(
|
|
103
|
+
self,
|
|
104
|
+
wave: PortfolioVariationWaveRequest,
|
|
105
|
+
result: PortfolioVariationWaveResult,
|
|
106
|
+
) -> TargetConditionedAllocationContext: ...
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class SelectedMarginalUtilityProjector(Protocol):
|
|
110
|
+
def project(
|
|
111
|
+
self,
|
|
112
|
+
*,
|
|
113
|
+
snapshot: object,
|
|
114
|
+
results: tuple[PortfolioVariationWaveResult, ...],
|
|
115
|
+
) -> tuple[tuple[float, ...], ...]: ...
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@dataclass(frozen=True, slots=True)
|
|
119
|
+
class TargetConditionedCampaignSpecification:
|
|
120
|
+
"""Portable frozen prior/profile pair used by every workload launcher."""
|
|
121
|
+
|
|
122
|
+
profile: TargetConditionedAcquisitionProfile
|
|
123
|
+
meta_prior: TargetConditionedMetaPrior
|
|
124
|
+
|
|
125
|
+
def __post_init__(self) -> None:
|
|
126
|
+
if type(self.profile) is not TargetConditionedAcquisitionProfile:
|
|
127
|
+
raise TypeError("profile must be exact")
|
|
128
|
+
self.profile.__post_init__()
|
|
129
|
+
if type(self.meta_prior) is not TargetConditionedMetaPrior:
|
|
130
|
+
raise TypeError("meta_prior must be exact")
|
|
131
|
+
self.meta_prior.__post_init__()
|
|
132
|
+
if (
|
|
133
|
+
self.meta_prior.marginal_head.feature_names
|
|
134
|
+
!= self.meta_prior.direction_head.feature_names
|
|
135
|
+
):
|
|
136
|
+
raise ValueError("target-conditioned prior feature schemas disagree")
|
|
137
|
+
|
|
138
|
+
@classmethod
|
|
139
|
+
def from_freeze_record(
|
|
140
|
+
cls, record: object
|
|
141
|
+
) -> TargetConditionedCampaignSpecification:
|
|
142
|
+
if type(record) is not dict:
|
|
143
|
+
raise TypeError("target-conditioned freeze record must be an object")
|
|
144
|
+
if record.get("schema_version") != 1:
|
|
145
|
+
raise ValueError("unsupported target-conditioned freeze schema")
|
|
146
|
+
if record.get("artifact_id") != "trap_portable_profile_v1":
|
|
147
|
+
raise ValueError("target-conditioned freeze names a foreign artifact")
|
|
148
|
+
return cls(
|
|
149
|
+
profile=TargetConditionedAcquisitionProfile.from_record(
|
|
150
|
+
record.get("profile")
|
|
151
|
+
),
|
|
152
|
+
meta_prior=TargetConditionedMetaPrior.from_record(
|
|
153
|
+
record.get("meta_prior")
|
|
154
|
+
),
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def specification_sha256(self) -> str:
|
|
159
|
+
self.__post_init__()
|
|
160
|
+
return hashlib.sha256(
|
|
161
|
+
_SPECIFICATION_DOMAIN
|
|
162
|
+
+ _canonical_json(
|
|
163
|
+
{
|
|
164
|
+
"schema_version": 1,
|
|
165
|
+
"profile": self.profile.to_record(),
|
|
166
|
+
"meta_prior": self.meta_prior.to_record(),
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
).hexdigest()
|
|
170
|
+
|
|
171
|
+
def build_allocator(
|
|
172
|
+
self,
|
|
173
|
+
context_provider: TargetConditionedAllocationContextProvider | None = None,
|
|
174
|
+
) -> TargetConditionedSlateAllocatorAdapter:
|
|
175
|
+
self.__post_init__()
|
|
176
|
+
return TargetConditionedSlateAllocatorAdapter(
|
|
177
|
+
context_provider=(
|
|
178
|
+
RegisteredTargetConditionedAllocationContextProvider()
|
|
179
|
+
if context_provider is None
|
|
180
|
+
else context_provider
|
|
181
|
+
),
|
|
182
|
+
profile=self.profile,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def initial_state(
|
|
186
|
+
self, *, campaign_scope_sha256: str
|
|
187
|
+
) -> TargetConditionedAcquisitionState:
|
|
188
|
+
self.__post_init__()
|
|
189
|
+
return self.meta_prior.initial_state(
|
|
190
|
+
campaign_scope_sha256=campaign_scope_sha256
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def selected_target_improvements(
|
|
195
|
+
decision: TargetConditionedSlateDecision,
|
|
196
|
+
allocation_context: TargetConditionedAllocationContext,
|
|
197
|
+
result: PortfolioVariationWaveResult,
|
|
198
|
+
) -> tuple[float, ...]:
|
|
199
|
+
"""Project evaluated members onto their pre-call affine target in [-1, 1]."""
|
|
200
|
+
|
|
201
|
+
if type(decision) is not TargetConditionedSlateDecision:
|
|
202
|
+
raise TypeError("decision must be exact TargetConditionedSlateDecision")
|
|
203
|
+
decision.revalidate()
|
|
204
|
+
if type(allocation_context) is not TargetConditionedAllocationContext:
|
|
205
|
+
raise TypeError("allocation_context must be exact")
|
|
206
|
+
allocation_context.__post_init__()
|
|
207
|
+
if type(result) is not PortfolioVariationWaveResult:
|
|
208
|
+
raise TypeError("result must be exact PortfolioVariationWaveResult")
|
|
209
|
+
result.__post_init__()
|
|
210
|
+
request = decision.request
|
|
211
|
+
if (
|
|
212
|
+
allocation_context.frontier_target != request.frontier_target
|
|
213
|
+
or allocation_context.state != request.state
|
|
214
|
+
or allocation_context.campaign_generation != request.campaign_generation
|
|
215
|
+
or allocation_context.remaining_proposal_horizon
|
|
216
|
+
!= request.remaining_proposal_horizon
|
|
217
|
+
):
|
|
218
|
+
raise ValueError("allocation context differs from the selected decision")
|
|
219
|
+
allocation_context.require_request(request.allocation_request)
|
|
220
|
+
|
|
221
|
+
archive = thaw_json(allocation_context.archive_context.payload)
|
|
222
|
+
target = thaw_json(request.frontier_target.payload)
|
|
223
|
+
if type(archive) is not dict or type(target) is not dict:
|
|
224
|
+
raise TypeError("affine archive and target payloads must be objects")
|
|
225
|
+
frame = archive.get("optimization_frame")
|
|
226
|
+
parent = archive.get("parent")
|
|
227
|
+
target_direction = target.get("target_direction")
|
|
228
|
+
assigned_parent = target.get("assigned_parent")
|
|
229
|
+
if any(
|
|
230
|
+
type(value) is not dict
|
|
231
|
+
for value in (frame, parent, target_direction, assigned_parent)
|
|
232
|
+
):
|
|
233
|
+
raise ValueError("affine archive or target payload is incomplete")
|
|
234
|
+
axes_raw = frame.get("axes")
|
|
235
|
+
parent_raw = parent.get("normalized_point_decimal")
|
|
236
|
+
weights_raw = target_direction.get("normalized_weights_decimal")
|
|
237
|
+
assigned_parent_raw = assigned_parent.get("normalized_point_decimal")
|
|
238
|
+
if (
|
|
239
|
+
type(axes_raw) is not list
|
|
240
|
+
or len(axes_raw) not in (2, 3)
|
|
241
|
+
or type(parent_raw) is not list
|
|
242
|
+
or type(weights_raw) is not list
|
|
243
|
+
or type(assigned_parent_raw) is not list
|
|
244
|
+
or len(parent_raw) != len(axes_raw)
|
|
245
|
+
or len(weights_raw) != len(axes_raw)
|
|
246
|
+
or len(assigned_parent_raw) != len(axes_raw)
|
|
247
|
+
):
|
|
248
|
+
raise ValueError("affine target geometry has an unsupported shape")
|
|
249
|
+
|
|
250
|
+
axes: list[tuple[str, str, float, float]] = []
|
|
251
|
+
for index, raw in enumerate(axes_raw):
|
|
252
|
+
if type(raw) is not dict:
|
|
253
|
+
raise TypeError(f"archive axis {index} must be an object")
|
|
254
|
+
metric_id = raw.get("metric_id")
|
|
255
|
+
goal = raw.get("source_goal")
|
|
256
|
+
if type(metric_id) is not str or not metric_id:
|
|
257
|
+
raise ValueError(f"archive axis {index} omitted metric_id")
|
|
258
|
+
if goal not in ("min", "max"):
|
|
259
|
+
raise ValueError(f"archive axis {index} has an unsupported source_goal")
|
|
260
|
+
ideal = _decimal(raw.get("ideal_decimal"), name=f"axis[{index}].ideal")
|
|
261
|
+
reference = _decimal(
|
|
262
|
+
raw.get("reference_decimal"), name=f"axis[{index}].reference"
|
|
263
|
+
)
|
|
264
|
+
if (goal == "min" and not reference > ideal) or (
|
|
265
|
+
goal == "max" and not ideal > reference
|
|
266
|
+
):
|
|
267
|
+
raise ValueError(f"archive axis {index} has invalid affine bounds")
|
|
268
|
+
axes.append((metric_id, goal, ideal, reference))
|
|
269
|
+
metric_ids = tuple(value[0] for value in axes)
|
|
270
|
+
if len(set(metric_ids)) != len(metric_ids):
|
|
271
|
+
raise ValueError("affine archive axes repeat a metric ID")
|
|
272
|
+
|
|
273
|
+
parent_point = tuple(
|
|
274
|
+
_decimal(value, name="archive parent point") for value in parent_raw
|
|
275
|
+
)
|
|
276
|
+
assigned_parent_point = tuple(
|
|
277
|
+
_decimal(value, name="target parent point") for value in assigned_parent_raw
|
|
278
|
+
)
|
|
279
|
+
if any(
|
|
280
|
+
not math.isclose(left, right, rel_tol=0.0, abs_tol=1e-12)
|
|
281
|
+
for left, right in zip(parent_point, assigned_parent_point, strict=True)
|
|
282
|
+
):
|
|
283
|
+
raise ValueError("frontier target parent differs from archive context")
|
|
284
|
+
weights = tuple(_decimal(value, name="target weight") for value in weights_raw)
|
|
285
|
+
if any(value < 0.0 for value in weights) or max(weights) <= 0.0:
|
|
286
|
+
raise ValueError("target weights must be non-negative and non-zero")
|
|
287
|
+
parent_achievement = _decimal(
|
|
288
|
+
assigned_parent.get("achievement_decimal"),
|
|
289
|
+
name="parent achievement",
|
|
290
|
+
)
|
|
291
|
+
recomputed_parent_achievement = _achievement(parent_point, weights)
|
|
292
|
+
if not math.isclose(
|
|
293
|
+
parent_achievement,
|
|
294
|
+
recomputed_parent_achievement,
|
|
295
|
+
rel_tol=0.0,
|
|
296
|
+
abs_tol=1e-12,
|
|
297
|
+
):
|
|
298
|
+
raise ValueError("frontier target parent achievement is invalid")
|
|
299
|
+
opportunity = _decimal(
|
|
300
|
+
target_direction.get("opportunity_from_ideal_decimal"),
|
|
301
|
+
name="target opportunity",
|
|
302
|
+
)
|
|
303
|
+
if opportunity < 0.0:
|
|
304
|
+
raise ValueError("target opportunity must be non-negative")
|
|
305
|
+
denominator = max(opportunity, parent_achievement, 1e-12)
|
|
306
|
+
|
|
307
|
+
selected_ids = tuple(value.option_id for value in decision.selected)
|
|
308
|
+
received_ids = tuple(
|
|
309
|
+
value.materialization.option_id for value in result.receipt.members
|
|
310
|
+
)
|
|
311
|
+
if selected_ids != received_ids:
|
|
312
|
+
raise ValueError("selected decision differs from evaluated member order")
|
|
313
|
+
values: list[float] = []
|
|
314
|
+
for member, outcome in zip(result.receipt.members, result.outcomes, strict=True):
|
|
315
|
+
if member.disposition is PortfolioMemberDisposition.CANDIDATE_INFEASIBLE:
|
|
316
|
+
values.append(-1.0)
|
|
317
|
+
continue
|
|
318
|
+
candidate = outcome.candidate
|
|
319
|
+
if candidate is None:
|
|
320
|
+
raise ValueError("scored selected outcome omitted its candidate")
|
|
321
|
+
objective_map = candidate.objective_map
|
|
322
|
+
if set(objective_map) != set(metric_ids):
|
|
323
|
+
raise ValueError("candidate objectives differ from affine archive axes")
|
|
324
|
+
point = []
|
|
325
|
+
for metric_id, goal, ideal, reference in axes:
|
|
326
|
+
raw_value = float(objective_map[metric_id])
|
|
327
|
+
if not math.isfinite(raw_value):
|
|
328
|
+
raise ValueError("candidate objective must be finite")
|
|
329
|
+
normalized = (
|
|
330
|
+
(raw_value - ideal) / (reference - ideal)
|
|
331
|
+
if goal == "min"
|
|
332
|
+
else (ideal - raw_value) / (ideal - reference)
|
|
333
|
+
)
|
|
334
|
+
point.append(normalized)
|
|
335
|
+
candidate_achievement = _achievement(tuple(point), weights)
|
|
336
|
+
improvement = (parent_achievement - candidate_achievement) / denominator
|
|
337
|
+
values.append(max(-1.0, min(1.0, improvement)))
|
|
338
|
+
return tuple(values)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@dataclass(slots=True)
|
|
342
|
+
class TargetConditionedCampaignOutcomeUpdater:
|
|
343
|
+
"""Prepare and atomically publish selected-only T-RAP posterior updates."""
|
|
344
|
+
|
|
345
|
+
state: TargetConditionedAcquisitionState
|
|
346
|
+
selected_decision: SelectedTargetConditionedDecisionProvider
|
|
347
|
+
selected_context: SelectedTargetConditionedContextProvider
|
|
348
|
+
marginal_utility: SelectedMarginalUtilityProjector
|
|
349
|
+
_prepared: dict[
|
|
350
|
+
str,
|
|
351
|
+
tuple[CampaignPortfolioOutcomePreparation, TargetConditionedStateUpdateReceipt],
|
|
352
|
+
] = field(init=False, default_factory=dict, repr=False)
|
|
353
|
+
|
|
354
|
+
def __post_init__(self) -> None:
|
|
355
|
+
if type(self.state) is not TargetConditionedAcquisitionState:
|
|
356
|
+
raise TypeError("state must be exact TargetConditionedAcquisitionState")
|
|
357
|
+
self.state.__post_init__()
|
|
358
|
+
if not callable(self.selected_decision):
|
|
359
|
+
raise TypeError("selected_decision must be callable")
|
|
360
|
+
if not callable(self.selected_context):
|
|
361
|
+
raise TypeError("selected_context must be callable")
|
|
362
|
+
if not callable(getattr(self.marginal_utility, "project", None)):
|
|
363
|
+
raise TypeError("marginal_utility must implement its projection port")
|
|
364
|
+
|
|
365
|
+
def context_for_wave(
|
|
366
|
+
self,
|
|
367
|
+
*,
|
|
368
|
+
build: CampaignPortfolioWaveContext,
|
|
369
|
+
selection: PortfolioSelectionRequest,
|
|
370
|
+
) -> TargetConditionedAllocationContext:
|
|
371
|
+
"""Build one complete pre-call context from generic campaign facts."""
|
|
372
|
+
|
|
373
|
+
self.__post_init__()
|
|
374
|
+
if type(build) is not CampaignPortfolioWaveContext:
|
|
375
|
+
raise TypeError("build must be exact CampaignPortfolioWaveContext")
|
|
376
|
+
build.__post_init__()
|
|
377
|
+
if type(selection) is not PortfolioSelectionRequest:
|
|
378
|
+
raise TypeError("selection must be exact PortfolioSelectionRequest")
|
|
379
|
+
selection.__post_init__()
|
|
380
|
+
archive_context = build.archive_context
|
|
381
|
+
frontier_target = build.frontier_target
|
|
382
|
+
if archive_context is None or frontier_target is None:
|
|
383
|
+
raise ValueError(
|
|
384
|
+
"target-conditioned waves require archive context and frontier target"
|
|
385
|
+
)
|
|
386
|
+
generation = build.stage_request.step.generation
|
|
387
|
+
future_portfolio_generations = sum(
|
|
388
|
+
value.kind is CampaignGenerationKind.PORTFOLIO
|
|
389
|
+
and value.generation > generation
|
|
390
|
+
for value in build.prepared.schedule.steps
|
|
391
|
+
)
|
|
392
|
+
cutoff_record = {
|
|
393
|
+
"schema_version": 1,
|
|
394
|
+
"campaign_state_sha256": self.state.state_sha256,
|
|
395
|
+
"archive_cutoff_request_sha256": (
|
|
396
|
+
build.stage_request.archive_cutoff.request_sha256
|
|
397
|
+
),
|
|
398
|
+
"archive_utility_snapshot_sha256": (
|
|
399
|
+
build.stage_request.archive_utility.snapshot_sha256
|
|
400
|
+
),
|
|
401
|
+
"frontier_target_sha256": frontier_target.target_sha256,
|
|
402
|
+
"generation": generation,
|
|
403
|
+
"lane_id": build.parent_lane.lane_id,
|
|
404
|
+
"current_or_future_outcomes_consulted": False,
|
|
405
|
+
}
|
|
406
|
+
return TargetConditionedAllocationContext(
|
|
407
|
+
finite_contract_sha256=(
|
|
408
|
+
selection.finite_variation_contract.identity_sha256
|
|
409
|
+
),
|
|
410
|
+
cutoff_receipt_sha256=hashlib.sha256(
|
|
411
|
+
_CUTOFF_DOMAIN + _canonical_json(cutoff_record)
|
|
412
|
+
).hexdigest(),
|
|
413
|
+
archive_context=archive_context,
|
|
414
|
+
frontier_target=frontier_target,
|
|
415
|
+
state=self.state,
|
|
416
|
+
transition_receipts=(),
|
|
417
|
+
campaign_generation=generation,
|
|
418
|
+
lane_slot=build.parent_slot,
|
|
419
|
+
remaining_proposal_horizon=future_portfolio_generations,
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
async def prepare_update(
|
|
423
|
+
self,
|
|
424
|
+
request: CampaignStageRequest,
|
|
425
|
+
waves: tuple[PortfolioVariationWaveRequest, ...],
|
|
426
|
+
results: tuple[PortfolioVariationWaveResult, ...],
|
|
427
|
+
prior_memory: FrozenJsonObject,
|
|
428
|
+
) -> CampaignPortfolioOutcomePreparation:
|
|
429
|
+
self.__post_init__()
|
|
430
|
+
if type(request) is not CampaignStageRequest:
|
|
431
|
+
raise TypeError("request must be exact CampaignStageRequest")
|
|
432
|
+
request.__post_init__()
|
|
433
|
+
if request.step.kind is not CampaignGenerationKind.PORTFOLIO:
|
|
434
|
+
raise ValueError("target-conditioned updates require a portfolio stage")
|
|
435
|
+
if (
|
|
436
|
+
type(waves) is not tuple
|
|
437
|
+
or type(results) is not tuple
|
|
438
|
+
or not waves
|
|
439
|
+
or len(waves) != len(results)
|
|
440
|
+
):
|
|
441
|
+
raise ValueError("waves and results must be equal non-empty tuples")
|
|
442
|
+
if type(prior_memory) is not FrozenJsonObject:
|
|
443
|
+
raise TypeError("prior_memory must be an exact frozen object")
|
|
444
|
+
decisions = tuple(
|
|
445
|
+
self.selected_decision(wave, result)
|
|
446
|
+
for wave, result in zip(waves, results, strict=True)
|
|
447
|
+
)
|
|
448
|
+
contexts = tuple(
|
|
449
|
+
self.selected_context(wave, result)
|
|
450
|
+
for wave, result in zip(waves, results, strict=True)
|
|
451
|
+
)
|
|
452
|
+
if any(type(value) is not TargetConditionedSlateDecision for value in decisions):
|
|
453
|
+
raise TypeError("decision provider returned a foreign allocation")
|
|
454
|
+
if any(type(value) is not TargetConditionedAllocationContext for value in contexts):
|
|
455
|
+
raise TypeError("context provider returned a foreign allocation context")
|
|
456
|
+
marginal = self.marginal_utility.project(
|
|
457
|
+
snapshot=request.archive_utility,
|
|
458
|
+
results=results,
|
|
459
|
+
)
|
|
460
|
+
if len(marginal) != len(results):
|
|
461
|
+
raise ValueError("marginal utility projection differs from wave count")
|
|
462
|
+
observations: list[TargetConditionedSelectedObservation] = []
|
|
463
|
+
for decision, allocation_context, result, utilities in zip(
|
|
464
|
+
decisions, contexts, results, marginal, strict=True
|
|
465
|
+
):
|
|
466
|
+
if len(utilities) != len(result.receipt.members):
|
|
467
|
+
raise ValueError("marginal utilities differ from selected members")
|
|
468
|
+
selected_ids = tuple(value.option_id for value in decision.selected)
|
|
469
|
+
receipt_ids = tuple(
|
|
470
|
+
value.materialization.option_id for value in result.receipt.members
|
|
471
|
+
)
|
|
472
|
+
if selected_ids != receipt_ids:
|
|
473
|
+
raise ValueError("T-RAP allocation differs from evaluated member order")
|
|
474
|
+
improvements = selected_target_improvements(
|
|
475
|
+
decision,
|
|
476
|
+
allocation_context,
|
|
477
|
+
result,
|
|
478
|
+
)
|
|
479
|
+
features = {
|
|
480
|
+
value.option_id: value for value in decision.request.member_features
|
|
481
|
+
}
|
|
482
|
+
for selected, member, utility, improvement in zip(
|
|
483
|
+
decision.selected,
|
|
484
|
+
result.receipt.members,
|
|
485
|
+
utilities,
|
|
486
|
+
improvements,
|
|
487
|
+
strict=True,
|
|
488
|
+
):
|
|
489
|
+
feature = features[selected.option_id]
|
|
490
|
+
observations.append(
|
|
491
|
+
TargetConditionedSelectedObservation(
|
|
492
|
+
decision_sha256=decision.decision_sha256,
|
|
493
|
+
campaign_generation=request.step.generation,
|
|
494
|
+
option_id=selected.option_id,
|
|
495
|
+
option_identity_sha256=selected.option_identity_sha256,
|
|
496
|
+
feature_row_sha256=feature.feature_row_sha256,
|
|
497
|
+
feature_values=feature.values,
|
|
498
|
+
normalized_marginal_utility=float(utility),
|
|
499
|
+
normalized_target_improvement=improvement,
|
|
500
|
+
evaluator_receipt_sha256=member.outcome_sha256,
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
update = update_target_conditioned_state(
|
|
504
|
+
self.state,
|
|
505
|
+
decisions=decisions,
|
|
506
|
+
observations=tuple(observations),
|
|
507
|
+
)
|
|
508
|
+
preparation = CampaignPortfolioOutcomePreparation(
|
|
509
|
+
request_sha256=request.request_sha256,
|
|
510
|
+
generation=request.step.generation,
|
|
511
|
+
wave_request_sha256s=tuple(
|
|
512
|
+
value.selection_request.request_sha256 for value in waves
|
|
513
|
+
),
|
|
514
|
+
result_receipt_sha256s=tuple(
|
|
515
|
+
value.receipt.receipt_sha256 for value in results
|
|
516
|
+
),
|
|
517
|
+
prior_memory_sha256=typed_json_sha256(prior_memory),
|
|
518
|
+
updated_memory=prior_memory,
|
|
519
|
+
evidence=_object(
|
|
520
|
+
{
|
|
521
|
+
"schema_version": 1,
|
|
522
|
+
"target_conditioned_state_update": update.to_record(),
|
|
523
|
+
"marginal_label_scope": (
|
|
524
|
+
"selected_fixed_reference_candidate_marginal_utility"
|
|
525
|
+
),
|
|
526
|
+
"target_label_scope": (
|
|
527
|
+
"selected_affine_target_achievement_improvement"
|
|
528
|
+
),
|
|
529
|
+
"rejected_outcomes_consulted": False,
|
|
530
|
+
"provider_calls": 0,
|
|
531
|
+
}
|
|
532
|
+
),
|
|
533
|
+
)
|
|
534
|
+
if preparation.preparation_sha256 in self._prepared:
|
|
535
|
+
raise ValueError("target-conditioned update is already pending")
|
|
536
|
+
self._prepared[preparation.preparation_sha256] = (preparation, update)
|
|
537
|
+
return preparation
|
|
538
|
+
|
|
539
|
+
def commit_update(self, preparation: CampaignPortfolioOutcomePreparation) -> None:
|
|
540
|
+
pending = self._require_pending(preparation)
|
|
541
|
+
self._prepared.pop(preparation.preparation_sha256)
|
|
542
|
+
self.state = pending.next_state
|
|
543
|
+
|
|
544
|
+
def abort_update(self, preparation: CampaignPortfolioOutcomePreparation) -> None:
|
|
545
|
+
self._require_pending(preparation)
|
|
546
|
+
self._prepared.pop(preparation.preparation_sha256)
|
|
547
|
+
|
|
548
|
+
def _require_pending(
|
|
549
|
+
self, preparation: CampaignPortfolioOutcomePreparation
|
|
550
|
+
) -> TargetConditionedStateUpdateReceipt:
|
|
551
|
+
if type(preparation) is not CampaignPortfolioOutcomePreparation:
|
|
552
|
+
raise TypeError("preparation must be exact")
|
|
553
|
+
preparation.__post_init__()
|
|
554
|
+
pending = self._prepared.get(preparation.preparation_sha256)
|
|
555
|
+
if pending is None or pending[0] != preparation:
|
|
556
|
+
raise ValueError("target-conditioned update is foreign or not pending")
|
|
557
|
+
return pending[1]
|
|
558
|
+
|
|
559
|
+
__all__ = [
|
|
560
|
+
"SelectedMarginalUtilityProjector",
|
|
561
|
+
"SelectedTargetConditionedContextProvider",
|
|
562
|
+
"SelectedTargetConditionedDecisionProvider",
|
|
563
|
+
"TargetConditionedCampaignSpecification",
|
|
564
|
+
"TargetConditionedCampaignOutcomeUpdater",
|
|
565
|
+
"selected_target_improvements",
|
|
566
|
+
]
|