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,640 @@
|
|
|
1
|
+
"""Authenticated inner-policy inputs for calibrated portfolio allocation.
|
|
2
|
+
|
|
3
|
+
The provider adapter must freeze this binding before it sends a prompt. It
|
|
4
|
+
therefore cannot choose structural evidence after observing the model's slate,
|
|
5
|
+
and the model cannot author calibration, objective, or archive facts.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
|
|
16
|
+
from agent_evolve.domain.finite_variation import FiniteVariationOption
|
|
17
|
+
from agent_evolve.domain.patch import require_sha256
|
|
18
|
+
from agent_evolve.policies.selection.calibrated_slate import (
|
|
19
|
+
SlateMetricObjective,
|
|
20
|
+
SlateStructuralEvidence,
|
|
21
|
+
)
|
|
22
|
+
from agent_evolve.policies.selection.forecast_calibration import (
|
|
23
|
+
ForecastCalibrationScope,
|
|
24
|
+
ForecastCalibrationSnapshot,
|
|
25
|
+
)
|
|
26
|
+
from agent_evolve.policies.selection.proposal_support import (
|
|
27
|
+
ProposalSupportCandidate,
|
|
28
|
+
ProposalSupportDecision,
|
|
29
|
+
StructuralProposalSupportPolicy,
|
|
30
|
+
)
|
|
31
|
+
from agent_evolve.policies.selection.finite_option_prompt_projection import (
|
|
32
|
+
FiniteOptionPromptProjection,
|
|
33
|
+
)
|
|
34
|
+
from agent_evolve.policies.selection.common_candidate_pool import (
|
|
35
|
+
CommonCandidatePoolDecision,
|
|
36
|
+
TaskKeyedCommonCandidatePoolPolicy,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.policies.variation.compositional_finite_catalog import (
|
|
39
|
+
COMPOSITION_REQUIRED_PROPOSALS_METADATA_KEY,
|
|
40
|
+
COMPOSITION_SELECTION_EXPOSURE_METADATA_KEY,
|
|
41
|
+
CompositionSelectionExposure,
|
|
42
|
+
)
|
|
43
|
+
from agent_evolve.policies.variation.source_union_finite_catalog import (
|
|
44
|
+
required_source_evaluation_option_ids,
|
|
45
|
+
)
|
|
46
|
+
from agent_evolve.ports.portfolio_selection import PortfolioSelectionRequest
|
|
47
|
+
from agent_evolve.ports.contextual_search_allocation import (
|
|
48
|
+
ContextualPortfolioAllocationContract,
|
|
49
|
+
)
|
|
50
|
+
from agent_evolve.ports.variation_source import (
|
|
51
|
+
finite_variation_candidate_pool_required_option_ids,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
|
|
56
|
+
_OPTION_ID = re.compile(r"^[a-z][a-z0-9_.-]{0,255}$")
|
|
57
|
+
_BINDING_DOMAIN = b"agent-evolve:calibrated-portfolio-input-binding:v1\x00"
|
|
58
|
+
_PROJECTED_BINDING_DOMAIN = (
|
|
59
|
+
b"agent-evolve:calibrated-portfolio-input-binding:v2\x00"
|
|
60
|
+
)
|
|
61
|
+
_COMMON_POOL_BINDING_DOMAIN = (
|
|
62
|
+
b"agent-evolve:calibrated-portfolio-input-binding:v4-common-pool-required\x00"
|
|
63
|
+
)
|
|
64
|
+
_PROPOSAL_SUPPORT_BINDING_DOMAIN = (
|
|
65
|
+
b"agent-evolve:calibrated-portfolio-input-binding:v5-proposal-support\x00"
|
|
66
|
+
)
|
|
67
|
+
_CONTEXTUAL_ALLOCATION_BINDING_DOMAIN = (
|
|
68
|
+
b"agent-evolve:calibrated-portfolio-input-binding:v6-contextual-allocation\x00"
|
|
69
|
+
)
|
|
70
|
+
_HIERARCHICAL_POOL_SUPPORT_DOMAIN = (
|
|
71
|
+
b"agent-evolve:calibrated-hierarchical-pool-support:v1\x00"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _canonical_json(value: object) -> bytes:
|
|
76
|
+
return json.dumps(
|
|
77
|
+
value,
|
|
78
|
+
allow_nan=False,
|
|
79
|
+
ensure_ascii=True,
|
|
80
|
+
separators=(",", ":"),
|
|
81
|
+
sort_keys=True,
|
|
82
|
+
).encode("ascii", errors="strict")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _canonical_card_keys(values: tuple[str, ...], *, name: str) -> None:
|
|
86
|
+
if type(values) is not tuple or any(
|
|
87
|
+
type(value) is not str or _TOKEN.fullmatch(value) is None for value in values
|
|
88
|
+
):
|
|
89
|
+
raise TypeError(f"{name} must be an exact tuple of closed card keys")
|
|
90
|
+
if values != tuple(sorted(set(values))):
|
|
91
|
+
raise ValueError(f"{name} must be unique and canonical")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def common_pool_required_option_ids(
|
|
95
|
+
request: PortfolioSelectionRequest,
|
|
96
|
+
) -> tuple[str, ...]:
|
|
97
|
+
"""Return every precommitted action required in the common candidate pool.
|
|
98
|
+
|
|
99
|
+
Advisory cards do not alter pool membership. A bounded dose, however,
|
|
100
|
+
cannot be an honest provider constraint when all of its compatible finite
|
|
101
|
+
actions were removed by an earlier model-blind pool sample. Binding the
|
|
102
|
+
complete support union into the pool decision closes that failure mode.
|
|
103
|
+
Scientific matched arms may also name the same explicit pool actions in M
|
|
104
|
+
and N, preventing candidate-availability leakage when the neutral view has
|
|
105
|
+
no prompt-visible action evidence. Both sources remain workload-, model-,
|
|
106
|
+
provider-, and outcome-neutral.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
if type(request) is not PortfolioSelectionRequest:
|
|
110
|
+
raise TypeError("request must be an exact PortfolioSelectionRequest")
|
|
111
|
+
request.__post_init__()
|
|
112
|
+
hierarchical: list[tuple[str, int]] = []
|
|
113
|
+
for option in request.finite_variation_contract.options:
|
|
114
|
+
metadata = dict(option.metadata)
|
|
115
|
+
if metadata.get(COMPOSITION_SELECTION_EXPOSURE_METADATA_KEY) != (
|
|
116
|
+
CompositionSelectionExposure.HIERARCHICAL_RANKED_UNION.value
|
|
117
|
+
):
|
|
118
|
+
continue
|
|
119
|
+
try:
|
|
120
|
+
required = int(metadata[COMPOSITION_REQUIRED_PROPOSALS_METADATA_KEY])
|
|
121
|
+
except (KeyError, ValueError) as error:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
"hierarchical finite option omitted its pool-support count"
|
|
124
|
+
) from error
|
|
125
|
+
hierarchical.append((option.option_id, required))
|
|
126
|
+
topology_support: tuple[str, ...] = ()
|
|
127
|
+
if hierarchical:
|
|
128
|
+
counts = {value[1] for value in hierarchical}
|
|
129
|
+
if len(counts) != 1:
|
|
130
|
+
raise ValueError("hierarchical finite options disagree on support count")
|
|
131
|
+
required = next(iter(counts))
|
|
132
|
+
if not 1 <= required < 8 or len(hierarchical) < required:
|
|
133
|
+
raise ValueError("hierarchical finite contract has invalid pool support")
|
|
134
|
+
contract_sha256 = request.finite_variation_contract.identity_sha256
|
|
135
|
+
topology_support = tuple(
|
|
136
|
+
option_id
|
|
137
|
+
for option_id, _count in sorted(
|
|
138
|
+
hierarchical,
|
|
139
|
+
key=lambda value: (
|
|
140
|
+
hashlib.sha256(
|
|
141
|
+
_HIERARCHICAL_POOL_SUPPORT_DOMAIN
|
|
142
|
+
+ bytes.fromhex(contract_sha256)
|
|
143
|
+
+ value[0].encode("ascii", errors="strict")
|
|
144
|
+
).digest(),
|
|
145
|
+
value[0],
|
|
146
|
+
),
|
|
147
|
+
)[:required]
|
|
148
|
+
)
|
|
149
|
+
return tuple(
|
|
150
|
+
sorted(
|
|
151
|
+
{
|
|
152
|
+
*request.candidate_pool_required_option_ids,
|
|
153
|
+
*finite_variation_candidate_pool_required_option_ids(
|
|
154
|
+
request.finite_variation_contract
|
|
155
|
+
),
|
|
156
|
+
*topology_support,
|
|
157
|
+
*required_source_evaluation_option_ids(
|
|
158
|
+
request.finite_variation_contract
|
|
159
|
+
),
|
|
160
|
+
*(
|
|
161
|
+
option_id
|
|
162
|
+
for support in (
|
|
163
|
+
()
|
|
164
|
+
if request.memory_dose_contract is None
|
|
165
|
+
else request.memory_dose_contract.card_supports
|
|
166
|
+
)
|
|
167
|
+
for option_id, _option_identity_sha256 in support.compatible_options
|
|
168
|
+
),
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass(frozen=True, slots=True)
|
|
175
|
+
class CalibratedPortfolioAllocationContext:
|
|
176
|
+
"""Prior-only engine facts frozen before one current-wave model call."""
|
|
177
|
+
|
|
178
|
+
scope: ForecastCalibrationScope
|
|
179
|
+
wave_index: int
|
|
180
|
+
parent_candidate_identity_sha256: str
|
|
181
|
+
objectives: tuple[SlateMetricObjective, ...]
|
|
182
|
+
assigned_card_keys: tuple[str, ...]
|
|
183
|
+
calibration_snapshot: ForecastCalibrationSnapshot
|
|
184
|
+
|
|
185
|
+
def __post_init__(self) -> None:
|
|
186
|
+
if type(self.scope) is not ForecastCalibrationScope:
|
|
187
|
+
raise TypeError("scope must be exact ForecastCalibrationScope")
|
|
188
|
+
self.scope.revalidate()
|
|
189
|
+
if type(self.wave_index) is not int or self.wave_index <= 0:
|
|
190
|
+
raise ValueError("wave_index must be a positive exact integer")
|
|
191
|
+
require_sha256(
|
|
192
|
+
self.parent_candidate_identity_sha256,
|
|
193
|
+
"parent_candidate_identity_sha256",
|
|
194
|
+
)
|
|
195
|
+
if (
|
|
196
|
+
type(self.objectives) is not tuple
|
|
197
|
+
or not self.objectives
|
|
198
|
+
or any(type(value) is not SlateMetricObjective for value in self.objectives)
|
|
199
|
+
):
|
|
200
|
+
raise ValueError("objectives must contain exact metric objectives")
|
|
201
|
+
for value in self.objectives:
|
|
202
|
+
value.__post_init__()
|
|
203
|
+
objective_ids = tuple(value.metric_id for value in self.objectives)
|
|
204
|
+
if objective_ids != tuple(sorted(set(objective_ids))):
|
|
205
|
+
raise ValueError("objectives must use unique canonical metric order")
|
|
206
|
+
_canonical_card_keys(self.assigned_card_keys, name="assigned_card_keys")
|
|
207
|
+
if type(self.calibration_snapshot) is not ForecastCalibrationSnapshot:
|
|
208
|
+
raise TypeError("calibration_snapshot must be exact")
|
|
209
|
+
self.calibration_snapshot.revalidate()
|
|
210
|
+
if self.calibration_snapshot.scope != self.scope:
|
|
211
|
+
raise ValueError("calibration snapshot has a foreign scope")
|
|
212
|
+
if self.calibration_snapshot.cutoff_wave_index_exclusive > self.wave_index:
|
|
213
|
+
raise ValueError(
|
|
214
|
+
"current/future-wave calibration evidence cannot allocate this wave"
|
|
215
|
+
)
|
|
216
|
+
if any(
|
|
217
|
+
value.prediction.wave_index >= self.wave_index
|
|
218
|
+
for value in self.calibration_snapshot.observations
|
|
219
|
+
):
|
|
220
|
+
raise ValueError(
|
|
221
|
+
"current/future-wave calibration evidence cannot allocate this wave"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
def revalidate(self) -> None:
|
|
225
|
+
if type(self) is not CalibratedPortfolioAllocationContext:
|
|
226
|
+
raise TypeError("context must be exact CalibratedPortfolioAllocationContext")
|
|
227
|
+
CalibratedPortfolioAllocationContext.__post_init__(self)
|
|
228
|
+
|
|
229
|
+
def to_record(self) -> dict[str, object]:
|
|
230
|
+
self.revalidate()
|
|
231
|
+
return {
|
|
232
|
+
"schema_version": 1,
|
|
233
|
+
"scope": self.scope.to_record(),
|
|
234
|
+
"wave_index": self.wave_index,
|
|
235
|
+
"parent_candidate_identity_sha256": (
|
|
236
|
+
self.parent_candidate_identity_sha256
|
|
237
|
+
),
|
|
238
|
+
"objectives": [value.to_record() for value in self.objectives],
|
|
239
|
+
"assigned_card_keys": list(self.assigned_card_keys),
|
|
240
|
+
"calibration_snapshot": self.calibration_snapshot.to_record(),
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@dataclass(frozen=True, slots=True)
|
|
245
|
+
class CalibratedPortfolioOptionEvidence:
|
|
246
|
+
"""Workload-owned structural projection for one exact sealed option."""
|
|
247
|
+
|
|
248
|
+
option_id: str
|
|
249
|
+
option_identity_sha256: str
|
|
250
|
+
locus_key: str
|
|
251
|
+
phenotype_identity_sha256: str
|
|
252
|
+
structural_evidence: SlateStructuralEvidence
|
|
253
|
+
|
|
254
|
+
def __post_init__(self) -> None:
|
|
255
|
+
if (
|
|
256
|
+
type(self.option_id) is not str
|
|
257
|
+
or _OPTION_ID.fullmatch(self.option_id) is None
|
|
258
|
+
):
|
|
259
|
+
raise ValueError("option_id must use the closed token grammar")
|
|
260
|
+
require_sha256(self.option_identity_sha256, "option_identity_sha256")
|
|
261
|
+
if type(self.locus_key) is not str or _TOKEN.fullmatch(self.locus_key) is None:
|
|
262
|
+
raise ValueError("locus_key must use the closed token grammar")
|
|
263
|
+
require_sha256(
|
|
264
|
+
self.phenotype_identity_sha256,
|
|
265
|
+
"phenotype_identity_sha256",
|
|
266
|
+
)
|
|
267
|
+
if type(self.structural_evidence) is not SlateStructuralEvidence:
|
|
268
|
+
raise TypeError("structural_evidence must be exact")
|
|
269
|
+
self.structural_evidence.__post_init__()
|
|
270
|
+
|
|
271
|
+
def revalidate(self) -> None:
|
|
272
|
+
if type(self) is not CalibratedPortfolioOptionEvidence:
|
|
273
|
+
raise TypeError("evidence must be exact CalibratedPortfolioOptionEvidence")
|
|
274
|
+
CalibratedPortfolioOptionEvidence.__post_init__(self)
|
|
275
|
+
|
|
276
|
+
def to_record(self) -> dict[str, object]:
|
|
277
|
+
self.revalidate()
|
|
278
|
+
return {
|
|
279
|
+
"option_id": self.option_id,
|
|
280
|
+
"option_identity_sha256": self.option_identity_sha256,
|
|
281
|
+
"locus_key": self.locus_key,
|
|
282
|
+
"phenotype_identity_sha256": self.phenotype_identity_sha256,
|
|
283
|
+
"structural_evidence": self.structural_evidence.to_record(),
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def proposal_support_candidates(
|
|
288
|
+
request: PortfolioSelectionRequest,
|
|
289
|
+
option_evidence: tuple[CalibratedPortfolioOptionEvidence, ...],
|
|
290
|
+
common_candidate_pool: CommonCandidatePoolDecision,
|
|
291
|
+
) -> tuple[ProposalSupportCandidate, ...]:
|
|
292
|
+
"""Project the exact model-visible common pool into structural rows."""
|
|
293
|
+
|
|
294
|
+
if type(request) is not PortfolioSelectionRequest:
|
|
295
|
+
raise TypeError("request must be an exact PortfolioSelectionRequest")
|
|
296
|
+
request.__post_init__()
|
|
297
|
+
if type(option_evidence) is not tuple or any(
|
|
298
|
+
type(value) is not CalibratedPortfolioOptionEvidence
|
|
299
|
+
for value in option_evidence
|
|
300
|
+
):
|
|
301
|
+
raise TypeError("option_evidence must contain exact evidence rows")
|
|
302
|
+
for value in option_evidence:
|
|
303
|
+
value.revalidate()
|
|
304
|
+
if type(common_candidate_pool) is not CommonCandidatePoolDecision:
|
|
305
|
+
raise TypeError("common_candidate_pool must be an exact decision")
|
|
306
|
+
common_candidate_pool.__post_init__()
|
|
307
|
+
evidence_by_id = {value.option_id: value for value in option_evidence}
|
|
308
|
+
if not set(common_candidate_pool.option_ids).issubset(evidence_by_id):
|
|
309
|
+
raise ValueError("common candidate pool escapes the structural evidence")
|
|
310
|
+
contract = request.finite_variation_contract
|
|
311
|
+
# ``request.__post_init__`` above authenticates the complete finite
|
|
312
|
+
# contract once at this trust boundary. Resolving every common-pool row
|
|
313
|
+
# through ``contract.resolve`` would revalidate that complete contract for
|
|
314
|
+
# every option, making this projection quadratic for large finite spaces.
|
|
315
|
+
option_by_id = {value.option_id: value for value in contract.options}
|
|
316
|
+
if not set(common_candidate_pool.option_ids).issubset(option_by_id):
|
|
317
|
+
raise ValueError("common candidate pool escapes the sealed finite contract")
|
|
318
|
+
return tuple(
|
|
319
|
+
ProposalSupportCandidate(
|
|
320
|
+
option_id=option_id,
|
|
321
|
+
option_identity_sha256=evidence_by_id[option_id].option_identity_sha256,
|
|
322
|
+
family=option_by_id[option_id].family,
|
|
323
|
+
locus_key=evidence_by_id[option_id].locus_key,
|
|
324
|
+
phenotype_identity_sha256=(
|
|
325
|
+
evidence_by_id[option_id].phenotype_identity_sha256
|
|
326
|
+
),
|
|
327
|
+
frozen_archive_snapshot_sha256=(
|
|
328
|
+
evidence_by_id[
|
|
329
|
+
option_id
|
|
330
|
+
].structural_evidence.frozen_archive_snapshot_sha256
|
|
331
|
+
),
|
|
332
|
+
structural_evidence_receipt_sha256=(
|
|
333
|
+
evidence_by_id[
|
|
334
|
+
option_id
|
|
335
|
+
].structural_evidence.evidence_receipt_sha256
|
|
336
|
+
),
|
|
337
|
+
archive_novelty_score=(
|
|
338
|
+
evidence_by_id[option_id].structural_evidence.archive_novelty_score
|
|
339
|
+
),
|
|
340
|
+
structural_coverage_score=(
|
|
341
|
+
evidence_by_id[
|
|
342
|
+
option_id
|
|
343
|
+
].structural_evidence.structural_coverage_score
|
|
344
|
+
),
|
|
345
|
+
)
|
|
346
|
+
for option_id in common_candidate_pool.option_ids
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
351
|
+
class CalibratedPortfolioInputBinding:
|
|
352
|
+
"""One request-bound immutable context and all-option evidence snapshot."""
|
|
353
|
+
|
|
354
|
+
request_sha256: str
|
|
355
|
+
context: CalibratedPortfolioAllocationContext
|
|
356
|
+
option_evidence: tuple[CalibratedPortfolioOptionEvidence, ...]
|
|
357
|
+
option_prompt_projection: FiniteOptionPromptProjection | None = None
|
|
358
|
+
common_candidate_pool: CommonCandidatePoolDecision | None = None
|
|
359
|
+
proposal_support: ProposalSupportDecision | None = None
|
|
360
|
+
contextual_allocation: ContextualPortfolioAllocationContract | None = None
|
|
361
|
+
|
|
362
|
+
def __post_init__(self) -> None:
|
|
363
|
+
require_sha256(self.request_sha256, "request_sha256")
|
|
364
|
+
if type(self.context) is not CalibratedPortfolioAllocationContext:
|
|
365
|
+
raise TypeError("context must be exact CalibratedPortfolioAllocationContext")
|
|
366
|
+
self.context.revalidate()
|
|
367
|
+
if type(self.option_evidence) is not tuple or any(
|
|
368
|
+
type(value) is not CalibratedPortfolioOptionEvidence
|
|
369
|
+
for value in self.option_evidence
|
|
370
|
+
):
|
|
371
|
+
raise TypeError("option_evidence must contain exact evidence values")
|
|
372
|
+
if not self.option_evidence:
|
|
373
|
+
raise ValueError("option_evidence must be non-empty")
|
|
374
|
+
for value in self.option_evidence:
|
|
375
|
+
value.revalidate()
|
|
376
|
+
option_ids = tuple(value.option_id for value in self.option_evidence)
|
|
377
|
+
if option_ids != tuple(sorted(set(option_ids))):
|
|
378
|
+
raise ValueError("option_evidence must use unique canonical option order")
|
|
379
|
+
archive_snapshots = {
|
|
380
|
+
value.structural_evidence.frozen_archive_snapshot_sha256
|
|
381
|
+
for value in self.option_evidence
|
|
382
|
+
}
|
|
383
|
+
if len(archive_snapshots) != 1:
|
|
384
|
+
raise ValueError("all option evidence must share one frozen archive")
|
|
385
|
+
if self.option_prompt_projection is not None:
|
|
386
|
+
if type(self.option_prompt_projection) is not FiniteOptionPromptProjection:
|
|
387
|
+
raise TypeError(
|
|
388
|
+
"option_prompt_projection must be exact prompt projection"
|
|
389
|
+
)
|
|
390
|
+
self.option_prompt_projection.__post_init__()
|
|
391
|
+
if self.common_candidate_pool is not None:
|
|
392
|
+
if type(self.common_candidate_pool) is not CommonCandidatePoolDecision:
|
|
393
|
+
raise TypeError(
|
|
394
|
+
"common_candidate_pool must be an exact decision or None"
|
|
395
|
+
)
|
|
396
|
+
self.common_candidate_pool.__post_init__()
|
|
397
|
+
if self.proposal_support is not None:
|
|
398
|
+
if type(self.proposal_support) is not ProposalSupportDecision:
|
|
399
|
+
raise TypeError(
|
|
400
|
+
"proposal_support must be an exact decision or None"
|
|
401
|
+
)
|
|
402
|
+
self.proposal_support.__post_init__()
|
|
403
|
+
if self.common_candidate_pool is None:
|
|
404
|
+
raise ValueError(
|
|
405
|
+
"proposal support requires a task-keyed common candidate pool"
|
|
406
|
+
)
|
|
407
|
+
if self.contextual_allocation is not None:
|
|
408
|
+
if type(self.contextual_allocation) is not (
|
|
409
|
+
ContextualPortfolioAllocationContract
|
|
410
|
+
):
|
|
411
|
+
raise TypeError(
|
|
412
|
+
"contextual_allocation must be an exact contract or None"
|
|
413
|
+
)
|
|
414
|
+
self.contextual_allocation.__post_init__()
|
|
415
|
+
if (
|
|
416
|
+
self.contextual_allocation.campaign_generation
|
|
417
|
+
!= self.context.wave_index
|
|
418
|
+
):
|
|
419
|
+
raise ValueError(
|
|
420
|
+
"contextual allocation differs from the campaign generation"
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
def revalidate(self) -> None:
|
|
424
|
+
if type(self) is not CalibratedPortfolioInputBinding:
|
|
425
|
+
raise TypeError("binding must be exact CalibratedPortfolioInputBinding")
|
|
426
|
+
CalibratedPortfolioInputBinding.__post_init__(self)
|
|
427
|
+
|
|
428
|
+
def require_request(self, request: PortfolioSelectionRequest) -> None:
|
|
429
|
+
"""Authenticate the complete binding against one exact public request."""
|
|
430
|
+
|
|
431
|
+
self.revalidate()
|
|
432
|
+
if type(request) is not PortfolioSelectionRequest:
|
|
433
|
+
raise TypeError("request must be exact PortfolioSelectionRequest")
|
|
434
|
+
request.__post_init__()
|
|
435
|
+
if self.request_sha256 != request.request_sha256:
|
|
436
|
+
raise ValueError("calibrated input binding names a foreign request")
|
|
437
|
+
contract = request.finite_variation_contract
|
|
438
|
+
if (
|
|
439
|
+
self.context.parent_candidate_identity_sha256
|
|
440
|
+
!= contract.parent_configuration_sha256
|
|
441
|
+
):
|
|
442
|
+
raise ValueError("allocation context names a foreign parent")
|
|
443
|
+
if tuple(value.metric_id for value in self.context.objectives) != (
|
|
444
|
+
request.required_metric_ids
|
|
445
|
+
):
|
|
446
|
+
raise ValueError("allocation objectives differ from requested metrics")
|
|
447
|
+
request_card_keys = {value.card_key for value in request.cards}
|
|
448
|
+
if not set(self.context.assigned_card_keys).issubset(request_card_keys):
|
|
449
|
+
raise ValueError("assigned cards escape the request snapshot")
|
|
450
|
+
expected = {
|
|
451
|
+
value.option_id: value.identity_sha256 for value in contract.options
|
|
452
|
+
}
|
|
453
|
+
observed = {
|
|
454
|
+
value.option_id: value.option_identity_sha256
|
|
455
|
+
for value in self.option_evidence
|
|
456
|
+
}
|
|
457
|
+
if observed != expected:
|
|
458
|
+
raise ValueError("option evidence differs from the sealed finite contract")
|
|
459
|
+
if self.option_prompt_projection is not None:
|
|
460
|
+
self.option_prompt_projection.require_contract(contract)
|
|
461
|
+
if self.common_candidate_pool is not None:
|
|
462
|
+
policy = TaskKeyedCommonCandidatePoolPolicy(
|
|
463
|
+
replicate_seed=self.common_candidate_pool.replicate_seed,
|
|
464
|
+
candidate_pool_size=(
|
|
465
|
+
self.common_candidate_pool.candidate_pool_size
|
|
466
|
+
),
|
|
467
|
+
model_selection_size=(
|
|
468
|
+
self.common_candidate_pool.model_selection_size
|
|
469
|
+
),
|
|
470
|
+
)
|
|
471
|
+
policy.require_decision(
|
|
472
|
+
self.common_candidate_pool,
|
|
473
|
+
benchmark_sha256=self.context.scope.benchmark_sha256,
|
|
474
|
+
wave_index=self.context.wave_index,
|
|
475
|
+
parent_configuration_sha256=(
|
|
476
|
+
self.context.parent_candidate_identity_sha256
|
|
477
|
+
),
|
|
478
|
+
contract=contract,
|
|
479
|
+
evaluation_size=request.portfolio_size,
|
|
480
|
+
min_distinct_families=request.min_distinct_families,
|
|
481
|
+
require_pairwise_disjoint_parent_patches=(
|
|
482
|
+
request.require_pairwise_disjoint_parent_patches
|
|
483
|
+
),
|
|
484
|
+
required_option_ids=common_pool_required_option_ids(request),
|
|
485
|
+
certified_feasibility_witness_option_ids=(
|
|
486
|
+
self.common_candidate_pool.certified_feasibility_witness_option_ids
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
if self.proposal_support is not None:
|
|
490
|
+
assert self.common_candidate_pool is not None
|
|
491
|
+
candidates = proposal_support_candidates(
|
|
492
|
+
request,
|
|
493
|
+
self.option_evidence,
|
|
494
|
+
self.common_candidate_pool,
|
|
495
|
+
)
|
|
496
|
+
expected_support = StructuralProposalSupportPolicy().select(
|
|
497
|
+
request_sha256=request.request_sha256,
|
|
498
|
+
common_candidate_pool_decision_sha256=(
|
|
499
|
+
self.common_candidate_pool.decision_sha256
|
|
500
|
+
),
|
|
501
|
+
model_selection_size=(
|
|
502
|
+
self.common_candidate_pool.model_selection_size
|
|
503
|
+
),
|
|
504
|
+
candidates=candidates,
|
|
505
|
+
)
|
|
506
|
+
if self.proposal_support != expected_support:
|
|
507
|
+
raise ValueError(
|
|
508
|
+
"proposal-support decision differs from the sealed input binding"
|
|
509
|
+
)
|
|
510
|
+
if self.contextual_allocation is not None:
|
|
511
|
+
if self.contextual_allocation.evaluation_slots != request.portfolio_size:
|
|
512
|
+
raise ValueError(
|
|
513
|
+
"contextual allocation differs from the evaluation width"
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
def prompt_records_for(
|
|
517
|
+
self,
|
|
518
|
+
request: PortfolioSelectionRequest,
|
|
519
|
+
) -> tuple[dict[str, object], ...]:
|
|
520
|
+
"""Return only this binding's authenticated model-visible option view."""
|
|
521
|
+
|
|
522
|
+
self.require_request(request)
|
|
523
|
+
records = (
|
|
524
|
+
request.finite_variation_contract.prompt_records()
|
|
525
|
+
if self.option_prompt_projection is None
|
|
526
|
+
else self.option_prompt_projection.prompt_records()
|
|
527
|
+
)
|
|
528
|
+
if self.common_candidate_pool is None:
|
|
529
|
+
return records
|
|
530
|
+
by_id = {str(value["option_id"]): value for value in records}
|
|
531
|
+
return tuple(
|
|
532
|
+
by_id[option_id]
|
|
533
|
+
for option_id in self.common_candidate_pool.option_ids
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
def prompt_projection_contract_for(
|
|
537
|
+
self,
|
|
538
|
+
request: PortfolioSelectionRequest,
|
|
539
|
+
) -> dict[str, object] | None:
|
|
540
|
+
"""Return the compact projection receipt, if this binding opted in."""
|
|
541
|
+
|
|
542
|
+
self.require_request(request)
|
|
543
|
+
if self.option_prompt_projection is None:
|
|
544
|
+
return None
|
|
545
|
+
return self.option_prompt_projection.to_prompt_contract_record()
|
|
546
|
+
|
|
547
|
+
def evidence_for(
|
|
548
|
+
self,
|
|
549
|
+
request: PortfolioSelectionRequest,
|
|
550
|
+
option: FiniteVariationOption,
|
|
551
|
+
) -> CalibratedPortfolioOptionEvidence:
|
|
552
|
+
self.require_request(request)
|
|
553
|
+
if type(option) is not FiniteVariationOption:
|
|
554
|
+
raise TypeError("option must be exact FiniteVariationOption")
|
|
555
|
+
resolved = request.finite_variation_contract.resolve(option.option_id)
|
|
556
|
+
if resolved != option:
|
|
557
|
+
raise ValueError("option belongs to a foreign finite contract")
|
|
558
|
+
evidence = next(
|
|
559
|
+
value for value in self.option_evidence if value.option_id == option.option_id
|
|
560
|
+
)
|
|
561
|
+
if evidence.option_identity_sha256 != option.identity_sha256:
|
|
562
|
+
raise ValueError("structural evidence belongs to a foreign option")
|
|
563
|
+
return evidence
|
|
564
|
+
|
|
565
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
566
|
+
self.revalidate()
|
|
567
|
+
record: dict[str, object] = {
|
|
568
|
+
"schema_version": (
|
|
569
|
+
6
|
|
570
|
+
if self.contextual_allocation is not None
|
|
571
|
+
else 5
|
|
572
|
+
if self.proposal_support is not None
|
|
573
|
+
else 4
|
|
574
|
+
if self.common_candidate_pool is not None
|
|
575
|
+
else (1 if self.option_prompt_projection is None else 2)
|
|
576
|
+
),
|
|
577
|
+
"request_sha256": self.request_sha256,
|
|
578
|
+
"context": self.context.to_record(),
|
|
579
|
+
"option_evidence": [value.to_record() for value in self.option_evidence],
|
|
580
|
+
}
|
|
581
|
+
# Absence is the legacy representation. Do not add a null field: that
|
|
582
|
+
# would silently invalidate every finalized v2/four-role binding.
|
|
583
|
+
if self.option_prompt_projection is not None:
|
|
584
|
+
record["option_prompt_projection"] = (
|
|
585
|
+
self.option_prompt_projection.to_binding_record()
|
|
586
|
+
)
|
|
587
|
+
if self.common_candidate_pool is not None:
|
|
588
|
+
record["common_candidate_pool"] = self.common_candidate_pool.to_record()
|
|
589
|
+
if self.proposal_support is not None:
|
|
590
|
+
record["proposal_support"] = self.proposal_support.to_record()
|
|
591
|
+
if self.contextual_allocation is not None:
|
|
592
|
+
record["contextual_allocation"] = (
|
|
593
|
+
self.contextual_allocation.to_record()
|
|
594
|
+
)
|
|
595
|
+
return record
|
|
596
|
+
|
|
597
|
+
@property
|
|
598
|
+
def binding_sha256(self) -> str:
|
|
599
|
+
domain = (
|
|
600
|
+
_CONTEXTUAL_ALLOCATION_BINDING_DOMAIN
|
|
601
|
+
if self.contextual_allocation is not None
|
|
602
|
+
else _PROPOSAL_SUPPORT_BINDING_DOMAIN
|
|
603
|
+
if self.proposal_support is not None
|
|
604
|
+
else _COMMON_POOL_BINDING_DOMAIN
|
|
605
|
+
if self.common_candidate_pool is not None
|
|
606
|
+
else (
|
|
607
|
+
_BINDING_DOMAIN
|
|
608
|
+
if self.option_prompt_projection is None
|
|
609
|
+
else _PROJECTED_BINDING_DOMAIN
|
|
610
|
+
)
|
|
611
|
+
)
|
|
612
|
+
return hashlib.sha256(
|
|
613
|
+
domain + _canonical_json(self._unsigned_record())
|
|
614
|
+
).hexdigest()
|
|
615
|
+
|
|
616
|
+
def to_record(self) -> dict[str, object]:
|
|
617
|
+
return {**self._unsigned_record(), "binding_sha256": self.binding_sha256}
|
|
618
|
+
|
|
619
|
+
def __eq__(self, other: object) -> bool:
|
|
620
|
+
return (
|
|
621
|
+
type(other) is CalibratedPortfolioInputBinding
|
|
622
|
+
and self.binding_sha256 == other.binding_sha256
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
__hash__ = None
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
CalibratedPortfolioBindingProvider = Callable[
|
|
629
|
+
[PortfolioSelectionRequest], CalibratedPortfolioInputBinding
|
|
630
|
+
]
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
__all__ = [
|
|
634
|
+
"CalibratedPortfolioAllocationContext",
|
|
635
|
+
"CalibratedPortfolioBindingProvider",
|
|
636
|
+
"CalibratedPortfolioInputBinding",
|
|
637
|
+
"CalibratedPortfolioOptionEvidence",
|
|
638
|
+
"common_pool_required_option_ids",
|
|
639
|
+
"proposal_support_candidates",
|
|
640
|
+
]
|