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,316 @@
|
|
|
1
|
+
"""Project a same-prefix forecast shadow into calibration evidence.
|
|
2
|
+
|
|
3
|
+
The projector joins only authenticated, already-observed records:
|
|
4
|
+
|
|
5
|
+
* the protected forecast-opportunity decision and its sealed raw score;
|
|
6
|
+
* the portable action descriptor used before evaluation; and
|
|
7
|
+
* the final same-prefix challenger-versus-fallback observation.
|
|
8
|
+
|
|
9
|
+
It does not inspect workload schemas, objective names, prompts, models, or
|
|
10
|
+
providers. The resulting observation can therefore enter the generic
|
|
11
|
+
prequential calibration memory without adding a workload integration method.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import hashlib
|
|
17
|
+
import json
|
|
18
|
+
import math
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
|
|
21
|
+
from agent_evolve.application.outcome_adaptive_action_racing import (
|
|
22
|
+
AdaptiveActionDescriptor,
|
|
23
|
+
AdaptiveActionRacingDecision,
|
|
24
|
+
)
|
|
25
|
+
from agent_evolve.application.prequential_archive_opportunity_calibration import (
|
|
26
|
+
ArchiveOpportunityActionContext,
|
|
27
|
+
ArchiveOpportunityCalibrationEvidenceRole,
|
|
28
|
+
ArchiveOpportunityCalibrationObservation,
|
|
29
|
+
ArchiveOpportunityCalibrationRequest,
|
|
30
|
+
)
|
|
31
|
+
from agent_evolve.application.same_prefix_paired_audit import (
|
|
32
|
+
FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS,
|
|
33
|
+
FORECAST_OPPORTUNITY_SAME_PREFIX_SHADOW_DESIGNER_ID,
|
|
34
|
+
FORECAST_STRATIFIED_SAME_PREFIX_AUDIT_DESIGNER_ID,
|
|
35
|
+
SamePrefixPairedAuditArm,
|
|
36
|
+
SamePrefixPairedAuditObservation,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.domain.typed_json import thaw_json
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID = (
|
|
42
|
+
"forecast_opportunity_shadow_calibration"
|
|
43
|
+
)
|
|
44
|
+
FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION = 2
|
|
45
|
+
_DEFINITION_DOMAIN = (
|
|
46
|
+
b"agent-evolve:forecast-opportunity-shadow-calibration-projector:v2\x00"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _canonical_json(value: object) -> bytes:
|
|
51
|
+
return json.dumps(
|
|
52
|
+
value,
|
|
53
|
+
allow_nan=False,
|
|
54
|
+
ensure_ascii=True,
|
|
55
|
+
separators=(",", ":"),
|
|
56
|
+
sort_keys=True,
|
|
57
|
+
).encode("ascii", errors="strict")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
61
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _read_nonnegative_hex(record: dict[str, object], key: str) -> float:
|
|
65
|
+
raw = record.get(key)
|
|
66
|
+
if type(raw) is not str:
|
|
67
|
+
raise TypeError(f"{key} must be an exact hexadecimal float")
|
|
68
|
+
try:
|
|
69
|
+
value = float.fromhex(raw)
|
|
70
|
+
except ValueError as error:
|
|
71
|
+
raise ValueError(f"{key} is not a hexadecimal float") from error
|
|
72
|
+
if not math.isfinite(value) or value < 0.0:
|
|
73
|
+
raise ValueError(f"{key} must be finite and non-negative")
|
|
74
|
+
return float(value)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass(frozen=True, slots=True)
|
|
78
|
+
class ForecastOpportunityShadowCalibrationProjector:
|
|
79
|
+
"""Create one calibration target from a sealed same-prefix forecast arm."""
|
|
80
|
+
|
|
81
|
+
projector_id: str = (
|
|
82
|
+
FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID
|
|
83
|
+
)
|
|
84
|
+
projector_version: int = (
|
|
85
|
+
FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION
|
|
86
|
+
)
|
|
87
|
+
definition_sha256: str = field(init=False)
|
|
88
|
+
|
|
89
|
+
def __post_init__(self) -> None:
|
|
90
|
+
if (
|
|
91
|
+
self.projector_id
|
|
92
|
+
!= FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID
|
|
93
|
+
or self.projector_version
|
|
94
|
+
!= FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION
|
|
95
|
+
):
|
|
96
|
+
raise ValueError("shadow calibration projector identity is immutable")
|
|
97
|
+
object.__setattr__(
|
|
98
|
+
self,
|
|
99
|
+
"definition_sha256",
|
|
100
|
+
_hash(
|
|
101
|
+
_DEFINITION_DOMAIN,
|
|
102
|
+
{
|
|
103
|
+
"schema_version": 1,
|
|
104
|
+
"projector_id": self.projector_id,
|
|
105
|
+
"projector_version": self.projector_version,
|
|
106
|
+
"forecast_source": (
|
|
107
|
+
"authenticated-protected-decision-raw-score"
|
|
108
|
+
),
|
|
109
|
+
"target": (
|
|
110
|
+
"exact-forecast-arm-conditional-gain-at-identical-"
|
|
111
|
+
"prefix"
|
|
112
|
+
),
|
|
113
|
+
"accepted_designers": sorted(
|
|
114
|
+
FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS
|
|
115
|
+
),
|
|
116
|
+
"fallback_target_retained_in_paired_observation": True,
|
|
117
|
+
"paired_evidence_role_and_sampling_propensity_recorded": (
|
|
118
|
+
True
|
|
119
|
+
),
|
|
120
|
+
"current_or_future_candidate_outcomes_used_for_forecast": (
|
|
121
|
+
False
|
|
122
|
+
),
|
|
123
|
+
"workload_objective_model_provider_prompt_config_"
|
|
124
|
+
"branches": False,
|
|
125
|
+
},
|
|
126
|
+
),
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def _score_record(
|
|
131
|
+
decision: AdaptiveActionRacingDecision,
|
|
132
|
+
action_sha256: str,
|
|
133
|
+
*,
|
|
134
|
+
require_recommended: bool,
|
|
135
|
+
) -> dict[str, object]:
|
|
136
|
+
evidence = thaw_json(decision.evidence)
|
|
137
|
+
ranking = evidence.get("opportunity_ranking")
|
|
138
|
+
if type(ranking) is not dict:
|
|
139
|
+
raise TypeError("decision lacks an exact opportunity ranking")
|
|
140
|
+
recommended = ranking.get("recommended_action_sha256s")
|
|
141
|
+
scores = ranking.get("scores")
|
|
142
|
+
if (
|
|
143
|
+
type(recommended) is not list
|
|
144
|
+
or type(scores) is not list
|
|
145
|
+
):
|
|
146
|
+
raise TypeError("decision opportunity ranking is incomplete")
|
|
147
|
+
if require_recommended and action_sha256 not in recommended:
|
|
148
|
+
raise ValueError(
|
|
149
|
+
"legacy shadow challenger is not a recommendation"
|
|
150
|
+
)
|
|
151
|
+
matches = [
|
|
152
|
+
value
|
|
153
|
+
for value in scores
|
|
154
|
+
if type(value) is dict
|
|
155
|
+
and value.get("action_sha256") == action_sha256
|
|
156
|
+
]
|
|
157
|
+
if len(matches) != 1:
|
|
158
|
+
raise ValueError(
|
|
159
|
+
"opportunity ranking must expose one challenger score"
|
|
160
|
+
)
|
|
161
|
+
return matches[0]
|
|
162
|
+
|
|
163
|
+
def project(
|
|
164
|
+
self,
|
|
165
|
+
*,
|
|
166
|
+
decision_index: int,
|
|
167
|
+
evidence_cutoff_ordinal: int,
|
|
168
|
+
decision: AdaptiveActionRacingDecision,
|
|
169
|
+
action: AdaptiveActionDescriptor,
|
|
170
|
+
observation: SamePrefixPairedAuditObservation,
|
|
171
|
+
) -> ArchiveOpportunityCalibrationObservation:
|
|
172
|
+
"""Join the sealed raw score to the later real challenger outcome."""
|
|
173
|
+
|
|
174
|
+
self.__post_init__()
|
|
175
|
+
if type(decision_index) is not int or decision_index <= 0:
|
|
176
|
+
raise ValueError("decision_index must be positive")
|
|
177
|
+
if (
|
|
178
|
+
type(evidence_cutoff_ordinal) is not int
|
|
179
|
+
or evidence_cutoff_ordinal <= 0
|
|
180
|
+
):
|
|
181
|
+
raise ValueError("evidence_cutoff_ordinal must be positive")
|
|
182
|
+
if type(decision) is not AdaptiveActionRacingDecision:
|
|
183
|
+
raise TypeError("decision must be exact")
|
|
184
|
+
if type(action) is not AdaptiveActionDescriptor:
|
|
185
|
+
raise TypeError("action must be exact")
|
|
186
|
+
if type(observation) is not SamePrefixPairedAuditObservation:
|
|
187
|
+
raise TypeError("observation must be exact")
|
|
188
|
+
decision.__post_init__()
|
|
189
|
+
action.__post_init__()
|
|
190
|
+
observation.__post_init__()
|
|
191
|
+
plan = observation.plan
|
|
192
|
+
if plan.designer_id not in (
|
|
193
|
+
FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS
|
|
194
|
+
):
|
|
195
|
+
raise ValueError("observation is not a forecast audit")
|
|
196
|
+
is_legacy_final_shadow = (
|
|
197
|
+
plan.designer_id
|
|
198
|
+
== FORECAST_OPPORTUNITY_SAME_PREFIX_SHADOW_DESIGNER_ID
|
|
199
|
+
)
|
|
200
|
+
if (
|
|
201
|
+
plan.racing_decision_sha256 != decision.decision_sha256
|
|
202
|
+
or plan.exploration_action_sha256 != action.action_sha256
|
|
203
|
+
or decision.selected_action_sha256s
|
|
204
|
+
!= (plan.authoritative_action_sha256,)
|
|
205
|
+
or decision.prior_selected_action_sha256s
|
|
206
|
+
!= plan.common_prefix_action_sha256s
|
|
207
|
+
or (
|
|
208
|
+
is_legacy_final_shadow
|
|
209
|
+
and plan.authoritative_arm
|
|
210
|
+
is not SamePrefixPairedAuditArm.EXPLORATION
|
|
211
|
+
)
|
|
212
|
+
or (
|
|
213
|
+
plan.designer_id
|
|
214
|
+
== FORECAST_STRATIFIED_SAME_PREFIX_AUDIT_DESIGNER_ID
|
|
215
|
+
and plan.authoritative_arm
|
|
216
|
+
not in {
|
|
217
|
+
SamePrefixPairedAuditArm.LEGACY,
|
|
218
|
+
SamePrefixPairedAuditArm.EXPLORATION,
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
):
|
|
222
|
+
raise ValueError(
|
|
223
|
+
"decision, descriptor, and forecast shadow do not join"
|
|
224
|
+
)
|
|
225
|
+
score = self._score_record(
|
|
226
|
+
decision,
|
|
227
|
+
action.action_sha256,
|
|
228
|
+
require_recommended=is_legacy_final_shadow,
|
|
229
|
+
)
|
|
230
|
+
raw_acquisition_key = (
|
|
231
|
+
"raw_acquisition_value_hex"
|
|
232
|
+
if "raw_acquisition_value_hex" in score
|
|
233
|
+
else "acquisition_value_hex"
|
|
234
|
+
)
|
|
235
|
+
paired_role = (
|
|
236
|
+
ArchiveOpportunityCalibrationEvidenceRole
|
|
237
|
+
.SAME_PREFIX_PAIRED_AUTHORITATIVE
|
|
238
|
+
if plan.authoritative_arm
|
|
239
|
+
is SamePrefixPairedAuditArm.EXPLORATION
|
|
240
|
+
else (
|
|
241
|
+
ArchiveOpportunityCalibrationEvidenceRole
|
|
242
|
+
.SAME_PREFIX_PAIRED_COUNTERFACTUAL
|
|
243
|
+
)
|
|
244
|
+
)
|
|
245
|
+
return ArchiveOpportunityCalibrationObservation(
|
|
246
|
+
request=ArchiveOpportunityCalibrationRequest(
|
|
247
|
+
context=ArchiveOpportunityActionContext(
|
|
248
|
+
action_sha256=action.action_sha256,
|
|
249
|
+
decision_index=decision_index,
|
|
250
|
+
lane_id=action.lane_id,
|
|
251
|
+
operator_id=action.operator_id,
|
|
252
|
+
native_rank=action.native_rank,
|
|
253
|
+
lane_size=action.lane_size,
|
|
254
|
+
prior_score=action.prior_score,
|
|
255
|
+
parent_generated_in_current_run=(
|
|
256
|
+
action.parent_generated_in_current_run
|
|
257
|
+
),
|
|
258
|
+
),
|
|
259
|
+
forecast_reliability=_read_nonnegative_hex(
|
|
260
|
+
score,
|
|
261
|
+
"reliability_hex",
|
|
262
|
+
),
|
|
263
|
+
raw_adverse_gain=_read_nonnegative_hex(
|
|
264
|
+
score,
|
|
265
|
+
"adverse_gain_hex",
|
|
266
|
+
),
|
|
267
|
+
raw_central_gain=_read_nonnegative_hex(
|
|
268
|
+
score,
|
|
269
|
+
"central_gain_hex",
|
|
270
|
+
),
|
|
271
|
+
raw_favorable_gain=_read_nonnegative_hex(
|
|
272
|
+
score,
|
|
273
|
+
"favorable_gain_hex",
|
|
274
|
+
),
|
|
275
|
+
raw_acquisition_value=_read_nonnegative_hex(
|
|
276
|
+
score,
|
|
277
|
+
raw_acquisition_key,
|
|
278
|
+
),
|
|
279
|
+
prefix_gain=float(
|
|
280
|
+
observation.exploration_set_outcome
|
|
281
|
+
.prior_selected_set_gain
|
|
282
|
+
),
|
|
283
|
+
prefix_action_count=len(
|
|
284
|
+
plan.common_prefix_action_sha256s
|
|
285
|
+
),
|
|
286
|
+
),
|
|
287
|
+
realized_conditional_gain=float(
|
|
288
|
+
observation.exploration_set_outcome.conditional_set_gain
|
|
289
|
+
),
|
|
290
|
+
decision_sha256=decision.decision_sha256,
|
|
291
|
+
outcome_sha256=observation.exploration_outcome.outcome_sha256,
|
|
292
|
+
evidence_cutoff_ordinal=evidence_cutoff_ordinal,
|
|
293
|
+
evidence_role=(
|
|
294
|
+
ArchiveOpportunityCalibrationEvidenceRole
|
|
295
|
+
.AUTHORITATIVE_SELECTED
|
|
296
|
+
if is_legacy_final_shadow
|
|
297
|
+
else paired_role
|
|
298
|
+
),
|
|
299
|
+
sampling_propensity=(
|
|
300
|
+
1.0
|
|
301
|
+
if is_legacy_final_shadow
|
|
302
|
+
else plan.exploration_selection_propensity
|
|
303
|
+
),
|
|
304
|
+
paired_observation_sha256=(
|
|
305
|
+
None
|
|
306
|
+
if is_legacy_final_shadow
|
|
307
|
+
else observation.observation_sha256
|
|
308
|
+
),
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
__all__ = [
|
|
313
|
+
"FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID",
|
|
314
|
+
"FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION",
|
|
315
|
+
"ForecastOpportunityShadowCalibrationProjector",
|
|
316
|
+
]
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""Front-proximity admission: drop the market's dominated-parent tail.
|
|
2
|
+
|
|
3
|
+
A candidate's *parent anchor* is the objective point its action was derived
|
|
4
|
+
from. The anchor's Chebyshev excess over the current archive front measures
|
|
5
|
+
how deep inside the dominated interior that anchor sits: a value at or below
|
|
6
|
+
zero means the anchor is itself non-dominated, and larger values mean the
|
|
7
|
+
anchor is buried further behind the front.
|
|
8
|
+
|
|
9
|
+
On the jul28 sealed BOiLS held-out markets this quantity is the strongest
|
|
10
|
+
outcome-blind discriminator measured (pooled AUC 0.732 for individual
|
|
11
|
+
positivity, 8 of 8 markets at or above 0.50), and its worst band is
|
|
12
|
+
effectively empty: anchors more than 0.05 normalized units behind the front
|
|
13
|
+
hold 26% of the market mass, 1 of 88 positives and 1.6% of the realised
|
|
14
|
+
gain. This module turns that observation into a *support restriction* that
|
|
15
|
+
composes over any allocation policy: the wrapped policy still makes every
|
|
16
|
+
decision, it simply never sees the tail of the market that carries no
|
|
17
|
+
outcome mass.
|
|
18
|
+
|
|
19
|
+
The rule is deliberately RELATIVE — it keeps the market's own best
|
|
20
|
+
``keep_fraction`` of anchors — so it introduces no absolute threshold, no
|
|
21
|
+
workload constant, no metric name and no scale assumption. Candidates whose
|
|
22
|
+
anchor is unknown are scored at the market's median anchor so an anchorless
|
|
23
|
+
lane is never systematically evicted or systematically protected.
|
|
24
|
+
|
|
25
|
+
The signal replicates: pooled AUC 0.700 on the five jul27 replay-corpus
|
|
26
|
+
markets that record parent anchors (0.583 to 0.767 per market), against
|
|
27
|
+
0.732 on the eight held-out markets. What has NOT been shown is that any
|
|
28
|
+
deterministic policy built on it beats the ``lane_heads`` incumbent on four
|
|
29
|
+
sealed cells; the incumbent's own headline sits at the p = 0.08 tail of the
|
|
30
|
+
uniform null, so a four-cell single-run comparison cannot resolve it.
|
|
31
|
+
|
|
32
|
+
Claim boundary: replay-evaluation only. Nothing here carries live campaign
|
|
33
|
+
authority. See
|
|
34
|
+
``research_artifacts/jul28_large_gain_anatomy_and_refinement.md``.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
from __future__ import annotations
|
|
38
|
+
|
|
39
|
+
import hashlib
|
|
40
|
+
import json
|
|
41
|
+
import math
|
|
42
|
+
import re
|
|
43
|
+
from dataclasses import dataclass, field
|
|
44
|
+
|
|
45
|
+
from agent_evolve.application.calibrated_positive_gain_opportunity import (
|
|
46
|
+
ObjectivePoint,
|
|
47
|
+
chebyshev_excess,
|
|
48
|
+
non_dominated,
|
|
49
|
+
)
|
|
50
|
+
from agent_evolve.application.sequential_market_replay import (
|
|
51
|
+
MarketRecord,
|
|
52
|
+
ReplaySelection,
|
|
53
|
+
ReplayStepReceipt,
|
|
54
|
+
_corpus_action_sha256,
|
|
55
|
+
_normalized_point,
|
|
56
|
+
)
|
|
57
|
+
from agent_evolve.domain.patch import require_sha256
|
|
58
|
+
|
|
59
|
+
FRONT_PROXIMITY_ADMISSION_ID = "front_proximity_admission"
|
|
60
|
+
FRONT_PROXIMITY_ADMISSION_VERSION = 1
|
|
61
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
62
|
+
_DEFINITION_DOMAIN = b"agent-evolve:front-proximity-admission: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(value: object) -> str:
|
|
76
|
+
return hashlib.sha256(
|
|
77
|
+
_DEFINITION_DOMAIN + _canonical_json(value)
|
|
78
|
+
).hexdigest()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# ``non_dominated`` and ``chebyshev_excess`` now live in the calibrated
|
|
82
|
+
# scorer, which consumes the same geometry directly; they are re-exported
|
|
83
|
+
# here unchanged so every existing import keeps resolving.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass(frozen=True, slots=True)
|
|
87
|
+
class FrontProximityAdmissionConfig:
|
|
88
|
+
"""How much of the market's anchor distribution stays selectable."""
|
|
89
|
+
|
|
90
|
+
#: Fraction of the market's known anchors retained, best (smallest
|
|
91
|
+
#: Chebyshev excess) first. 1.0 disables the restriction entirely.
|
|
92
|
+
keep_fraction: float = 0.50
|
|
93
|
+
#: Never shrink the support below this many candidates, so a small
|
|
94
|
+
#: market can never be reduced to a single forced choice.
|
|
95
|
+
minimum_support: int = 2
|
|
96
|
+
|
|
97
|
+
def __post_init__(self) -> None:
|
|
98
|
+
if (
|
|
99
|
+
type(self.keep_fraction) is not float
|
|
100
|
+
or not math.isfinite(self.keep_fraction)
|
|
101
|
+
or not 0.0 < self.keep_fraction <= 1.0
|
|
102
|
+
):
|
|
103
|
+
raise ValueError("keep_fraction must lie in (0, 1]")
|
|
104
|
+
if type(self.minimum_support) is not int or self.minimum_support < 1:
|
|
105
|
+
raise ValueError("minimum_support must be a positive integer")
|
|
106
|
+
|
|
107
|
+
def to_record(self) -> dict[str, object]:
|
|
108
|
+
return {
|
|
109
|
+
"keep_fraction_hex": float(self.keep_fraction).hex(),
|
|
110
|
+
"minimum_support": self.minimum_support,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@dataclass(frozen=True, slots=True)
|
|
115
|
+
class FrontProximityAdmission:
|
|
116
|
+
"""Restrict a replay policy to the front-proximal part of its market.
|
|
117
|
+
|
|
118
|
+
``anchors`` maps ``action_sha256`` to that candidate's parent objective
|
|
119
|
+
point in the market's own normalized metric frame. Candidates absent
|
|
120
|
+
from the map are scored at the median known excess.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
inner: object
|
|
124
|
+
anchors: dict[str, ObjectivePoint]
|
|
125
|
+
config: FrontProximityAdmissionConfig = field(
|
|
126
|
+
default_factory=FrontProximityAdmissionConfig
|
|
127
|
+
)
|
|
128
|
+
policy_id: str = "replay_arm.front_proximity_admission"
|
|
129
|
+
definition_sha256: str = field(init=False)
|
|
130
|
+
|
|
131
|
+
def __post_init__(self) -> None:
|
|
132
|
+
if not hasattr(self.inner, "select"):
|
|
133
|
+
raise TypeError("inner must expose an exact select()")
|
|
134
|
+
if type(self.anchors) is not dict:
|
|
135
|
+
raise TypeError("anchors must be an exact mapping")
|
|
136
|
+
for action_sha256, point in self.anchors.items():
|
|
137
|
+
require_sha256(action_sha256, "anchors key")
|
|
138
|
+
if type(point) is not tuple or not point:
|
|
139
|
+
raise TypeError("anchor points must be exact tuples")
|
|
140
|
+
self.config.__post_init__()
|
|
141
|
+
if _TOKEN.fullmatch(self.policy_id) is None:
|
|
142
|
+
raise ValueError("policy_id must use the closed token grammar")
|
|
143
|
+
object.__setattr__(
|
|
144
|
+
self,
|
|
145
|
+
"definition_sha256",
|
|
146
|
+
_hash(
|
|
147
|
+
{
|
|
148
|
+
"arm": FRONT_PROXIMITY_ADMISSION_ID,
|
|
149
|
+
"version": FRONT_PROXIMITY_ADMISSION_VERSION,
|
|
150
|
+
"config": self.config.to_record(),
|
|
151
|
+
"inner_policy_id": str(
|
|
152
|
+
getattr(self.inner, "policy_id", "")
|
|
153
|
+
),
|
|
154
|
+
"inner_definition_sha256": str(
|
|
155
|
+
getattr(self.inner, "definition_sha256", "")
|
|
156
|
+
),
|
|
157
|
+
"rule": (
|
|
158
|
+
"keep the market's best keep_fraction of candidates "
|
|
159
|
+
"by parent-anchor chebyshev excess over the archive "
|
|
160
|
+
"front, unknown anchors scored at the median, never "
|
|
161
|
+
"below minimum_support"
|
|
162
|
+
),
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def admissible(
|
|
168
|
+
self,
|
|
169
|
+
*,
|
|
170
|
+
record: MarketRecord,
|
|
171
|
+
revealed: tuple[ReplayStepReceipt, ...],
|
|
172
|
+
selectable_action_sha256s: tuple[str, ...],
|
|
173
|
+
) -> tuple[str, ...]:
|
|
174
|
+
"""The retained support, outcome-blind except for revealed points."""
|
|
175
|
+
|
|
176
|
+
support = tuple(sorted(set(selectable_action_sha256s)))
|
|
177
|
+
if not support:
|
|
178
|
+
raise ValueError("selectable support must be non-empty")
|
|
179
|
+
if self.config.keep_fraction >= 1.0:
|
|
180
|
+
return support
|
|
181
|
+
metric_ids = record.metric_ids
|
|
182
|
+
archive: list[ObjectivePoint] = list(record.archive_points)
|
|
183
|
+
for receipt in revealed:
|
|
184
|
+
candidate = record.candidate(receipt.action_sha256)
|
|
185
|
+
if candidate.objectives is not None:
|
|
186
|
+
archive.append(candidate.objectives)
|
|
187
|
+
frozen_archive = tuple(archive)
|
|
188
|
+
scored: list[tuple[str, float | None]] = []
|
|
189
|
+
for action_sha256 in support:
|
|
190
|
+
anchor = self.anchors.get(action_sha256)
|
|
191
|
+
scored.append(
|
|
192
|
+
(
|
|
193
|
+
action_sha256,
|
|
194
|
+
None
|
|
195
|
+
if anchor is None
|
|
196
|
+
else chebyshev_excess(
|
|
197
|
+
anchor, frozen_archive, metric_ids
|
|
198
|
+
),
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
known = sorted(
|
|
202
|
+
value for _sha, value in scored if value is not None
|
|
203
|
+
)
|
|
204
|
+
if not known:
|
|
205
|
+
return support
|
|
206
|
+
median = known[len(known) // 2]
|
|
207
|
+
index = int(round(self.config.keep_fraction * len(known))) - 1
|
|
208
|
+
index = max(0, min(len(known) - 1, index))
|
|
209
|
+
cutoff = known[index]
|
|
210
|
+
kept = tuple(
|
|
211
|
+
action_sha256
|
|
212
|
+
for action_sha256, value in scored
|
|
213
|
+
if (median if value is None else value) <= cutoff
|
|
214
|
+
)
|
|
215
|
+
if len(kept) < min(self.config.minimum_support, len(support)):
|
|
216
|
+
# Restore in ascending excess order until the floor is met, so
|
|
217
|
+
# the restriction degrades continuously instead of collapsing.
|
|
218
|
+
order = sorted(
|
|
219
|
+
scored,
|
|
220
|
+
key=lambda item: (
|
|
221
|
+
median if item[1] is None else item[1],
|
|
222
|
+
item[0],
|
|
223
|
+
),
|
|
224
|
+
)
|
|
225
|
+
kept = tuple(
|
|
226
|
+
action_sha256
|
|
227
|
+
for action_sha256, _value in order[
|
|
228
|
+
: min(self.config.minimum_support, len(support))
|
|
229
|
+
]
|
|
230
|
+
)
|
|
231
|
+
return tuple(sorted(kept)) or support
|
|
232
|
+
|
|
233
|
+
def select(
|
|
234
|
+
self,
|
|
235
|
+
*,
|
|
236
|
+
record: MarketRecord,
|
|
237
|
+
revealed: tuple[ReplayStepReceipt, ...],
|
|
238
|
+
selectable_action_sha256s: tuple[str, ...],
|
|
239
|
+
step_index: int,
|
|
240
|
+
budget: int,
|
|
241
|
+
) -> ReplaySelection:
|
|
242
|
+
kept = self.admissible(
|
|
243
|
+
record=record,
|
|
244
|
+
revealed=revealed,
|
|
245
|
+
selectable_action_sha256s=selectable_action_sha256s,
|
|
246
|
+
)
|
|
247
|
+
selection = self.inner.select(
|
|
248
|
+
record=record,
|
|
249
|
+
revealed=revealed,
|
|
250
|
+
selectable_action_sha256s=kept,
|
|
251
|
+
step_index=step_index,
|
|
252
|
+
budget=budget,
|
|
253
|
+
)
|
|
254
|
+
if type(selection) is not ReplaySelection:
|
|
255
|
+
raise TypeError("inner policy must return an exact selection")
|
|
256
|
+
if selection.action_sha256 not in kept:
|
|
257
|
+
raise ValueError("inner policy escaped the admissible support")
|
|
258
|
+
return ReplaySelection(
|
|
259
|
+
action_sha256=selection.action_sha256,
|
|
260
|
+
selection_propensity=selection.selection_propensity,
|
|
261
|
+
evidence={
|
|
262
|
+
**dict(selection.evidence),
|
|
263
|
+
"admissible_support_size": len(kept),
|
|
264
|
+
"offered_support_size": len(
|
|
265
|
+
set(selectable_action_sha256s)
|
|
266
|
+
),
|
|
267
|
+
},
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def anchors_from_corpus(
|
|
272
|
+
payload: dict[str, object],
|
|
273
|
+
) -> dict[str, ObjectivePoint]:
|
|
274
|
+
"""Parent anchors for one jul27 replay-corpus payload, if recorded.
|
|
275
|
+
|
|
276
|
+
Candidates with no recorded parent objective vector are simply absent,
|
|
277
|
+
which the admission rule treats as the median anchor.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
market_id = str(payload["market_id"])
|
|
281
|
+
axes = tuple(payload["hv_reference_point"]["axes"]) # type: ignore[index]
|
|
282
|
+
metric_ids = tuple(sorted(str(axis["metric_id"]) for axis in axes))
|
|
283
|
+
anchors: dict[str, ObjectivePoint] = {}
|
|
284
|
+
for raw in payload["candidates"]: # type: ignore[union-attr]
|
|
285
|
+
parent = raw.get("parent")
|
|
286
|
+
if not isinstance(parent, dict):
|
|
287
|
+
continue
|
|
288
|
+
objectives = parent.get("objectives")
|
|
289
|
+
if not isinstance(objectives, dict):
|
|
290
|
+
continue
|
|
291
|
+
if not set(metric_ids) <= set(objectives):
|
|
292
|
+
continue
|
|
293
|
+
anchors[_corpus_action_sha256(market_id, raw)] = _normalized_point(
|
|
294
|
+
{
|
|
295
|
+
metric_id: float(objectives[metric_id])
|
|
296
|
+
for metric_id in metric_ids
|
|
297
|
+
},
|
|
298
|
+
axes,
|
|
299
|
+
)
|
|
300
|
+
return anchors
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
__all__ = [
|
|
304
|
+
"FRONT_PROXIMITY_ADMISSION_ID",
|
|
305
|
+
"FRONT_PROXIMITY_ADMISSION_VERSION",
|
|
306
|
+
"FrontProximityAdmission",
|
|
307
|
+
"FrontProximityAdmissionConfig",
|
|
308
|
+
"anchors_from_corpus",
|
|
309
|
+
"chebyshev_excess",
|
|
310
|
+
"non_dominated",
|
|
311
|
+
]
|