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,911 @@
|
|
|
1
|
+
"""Hierarchical region-conditional credit with learned forecast trust (R1).
|
|
2
|
+
|
|
3
|
+
Defect D1 (jul28 pareto defect theory): the live broker estimated its
|
|
4
|
+
``gain``/``positive`` channels at LANE level with n=1, so a single win
|
|
5
|
+
propagated positive=1.0 to every sibling proposal of the lane, and the
|
|
6
|
+
``forecast_error`` channel was never populated, so anti-calibrated
|
|
7
|
+
forecasts kept full weight. This module replaces the lane-level leaf with
|
|
8
|
+
credit cells keyed by (engine x parent-front-region x radius-or-operator
|
|
9
|
+
class), estimated with the EXISTING Beta-shrinkage machinery in a capped
|
|
10
|
+
three-level hierarchy (cell -> engine -> global), and adds a learned
|
|
11
|
+
forecast-trust channel: per-engine Beta posteriors over forecast direction
|
|
12
|
+
correctness, updated only from (predicted, actual) pairs revealed BEFORE
|
|
13
|
+
the current decision, applied as a demote-only multiplicative weight on
|
|
14
|
+
forecast-derived probability evidence. With no trust evidence the
|
|
15
|
+
multiplier is exactly one, so behavior degrades to the calibrated
|
|
16
|
+
challenger's; measured anti-calibration demotes the forecast channel
|
|
17
|
+
toward zero.
|
|
18
|
+
|
|
19
|
+
This module never modifies the calibrated challenger: it composes over an
|
|
20
|
+
injected ``CalibratedPositiveGainOpportunityPolicy`` (forecast geometry,
|
|
21
|
+
clamping, and score algebra are delegated or mirrored bit-for-bit) and is
|
|
22
|
+
enabled only through config-gated composition (``v9_candidate_policy``).
|
|
23
|
+
The policy knows no workload, objective name, model, provider, or prompt.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import hashlib
|
|
29
|
+
import json
|
|
30
|
+
import math
|
|
31
|
+
import re
|
|
32
|
+
from dataclasses import dataclass, field
|
|
33
|
+
|
|
34
|
+
from agent_evolve.application.calibrated_positive_gain_opportunity import (
|
|
35
|
+
CalibratedPositiveGainOpportunityPolicy,
|
|
36
|
+
CalibratedPositiveGainRanking,
|
|
37
|
+
CalibratedPositiveGainScore,
|
|
38
|
+
ObjectivePoint,
|
|
39
|
+
PositiveGainCandidate,
|
|
40
|
+
_beta_posterior_mean,
|
|
41
|
+
_require_objective_point,
|
|
42
|
+
_shrunk_magnitude,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
REGION_CONDITIONAL_CREDIT_POLICY_ID = "region_conditional_credit"
|
|
46
|
+
REGION_CONDITIONAL_CREDIT_POLICY_VERSION = 1
|
|
47
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
48
|
+
_DEFINITION_DOMAIN = (
|
|
49
|
+
b"agent-evolve:region-conditional-credit-definition:v1\x00"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
REGION_NO_PARENT = "region.no_parent"
|
|
53
|
+
RADIUS_CLASS_NONE = "radius.none"
|
|
54
|
+
RADIUS_CLASS_SHORT = "radius.short"
|
|
55
|
+
RADIUS_CLASS_MID = "radius.mid"
|
|
56
|
+
RADIUS_CLASS_LONG = "radius.long"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _canonical_json(value: object) -> bytes:
|
|
60
|
+
return json.dumps(
|
|
61
|
+
value,
|
|
62
|
+
allow_nan=False,
|
|
63
|
+
ensure_ascii=True,
|
|
64
|
+
separators=(",", ":"),
|
|
65
|
+
sort_keys=True,
|
|
66
|
+
).encode("ascii", errors="strict")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
70
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _require_token(value: str, *, name: str) -> None:
|
|
74
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
75
|
+
raise ValueError(f"{name} must use the closed token grammar")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _point_values(
|
|
79
|
+
point: ObjectivePoint,
|
|
80
|
+
metric_ids: tuple[str, ...],
|
|
81
|
+
) -> tuple[float, ...]:
|
|
82
|
+
mapping = dict(point)
|
|
83
|
+
if tuple(sorted(mapping)) != metric_ids:
|
|
84
|
+
raise ValueError("objective point uses a foreign metric frame")
|
|
85
|
+
return tuple(mapping[metric_id] for metric_id in metric_ids)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def parent_front_distance(
|
|
89
|
+
archive_points: tuple[ObjectivePoint, ...],
|
|
90
|
+
parent_point: ObjectivePoint,
|
|
91
|
+
) -> float:
|
|
92
|
+
"""Additive-epsilon distance of a parent behind the archive front.
|
|
93
|
+
|
|
94
|
+
``min over archive points a of max over objectives j of (p_j - a_j)``,
|
|
95
|
+
clamped at zero: the smallest uniform improvement that would move the
|
|
96
|
+
parent onto (or past) some archive point. Zero exactly for parents on
|
|
97
|
+
or beyond the front; dimension-generic and workload-free (operates on
|
|
98
|
+
whatever normalized objective frame the caller uses).
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
_require_objective_point(parent_point, name="parent point")
|
|
102
|
+
if type(archive_points) is not tuple or not archive_points:
|
|
103
|
+
raise ValueError("archive_points must be a non-empty exact tuple")
|
|
104
|
+
metric_ids = tuple(metric_id for metric_id, _value in parent_point)
|
|
105
|
+
parent = _point_values(parent_point, metric_ids)
|
|
106
|
+
best = math.inf
|
|
107
|
+
for point in archive_points:
|
|
108
|
+
_require_objective_point(point, name="archive point")
|
|
109
|
+
values = _point_values(point, metric_ids)
|
|
110
|
+
best = min(
|
|
111
|
+
best,
|
|
112
|
+
max(
|
|
113
|
+
p - a
|
|
114
|
+
for p, a in zip(parent, values, strict=True)
|
|
115
|
+
),
|
|
116
|
+
)
|
|
117
|
+
return float(max(best, 0.0))
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def parent_front_region(
|
|
121
|
+
*,
|
|
122
|
+
archive_points: tuple[ObjectivePoint, ...],
|
|
123
|
+
reference_point: ObjectivePoint,
|
|
124
|
+
parent_point: ObjectivePoint | None,
|
|
125
|
+
near_front_epsilon: float,
|
|
126
|
+
extreme_affinity_threshold: float,
|
|
127
|
+
) -> str:
|
|
128
|
+
"""Classify a parent into a front region token.
|
|
129
|
+
|
|
130
|
+
Region = distance band (near/far by additive-epsilon distance) crossed
|
|
131
|
+
with a wedge: the objective extreme the parent has the strongest
|
|
132
|
+
relative affinity to, or interior when no per-objective affinity is
|
|
133
|
+
strong enough. One wedge per objective plus interior, so the region
|
|
134
|
+
set is dimension-generic (memo R4's wedge construction). Parents are
|
|
135
|
+
absent for archive-seeded candidates: those map to a dedicated token.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
if parent_point is None:
|
|
139
|
+
return REGION_NO_PARENT
|
|
140
|
+
distance = parent_front_distance(archive_points, parent_point)
|
|
141
|
+
band = "near" if distance <= near_front_epsilon else "far"
|
|
142
|
+
metric_ids = tuple(metric_id for metric_id, _value in parent_point)
|
|
143
|
+
parent = _point_values(parent_point, metric_ids)
|
|
144
|
+
reference = _point_values(reference_point, metric_ids)
|
|
145
|
+
best_per_metric = tuple(
|
|
146
|
+
min(
|
|
147
|
+
_point_values(point, metric_ids)[index]
|
|
148
|
+
for point in archive_points
|
|
149
|
+
)
|
|
150
|
+
for index in range(len(metric_ids))
|
|
151
|
+
)
|
|
152
|
+
affinities: list[tuple[float, str]] = []
|
|
153
|
+
for index, metric_id in enumerate(metric_ids):
|
|
154
|
+
span = reference[index] - best_per_metric[index]
|
|
155
|
+
if span <= 0.0:
|
|
156
|
+
affinity = 0.0
|
|
157
|
+
else:
|
|
158
|
+
affinity = max(
|
|
159
|
+
(parent[index] - best_per_metric[index]) / span,
|
|
160
|
+
0.0,
|
|
161
|
+
)
|
|
162
|
+
affinities.append((affinity, metric_id))
|
|
163
|
+
affinity, metric_id = min(affinities)
|
|
164
|
+
if affinity <= extreme_affinity_threshold:
|
|
165
|
+
return f"region.{band}.extreme:{metric_id}"
|
|
166
|
+
return f"region.{band}.interior"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def radius_operator_class(
|
|
170
|
+
*,
|
|
171
|
+
radius: int | None,
|
|
172
|
+
operator_class: str | None,
|
|
173
|
+
radius_breakpoints: tuple[int, int],
|
|
174
|
+
) -> str:
|
|
175
|
+
"""Map a move radius (or operator class fallback) into a class token."""
|
|
176
|
+
|
|
177
|
+
short_cap, mid_cap = radius_breakpoints
|
|
178
|
+
if radius is not None:
|
|
179
|
+
if type(radius) is not int or radius < 0:
|
|
180
|
+
raise ValueError("radius must be a non-negative integer")
|
|
181
|
+
if radius <= short_cap:
|
|
182
|
+
return RADIUS_CLASS_SHORT
|
|
183
|
+
if radius <= mid_cap:
|
|
184
|
+
return RADIUS_CLASS_MID
|
|
185
|
+
return RADIUS_CLASS_LONG
|
|
186
|
+
if operator_class is not None:
|
|
187
|
+
_require_token(operator_class, name="operator_class")
|
|
188
|
+
return f"op.{operator_class}"
|
|
189
|
+
return RADIUS_CLASS_NONE
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@dataclass(frozen=True, slots=True)
|
|
193
|
+
class RegionFeatures:
|
|
194
|
+
"""Outcome-blind provenance features of one market candidate."""
|
|
195
|
+
|
|
196
|
+
parent_point: ObjectivePoint | None = None
|
|
197
|
+
radius: int | None = None
|
|
198
|
+
operator_class: str | None = None
|
|
199
|
+
|
|
200
|
+
def __post_init__(self) -> None:
|
|
201
|
+
if self.parent_point is not None:
|
|
202
|
+
_require_objective_point(
|
|
203
|
+
self.parent_point,
|
|
204
|
+
name="parent point",
|
|
205
|
+
)
|
|
206
|
+
if self.radius is not None and (
|
|
207
|
+
type(self.radius) is not int or self.radius < 0
|
|
208
|
+
):
|
|
209
|
+
raise ValueError("radius must be a non-negative integer")
|
|
210
|
+
if self.operator_class is not None:
|
|
211
|
+
_require_token(self.operator_class, name="operator_class")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@dataclass(frozen=True, slots=True)
|
|
215
|
+
class RegionConditionalOutcome:
|
|
216
|
+
"""One real outcome observed strictly before the current decision.
|
|
217
|
+
|
|
218
|
+
``region_id`` is None for evidence imported from OUTSIDE the current
|
|
219
|
+
market (warm priors): such outcomes carry no comparable parent
|
|
220
|
+
geometry, so they contribute only to the global and engine levels of
|
|
221
|
+
the hierarchy, never to a leaf cell. Forecast direction fields are
|
|
222
|
+
jointly present exactly when the outcome's candidate carried a
|
|
223
|
+
forecast: ``forecast_predicted_positive`` is whether the forecast's
|
|
224
|
+
central scenario claimed positive archive gain, and
|
|
225
|
+
``forecast_actual_positive`` whether the realized point achieved
|
|
226
|
+
positive gain against the same base archive.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
observation_ordinal: int
|
|
230
|
+
engine_id: str
|
|
231
|
+
feasible: bool
|
|
232
|
+
marginal_archive_gain: float
|
|
233
|
+
region_id: str | None = None
|
|
234
|
+
radius_class_id: str | None = None
|
|
235
|
+
forecast_predicted_positive: bool | None = None
|
|
236
|
+
forecast_actual_positive: bool | None = None
|
|
237
|
+
|
|
238
|
+
def __post_init__(self) -> None:
|
|
239
|
+
if (
|
|
240
|
+
type(self.observation_ordinal) is not int
|
|
241
|
+
or self.observation_ordinal <= 0
|
|
242
|
+
):
|
|
243
|
+
raise ValueError("observation_ordinal must be positive")
|
|
244
|
+
_require_token(self.engine_id, name="engine_id")
|
|
245
|
+
if type(self.feasible) is not bool:
|
|
246
|
+
raise TypeError("feasible must be exact")
|
|
247
|
+
if (
|
|
248
|
+
type(self.marginal_archive_gain) is not float
|
|
249
|
+
or not math.isfinite(self.marginal_archive_gain)
|
|
250
|
+
or self.marginal_archive_gain < 0.0
|
|
251
|
+
):
|
|
252
|
+
raise ValueError(
|
|
253
|
+
"marginal_archive_gain must be finite and non-negative"
|
|
254
|
+
)
|
|
255
|
+
if not self.feasible and self.marginal_archive_gain != 0.0:
|
|
256
|
+
raise ValueError("an infeasible outcome cannot contribute gain")
|
|
257
|
+
if (self.region_id is None) != (self.radius_class_id is None):
|
|
258
|
+
raise ValueError(
|
|
259
|
+
"region and radius class must be jointly present or absent"
|
|
260
|
+
)
|
|
261
|
+
if self.region_id is not None:
|
|
262
|
+
_require_token(self.region_id, name="region_id")
|
|
263
|
+
_require_token(
|
|
264
|
+
self.radius_class_id,
|
|
265
|
+
name="radius_class_id",
|
|
266
|
+
)
|
|
267
|
+
forecast_fields = (
|
|
268
|
+
self.forecast_predicted_positive,
|
|
269
|
+
self.forecast_actual_positive,
|
|
270
|
+
)
|
|
271
|
+
if any(value is None for value in forecast_fields) != all(
|
|
272
|
+
value is None for value in forecast_fields
|
|
273
|
+
):
|
|
274
|
+
raise ValueError(
|
|
275
|
+
"forecast direction fields must be jointly present or absent"
|
|
276
|
+
)
|
|
277
|
+
for value in forecast_fields:
|
|
278
|
+
if value is not None and type(value) is not bool:
|
|
279
|
+
raise TypeError("forecast direction fields must be exact")
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def positive(self) -> bool:
|
|
283
|
+
return self.marginal_archive_gain > 0.0
|
|
284
|
+
|
|
285
|
+
@property
|
|
286
|
+
def forecast_direction_correct(self) -> bool | None:
|
|
287
|
+
if self.forecast_predicted_positive is None:
|
|
288
|
+
return None
|
|
289
|
+
return (
|
|
290
|
+
self.forecast_predicted_positive
|
|
291
|
+
== self.forecast_actual_positive
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@dataclass(frozen=True, slots=True)
|
|
296
|
+
class RegionScoredCandidate:
|
|
297
|
+
"""One eligible candidate with its provenance features attached."""
|
|
298
|
+
|
|
299
|
+
candidate: PositiveGainCandidate
|
|
300
|
+
features: RegionFeatures = RegionFeatures()
|
|
301
|
+
|
|
302
|
+
def __post_init__(self) -> None:
|
|
303
|
+
if type(self.candidate) is not PositiveGainCandidate:
|
|
304
|
+
raise TypeError("candidate must be exact")
|
|
305
|
+
self.candidate.__post_init__()
|
|
306
|
+
if type(self.features) is not RegionFeatures:
|
|
307
|
+
raise TypeError("features must be exact")
|
|
308
|
+
self.features.__post_init__()
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
@dataclass(frozen=True, slots=True)
|
|
312
|
+
class RegionCreditConfig:
|
|
313
|
+
"""All R1 constants; every value is an exact dyadic float."""
|
|
314
|
+
|
|
315
|
+
near_front_epsilon: float = 0.125
|
|
316
|
+
extreme_affinity_threshold: float = 0.25
|
|
317
|
+
radius_breakpoints: tuple[int, int] = (1, 3)
|
|
318
|
+
forecast_trust_prior: float = 0.5
|
|
319
|
+
|
|
320
|
+
def __post_init__(self) -> None:
|
|
321
|
+
for name in ("near_front_epsilon", "extreme_affinity_threshold"):
|
|
322
|
+
value = getattr(self, name)
|
|
323
|
+
if (
|
|
324
|
+
type(value) is not float
|
|
325
|
+
or not math.isfinite(value)
|
|
326
|
+
or value < 0.0
|
|
327
|
+
):
|
|
328
|
+
raise ValueError(
|
|
329
|
+
f"{name} must be finite and non-negative"
|
|
330
|
+
)
|
|
331
|
+
if (
|
|
332
|
+
type(self.radius_breakpoints) is not tuple
|
|
333
|
+
or len(self.radius_breakpoints) != 2
|
|
334
|
+
or any(
|
|
335
|
+
type(value) is not int or value < 0
|
|
336
|
+
for value in self.radius_breakpoints
|
|
337
|
+
)
|
|
338
|
+
or not self.radius_breakpoints[0]
|
|
339
|
+
<= self.radius_breakpoints[1]
|
|
340
|
+
):
|
|
341
|
+
raise ValueError(
|
|
342
|
+
"radius_breakpoints must be two ascending non-negative "
|
|
343
|
+
"integers"
|
|
344
|
+
)
|
|
345
|
+
if (
|
|
346
|
+
type(self.forecast_trust_prior) is not float
|
|
347
|
+
or not math.isfinite(self.forecast_trust_prior)
|
|
348
|
+
or not 0.0 < self.forecast_trust_prior < 1.0
|
|
349
|
+
):
|
|
350
|
+
raise ValueError(
|
|
351
|
+
"forecast_trust_prior must lie in (0, 1)"
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
def to_record(self) -> dict[str, object]:
|
|
355
|
+
self.__post_init__()
|
|
356
|
+
return {
|
|
357
|
+
"near_front_epsilon_hex": self.near_front_epsilon.hex(),
|
|
358
|
+
"extreme_affinity_threshold_hex": (
|
|
359
|
+
self.extreme_affinity_threshold.hex()
|
|
360
|
+
),
|
|
361
|
+
"radius_breakpoints": list(self.radius_breakpoints),
|
|
362
|
+
"forecast_trust_prior_hex": (
|
|
363
|
+
self.forecast_trust_prior.hex()
|
|
364
|
+
),
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
@dataclass(frozen=True, slots=True)
|
|
369
|
+
class _RegionCellEvidence:
|
|
370
|
+
observation_count: float
|
|
371
|
+
positive_count: float
|
|
372
|
+
feasible_count: float
|
|
373
|
+
positive_gain_sum: float
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
@dataclass(frozen=True, slots=True)
|
|
377
|
+
class RegionConditionalChallengerPolicy:
|
|
378
|
+
"""Score eligible candidates with region-conditional credit.
|
|
379
|
+
|
|
380
|
+
The score algebra is the calibrated positive-gain challenger's,
|
|
381
|
+
bit-for-bit, with exactly two substitutions:
|
|
382
|
+
|
|
383
|
+
* conversion evidence is estimated over the capped hierarchy
|
|
384
|
+
global -> engine -> (engine x region x radius class) instead of
|
|
385
|
+
global -> engine -> (engine x rank band); and
|
|
386
|
+
* the forecast probability weight is multiplied by the engine's
|
|
387
|
+
learned forecast-trust multiplier (demote-only; exactly one with
|
|
388
|
+
no trust evidence).
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
base: CalibratedPositiveGainOpportunityPolicy = field(repr=False)
|
|
392
|
+
credit: RegionCreditConfig = RegionCreditConfig()
|
|
393
|
+
policy_id: str = REGION_CONDITIONAL_CREDIT_POLICY_ID
|
|
394
|
+
policy_version: int = REGION_CONDITIONAL_CREDIT_POLICY_VERSION
|
|
395
|
+
definition_sha256: str = field(init=False)
|
|
396
|
+
|
|
397
|
+
def __post_init__(self) -> None:
|
|
398
|
+
if type(self.base) is not CalibratedPositiveGainOpportunityPolicy:
|
|
399
|
+
raise TypeError(
|
|
400
|
+
"base must be an exact calibrated challenger"
|
|
401
|
+
)
|
|
402
|
+
self.base.__post_init__()
|
|
403
|
+
if type(self.credit) is not RegionCreditConfig:
|
|
404
|
+
raise TypeError("credit must be an exact region config")
|
|
405
|
+
self.credit.__post_init__()
|
|
406
|
+
_require_token(self.policy_id, name="policy_id")
|
|
407
|
+
if (
|
|
408
|
+
self.policy_id != REGION_CONDITIONAL_CREDIT_POLICY_ID
|
|
409
|
+
or self.policy_version
|
|
410
|
+
!= REGION_CONDITIONAL_CREDIT_POLICY_VERSION
|
|
411
|
+
):
|
|
412
|
+
raise ValueError("policy identity is immutable")
|
|
413
|
+
object.__setattr__(
|
|
414
|
+
self,
|
|
415
|
+
"definition_sha256",
|
|
416
|
+
_hash(
|
|
417
|
+
_DEFINITION_DOMAIN,
|
|
418
|
+
{
|
|
419
|
+
"schema_version": 1,
|
|
420
|
+
"policy_id": self.policy_id,
|
|
421
|
+
"policy_version": self.policy_version,
|
|
422
|
+
"base_challenger": {
|
|
423
|
+
"policy_id": self.base.policy_id,
|
|
424
|
+
"policy_version": self.base.policy_version,
|
|
425
|
+
"definition_sha256": (
|
|
426
|
+
self.base.definition_sha256
|
|
427
|
+
),
|
|
428
|
+
},
|
|
429
|
+
"credit": self.credit.to_record(),
|
|
430
|
+
"conversion_evidence": (
|
|
431
|
+
"prequential_engine_region_radius_cell_"
|
|
432
|
+
"hierarchical_beta_shrinkage_capped_three_levels"
|
|
433
|
+
),
|
|
434
|
+
"hierarchy": "cell_engine_global",
|
|
435
|
+
"prior_market_evidence_leaf_cells": False,
|
|
436
|
+
"forecast_trust": (
|
|
437
|
+
"per_engine_direction_correct_beta_posterior_"
|
|
438
|
+
"demote_only_multiplier_min_one_two_posterior"
|
|
439
|
+
),
|
|
440
|
+
"lane_level_n1_credit_propagation": False,
|
|
441
|
+
"hard_abstention": False,
|
|
442
|
+
"eligible_candidate_outcomes_observed": False,
|
|
443
|
+
"workload_objective_model_provider_prompt_branches": (
|
|
444
|
+
False
|
|
445
|
+
),
|
|
446
|
+
},
|
|
447
|
+
),
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
def region_for(
|
|
451
|
+
self,
|
|
452
|
+
*,
|
|
453
|
+
archive_points: tuple[ObjectivePoint, ...],
|
|
454
|
+
reference_point: ObjectivePoint,
|
|
455
|
+
features: RegionFeatures,
|
|
456
|
+
) -> tuple[str, str]:
|
|
457
|
+
"""(region token, radius class token) of one candidate."""
|
|
458
|
+
|
|
459
|
+
features.__post_init__()
|
|
460
|
+
return (
|
|
461
|
+
parent_front_region(
|
|
462
|
+
archive_points=archive_points,
|
|
463
|
+
reference_point=reference_point,
|
|
464
|
+
parent_point=features.parent_point,
|
|
465
|
+
near_front_epsilon=self.credit.near_front_epsilon,
|
|
466
|
+
extreme_affinity_threshold=(
|
|
467
|
+
self.credit.extreme_affinity_threshold
|
|
468
|
+
),
|
|
469
|
+
),
|
|
470
|
+
radius_operator_class(
|
|
471
|
+
radius=features.radius,
|
|
472
|
+
operator_class=features.operator_class,
|
|
473
|
+
radius_breakpoints=self.credit.radius_breakpoints,
|
|
474
|
+
),
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
@staticmethod
|
|
478
|
+
def _validated_outcomes(
|
|
479
|
+
observed_outcomes: tuple[RegionConditionalOutcome, ...],
|
|
480
|
+
) -> tuple[RegionConditionalOutcome, ...]:
|
|
481
|
+
if type(observed_outcomes) is not tuple or any(
|
|
482
|
+
type(value) is not RegionConditionalOutcome
|
|
483
|
+
for value in observed_outcomes
|
|
484
|
+
):
|
|
485
|
+
raise TypeError(
|
|
486
|
+
"observed_outcomes must contain exact region outcomes"
|
|
487
|
+
)
|
|
488
|
+
ordinals = tuple(
|
|
489
|
+
value.observation_ordinal for value in observed_outcomes
|
|
490
|
+
)
|
|
491
|
+
if ordinals != tuple(sorted(set(ordinals))):
|
|
492
|
+
raise ValueError(
|
|
493
|
+
"observed outcomes must use unique ascending ordinals"
|
|
494
|
+
)
|
|
495
|
+
for value in observed_outcomes:
|
|
496
|
+
value.__post_init__()
|
|
497
|
+
return observed_outcomes
|
|
498
|
+
|
|
499
|
+
def _conversion_evidence(
|
|
500
|
+
self,
|
|
501
|
+
observed_outcomes: tuple[RegionConditionalOutcome, ...],
|
|
502
|
+
) -> dict[object, _RegionCellEvidence]:
|
|
503
|
+
counts: dict[object, list[float]] = {}
|
|
504
|
+
for value in observed_outcomes:
|
|
505
|
+
keys: list[object] = [None, value.engine_id]
|
|
506
|
+
if value.region_id is not None:
|
|
507
|
+
keys.append(
|
|
508
|
+
(
|
|
509
|
+
value.engine_id,
|
|
510
|
+
value.region_id,
|
|
511
|
+
value.radius_class_id,
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
for key in keys:
|
|
515
|
+
row = counts.setdefault(key, [0.0, 0.0, 0.0, 0.0])
|
|
516
|
+
row[0] += 1.0
|
|
517
|
+
row[1] += float(value.positive)
|
|
518
|
+
row[2] += float(value.feasible)
|
|
519
|
+
row[3] += (
|
|
520
|
+
value.marginal_archive_gain
|
|
521
|
+
if value.positive
|
|
522
|
+
else 0.0
|
|
523
|
+
)
|
|
524
|
+
return {
|
|
525
|
+
key: _RegionCellEvidence(
|
|
526
|
+
observation_count=row[0],
|
|
527
|
+
positive_count=row[1],
|
|
528
|
+
feasible_count=row[2],
|
|
529
|
+
positive_gain_sum=row[3],
|
|
530
|
+
)
|
|
531
|
+
for key, row in counts.items()
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
def _hierarchical_estimates(
|
|
535
|
+
self,
|
|
536
|
+
*,
|
|
537
|
+
evidence: dict[object, _RegionCellEvidence],
|
|
538
|
+
engine_id: str,
|
|
539
|
+
region_id: str,
|
|
540
|
+
radius_class_id: str,
|
|
541
|
+
) -> dict[str, float]:
|
|
542
|
+
empty = _RegionCellEvidence(0.0, 0.0, 0.0, 0.0)
|
|
543
|
+
chain = (
|
|
544
|
+
evidence.get(None, empty),
|
|
545
|
+
evidence.get(engine_id, empty),
|
|
546
|
+
evidence.get(
|
|
547
|
+
(engine_id, region_id, radius_class_id),
|
|
548
|
+
empty,
|
|
549
|
+
),
|
|
550
|
+
)
|
|
551
|
+
p_positive = self.base.root_prior_probability
|
|
552
|
+
p_feasible = self.base.root_prior_probability
|
|
553
|
+
magnitude = self.base.reference_gain_scale
|
|
554
|
+
for level in chain:
|
|
555
|
+
p_positive = _beta_posterior_mean(
|
|
556
|
+
prior_mean=p_positive,
|
|
557
|
+
prior_strength=self.base.prior_strength,
|
|
558
|
+
successes=level.positive_count,
|
|
559
|
+
failures=level.observation_count - level.positive_count,
|
|
560
|
+
)
|
|
561
|
+
p_feasible = _beta_posterior_mean(
|
|
562
|
+
prior_mean=p_feasible,
|
|
563
|
+
prior_strength=self.base.prior_strength,
|
|
564
|
+
successes=level.feasible_count,
|
|
565
|
+
failures=level.observation_count - level.feasible_count,
|
|
566
|
+
)
|
|
567
|
+
magnitude = _shrunk_magnitude(
|
|
568
|
+
prior_mean=magnitude,
|
|
569
|
+
prior_strength=self.base.prior_strength,
|
|
570
|
+
positive_gain_sum=level.positive_gain_sum,
|
|
571
|
+
positive_count=level.positive_count,
|
|
572
|
+
)
|
|
573
|
+
cell = chain[2]
|
|
574
|
+
return {
|
|
575
|
+
"p_positive": p_positive,
|
|
576
|
+
"p_feasible": p_feasible,
|
|
577
|
+
"magnitude": magnitude,
|
|
578
|
+
"effective_sample_size": (
|
|
579
|
+
self.base.prior_strength + cell.observation_count
|
|
580
|
+
),
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
def forecast_trust_multiplier(
|
|
584
|
+
self,
|
|
585
|
+
*,
|
|
586
|
+
observed_outcomes: tuple[RegionConditionalOutcome, ...],
|
|
587
|
+
engine_id: str,
|
|
588
|
+
) -> float:
|
|
589
|
+
"""Demote-only trust weight for one engine's forecast channel.
|
|
590
|
+
|
|
591
|
+
Beta posterior over forecast direction correctness with prior
|
|
592
|
+
mean ``forecast_trust_prior`` and the base challenger's prior
|
|
593
|
+
strength, mapped through ``min(1, 2 * posterior)``: exactly one
|
|
594
|
+
with no evidence or calibrated forecasts, strictly below one
|
|
595
|
+
once measured accuracy falls below one half (anti-calibration).
|
|
596
|
+
"""
|
|
597
|
+
|
|
598
|
+
successes = 0.0
|
|
599
|
+
failures = 0.0
|
|
600
|
+
for value in observed_outcomes:
|
|
601
|
+
correct = value.forecast_direction_correct
|
|
602
|
+
if correct is None or value.engine_id != engine_id:
|
|
603
|
+
continue
|
|
604
|
+
if correct:
|
|
605
|
+
successes += 1.0
|
|
606
|
+
else:
|
|
607
|
+
failures += 1.0
|
|
608
|
+
posterior = _beta_posterior_mean(
|
|
609
|
+
prior_mean=self.credit.forecast_trust_prior,
|
|
610
|
+
prior_strength=self.base.prior_strength,
|
|
611
|
+
successes=successes,
|
|
612
|
+
failures=failures,
|
|
613
|
+
)
|
|
614
|
+
return float(min(1.0, 2.0 * posterior))
|
|
615
|
+
|
|
616
|
+
def score_market(
|
|
617
|
+
self,
|
|
618
|
+
*,
|
|
619
|
+
candidates: tuple[RegionScoredCandidate, ...],
|
|
620
|
+
archive_points: tuple[ObjectivePoint, ...],
|
|
621
|
+
reference_point: ObjectivePoint,
|
|
622
|
+
observed_outcomes: tuple[RegionConditionalOutcome, ...],
|
|
623
|
+
future_seats_remaining: int,
|
|
624
|
+
horizon_total: int,
|
|
625
|
+
frozen_fit_training_run_count: int = 0,
|
|
626
|
+
) -> CalibratedPositiveGainRanking:
|
|
627
|
+
"""Score and rank the whole market; never abstain."""
|
|
628
|
+
|
|
629
|
+
self.__post_init__()
|
|
630
|
+
if type(candidates) is not tuple or not candidates:
|
|
631
|
+
raise ValueError("candidates must be a non-empty exact tuple")
|
|
632
|
+
for value in candidates:
|
|
633
|
+
if type(value) is not RegionScoredCandidate:
|
|
634
|
+
raise TypeError(
|
|
635
|
+
"candidates must contain exact region candidates"
|
|
636
|
+
)
|
|
637
|
+
value.__post_init__()
|
|
638
|
+
action_ids = tuple(
|
|
639
|
+
value.candidate.action_sha256 for value in candidates
|
|
640
|
+
)
|
|
641
|
+
if len(action_ids) != len(set(action_ids)):
|
|
642
|
+
raise ValueError("candidate identities repeat")
|
|
643
|
+
if type(archive_points) is not tuple or not archive_points:
|
|
644
|
+
raise ValueError(
|
|
645
|
+
"archive_points must be a non-empty exact tuple"
|
|
646
|
+
)
|
|
647
|
+
for value in archive_points:
|
|
648
|
+
_require_objective_point(value, name="archive point")
|
|
649
|
+
_require_objective_point(
|
|
650
|
+
reference_point,
|
|
651
|
+
name="reference point",
|
|
652
|
+
)
|
|
653
|
+
if (
|
|
654
|
+
type(future_seats_remaining) is not int
|
|
655
|
+
or type(horizon_total) is not int
|
|
656
|
+
or horizon_total <= 0
|
|
657
|
+
or not 0 <= future_seats_remaining <= horizon_total
|
|
658
|
+
):
|
|
659
|
+
raise ValueError(
|
|
660
|
+
"future seats must fit the positive horizon total"
|
|
661
|
+
)
|
|
662
|
+
if (
|
|
663
|
+
type(frozen_fit_training_run_count) is not int
|
|
664
|
+
or frozen_fit_training_run_count < 0
|
|
665
|
+
):
|
|
666
|
+
raise ValueError(
|
|
667
|
+
"frozen_fit_training_run_count must be non-negative"
|
|
668
|
+
)
|
|
669
|
+
outcomes = self._validated_outcomes(observed_outcomes)
|
|
670
|
+
evidence = self._conversion_evidence(outcomes)
|
|
671
|
+
trust_by_engine = {
|
|
672
|
+
engine_id: self.forecast_trust_multiplier(
|
|
673
|
+
observed_outcomes=outcomes,
|
|
674
|
+
engine_id=engine_id,
|
|
675
|
+
)
|
|
676
|
+
for engine_id in {
|
|
677
|
+
value.candidate.engine_id for value in candidates
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
frozen_history_sufficient = (
|
|
681
|
+
frozen_fit_training_run_count
|
|
682
|
+
>= self.base.frozen_score_minimum_training_runs
|
|
683
|
+
)
|
|
684
|
+
horizon_fraction = future_seats_remaining / horizon_total
|
|
685
|
+
effective_beta = self.base.beta * horizon_fraction
|
|
686
|
+
scores: list[CalibratedPositiveGainScore] = []
|
|
687
|
+
by_action = {
|
|
688
|
+
value.candidate.action_sha256: value
|
|
689
|
+
for value in candidates
|
|
690
|
+
}
|
|
691
|
+
for scored in sorted(
|
|
692
|
+
candidates,
|
|
693
|
+
key=lambda value: value.candidate.action_sha256,
|
|
694
|
+
):
|
|
695
|
+
candidate = scored.candidate
|
|
696
|
+
region_id, radius_class_id = self.region_for(
|
|
697
|
+
archive_points=archive_points,
|
|
698
|
+
reference_point=reference_point,
|
|
699
|
+
features=scored.features,
|
|
700
|
+
)
|
|
701
|
+
conversion = self._hierarchical_estimates(
|
|
702
|
+
evidence=evidence,
|
|
703
|
+
engine_id=candidate.engine_id,
|
|
704
|
+
region_id=region_id,
|
|
705
|
+
radius_class_id=radius_class_id,
|
|
706
|
+
)
|
|
707
|
+
p_conversion = conversion["p_positive"]
|
|
708
|
+
conversion_magnitude = conversion["magnitude"]
|
|
709
|
+
if candidate.forecast is None:
|
|
710
|
+
geometry: dict[str, float] | None = None
|
|
711
|
+
raw_forecast_weight = 0.0
|
|
712
|
+
else:
|
|
713
|
+
geometry = self.base._forecast_geometry(
|
|
714
|
+
archive_points=archive_points,
|
|
715
|
+
forecast=candidate.forecast,
|
|
716
|
+
)
|
|
717
|
+
raw_forecast_weight = (
|
|
718
|
+
self.base.mixture_weight
|
|
719
|
+
* candidate.forecast.reliability
|
|
720
|
+
* trust_by_engine[candidate.engine_id]
|
|
721
|
+
)
|
|
722
|
+
raw_conversion_weight = 1.0 - self.base.mixture_weight
|
|
723
|
+
frozen_active = (
|
|
724
|
+
candidate.frozen_score is not None
|
|
725
|
+
and frozen_history_sufficient
|
|
726
|
+
and self.base.frozen_score_weight > 0.0
|
|
727
|
+
)
|
|
728
|
+
raw_frozen_weight = (
|
|
729
|
+
self.base.frozen_score_weight if frozen_active else 0.0
|
|
730
|
+
)
|
|
731
|
+
probability_total = (
|
|
732
|
+
raw_forecast_weight
|
|
733
|
+
+ raw_conversion_weight
|
|
734
|
+
+ raw_frozen_weight
|
|
735
|
+
)
|
|
736
|
+
if (
|
|
737
|
+
geometry is None and not frozen_active
|
|
738
|
+
) or probability_total <= 0.0:
|
|
739
|
+
p_positive = p_conversion
|
|
740
|
+
else:
|
|
741
|
+
blended_logit = (
|
|
742
|
+
raw_conversion_weight
|
|
743
|
+
* self.base._logit(p_conversion)
|
|
744
|
+
+ (
|
|
745
|
+
raw_forecast_weight
|
|
746
|
+
* self.base._logit(geometry["probability"])
|
|
747
|
+
if geometry is not None
|
|
748
|
+
else 0.0
|
|
749
|
+
)
|
|
750
|
+
+ (
|
|
751
|
+
raw_frozen_weight
|
|
752
|
+
* self.base._logit(candidate.frozen_score)
|
|
753
|
+
if frozen_active
|
|
754
|
+
else 0.0
|
|
755
|
+
)
|
|
756
|
+
) / probability_total
|
|
757
|
+
p_positive = 1.0 / (1.0 + math.exp(-blended_logit))
|
|
758
|
+
frozen_evidence_weight = (
|
|
759
|
+
raw_frozen_weight / probability_total
|
|
760
|
+
if frozen_active
|
|
761
|
+
else 0.0
|
|
762
|
+
)
|
|
763
|
+
magnitude_total = raw_forecast_weight + raw_conversion_weight
|
|
764
|
+
forecast_weight = (
|
|
765
|
+
raw_forecast_weight / magnitude_total
|
|
766
|
+
if magnitude_total > 0.0
|
|
767
|
+
else 0.0
|
|
768
|
+
)
|
|
769
|
+
conversion_weight = 1.0 - forecast_weight
|
|
770
|
+
if geometry is None:
|
|
771
|
+
expected_positive_gain = conversion_magnitude
|
|
772
|
+
tail_risk = (
|
|
773
|
+
conversion_weight
|
|
774
|
+
* (1.0 - p_conversion)
|
|
775
|
+
* conversion_magnitude
|
|
776
|
+
)
|
|
777
|
+
else:
|
|
778
|
+
expected_positive_gain = (
|
|
779
|
+
forecast_weight * geometry["magnitude"]
|
|
780
|
+
+ conversion_weight * conversion_magnitude
|
|
781
|
+
)
|
|
782
|
+
tail_risk = forecast_weight * geometry[
|
|
783
|
+
"shortfall"
|
|
784
|
+
] + conversion_weight * (
|
|
785
|
+
(1.0 - p_conversion) * conversion_magnitude
|
|
786
|
+
)
|
|
787
|
+
uncertainty = math.sqrt(
|
|
788
|
+
p_conversion
|
|
789
|
+
* (1.0 - p_conversion)
|
|
790
|
+
/ (conversion["effective_sample_size"] + 1.0)
|
|
791
|
+
)
|
|
792
|
+
value_of_information = (
|
|
793
|
+
uncertainty
|
|
794
|
+
* max(
|
|
795
|
+
expected_positive_gain,
|
|
796
|
+
self.base.reference_gain_scale,
|
|
797
|
+
)
|
|
798
|
+
if future_seats_remaining > 0
|
|
799
|
+
else 0.0
|
|
800
|
+
)
|
|
801
|
+
score = (
|
|
802
|
+
p_positive * expected_positive_gain
|
|
803
|
+
- self.base.lambda_ * tail_risk
|
|
804
|
+
+ effective_beta * value_of_information
|
|
805
|
+
)
|
|
806
|
+
scores.append(
|
|
807
|
+
CalibratedPositiveGainScore(
|
|
808
|
+
action_sha256=candidate.action_sha256,
|
|
809
|
+
p_feasible=conversion["p_feasible"],
|
|
810
|
+
p_positive_archive_gain=float(p_positive),
|
|
811
|
+
expected_positive_gain=float(
|
|
812
|
+
expected_positive_gain
|
|
813
|
+
),
|
|
814
|
+
tail_risk=float(tail_risk),
|
|
815
|
+
value_of_information=float(value_of_information),
|
|
816
|
+
uncertainty=float(uncertainty),
|
|
817
|
+
effective_sample_size=float(
|
|
818
|
+
conversion["effective_sample_size"]
|
|
819
|
+
),
|
|
820
|
+
score=float(score),
|
|
821
|
+
forecast_probability=(
|
|
822
|
+
None
|
|
823
|
+
if geometry is None
|
|
824
|
+
else float(geometry["probability"])
|
|
825
|
+
),
|
|
826
|
+
forecast_magnitude=(
|
|
827
|
+
None
|
|
828
|
+
if geometry is None
|
|
829
|
+
else float(geometry["magnitude"])
|
|
830
|
+
),
|
|
831
|
+
forecast_nondominated_fraction=(
|
|
832
|
+
None
|
|
833
|
+
if geometry is None
|
|
834
|
+
else float(geometry["nondominated_fraction"])
|
|
835
|
+
),
|
|
836
|
+
conversion_probability=float(p_conversion),
|
|
837
|
+
conversion_magnitude=float(conversion_magnitude),
|
|
838
|
+
frozen_score_probability=candidate.frozen_score,
|
|
839
|
+
frozen_evidence_weight=float(
|
|
840
|
+
frozen_evidence_weight
|
|
841
|
+
),
|
|
842
|
+
)
|
|
843
|
+
)
|
|
844
|
+
rank_quality_by_action = {
|
|
845
|
+
value.candidate.action_sha256: (
|
|
846
|
+
1.0
|
|
847
|
+
if value.candidate.lane_size == 1
|
|
848
|
+
else 1.0
|
|
849
|
+
- (value.candidate.native_rank - 1)
|
|
850
|
+
/ float(value.candidate.lane_size - 1)
|
|
851
|
+
)
|
|
852
|
+
for value in candidates
|
|
853
|
+
}
|
|
854
|
+
ranked = tuple(
|
|
855
|
+
value.action_sha256
|
|
856
|
+
for value in sorted(
|
|
857
|
+
scores,
|
|
858
|
+
key=lambda value: (
|
|
859
|
+
-value.score,
|
|
860
|
+
-value.p_positive_archive_gain,
|
|
861
|
+
(
|
|
862
|
+
-rank_quality_by_action[value.action_sha256]
|
|
863
|
+
if self.base.within_cell_rank_tie_break
|
|
864
|
+
else 0.0
|
|
865
|
+
),
|
|
866
|
+
value.action_sha256,
|
|
867
|
+
),
|
|
868
|
+
)
|
|
869
|
+
)
|
|
870
|
+
assert set(ranked) == set(by_action)
|
|
871
|
+
return CalibratedPositiveGainRanking(
|
|
872
|
+
policy_id=self.policy_id,
|
|
873
|
+
policy_version=self.policy_version,
|
|
874
|
+
policy_definition_sha256=self.definition_sha256,
|
|
875
|
+
archive_sha256=_hash(
|
|
876
|
+
_DEFINITION_DOMAIN,
|
|
877
|
+
[
|
|
878
|
+
[
|
|
879
|
+
{
|
|
880
|
+
"metric_id": metric_id,
|
|
881
|
+
"value_hex": metric_value.hex(),
|
|
882
|
+
}
|
|
883
|
+
for metric_id, metric_value in value
|
|
884
|
+
]
|
|
885
|
+
for value in archive_points
|
|
886
|
+
],
|
|
887
|
+
),
|
|
888
|
+
future_seats_remaining=future_seats_remaining,
|
|
889
|
+
horizon_total=horizon_total,
|
|
890
|
+
scores=tuple(scores),
|
|
891
|
+
ranked_action_sha256s=ranked,
|
|
892
|
+
)
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
__all__ = [
|
|
896
|
+
"RADIUS_CLASS_LONG",
|
|
897
|
+
"RADIUS_CLASS_MID",
|
|
898
|
+
"RADIUS_CLASS_NONE",
|
|
899
|
+
"RADIUS_CLASS_SHORT",
|
|
900
|
+
"REGION_CONDITIONAL_CREDIT_POLICY_ID",
|
|
901
|
+
"REGION_CONDITIONAL_CREDIT_POLICY_VERSION",
|
|
902
|
+
"REGION_NO_PARENT",
|
|
903
|
+
"RegionConditionalChallengerPolicy",
|
|
904
|
+
"RegionConditionalOutcome",
|
|
905
|
+
"RegionCreditConfig",
|
|
906
|
+
"RegionFeatures",
|
|
907
|
+
"RegionScoredCandidate",
|
|
908
|
+
"parent_front_distance",
|
|
909
|
+
"parent_front_region",
|
|
910
|
+
"radius_operator_class",
|
|
911
|
+
]
|