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,799 @@
|
|
|
1
|
+
"""Generic set-valued allocation over sealed consequence scenarios.
|
|
2
|
+
|
|
3
|
+
The application core does not interpret objective names, directions, forecast
|
|
4
|
+
quantiles, workloads, models, providers, or configuration fields. An injected
|
|
5
|
+
projection binds every materialized action to one or more named hypothetical
|
|
6
|
+
objective points plus a bounded reliability. An injected archive-utility port
|
|
7
|
+
owns normalization, objective senses, reference points, and exact joint set
|
|
8
|
+
value.
|
|
9
|
+
|
|
10
|
+
This separation lets one sealed proposal market expose several complete policy
|
|
11
|
+
arms (central, optimistic, reliability-adjusted, or risk-adjusted) to the
|
|
12
|
+
precommitted portfolio race without granting any arm current-outcome access.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import hashlib
|
|
18
|
+
import json
|
|
19
|
+
import math
|
|
20
|
+
import re
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from enum import Enum
|
|
23
|
+
from typing import Protocol, runtime_checkable
|
|
24
|
+
|
|
25
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
26
|
+
from agent_evolve.application.candidate_archive_consequence import (
|
|
27
|
+
CandidateArchivePortfolioConsequenceUtilityPort,
|
|
28
|
+
validate_candidate_archive_portfolio_consequence_utility,
|
|
29
|
+
)
|
|
30
|
+
from agent_evolve.application.materialized_action_broker import (
|
|
31
|
+
MaterializedActionAllocationRequirement,
|
|
32
|
+
MaterializedActionDescriptor,
|
|
33
|
+
)
|
|
34
|
+
from agent_evolve.application.residual_portfolio_evolution import (
|
|
35
|
+
MaterializedActionProposalBatch,
|
|
36
|
+
ResidualPortfolioDecisionRequest,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.domain.patch import require_sha256
|
|
39
|
+
from agent_evolve.domain.typed_json import (
|
|
40
|
+
FrozenJsonObject,
|
|
41
|
+
freeze_json,
|
|
42
|
+
thaw_json,
|
|
43
|
+
typed_json_sha256,
|
|
44
|
+
)
|
|
45
|
+
from agent_evolve.ports.hard_feasibility import (
|
|
46
|
+
HardFeasibilityDecision,
|
|
47
|
+
HardFeasibilityPort,
|
|
48
|
+
HardFeasibilityRequest,
|
|
49
|
+
HardFeasibilityVerdict,
|
|
50
|
+
assess_hard_feasibility,
|
|
51
|
+
hard_feasibility_decision_batch_sha256,
|
|
52
|
+
validate_hard_feasibility_port,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
FORECAST_GEOMETRY_PORTFOLIO_POLICY_ID = "forecast_geometry_portfolio"
|
|
57
|
+
FORECAST_GEOMETRY_PORTFOLIO_POLICY_VERSION = 1
|
|
58
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
59
|
+
_MEMBER_DOMAIN = b"agent-evolve:forecast-geometry-member:v1\x00"
|
|
60
|
+
_BATCH_DOMAIN = b"agent-evolve:forecast-geometry-batch:v1\x00"
|
|
61
|
+
_POLICY_DOMAIN = b"agent-evolve:forecast-geometry-policy:v1\x00"
|
|
62
|
+
_PRIOR_DOMAIN = b"agent-evolve:forecast-geometry-prior:v1\x00"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _canonical_json(value: object) -> bytes:
|
|
66
|
+
return json.dumps(
|
|
67
|
+
value,
|
|
68
|
+
allow_nan=False,
|
|
69
|
+
ensure_ascii=True,
|
|
70
|
+
separators=(",", ":"),
|
|
71
|
+
sort_keys=True,
|
|
72
|
+
).encode("ascii", errors="strict")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
76
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _require_token(value: str, *, name: str) -> None:
|
|
80
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
81
|
+
raise ValueError(f"{name} must use the closed token grammar")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _projection_identity(
|
|
85
|
+
value: "MaterializedForecastGeometryProjectionPort",
|
|
86
|
+
) -> tuple[str, int, str]:
|
|
87
|
+
if not isinstance(value, MaterializedForecastGeometryProjectionPort):
|
|
88
|
+
raise TypeError("projection must implement its application port")
|
|
89
|
+
identity = (
|
|
90
|
+
getattr(value, "projection_id", None),
|
|
91
|
+
getattr(value, "projection_version", None),
|
|
92
|
+
getattr(value, "definition_sha256", None),
|
|
93
|
+
)
|
|
94
|
+
_require_token(identity[0], name="projection_id")
|
|
95
|
+
if type(identity[1]) is not int or identity[1] <= 0:
|
|
96
|
+
raise ValueError("projection_version must be positive")
|
|
97
|
+
require_sha256(identity[2], "projection definition_sha256")
|
|
98
|
+
return identity # type: ignore[return-value]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@dataclass(frozen=True, slots=True)
|
|
102
|
+
class ForecastGeometryScenario:
|
|
103
|
+
"""One named, raw objective point authored before evaluation."""
|
|
104
|
+
|
|
105
|
+
scenario_id: str
|
|
106
|
+
objective_point: tuple[tuple[str, float], ...]
|
|
107
|
+
|
|
108
|
+
def __post_init__(self) -> None:
|
|
109
|
+
_require_token(self.scenario_id, name="scenario_id")
|
|
110
|
+
if (
|
|
111
|
+
type(self.objective_point) is not tuple
|
|
112
|
+
or not self.objective_point
|
|
113
|
+
or self.objective_point
|
|
114
|
+
!= tuple(sorted(self.objective_point))
|
|
115
|
+
):
|
|
116
|
+
raise ValueError(
|
|
117
|
+
"objective_point must be non-empty and canonical"
|
|
118
|
+
)
|
|
119
|
+
metric_ids: list[str] = []
|
|
120
|
+
for metric_id, value in self.objective_point:
|
|
121
|
+
_require_token(metric_id, name="metric_id")
|
|
122
|
+
if type(value) is not float or not math.isfinite(value):
|
|
123
|
+
raise TypeError(
|
|
124
|
+
"objective-point values must be finite exact floats"
|
|
125
|
+
)
|
|
126
|
+
metric_ids.append(metric_id)
|
|
127
|
+
if len(metric_ids) != len(set(metric_ids)):
|
|
128
|
+
raise ValueError("objective_point repeats a metric")
|
|
129
|
+
|
|
130
|
+
def as_mapping(self) -> dict[str, float]:
|
|
131
|
+
self.__post_init__()
|
|
132
|
+
return dict(self.objective_point)
|
|
133
|
+
|
|
134
|
+
def to_record(self) -> dict[str, object]:
|
|
135
|
+
self.__post_init__()
|
|
136
|
+
return {
|
|
137
|
+
"scenario_id": self.scenario_id,
|
|
138
|
+
"objective_point": [
|
|
139
|
+
{"metric_id": metric_id, "value_hex": value.hex()}
|
|
140
|
+
for metric_id, value in self.objective_point
|
|
141
|
+
],
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass(frozen=True, slots=True)
|
|
146
|
+
class MaterializedForecastGeometryMember:
|
|
147
|
+
"""All pre-evaluation scenario geometry for one materialized action."""
|
|
148
|
+
|
|
149
|
+
action_sha256: str
|
|
150
|
+
phenotype_identity_sha256: str
|
|
151
|
+
reliability: float
|
|
152
|
+
scenarios: tuple[ForecastGeometryScenario, ...]
|
|
153
|
+
source_evidence_sha256: str
|
|
154
|
+
member_sha256: str = field(init=False)
|
|
155
|
+
|
|
156
|
+
def __post_init__(self) -> None:
|
|
157
|
+
require_sha256(self.action_sha256, "action_sha256")
|
|
158
|
+
require_sha256(
|
|
159
|
+
self.phenotype_identity_sha256,
|
|
160
|
+
"phenotype_identity_sha256",
|
|
161
|
+
)
|
|
162
|
+
require_sha256(
|
|
163
|
+
self.source_evidence_sha256,
|
|
164
|
+
"source_evidence_sha256",
|
|
165
|
+
)
|
|
166
|
+
if (
|
|
167
|
+
type(self.reliability) is not float
|
|
168
|
+
or not math.isfinite(self.reliability)
|
|
169
|
+
or not 0.0 <= self.reliability <= 1.0
|
|
170
|
+
):
|
|
171
|
+
raise ValueError("reliability must lie in [0, 1]")
|
|
172
|
+
if (
|
|
173
|
+
type(self.scenarios) is not tuple
|
|
174
|
+
or not self.scenarios
|
|
175
|
+
or any(
|
|
176
|
+
type(value) is not ForecastGeometryScenario
|
|
177
|
+
for value in self.scenarios
|
|
178
|
+
)
|
|
179
|
+
):
|
|
180
|
+
raise TypeError("scenarios must contain exact scenario values")
|
|
181
|
+
for value in self.scenarios:
|
|
182
|
+
value.__post_init__()
|
|
183
|
+
scenario_ids = tuple(value.scenario_id for value in self.scenarios)
|
|
184
|
+
if scenario_ids != tuple(sorted(set(scenario_ids))):
|
|
185
|
+
raise ValueError("scenario IDs must be unique and canonical")
|
|
186
|
+
metric_frames = {
|
|
187
|
+
tuple(metric_id for metric_id, _value in scenario.objective_point)
|
|
188
|
+
for scenario in self.scenarios
|
|
189
|
+
}
|
|
190
|
+
if len(metric_frames) != 1:
|
|
191
|
+
raise ValueError("all scenarios must use one objective frame")
|
|
192
|
+
object.__setattr__(
|
|
193
|
+
self,
|
|
194
|
+
"member_sha256",
|
|
195
|
+
_hash(_MEMBER_DOMAIN, self._unsigned_record()),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def scenario(self, scenario_id: str) -> ForecastGeometryScenario:
|
|
199
|
+
_require_token(scenario_id, name="scenario_id")
|
|
200
|
+
matches = tuple(
|
|
201
|
+
value
|
|
202
|
+
for value in self.scenarios
|
|
203
|
+
if value.scenario_id == scenario_id
|
|
204
|
+
)
|
|
205
|
+
if len(matches) != 1:
|
|
206
|
+
raise ValueError("member omits the requested scenario")
|
|
207
|
+
return matches[0]
|
|
208
|
+
|
|
209
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
210
|
+
return {
|
|
211
|
+
"schema_version": 1,
|
|
212
|
+
"action_sha256": self.action_sha256,
|
|
213
|
+
"phenotype_identity_sha256": self.phenotype_identity_sha256,
|
|
214
|
+
"reliability_hex": self.reliability.hex(),
|
|
215
|
+
"scenarios": [value.to_record() for value in self.scenarios],
|
|
216
|
+
"source_evidence_sha256": self.source_evidence_sha256,
|
|
217
|
+
"candidate_outcomes_observed": False,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
def to_record(self) -> dict[str, object]:
|
|
221
|
+
self.__post_init__()
|
|
222
|
+
return {**self._unsigned_record(), "member_sha256": self.member_sha256}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@dataclass(frozen=True, slots=True)
|
|
226
|
+
class MaterializedForecastGeometryBatch:
|
|
227
|
+
"""Authenticated geometry covering one complete sealed proposal market."""
|
|
228
|
+
|
|
229
|
+
projection_id: str
|
|
230
|
+
projection_version: int
|
|
231
|
+
projection_definition_sha256: str
|
|
232
|
+
residual_request_sha256: str
|
|
233
|
+
proposal_sha256s: tuple[str, ...]
|
|
234
|
+
members: tuple[MaterializedForecastGeometryMember, ...]
|
|
235
|
+
candidate_outcomes_observed: bool
|
|
236
|
+
evidence: FrozenJsonObject
|
|
237
|
+
batch_sha256: str = field(init=False)
|
|
238
|
+
|
|
239
|
+
def __post_init__(self) -> None:
|
|
240
|
+
_require_token(self.projection_id, name="projection_id")
|
|
241
|
+
if type(self.projection_version) is not int or self.projection_version <= 0:
|
|
242
|
+
raise ValueError("projection_version must be positive")
|
|
243
|
+
require_sha256(
|
|
244
|
+
self.projection_definition_sha256,
|
|
245
|
+
"projection_definition_sha256",
|
|
246
|
+
)
|
|
247
|
+
require_sha256(
|
|
248
|
+
self.residual_request_sha256,
|
|
249
|
+
"residual_request_sha256",
|
|
250
|
+
)
|
|
251
|
+
if (
|
|
252
|
+
type(self.proposal_sha256s) is not tuple
|
|
253
|
+
or not self.proposal_sha256s
|
|
254
|
+
or self.proposal_sha256s
|
|
255
|
+
!= tuple(sorted(set(self.proposal_sha256s)))
|
|
256
|
+
):
|
|
257
|
+
raise ValueError("proposal hashes must be non-empty and canonical")
|
|
258
|
+
for value in self.proposal_sha256s:
|
|
259
|
+
require_sha256(value, "proposal_sha256")
|
|
260
|
+
if (
|
|
261
|
+
type(self.members) is not tuple
|
|
262
|
+
or not self.members
|
|
263
|
+
or any(
|
|
264
|
+
type(value) is not MaterializedForecastGeometryMember
|
|
265
|
+
for value in self.members
|
|
266
|
+
)
|
|
267
|
+
):
|
|
268
|
+
raise TypeError("members must contain exact forecast geometry")
|
|
269
|
+
for value in self.members:
|
|
270
|
+
value.__post_init__()
|
|
271
|
+
action_ids = tuple(value.action_sha256 for value in self.members)
|
|
272
|
+
if action_ids != tuple(sorted(set(action_ids))):
|
|
273
|
+
raise ValueError("members must be unique and canonical")
|
|
274
|
+
if type(self.candidate_outcomes_observed) is not bool:
|
|
275
|
+
raise TypeError("candidate_outcomes_observed must be exact")
|
|
276
|
+
if self.candidate_outcomes_observed:
|
|
277
|
+
raise ValueError("forecast geometry cannot observe current outcomes")
|
|
278
|
+
if (
|
|
279
|
+
type(self.evidence) is not FrozenJsonObject
|
|
280
|
+
or freeze_json(self.evidence) is not self.evidence
|
|
281
|
+
):
|
|
282
|
+
raise TypeError("batch evidence must be a frozen object")
|
|
283
|
+
object.__setattr__(
|
|
284
|
+
self,
|
|
285
|
+
"batch_sha256",
|
|
286
|
+
_hash(_BATCH_DOMAIN, self._unsigned_record()),
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
290
|
+
return {
|
|
291
|
+
"schema_version": 1,
|
|
292
|
+
"projection": {
|
|
293
|
+
"projection_id": self.projection_id,
|
|
294
|
+
"projection_version": self.projection_version,
|
|
295
|
+
"definition_sha256": self.projection_definition_sha256,
|
|
296
|
+
},
|
|
297
|
+
"residual_request_sha256": self.residual_request_sha256,
|
|
298
|
+
"proposal_sha256s": list(self.proposal_sha256s),
|
|
299
|
+
"member_sha256s": [
|
|
300
|
+
value.member_sha256 for value in self.members
|
|
301
|
+
],
|
|
302
|
+
"candidate_outcomes_observed": self.candidate_outcomes_observed,
|
|
303
|
+
"evidence_sha256": typed_json_sha256(self.evidence),
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
def to_record(self, *, include_evidence: bool = False) -> dict[str, object]:
|
|
307
|
+
self.__post_init__()
|
|
308
|
+
record = {
|
|
309
|
+
**self._unsigned_record(),
|
|
310
|
+
"members": [value.to_record() for value in self.members],
|
|
311
|
+
"batch_sha256": self.batch_sha256,
|
|
312
|
+
}
|
|
313
|
+
if include_evidence:
|
|
314
|
+
record["evidence"] = thaw_json(self.evidence)
|
|
315
|
+
return record
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
@runtime_checkable
|
|
319
|
+
class MaterializedForecastGeometryProjectionPort(Protocol):
|
|
320
|
+
"""Project a sealed materialized market into named consequence scenarios."""
|
|
321
|
+
|
|
322
|
+
projection_id: str
|
|
323
|
+
projection_version: int
|
|
324
|
+
definition_sha256: str
|
|
325
|
+
|
|
326
|
+
async def project(
|
|
327
|
+
self,
|
|
328
|
+
request: ResidualPortfolioDecisionRequest,
|
|
329
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
330
|
+
) -> MaterializedForecastGeometryBatch: ...
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class ForecastGeometryPortfolioMode(str, Enum):
|
|
334
|
+
SCENARIO = "scenario"
|
|
335
|
+
RELIABILITY_ADJUSTED_SCENARIO = "reliability_adjusted_scenario"
|
|
336
|
+
RISK_ADJUSTED_SCENARIO = "risk_adjusted_scenario"
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def _prior_sha256(
|
|
340
|
+
candidates: tuple[EvolutionCandidate, ...],
|
|
341
|
+
) -> str:
|
|
342
|
+
return _hash(
|
|
343
|
+
_PRIOR_DOMAIN,
|
|
344
|
+
[
|
|
345
|
+
{
|
|
346
|
+
"candidate_id": value.candidate_id.value,
|
|
347
|
+
"configuration_sha256": value.occurrence.configuration_hash,
|
|
348
|
+
"generation": value.generation,
|
|
349
|
+
"valid": value.valid,
|
|
350
|
+
"operator_compliant": value.operator_compliant,
|
|
351
|
+
"evidence_compliant": value.evidence_compliant,
|
|
352
|
+
"objectives": [
|
|
353
|
+
{"metric_id": metric_id, "value_hex": number.hex()}
|
|
354
|
+
for metric_id, number in value.objectives
|
|
355
|
+
],
|
|
356
|
+
}
|
|
357
|
+
for value in candidates
|
|
358
|
+
],
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@dataclass(frozen=True, slots=True)
|
|
363
|
+
class ForecastGeometryPortfolioPolicy:
|
|
364
|
+
"""Greedy exact-K joint archive allocation for one typed scenario arm."""
|
|
365
|
+
|
|
366
|
+
prior_candidates: tuple[EvolutionCandidate, ...]
|
|
367
|
+
projection: MaterializedForecastGeometryProjectionPort = field(
|
|
368
|
+
repr=False,
|
|
369
|
+
compare=False,
|
|
370
|
+
)
|
|
371
|
+
archive_utility: CandidateArchivePortfolioConsequenceUtilityPort = field(
|
|
372
|
+
repr=False,
|
|
373
|
+
compare=False,
|
|
374
|
+
)
|
|
375
|
+
mode: ForecastGeometryPortfolioMode
|
|
376
|
+
scenario_id: str
|
|
377
|
+
adverse_scenario_id: str | None = None
|
|
378
|
+
risk_aversion: float = 0.0
|
|
379
|
+
max_exact_reliability_members: int = 8
|
|
380
|
+
hard_feasibility: HardFeasibilityPort | None = field(
|
|
381
|
+
default=None,
|
|
382
|
+
repr=False,
|
|
383
|
+
compare=False,
|
|
384
|
+
)
|
|
385
|
+
policy_id: str = FORECAST_GEOMETRY_PORTFOLIO_POLICY_ID
|
|
386
|
+
policy_version: int = FORECAST_GEOMETRY_PORTFOLIO_POLICY_VERSION
|
|
387
|
+
definition_sha256: str = field(init=False)
|
|
388
|
+
|
|
389
|
+
def __post_init__(self) -> None:
|
|
390
|
+
if (
|
|
391
|
+
type(self.prior_candidates) is not tuple
|
|
392
|
+
or not self.prior_candidates
|
|
393
|
+
or any(
|
|
394
|
+
type(value) is not EvolutionCandidate
|
|
395
|
+
for value in self.prior_candidates
|
|
396
|
+
)
|
|
397
|
+
):
|
|
398
|
+
raise TypeError("prior_candidates must be non-empty exact candidates")
|
|
399
|
+
for value in self.prior_candidates:
|
|
400
|
+
value.__post_init__()
|
|
401
|
+
candidate_ids = tuple(
|
|
402
|
+
value.candidate_id for value in self.prior_candidates
|
|
403
|
+
)
|
|
404
|
+
if len(candidate_ids) != len(set(candidate_ids)):
|
|
405
|
+
raise ValueError("prior candidate IDs must be unique")
|
|
406
|
+
projection_identity = _projection_identity(self.projection)
|
|
407
|
+
utility_identity = (
|
|
408
|
+
validate_candidate_archive_portfolio_consequence_utility(
|
|
409
|
+
self.archive_utility
|
|
410
|
+
)
|
|
411
|
+
)
|
|
412
|
+
if type(self.mode) is not ForecastGeometryPortfolioMode:
|
|
413
|
+
raise TypeError("mode must be an exact forecast geometry mode")
|
|
414
|
+
_require_token(self.scenario_id, name="scenario_id")
|
|
415
|
+
if self.mode is ForecastGeometryPortfolioMode.RISK_ADJUSTED_SCENARIO:
|
|
416
|
+
if self.adverse_scenario_id is None:
|
|
417
|
+
raise ValueError("risk-adjusted mode requires an adverse scenario")
|
|
418
|
+
_require_token(
|
|
419
|
+
self.adverse_scenario_id,
|
|
420
|
+
name="adverse_scenario_id",
|
|
421
|
+
)
|
|
422
|
+
elif self.adverse_scenario_id is not None:
|
|
423
|
+
raise ValueError("only risk-adjusted mode accepts an adverse scenario")
|
|
424
|
+
if (
|
|
425
|
+
type(self.risk_aversion) is not float
|
|
426
|
+
or not math.isfinite(self.risk_aversion)
|
|
427
|
+
or self.risk_aversion < 0.0
|
|
428
|
+
):
|
|
429
|
+
raise ValueError("risk_aversion must be finite and non-negative")
|
|
430
|
+
if (
|
|
431
|
+
self.mode is not ForecastGeometryPortfolioMode.RISK_ADJUSTED_SCENARIO
|
|
432
|
+
and self.risk_aversion != 0.0
|
|
433
|
+
):
|
|
434
|
+
raise ValueError("risk_aversion applies only to risk-adjusted mode")
|
|
435
|
+
if (
|
|
436
|
+
type(self.max_exact_reliability_members) is not int
|
|
437
|
+
or not 1 <= self.max_exact_reliability_members <= 16
|
|
438
|
+
):
|
|
439
|
+
raise ValueError(
|
|
440
|
+
"max_exact_reliability_members must lie in [1, 16]"
|
|
441
|
+
)
|
|
442
|
+
feasibility_identity = (
|
|
443
|
+
None
|
|
444
|
+
if self.hard_feasibility is None
|
|
445
|
+
else validate_hard_feasibility_port(self.hard_feasibility)
|
|
446
|
+
)
|
|
447
|
+
_require_token(self.policy_id, name="policy_id")
|
|
448
|
+
if self.policy_id != FORECAST_GEOMETRY_PORTFOLIO_POLICY_ID:
|
|
449
|
+
raise ValueError("policy_id is immutable")
|
|
450
|
+
if self.policy_version != FORECAST_GEOMETRY_PORTFOLIO_POLICY_VERSION:
|
|
451
|
+
raise ValueError("policy_version is immutable")
|
|
452
|
+
object.__setattr__(
|
|
453
|
+
self,
|
|
454
|
+
"definition_sha256",
|
|
455
|
+
_hash(
|
|
456
|
+
_POLICY_DOMAIN,
|
|
457
|
+
{
|
|
458
|
+
"schema_version": 1,
|
|
459
|
+
"policy_id": self.policy_id,
|
|
460
|
+
"policy_version": self.policy_version,
|
|
461
|
+
"projection": {
|
|
462
|
+
"projection_id": projection_identity[0],
|
|
463
|
+
"projection_version": projection_identity[1],
|
|
464
|
+
"definition_sha256": projection_identity[2],
|
|
465
|
+
},
|
|
466
|
+
"archive_utility": {
|
|
467
|
+
"utility_id": utility_identity[0],
|
|
468
|
+
"utility_version": utility_identity[1],
|
|
469
|
+
"definition_sha256": utility_identity[2],
|
|
470
|
+
},
|
|
471
|
+
"mode": self.mode.value,
|
|
472
|
+
"scenario_id": self.scenario_id,
|
|
473
|
+
"adverse_scenario_id": self.adverse_scenario_id,
|
|
474
|
+
"risk_aversion_hex": self.risk_aversion.hex(),
|
|
475
|
+
"max_exact_reliability_members": (
|
|
476
|
+
self.max_exact_reliability_members
|
|
477
|
+
),
|
|
478
|
+
"allocation": (
|
|
479
|
+
"greedy_joint_marginal_archive_utility_exact_k"
|
|
480
|
+
),
|
|
481
|
+
"reliability": (
|
|
482
|
+
"exact_independent_bernoulli_set_expectation"
|
|
483
|
+
),
|
|
484
|
+
"hard_feasibility": (
|
|
485
|
+
None
|
|
486
|
+
if feasibility_identity is None
|
|
487
|
+
else {
|
|
488
|
+
"policy_id": feasibility_identity[0],
|
|
489
|
+
"policy_version": feasibility_identity[1],
|
|
490
|
+
"definition_sha256": feasibility_identity[2],
|
|
491
|
+
}
|
|
492
|
+
),
|
|
493
|
+
"candidate_outcomes_observed": False,
|
|
494
|
+
"workload_model_provider_branches": False,
|
|
495
|
+
},
|
|
496
|
+
),
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
def _joint_gain(
|
|
500
|
+
self,
|
|
501
|
+
members: tuple[MaterializedForecastGeometryMember, ...],
|
|
502
|
+
scenario_id: str,
|
|
503
|
+
cache: dict[tuple[str, tuple[str, ...]], float],
|
|
504
|
+
) -> float:
|
|
505
|
+
key = (
|
|
506
|
+
scenario_id,
|
|
507
|
+
tuple(sorted(value.action_sha256 for value in members)),
|
|
508
|
+
)
|
|
509
|
+
cached = cache.get(key)
|
|
510
|
+
if cached is not None:
|
|
511
|
+
return cached
|
|
512
|
+
result = self.archive_utility.portfolio_marginal_utility(
|
|
513
|
+
self.prior_candidates,
|
|
514
|
+
tuple(
|
|
515
|
+
value.scenario(scenario_id).as_mapping()
|
|
516
|
+
for value in members
|
|
517
|
+
),
|
|
518
|
+
)
|
|
519
|
+
if type(result) is not float or not math.isfinite(result) or result < 0.0:
|
|
520
|
+
raise ValueError(
|
|
521
|
+
"joint archive utility must be finite and non-negative"
|
|
522
|
+
)
|
|
523
|
+
cache[key] = result
|
|
524
|
+
return result
|
|
525
|
+
|
|
526
|
+
def _portfolio_value(
|
|
527
|
+
self,
|
|
528
|
+
members: tuple[MaterializedForecastGeometryMember, ...],
|
|
529
|
+
cache: dict[tuple[str, tuple[str, ...]], float],
|
|
530
|
+
) -> float:
|
|
531
|
+
if self.mode is ForecastGeometryPortfolioMode.SCENARIO:
|
|
532
|
+
return self._joint_gain(members, self.scenario_id, cache)
|
|
533
|
+
if (
|
|
534
|
+
self.mode
|
|
535
|
+
is ForecastGeometryPortfolioMode.RISK_ADJUSTED_SCENARIO
|
|
536
|
+
):
|
|
537
|
+
central = self._joint_gain(
|
|
538
|
+
members,
|
|
539
|
+
self.scenario_id,
|
|
540
|
+
cache,
|
|
541
|
+
)
|
|
542
|
+
assert self.adverse_scenario_id is not None
|
|
543
|
+
adverse = self._joint_gain(
|
|
544
|
+
members,
|
|
545
|
+
self.adverse_scenario_id,
|
|
546
|
+
cache,
|
|
547
|
+
)
|
|
548
|
+
return central - self.risk_aversion * max(
|
|
549
|
+
0.0,
|
|
550
|
+
central - adverse,
|
|
551
|
+
)
|
|
552
|
+
if len(members) > self.max_exact_reliability_members:
|
|
553
|
+
raise ValueError(
|
|
554
|
+
"reliability-adjusted portfolio exceeds exact integration limit"
|
|
555
|
+
)
|
|
556
|
+
expected = 0.0
|
|
557
|
+
for mask in range(1 << len(members)):
|
|
558
|
+
probability = 1.0
|
|
559
|
+
admitted: list[MaterializedForecastGeometryMember] = []
|
|
560
|
+
for index, member in enumerate(members):
|
|
561
|
+
if mask & (1 << index):
|
|
562
|
+
probability *= member.reliability
|
|
563
|
+
admitted.append(member)
|
|
564
|
+
else:
|
|
565
|
+
probability *= 1.0 - member.reliability
|
|
566
|
+
if probability:
|
|
567
|
+
expected += probability * self._joint_gain(
|
|
568
|
+
tuple(admitted),
|
|
569
|
+
self.scenario_id,
|
|
570
|
+
cache,
|
|
571
|
+
)
|
|
572
|
+
if not math.isfinite(expected) or expected < 0.0:
|
|
573
|
+
raise RuntimeError("expected joint archive utility became invalid")
|
|
574
|
+
return expected
|
|
575
|
+
|
|
576
|
+
async def require(
|
|
577
|
+
self,
|
|
578
|
+
request: ResidualPortfolioDecisionRequest,
|
|
579
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
580
|
+
) -> MaterializedActionAllocationRequirement:
|
|
581
|
+
self.__post_init__()
|
|
582
|
+
if type(request) is not ResidualPortfolioDecisionRequest:
|
|
583
|
+
raise TypeError("request must be exact")
|
|
584
|
+
request.__post_init__()
|
|
585
|
+
if any(
|
|
586
|
+
value.generation >= request.decision_index
|
|
587
|
+
for value in self.prior_candidates
|
|
588
|
+
):
|
|
589
|
+
raise ValueError("prior candidates cross the current cutoff")
|
|
590
|
+
if type(proposals) is not tuple or not proposals:
|
|
591
|
+
raise ValueError("proposals must be a non-empty exact tuple")
|
|
592
|
+
actions: list[MaterializedActionDescriptor] = []
|
|
593
|
+
for proposal in proposals:
|
|
594
|
+
if type(proposal) is not MaterializedActionProposalBatch:
|
|
595
|
+
raise TypeError("proposals must contain exact batches")
|
|
596
|
+
proposal.__post_init__()
|
|
597
|
+
proposal.require_request(request)
|
|
598
|
+
actions.extend(proposal.actions)
|
|
599
|
+
action_by_sha256 = {
|
|
600
|
+
value.action_sha256: value for value in actions
|
|
601
|
+
}
|
|
602
|
+
if len(action_by_sha256) != len(actions):
|
|
603
|
+
raise ValueError("proposal market repeats an action identity")
|
|
604
|
+
proposal_sha256s = tuple(
|
|
605
|
+
sorted(value.proposal_sha256 for value in proposals)
|
|
606
|
+
)
|
|
607
|
+
batch = await self.projection.project(request, proposals)
|
|
608
|
+
if type(batch) is not MaterializedForecastGeometryBatch:
|
|
609
|
+
raise TypeError("projection returned a foreign geometry batch")
|
|
610
|
+
batch.__post_init__()
|
|
611
|
+
if (
|
|
612
|
+
(
|
|
613
|
+
batch.projection_id,
|
|
614
|
+
batch.projection_version,
|
|
615
|
+
batch.projection_definition_sha256,
|
|
616
|
+
)
|
|
617
|
+
!= _projection_identity(self.projection)
|
|
618
|
+
or batch.residual_request_sha256 != request.request_sha256
|
|
619
|
+
or batch.proposal_sha256s != proposal_sha256s
|
|
620
|
+
or tuple(value.action_sha256 for value in batch.members)
|
|
621
|
+
!= tuple(sorted(action_by_sha256))
|
|
622
|
+
):
|
|
623
|
+
raise ValueError("forecast geometry differs from the sealed market")
|
|
624
|
+
member_by_action = {
|
|
625
|
+
value.action_sha256: value for value in batch.members
|
|
626
|
+
}
|
|
627
|
+
if any(
|
|
628
|
+
member_by_action[action_id].phenotype_identity_sha256
|
|
629
|
+
!= action.phenotype_identity_sha256
|
|
630
|
+
for action_id, action in action_by_sha256.items()
|
|
631
|
+
):
|
|
632
|
+
raise ValueError("forecast geometry changes phenotype identity")
|
|
633
|
+
required_scenarios = {
|
|
634
|
+
self.scenario_id,
|
|
635
|
+
*(
|
|
636
|
+
()
|
|
637
|
+
if self.adverse_scenario_id is None
|
|
638
|
+
else (self.adverse_scenario_id,)
|
|
639
|
+
),
|
|
640
|
+
}
|
|
641
|
+
if any(
|
|
642
|
+
not required_scenarios.issubset(
|
|
643
|
+
{scenario.scenario_id for scenario in member.scenarios}
|
|
644
|
+
)
|
|
645
|
+
for member in batch.members
|
|
646
|
+
):
|
|
647
|
+
raise ValueError("forecast geometry omits a policy scenario")
|
|
648
|
+
|
|
649
|
+
infeasible: set[str] = set()
|
|
650
|
+
feasibility_decisions: list[
|
|
651
|
+
tuple[str, HardFeasibilityDecision]
|
|
652
|
+
] = []
|
|
653
|
+
if self.hard_feasibility is not None:
|
|
654
|
+
for action_sha256 in sorted(action_by_sha256):
|
|
655
|
+
decision = assess_hard_feasibility(
|
|
656
|
+
self.hard_feasibility,
|
|
657
|
+
HardFeasibilityRequest(
|
|
658
|
+
campaign_scope_sha256=request.campaign_scope_sha256,
|
|
659
|
+
cutoff_index=request.decision_index,
|
|
660
|
+
configuration=action_by_sha256[
|
|
661
|
+
action_sha256
|
|
662
|
+
].configuration,
|
|
663
|
+
),
|
|
664
|
+
)
|
|
665
|
+
feasibility_decisions.append((action_sha256, decision))
|
|
666
|
+
if decision.verdict is HardFeasibilityVerdict.INFEASIBLE:
|
|
667
|
+
infeasible.add(action_sha256)
|
|
668
|
+
admissible = tuple(
|
|
669
|
+
sorted(
|
|
670
|
+
(
|
|
671
|
+
value
|
|
672
|
+
for value in batch.members
|
|
673
|
+
if value.action_sha256 not in infeasible
|
|
674
|
+
),
|
|
675
|
+
key=lambda value: value.action_sha256,
|
|
676
|
+
)
|
|
677
|
+
)
|
|
678
|
+
if len(
|
|
679
|
+
{
|
|
680
|
+
value.phenotype_identity_sha256
|
|
681
|
+
for value in admissible
|
|
682
|
+
}
|
|
683
|
+
) < request.evaluation_slots:
|
|
684
|
+
raise ValueError("forecast market cannot fill unique-phenotype K")
|
|
685
|
+
if (
|
|
686
|
+
self.mode
|
|
687
|
+
is ForecastGeometryPortfolioMode.RELIABILITY_ADJUSTED_SCENARIO
|
|
688
|
+
and request.evaluation_slots > self.max_exact_reliability_members
|
|
689
|
+
):
|
|
690
|
+
raise ValueError("evaluation K exceeds exact reliability limit")
|
|
691
|
+
|
|
692
|
+
selected: list[MaterializedForecastGeometryMember] = []
|
|
693
|
+
phenotypes: set[str] = set()
|
|
694
|
+
trace: list[dict[str, object]] = []
|
|
695
|
+
cache: dict[tuple[str, tuple[str, ...]], float] = {}
|
|
696
|
+
candidate_evaluations = 0
|
|
697
|
+
previous = self._portfolio_value((), cache)
|
|
698
|
+
for ordinal in range(1, request.evaluation_slots + 1):
|
|
699
|
+
candidates = tuple(
|
|
700
|
+
value
|
|
701
|
+
for value in admissible
|
|
702
|
+
if value.phenotype_identity_sha256 not in phenotypes
|
|
703
|
+
)
|
|
704
|
+
scored = []
|
|
705
|
+
for candidate in candidates:
|
|
706
|
+
value = self._portfolio_value(
|
|
707
|
+
tuple((*selected, candidate)),
|
|
708
|
+
cache,
|
|
709
|
+
)
|
|
710
|
+
candidate_evaluations += 1
|
|
711
|
+
scored.append((value, candidate))
|
|
712
|
+
if not scored:
|
|
713
|
+
raise RuntimeError("forecast geometry cannot close exact K")
|
|
714
|
+
value, winner = min(
|
|
715
|
+
scored,
|
|
716
|
+
key=lambda item: (
|
|
717
|
+
-item[0],
|
|
718
|
+
action_by_sha256[item[1].action_sha256].native_rank,
|
|
719
|
+
item[1].action_sha256,
|
|
720
|
+
),
|
|
721
|
+
)
|
|
722
|
+
selected.append(winner)
|
|
723
|
+
phenotypes.add(winner.phenotype_identity_sha256)
|
|
724
|
+
trace.append(
|
|
725
|
+
{
|
|
726
|
+
"ordinal": ordinal,
|
|
727
|
+
"allocation_kind": "forecast_geometry_joint_greedy",
|
|
728
|
+
"score_lane": (
|
|
729
|
+
f"forecast_geometry.{self.mode.value}."
|
|
730
|
+
f"{self.scenario_id}"
|
|
731
|
+
),
|
|
732
|
+
"action_sha256": winner.action_sha256,
|
|
733
|
+
"portfolio_value_before_hex": previous.hex(),
|
|
734
|
+
"portfolio_value_after_hex": value.hex(),
|
|
735
|
+
"marginal_portfolio_value_hex": (value - previous).hex(),
|
|
736
|
+
"member_reliability_hex": winner.reliability.hex(),
|
|
737
|
+
"candidate_outcomes_observed": False,
|
|
738
|
+
}
|
|
739
|
+
)
|
|
740
|
+
previous = value
|
|
741
|
+
|
|
742
|
+
feasibility_record = {
|
|
743
|
+
"enabled": self.hard_feasibility is not None,
|
|
744
|
+
"decision_batch_sha256": (
|
|
745
|
+
None
|
|
746
|
+
if not feasibility_decisions
|
|
747
|
+
else hard_feasibility_decision_batch_sha256(
|
|
748
|
+
tuple(
|
|
749
|
+
value.decision_sha256
|
|
750
|
+
for _action_sha256, value in feasibility_decisions
|
|
751
|
+
)
|
|
752
|
+
)
|
|
753
|
+
),
|
|
754
|
+
"rejected_action_sha256s": sorted(infeasible),
|
|
755
|
+
"unknown_actions_remain_eligible": True,
|
|
756
|
+
"candidate_outcomes_observed": False,
|
|
757
|
+
}
|
|
758
|
+
return MaterializedActionAllocationRequirement(
|
|
759
|
+
policy_id=self.policy_id,
|
|
760
|
+
policy_version=self.policy_version,
|
|
761
|
+
policy_definition_sha256=self.definition_sha256,
|
|
762
|
+
residual_request_sha256=request.request_sha256,
|
|
763
|
+
proposal_sha256s=proposal_sha256s,
|
|
764
|
+
required_action_sha256s=tuple(
|
|
765
|
+
sorted(value.action_sha256 for value in selected)
|
|
766
|
+
),
|
|
767
|
+
candidate_outcomes_observed=False,
|
|
768
|
+
evidence=freeze_json(
|
|
769
|
+
{
|
|
770
|
+
"forecast_geometry_batch_sha256": batch.batch_sha256,
|
|
771
|
+
"prior_candidate_set_sha256": _prior_sha256(
|
|
772
|
+
self.prior_candidates
|
|
773
|
+
),
|
|
774
|
+
"mode": self.mode.value,
|
|
775
|
+
"scenario_id": self.scenario_id,
|
|
776
|
+
"adverse_scenario_id": self.adverse_scenario_id,
|
|
777
|
+
"risk_aversion_hex": self.risk_aversion.hex(),
|
|
778
|
+
"final_portfolio_value_hex": previous.hex(),
|
|
779
|
+
"candidate_portfolio_evaluations": candidate_evaluations,
|
|
780
|
+
"selection_trace": trace,
|
|
781
|
+
"hard_feasibility": feasibility_record,
|
|
782
|
+
"joint_set_value_not_member_score_sum": True,
|
|
783
|
+
"candidate_outcomes_observed": False,
|
|
784
|
+
"workload_model_provider_branches": False,
|
|
785
|
+
}
|
|
786
|
+
),
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
__all__ = [
|
|
791
|
+
"FORECAST_GEOMETRY_PORTFOLIO_POLICY_ID",
|
|
792
|
+
"FORECAST_GEOMETRY_PORTFOLIO_POLICY_VERSION",
|
|
793
|
+
"ForecastGeometryPortfolioMode",
|
|
794
|
+
"ForecastGeometryPortfolioPolicy",
|
|
795
|
+
"ForecastGeometryScenario",
|
|
796
|
+
"MaterializedForecastGeometryBatch",
|
|
797
|
+
"MaterializedForecastGeometryMember",
|
|
798
|
+
"MaterializedForecastGeometryProjectionPort",
|
|
799
|
+
]
|