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,838 @@
|
|
|
1
|
+
"""Outcome-blind, set-aware composition of sealed action score authorities.
|
|
2
|
+
|
|
3
|
+
The policy consumes two inverted APIs:
|
|
4
|
+
|
|
5
|
+
* opaque scalar score authorities rank every sealed materialized action; and
|
|
6
|
+
* a semantic-cell projection exposes only categorical predicted objective
|
|
7
|
+
directions and whether the action descends from a previously generated
|
|
8
|
+
candidate.
|
|
9
|
+
|
|
10
|
+
It never parses workload configurations, objective names, model identities, or
|
|
11
|
+
provider identities. An exact recursive-lineage partition protects promising
|
|
12
|
+
descendants without allowing them to spill into ordinary score lanes, fixed
|
|
13
|
+
scorer shares conserve independent ranking authorities, and a rank-bounded
|
|
14
|
+
semantic coverage term prevents an evaluation slate from collapsing onto one
|
|
15
|
+
predicted trade-off direction.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import asyncio
|
|
21
|
+
import hashlib
|
|
22
|
+
import json
|
|
23
|
+
import math
|
|
24
|
+
import re
|
|
25
|
+
from dataclasses import dataclass, field
|
|
26
|
+
from typing import ClassVar, Protocol, runtime_checkable
|
|
27
|
+
|
|
28
|
+
from agent_evolve.application.materialized_action_broker import (
|
|
29
|
+
MaterializedActionAllocationRequirement,
|
|
30
|
+
MaterializedActionDescriptor,
|
|
31
|
+
)
|
|
32
|
+
from agent_evolve.application.prequential_score_portfolio import (
|
|
33
|
+
MaterializedActionScoreBatch,
|
|
34
|
+
MaterializedActionScorePort,
|
|
35
|
+
)
|
|
36
|
+
from agent_evolve.application.residual_portfolio_evolution import (
|
|
37
|
+
MaterializedActionProposalBatch,
|
|
38
|
+
ResidualPortfolioDecisionRequest,
|
|
39
|
+
)
|
|
40
|
+
from agent_evolve.domain.patch import require_sha256
|
|
41
|
+
from agent_evolve.domain.typed_json import (
|
|
42
|
+
FrozenJsonObject,
|
|
43
|
+
freeze_json,
|
|
44
|
+
typed_json_sha256,
|
|
45
|
+
)
|
|
46
|
+
from agent_evolve.ports.hard_feasibility import (
|
|
47
|
+
HardFeasibilityDecision,
|
|
48
|
+
HardFeasibilityPort,
|
|
49
|
+
HardFeasibilityRequest,
|
|
50
|
+
HardFeasibilityVerdict,
|
|
51
|
+
assess_hard_feasibility,
|
|
52
|
+
hard_feasibility_decision_batch_sha256,
|
|
53
|
+
validate_hard_feasibility_port,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_ID = (
|
|
58
|
+
"semantic_coverage_score_portfolio_allocator"
|
|
59
|
+
)
|
|
60
|
+
SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_VERSION = 1
|
|
61
|
+
|
|
62
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
63
|
+
_METRIC_ID = re.compile(r"^[A-Za-z][A-Za-z0-9_.:/-]{0,255}$")
|
|
64
|
+
_DIRECTIONS = frozenset({"decrease", "increase", "unchanged"})
|
|
65
|
+
_CELL_BATCH_DOMAIN = b"agent-evolve:action-semantic-cell-batch:v1\x00"
|
|
66
|
+
_POLICY_DOMAIN = b"agent-evolve:semantic-coverage-score-portfolio:v1\x00"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _canonical_json(value: object) -> bytes:
|
|
70
|
+
return json.dumps(
|
|
71
|
+
value,
|
|
72
|
+
allow_nan=False,
|
|
73
|
+
ensure_ascii=True,
|
|
74
|
+
separators=(",", ":"),
|
|
75
|
+
sort_keys=True,
|
|
76
|
+
).encode("ascii", errors="strict")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
80
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _require_token(value: str, *, name: str) -> None:
|
|
84
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
85
|
+
raise ValueError(f"{name} must use the closed token grammar")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _scorer_identity(
|
|
89
|
+
scorer: MaterializedActionScorePort,
|
|
90
|
+
) -> tuple[str, int, str]:
|
|
91
|
+
if not isinstance(scorer, MaterializedActionScorePort):
|
|
92
|
+
raise TypeError("scorer must implement MaterializedActionScorePort")
|
|
93
|
+
identity = (
|
|
94
|
+
getattr(scorer, "scorer_id", None),
|
|
95
|
+
getattr(scorer, "scorer_version", None),
|
|
96
|
+
getattr(scorer, "definition_sha256", None),
|
|
97
|
+
)
|
|
98
|
+
_require_token(identity[0], name="scorer_id")
|
|
99
|
+
if type(identity[1]) is not int or identity[1] <= 0:
|
|
100
|
+
raise ValueError("scorer_version must be positive")
|
|
101
|
+
require_sha256(identity[2], "scorer definition_sha256")
|
|
102
|
+
return identity # type: ignore[return-value]
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@dataclass(frozen=True, slots=True)
|
|
106
|
+
class MaterializedActionSemanticCell:
|
|
107
|
+
"""One sealed action's portable categorical coverage coordinates."""
|
|
108
|
+
|
|
109
|
+
action_sha256: str
|
|
110
|
+
direction_signature: tuple[tuple[str, str], ...]
|
|
111
|
+
recursive_lineage: bool
|
|
112
|
+
|
|
113
|
+
def __post_init__(self) -> None:
|
|
114
|
+
require_sha256(self.action_sha256, "action_sha256")
|
|
115
|
+
if type(self.direction_signature) is not tuple:
|
|
116
|
+
raise TypeError("direction_signature must be an exact tuple")
|
|
117
|
+
metric_ids: list[str] = []
|
|
118
|
+
for metric_id, direction in self.direction_signature:
|
|
119
|
+
if (
|
|
120
|
+
type(metric_id) is not str
|
|
121
|
+
or _METRIC_ID.fullmatch(metric_id) is None
|
|
122
|
+
):
|
|
123
|
+
raise ValueError("semantic metric_id has invalid syntax")
|
|
124
|
+
if direction not in _DIRECTIONS:
|
|
125
|
+
raise ValueError("semantic direction is not categorical")
|
|
126
|
+
metric_ids.append(metric_id)
|
|
127
|
+
if tuple(metric_ids) != tuple(sorted(set(metric_ids))):
|
|
128
|
+
raise ValueError("semantic directions must be metric-canonical")
|
|
129
|
+
if type(self.recursive_lineage) is not bool:
|
|
130
|
+
raise TypeError("recursive_lineage must be an exact bool")
|
|
131
|
+
|
|
132
|
+
def to_record(self) -> dict[str, object]:
|
|
133
|
+
self.__post_init__()
|
|
134
|
+
return {
|
|
135
|
+
"action_sha256": self.action_sha256,
|
|
136
|
+
"direction_signature": [
|
|
137
|
+
{"metric_id": metric_id, "direction": direction}
|
|
138
|
+
for metric_id, direction in self.direction_signature
|
|
139
|
+
],
|
|
140
|
+
"recursive_lineage": self.recursive_lineage,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@dataclass(frozen=True, slots=True)
|
|
145
|
+
class MaterializedActionSemanticCellBatch:
|
|
146
|
+
"""Authenticated semantic cells for a complete sealed proposal union."""
|
|
147
|
+
|
|
148
|
+
projection_id: str
|
|
149
|
+
projection_version: int
|
|
150
|
+
projection_definition_sha256: str
|
|
151
|
+
residual_request_sha256: str
|
|
152
|
+
proposal_sha256s: tuple[str, ...]
|
|
153
|
+
cells: tuple[MaterializedActionSemanticCell, ...]
|
|
154
|
+
candidate_outcomes_observed: bool
|
|
155
|
+
evidence: FrozenJsonObject
|
|
156
|
+
batch_sha256: str = field(init=False)
|
|
157
|
+
|
|
158
|
+
def __post_init__(self) -> None:
|
|
159
|
+
_require_token(self.projection_id, name="projection_id")
|
|
160
|
+
if type(self.projection_version) is not int or self.projection_version <= 0:
|
|
161
|
+
raise ValueError("projection_version must be positive")
|
|
162
|
+
require_sha256(
|
|
163
|
+
self.projection_definition_sha256,
|
|
164
|
+
"projection_definition_sha256",
|
|
165
|
+
)
|
|
166
|
+
require_sha256(
|
|
167
|
+
self.residual_request_sha256,
|
|
168
|
+
"residual_request_sha256",
|
|
169
|
+
)
|
|
170
|
+
if (
|
|
171
|
+
type(self.proposal_sha256s) is not tuple
|
|
172
|
+
or not self.proposal_sha256s
|
|
173
|
+
or self.proposal_sha256s
|
|
174
|
+
!= tuple(sorted(set(self.proposal_sha256s)))
|
|
175
|
+
):
|
|
176
|
+
raise ValueError("proposal_sha256s must be non-empty and canonical")
|
|
177
|
+
for value in self.proposal_sha256s:
|
|
178
|
+
require_sha256(value, "proposal_sha256")
|
|
179
|
+
if type(self.cells) is not tuple or not self.cells:
|
|
180
|
+
raise ValueError("semantic cells must be a non-empty exact tuple")
|
|
181
|
+
for value in self.cells:
|
|
182
|
+
if type(value) is not MaterializedActionSemanticCell:
|
|
183
|
+
raise TypeError("cells must contain exact semantic cells")
|
|
184
|
+
value.__post_init__()
|
|
185
|
+
action_sha256s = tuple(value.action_sha256 for value in self.cells)
|
|
186
|
+
if action_sha256s != tuple(sorted(set(action_sha256s))):
|
|
187
|
+
raise ValueError("semantic cells must be action-canonical")
|
|
188
|
+
if type(self.candidate_outcomes_observed) is not bool:
|
|
189
|
+
raise TypeError("candidate_outcomes_observed must be exact")
|
|
190
|
+
if self.candidate_outcomes_observed:
|
|
191
|
+
raise ValueError("semantic cells cannot observe current outcomes")
|
|
192
|
+
if (
|
|
193
|
+
type(self.evidence) is not FrozenJsonObject
|
|
194
|
+
or freeze_json(self.evidence) is not self.evidence
|
|
195
|
+
):
|
|
196
|
+
raise TypeError("semantic evidence must be an exact frozen object")
|
|
197
|
+
object.__setattr__(
|
|
198
|
+
self,
|
|
199
|
+
"batch_sha256",
|
|
200
|
+
_hash(_CELL_BATCH_DOMAIN, self._unsigned_record()),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
204
|
+
return {
|
|
205
|
+
"schema_version": 1,
|
|
206
|
+
"projection": {
|
|
207
|
+
"projection_id": self.projection_id,
|
|
208
|
+
"projection_version": self.projection_version,
|
|
209
|
+
"definition_sha256": self.projection_definition_sha256,
|
|
210
|
+
},
|
|
211
|
+
"residual_request_sha256": self.residual_request_sha256,
|
|
212
|
+
"proposal_sha256s": list(self.proposal_sha256s),
|
|
213
|
+
"cells": [value.to_record() for value in self.cells],
|
|
214
|
+
"candidate_outcomes_observed": self.candidate_outcomes_observed,
|
|
215
|
+
"evidence_sha256": typed_json_sha256(self.evidence),
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
def to_record(self) -> dict[str, object]:
|
|
219
|
+
self.__post_init__()
|
|
220
|
+
return {**self._unsigned_record(), "batch_sha256": self.batch_sha256}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@runtime_checkable
|
|
224
|
+
class MaterializedActionSemanticCellProjectionPort(Protocol):
|
|
225
|
+
"""Project portable semantic cells from a sealed proposal population."""
|
|
226
|
+
|
|
227
|
+
projection_id: str
|
|
228
|
+
projection_version: int
|
|
229
|
+
definition_sha256: str
|
|
230
|
+
|
|
231
|
+
async def project(
|
|
232
|
+
self,
|
|
233
|
+
request: ResidualPortfolioDecisionRequest,
|
|
234
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
235
|
+
) -> MaterializedActionSemanticCellBatch: ...
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _apportion(
|
|
239
|
+
capacity: int,
|
|
240
|
+
shares: tuple[tuple[str, float], ...],
|
|
241
|
+
) -> dict[str, int]:
|
|
242
|
+
raw = {name: capacity * share for name, share in shares}
|
|
243
|
+
quotas = {name: math.floor(value) for name, value in raw.items()}
|
|
244
|
+
remaining = capacity - sum(quotas.values())
|
|
245
|
+
order = sorted(
|
|
246
|
+
raw,
|
|
247
|
+
key=lambda name: (-(raw[name] - quotas[name]), name),
|
|
248
|
+
)
|
|
249
|
+
for name in order[:remaining]:
|
|
250
|
+
quotas[name] += 1
|
|
251
|
+
if sum(quotas.values()) != capacity:
|
|
252
|
+
raise AssertionError("largest-remainder apportionment did not close")
|
|
253
|
+
return quotas
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
@dataclass(frozen=True, slots=True)
|
|
257
|
+
class SemanticCoverageScorePortfolioPolicy:
|
|
258
|
+
"""Conserve score lanes under one explicit recursive-lineage contract."""
|
|
259
|
+
|
|
260
|
+
scorers: tuple[MaterializedActionScorePort, ...]
|
|
261
|
+
scorer_capacity_fractions: tuple[tuple[str, float], ...]
|
|
262
|
+
lineage_scorer_id: str
|
|
263
|
+
lineage_member_scorer_id: str
|
|
264
|
+
lineage_deficit_refill_scorer_id: str
|
|
265
|
+
lineage_capacity_fraction: float
|
|
266
|
+
semantic_projection: MaterializedActionSemanticCellProjectionPort = field(
|
|
267
|
+
repr=False,
|
|
268
|
+
compare=False,
|
|
269
|
+
)
|
|
270
|
+
coverage_strength: float = 1.0 / 3.0
|
|
271
|
+
allow_recursive_score_lane_spillover: bool = False
|
|
272
|
+
hard_feasibility: HardFeasibilityPort | None = field(
|
|
273
|
+
default=None,
|
|
274
|
+
repr=False,
|
|
275
|
+
compare=False,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
policy_id: ClassVar[str] = (
|
|
279
|
+
SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_ID
|
|
280
|
+
)
|
|
281
|
+
policy_version: ClassVar[int] = (
|
|
282
|
+
SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_VERSION
|
|
283
|
+
)
|
|
284
|
+
definition_sha256: str = field(init=False)
|
|
285
|
+
|
|
286
|
+
def __post_init__(self) -> None:
|
|
287
|
+
if type(self.scorers) is not tuple or len(self.scorers) < 2:
|
|
288
|
+
raise ValueError("semantic portfolio requires multiple scorers")
|
|
289
|
+
identities = tuple(_scorer_identity(value) for value in self.scorers)
|
|
290
|
+
scorer_ids = tuple(value[0] for value in identities)
|
|
291
|
+
if scorer_ids != tuple(sorted(set(scorer_ids))):
|
|
292
|
+
raise ValueError("scorers must use canonical unique IDs")
|
|
293
|
+
if (
|
|
294
|
+
type(self.scorer_capacity_fractions) is not tuple
|
|
295
|
+
or not self.scorer_capacity_fractions
|
|
296
|
+
):
|
|
297
|
+
raise ValueError("scorer fractions must be a non-empty exact tuple")
|
|
298
|
+
fraction_ids = tuple(
|
|
299
|
+
value[0] for value in self.scorer_capacity_fractions
|
|
300
|
+
)
|
|
301
|
+
if fraction_ids != scorer_ids:
|
|
302
|
+
raise ValueError("scorer fractions must canonically cover scorers")
|
|
303
|
+
for scorer_id, fraction in self.scorer_capacity_fractions:
|
|
304
|
+
_require_token(scorer_id, name="fraction scorer_id")
|
|
305
|
+
if (
|
|
306
|
+
type(fraction) is not float
|
|
307
|
+
or not math.isfinite(fraction)
|
|
308
|
+
or not 0.0 <= fraction < 1.0
|
|
309
|
+
):
|
|
310
|
+
raise ValueError("scorer fractions must lie in [0, 1)")
|
|
311
|
+
_require_token(self.lineage_scorer_id, name="lineage_scorer_id")
|
|
312
|
+
if self.lineage_scorer_id not in scorer_ids:
|
|
313
|
+
raise ValueError("lineage scorer is absent")
|
|
314
|
+
_require_token(
|
|
315
|
+
self.lineage_member_scorer_id,
|
|
316
|
+
name="lineage_member_scorer_id",
|
|
317
|
+
)
|
|
318
|
+
if self.lineage_member_scorer_id not in scorer_ids:
|
|
319
|
+
raise ValueError("lineage member scorer is absent")
|
|
320
|
+
_require_token(
|
|
321
|
+
self.lineage_deficit_refill_scorer_id,
|
|
322
|
+
name="lineage_deficit_refill_scorer_id",
|
|
323
|
+
)
|
|
324
|
+
if self.lineage_deficit_refill_scorer_id not in scorer_ids:
|
|
325
|
+
raise ValueError("lineage deficit refill scorer is absent")
|
|
326
|
+
if (
|
|
327
|
+
type(self.lineage_capacity_fraction) is not float
|
|
328
|
+
or not math.isfinite(self.lineage_capacity_fraction)
|
|
329
|
+
or not 0.0 <= self.lineage_capacity_fraction < 1.0
|
|
330
|
+
):
|
|
331
|
+
raise ValueError("lineage fraction must lie in [0, 1)")
|
|
332
|
+
total_fraction = math.fsum(
|
|
333
|
+
value for _, value in self.scorer_capacity_fractions
|
|
334
|
+
) + self.lineage_capacity_fraction
|
|
335
|
+
if not math.isclose(total_fraction, 1.0, abs_tol=1.0e-12):
|
|
336
|
+
raise ValueError("scorer and lineage fractions must sum to one")
|
|
337
|
+
if (
|
|
338
|
+
not isinstance(
|
|
339
|
+
self.semantic_projection,
|
|
340
|
+
MaterializedActionSemanticCellProjectionPort,
|
|
341
|
+
)
|
|
342
|
+
or type(self.semantic_projection.projection_version) is not int
|
|
343
|
+
or self.semantic_projection.projection_version <= 0
|
|
344
|
+
):
|
|
345
|
+
raise TypeError("semantic projection must implement its port")
|
|
346
|
+
_require_token(
|
|
347
|
+
self.semantic_projection.projection_id,
|
|
348
|
+
name="semantic projection_id",
|
|
349
|
+
)
|
|
350
|
+
require_sha256(
|
|
351
|
+
self.semantic_projection.definition_sha256,
|
|
352
|
+
"semantic projection definition_sha256",
|
|
353
|
+
)
|
|
354
|
+
if (
|
|
355
|
+
type(self.coverage_strength) is not float
|
|
356
|
+
or not math.isfinite(self.coverage_strength)
|
|
357
|
+
or not 0.0 < self.coverage_strength < 1.0
|
|
358
|
+
):
|
|
359
|
+
raise ValueError("coverage_strength must lie in (0, 1)")
|
|
360
|
+
if type(self.allow_recursive_score_lane_spillover) is not bool:
|
|
361
|
+
raise TypeError(
|
|
362
|
+
"allow_recursive_score_lane_spillover must be an exact bool"
|
|
363
|
+
)
|
|
364
|
+
feasibility_identity = (
|
|
365
|
+
None
|
|
366
|
+
if self.hard_feasibility is None
|
|
367
|
+
else validate_hard_feasibility_port(self.hard_feasibility)
|
|
368
|
+
)
|
|
369
|
+
object.__setattr__(
|
|
370
|
+
self,
|
|
371
|
+
"definition_sha256",
|
|
372
|
+
_hash(
|
|
373
|
+
_POLICY_DOMAIN,
|
|
374
|
+
{
|
|
375
|
+
"schema_version": 1,
|
|
376
|
+
"policy_id": self.policy_id,
|
|
377
|
+
"policy_version": self.policy_version,
|
|
378
|
+
"scorers": [
|
|
379
|
+
{
|
|
380
|
+
"scorer_id": scorer_id,
|
|
381
|
+
"scorer_version": scorer_version,
|
|
382
|
+
"definition_sha256": definition_sha256,
|
|
383
|
+
"capacity_fraction_hex": dict(
|
|
384
|
+
self.scorer_capacity_fractions
|
|
385
|
+
)[scorer_id].hex(),
|
|
386
|
+
}
|
|
387
|
+
for scorer_id, scorer_version, definition_sha256
|
|
388
|
+
in identities
|
|
389
|
+
],
|
|
390
|
+
"lineage": {
|
|
391
|
+
"scorer_id": self.lineage_scorer_id,
|
|
392
|
+
"member_scorer_id": self.lineage_member_scorer_id,
|
|
393
|
+
"deficit_refill_scorer_id": (
|
|
394
|
+
self.lineage_deficit_refill_scorer_id
|
|
395
|
+
),
|
|
396
|
+
"capacity_fraction_hex": (
|
|
397
|
+
self.lineage_capacity_fraction.hex()
|
|
398
|
+
),
|
|
399
|
+
"cell": "recursive_lineage_by_expert_id",
|
|
400
|
+
"partition": (
|
|
401
|
+
"pilot_floor_then_recursive_score_lane_competition"
|
|
402
|
+
if self.allow_recursive_score_lane_spillover
|
|
403
|
+
else (
|
|
404
|
+
"exact_maximum_then_nonrecursive_score_lanes"
|
|
405
|
+
)
|
|
406
|
+
),
|
|
407
|
+
},
|
|
408
|
+
"semantic_projection": {
|
|
409
|
+
"projection_id": (
|
|
410
|
+
self.semantic_projection.projection_id
|
|
411
|
+
),
|
|
412
|
+
"projection_version": (
|
|
413
|
+
self.semantic_projection.projection_version
|
|
414
|
+
),
|
|
415
|
+
"definition_sha256": (
|
|
416
|
+
self.semantic_projection.definition_sha256
|
|
417
|
+
),
|
|
418
|
+
},
|
|
419
|
+
"coverage": {
|
|
420
|
+
"feature": "categorical_metric_direction_signature",
|
|
421
|
+
"strength_hex": self.coverage_strength.hex(),
|
|
422
|
+
"score": (
|
|
423
|
+
"(1-strength)*within-lane-rank-percentile+"
|
|
424
|
+
"strength*new-direction-indicator"
|
|
425
|
+
),
|
|
426
|
+
},
|
|
427
|
+
"capacity_apportionment": (
|
|
428
|
+
"largest_remainder_fractional_quota"
|
|
429
|
+
),
|
|
430
|
+
"hard_feasibility": (
|
|
431
|
+
None
|
|
432
|
+
if feasibility_identity is None
|
|
433
|
+
else {
|
|
434
|
+
"policy_id": feasibility_identity[0],
|
|
435
|
+
"policy_version": feasibility_identity[1],
|
|
436
|
+
"definition_sha256": feasibility_identity[2],
|
|
437
|
+
}
|
|
438
|
+
),
|
|
439
|
+
"hard_feasibility_rejection": (
|
|
440
|
+
"authenticated_infeasible_only"
|
|
441
|
+
),
|
|
442
|
+
"candidate_outcomes_observed": False,
|
|
443
|
+
"workload_model_provider_branches": False,
|
|
444
|
+
},
|
|
445
|
+
),
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
async def require(
|
|
449
|
+
self,
|
|
450
|
+
request: ResidualPortfolioDecisionRequest,
|
|
451
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
452
|
+
) -> MaterializedActionAllocationRequirement:
|
|
453
|
+
self.__post_init__()
|
|
454
|
+
if type(request) is not ResidualPortfolioDecisionRequest:
|
|
455
|
+
raise TypeError("request must be exact")
|
|
456
|
+
request.__post_init__()
|
|
457
|
+
if type(proposals) is not tuple or not proposals:
|
|
458
|
+
raise ValueError("proposals must be a non-empty exact tuple")
|
|
459
|
+
for proposal in proposals:
|
|
460
|
+
if type(proposal) is not MaterializedActionProposalBatch:
|
|
461
|
+
raise TypeError("proposals must contain exact batches")
|
|
462
|
+
proposal.__post_init__()
|
|
463
|
+
proposal.require_request(request)
|
|
464
|
+
|
|
465
|
+
proposal_sha256s = tuple(
|
|
466
|
+
sorted(value.proposal_sha256 for value in proposals)
|
|
467
|
+
)
|
|
468
|
+
actions = tuple(
|
|
469
|
+
action for proposal in proposals for action in proposal.actions
|
|
470
|
+
)
|
|
471
|
+
action_by_sha256 = {
|
|
472
|
+
value.action_sha256: value for value in actions
|
|
473
|
+
}
|
|
474
|
+
if len(action_by_sha256) != len(actions):
|
|
475
|
+
raise ValueError("proposal union repeats an action identity")
|
|
476
|
+
action_sha256s = tuple(sorted(action_by_sha256))
|
|
477
|
+
scorer_by_id = {
|
|
478
|
+
_scorer_identity(value)[0]: value for value in self.scorers
|
|
479
|
+
}
|
|
480
|
+
gathered = await asyncio.gather(
|
|
481
|
+
*(scorer.score(request, proposals) for scorer in self.scorers),
|
|
482
|
+
self.semantic_projection.project(request, proposals),
|
|
483
|
+
)
|
|
484
|
+
score_batches = gathered[:-1]
|
|
485
|
+
semantic_batch = gathered[-1]
|
|
486
|
+
if type(semantic_batch) is not MaterializedActionSemanticCellBatch:
|
|
487
|
+
raise TypeError("semantic projection returned a foreign batch")
|
|
488
|
+
semantic_batch.__post_init__()
|
|
489
|
+
if (
|
|
490
|
+
semantic_batch.residual_request_sha256 != request.request_sha256
|
|
491
|
+
or semantic_batch.proposal_sha256s != proposal_sha256s
|
|
492
|
+
or tuple(value.action_sha256 for value in semantic_batch.cells)
|
|
493
|
+
!= action_sha256s
|
|
494
|
+
):
|
|
495
|
+
raise ValueError("semantic batch differs from sealed universe")
|
|
496
|
+
cell_by_action = {
|
|
497
|
+
value.action_sha256: value for value in semantic_batch.cells
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
batch_by_scorer: dict[str, MaterializedActionScoreBatch] = {}
|
|
501
|
+
for batch in score_batches:
|
|
502
|
+
if type(batch) is not MaterializedActionScoreBatch:
|
|
503
|
+
raise TypeError("scorer returned a foreign score batch")
|
|
504
|
+
batch.__post_init__()
|
|
505
|
+
scorer = scorer_by_id.get(batch.scorer_id)
|
|
506
|
+
if scorer is None:
|
|
507
|
+
raise ValueError("score batch names a foreign scorer")
|
|
508
|
+
if (
|
|
509
|
+
batch.scorer_id,
|
|
510
|
+
batch.scorer_version,
|
|
511
|
+
batch.scorer_definition_sha256,
|
|
512
|
+
) != _scorer_identity(scorer):
|
|
513
|
+
raise ValueError("score batch differs from scorer identity")
|
|
514
|
+
if (
|
|
515
|
+
batch.residual_request_sha256 != request.request_sha256
|
|
516
|
+
or batch.proposal_sha256s != proposal_sha256s
|
|
517
|
+
or tuple(value.action_sha256 for value in batch.scores)
|
|
518
|
+
!= action_sha256s
|
|
519
|
+
):
|
|
520
|
+
raise ValueError("score batch differs from sealed universe")
|
|
521
|
+
batch_by_scorer[batch.scorer_id] = batch
|
|
522
|
+
|
|
523
|
+
infeasible: set[str] = set()
|
|
524
|
+
feasibility_decisions: list[
|
|
525
|
+
tuple[str, HardFeasibilityDecision]
|
|
526
|
+
] = []
|
|
527
|
+
if self.hard_feasibility is not None:
|
|
528
|
+
for action_sha256 in action_sha256s:
|
|
529
|
+
decision = assess_hard_feasibility(
|
|
530
|
+
self.hard_feasibility,
|
|
531
|
+
HardFeasibilityRequest(
|
|
532
|
+
campaign_scope_sha256=request.campaign_scope_sha256,
|
|
533
|
+
cutoff_index=request.decision_index,
|
|
534
|
+
configuration=action_by_sha256[
|
|
535
|
+
action_sha256
|
|
536
|
+
].configuration,
|
|
537
|
+
),
|
|
538
|
+
)
|
|
539
|
+
feasibility_decisions.append((action_sha256, decision))
|
|
540
|
+
if decision.verdict is HardFeasibilityVerdict.INFEASIBLE:
|
|
541
|
+
infeasible.add(action_sha256)
|
|
542
|
+
admissible = tuple(
|
|
543
|
+
value
|
|
544
|
+
for value in actions
|
|
545
|
+
if value.action_sha256 not in infeasible
|
|
546
|
+
)
|
|
547
|
+
if len(admissible) < request.evaluation_slots:
|
|
548
|
+
raise ValueError("screened proposal union cannot fill capacity")
|
|
549
|
+
|
|
550
|
+
score_by_scorer = {
|
|
551
|
+
scorer_id: {
|
|
552
|
+
value.action_sha256: value.value
|
|
553
|
+
for value in batch_by_scorer[scorer_id].scores
|
|
554
|
+
}
|
|
555
|
+
for scorer_id in scorer_by_id
|
|
556
|
+
}
|
|
557
|
+
rankings = {
|
|
558
|
+
scorer_id: tuple(
|
|
559
|
+
sorted(
|
|
560
|
+
admissible,
|
|
561
|
+
key=lambda value, lane=scorer_id: (
|
|
562
|
+
-score_by_scorer[lane][value.action_sha256],
|
|
563
|
+
value.native_rank,
|
|
564
|
+
value.action_sha256,
|
|
565
|
+
),
|
|
566
|
+
)
|
|
567
|
+
)
|
|
568
|
+
for scorer_id in scorer_by_id
|
|
569
|
+
}
|
|
570
|
+
denominator = max(1, len(admissible) - 1)
|
|
571
|
+
percentiles = {
|
|
572
|
+
scorer_id: {
|
|
573
|
+
value.action_sha256: 1.0 - index / denominator
|
|
574
|
+
for index, value in enumerate(rankings[scorer_id])
|
|
575
|
+
}
|
|
576
|
+
for scorer_id in scorer_by_id
|
|
577
|
+
}
|
|
578
|
+
shares = (
|
|
579
|
+
("__lineage__", self.lineage_capacity_fraction),
|
|
580
|
+
*self.scorer_capacity_fractions,
|
|
581
|
+
)
|
|
582
|
+
quotas = _apportion(request.evaluation_slots, shares)
|
|
583
|
+
lineage_quota = quotas.pop("__lineage__")
|
|
584
|
+
|
|
585
|
+
selected: list[MaterializedActionDescriptor] = []
|
|
586
|
+
phenotypes: set[str] = set()
|
|
587
|
+
selection_trace: list[dict[str, object]] = []
|
|
588
|
+
|
|
589
|
+
def choose(
|
|
590
|
+
candidates: tuple[MaterializedActionDescriptor, ...],
|
|
591
|
+
*,
|
|
592
|
+
lane: str,
|
|
593
|
+
allocation_kind: str,
|
|
594
|
+
) -> bool:
|
|
595
|
+
eligible = tuple(
|
|
596
|
+
value
|
|
597
|
+
for value in candidates
|
|
598
|
+
if value.phenotype_identity_sha256 not in phenotypes
|
|
599
|
+
)
|
|
600
|
+
if not eligible:
|
|
601
|
+
return False
|
|
602
|
+
covered = {
|
|
603
|
+
cell_by_action[value.action_sha256].direction_signature
|
|
604
|
+
for value in selected
|
|
605
|
+
if cell_by_action[value.action_sha256].direction_signature
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
def coordinates(
|
|
609
|
+
value: MaterializedActionDescriptor,
|
|
610
|
+
) -> tuple[float, float, float]:
|
|
611
|
+
rank = percentiles[lane][value.action_sha256]
|
|
612
|
+
signature = cell_by_action[
|
|
613
|
+
value.action_sha256
|
|
614
|
+
].direction_signature
|
|
615
|
+
novelty = (
|
|
616
|
+
1.0 if signature and signature not in covered else 0.0
|
|
617
|
+
)
|
|
618
|
+
combined = (
|
|
619
|
+
(1.0 - self.coverage_strength) * rank
|
|
620
|
+
+ self.coverage_strength * novelty
|
|
621
|
+
)
|
|
622
|
+
return combined, rank, novelty
|
|
623
|
+
|
|
624
|
+
winner = min(
|
|
625
|
+
eligible,
|
|
626
|
+
key=lambda value: (
|
|
627
|
+
-coordinates(value)[0],
|
|
628
|
+
value.native_rank,
|
|
629
|
+
value.action_sha256,
|
|
630
|
+
),
|
|
631
|
+
)
|
|
632
|
+
combined, rank, novelty = coordinates(winner)
|
|
633
|
+
selected.append(winner)
|
|
634
|
+
phenotypes.add(winner.phenotype_identity_sha256)
|
|
635
|
+
selection_trace.append(
|
|
636
|
+
{
|
|
637
|
+
"ordinal": len(selected),
|
|
638
|
+
"allocation_kind": allocation_kind,
|
|
639
|
+
"score_lane": lane,
|
|
640
|
+
"action_sha256": winner.action_sha256,
|
|
641
|
+
"score_hex": score_by_scorer[lane][
|
|
642
|
+
winner.action_sha256
|
|
643
|
+
].hex(),
|
|
644
|
+
"rank_percentile_hex": rank.hex(),
|
|
645
|
+
"direction_novelty_hex": novelty.hex(),
|
|
646
|
+
"combined_selection_score_hex": combined.hex(),
|
|
647
|
+
"direction_signature": [
|
|
648
|
+
{
|
|
649
|
+
"metric_id": metric_id,
|
|
650
|
+
"direction": direction,
|
|
651
|
+
}
|
|
652
|
+
for metric_id, direction
|
|
653
|
+
in cell_by_action[
|
|
654
|
+
winner.action_sha256
|
|
655
|
+
].direction_signature
|
|
656
|
+
],
|
|
657
|
+
"recursive_lineage": cell_by_action[
|
|
658
|
+
winner.action_sha256
|
|
659
|
+
].recursive_lineage,
|
|
660
|
+
"candidate_outcomes_observed": False,
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
return True
|
|
664
|
+
|
|
665
|
+
lineage_expert_ids = tuple(
|
|
666
|
+
sorted(
|
|
667
|
+
{
|
|
668
|
+
value.expert_id
|
|
669
|
+
for value in admissible
|
|
670
|
+
if cell_by_action[
|
|
671
|
+
value.action_sha256
|
|
672
|
+
].recursive_lineage
|
|
673
|
+
}
|
|
674
|
+
)
|
|
675
|
+
)
|
|
676
|
+
lineage_cell_champions = tuple(
|
|
677
|
+
min(
|
|
678
|
+
(
|
|
679
|
+
value
|
|
680
|
+
for value in admissible
|
|
681
|
+
if value.expert_id == expert_id
|
|
682
|
+
and cell_by_action[
|
|
683
|
+
value.action_sha256
|
|
684
|
+
].recursive_lineage
|
|
685
|
+
),
|
|
686
|
+
key=lambda value: (
|
|
687
|
+
-score_by_scorer[self.lineage_member_scorer_id][
|
|
688
|
+
value.action_sha256
|
|
689
|
+
],
|
|
690
|
+
value.native_rank,
|
|
691
|
+
value.action_sha256,
|
|
692
|
+
),
|
|
693
|
+
)
|
|
694
|
+
for expert_id in lineage_expert_ids
|
|
695
|
+
)
|
|
696
|
+
lineage_remaining = tuple(lineage_cell_champions)
|
|
697
|
+
while lineage_remaining and len(selection_trace) < lineage_quota:
|
|
698
|
+
if not choose(
|
|
699
|
+
lineage_remaining,
|
|
700
|
+
lane=self.lineage_scorer_id,
|
|
701
|
+
allocation_kind="recursive_lineage_cell",
|
|
702
|
+
):
|
|
703
|
+
break
|
|
704
|
+
lineage_remaining = tuple(
|
|
705
|
+
value
|
|
706
|
+
for value in lineage_remaining
|
|
707
|
+
if value.action_sha256 != selected[-1].action_sha256
|
|
708
|
+
)
|
|
709
|
+
lineage_selected = len(selected)
|
|
710
|
+
|
|
711
|
+
score_lane_rankings = {
|
|
712
|
+
scorer_id: tuple(
|
|
713
|
+
value
|
|
714
|
+
for value in ranking
|
|
715
|
+
if (
|
|
716
|
+
self.allow_recursive_score_lane_spillover
|
|
717
|
+
or not cell_by_action[
|
|
718
|
+
value.action_sha256
|
|
719
|
+
].recursive_lineage
|
|
720
|
+
)
|
|
721
|
+
)
|
|
722
|
+
for scorer_id, ranking in rankings.items()
|
|
723
|
+
}
|
|
724
|
+
for ordinal in range(max(quotas.values(), default=0)):
|
|
725
|
+
for scorer_id in sorted(quotas):
|
|
726
|
+
if ordinal >= quotas[scorer_id]:
|
|
727
|
+
continue
|
|
728
|
+
if not choose(
|
|
729
|
+
score_lane_rankings[scorer_id],
|
|
730
|
+
lane=scorer_id,
|
|
731
|
+
allocation_kind="score_lane",
|
|
732
|
+
):
|
|
733
|
+
raise ValueError("semantic score lane cannot close")
|
|
734
|
+
while len(selected) < request.evaluation_slots:
|
|
735
|
+
if not choose(
|
|
736
|
+
score_lane_rankings[
|
|
737
|
+
self.lineage_deficit_refill_scorer_id
|
|
738
|
+
],
|
|
739
|
+
lane=self.lineage_deficit_refill_scorer_id,
|
|
740
|
+
allocation_kind="lineage_deficit_refill",
|
|
741
|
+
):
|
|
742
|
+
raise ValueError("lineage deficit refill cannot close capacity")
|
|
743
|
+
if len(selected) != request.evaluation_slots:
|
|
744
|
+
raise AssertionError("semantic portfolio exceeded capacity")
|
|
745
|
+
|
|
746
|
+
feasibility_record = {
|
|
747
|
+
"enabled": self.hard_feasibility is not None,
|
|
748
|
+
"decision_batch_sha256": (
|
|
749
|
+
None
|
|
750
|
+
if not feasibility_decisions
|
|
751
|
+
else hard_feasibility_decision_batch_sha256(
|
|
752
|
+
tuple(
|
|
753
|
+
decision.decision_sha256
|
|
754
|
+
for _action_sha256, decision
|
|
755
|
+
in feasibility_decisions
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
),
|
|
759
|
+
"rejected_actions": [
|
|
760
|
+
{
|
|
761
|
+
"action_sha256": action_sha256,
|
|
762
|
+
"decision": decision.to_record(),
|
|
763
|
+
}
|
|
764
|
+
for action_sha256, decision in feasibility_decisions
|
|
765
|
+
if decision.verdict
|
|
766
|
+
is HardFeasibilityVerdict.INFEASIBLE
|
|
767
|
+
],
|
|
768
|
+
"unknown_actions_remain_eligible": True,
|
|
769
|
+
"candidate_outcomes_observed": False,
|
|
770
|
+
}
|
|
771
|
+
return MaterializedActionAllocationRequirement(
|
|
772
|
+
policy_id=self.policy_id,
|
|
773
|
+
policy_version=self.policy_version,
|
|
774
|
+
policy_definition_sha256=self.definition_sha256,
|
|
775
|
+
residual_request_sha256=request.request_sha256,
|
|
776
|
+
proposal_sha256s=proposal_sha256s,
|
|
777
|
+
required_action_sha256s=tuple(
|
|
778
|
+
sorted(value.action_sha256 for value in selected)
|
|
779
|
+
),
|
|
780
|
+
candidate_outcomes_observed=False,
|
|
781
|
+
evidence=freeze_json(
|
|
782
|
+
{
|
|
783
|
+
"score_batch_sha256s": {
|
|
784
|
+
scorer_id: batch_by_scorer[
|
|
785
|
+
scorer_id
|
|
786
|
+
].batch_sha256
|
|
787
|
+
for scorer_id in sorted(batch_by_scorer)
|
|
788
|
+
},
|
|
789
|
+
"semantic_cell_batch_sha256": (
|
|
790
|
+
semantic_batch.batch_sha256
|
|
791
|
+
),
|
|
792
|
+
"nominal_capacity_quotas": {
|
|
793
|
+
"recursive_lineage": lineage_quota,
|
|
794
|
+
**{
|
|
795
|
+
scorer_id: quotas[scorer_id]
|
|
796
|
+
for scorer_id in sorted(quotas)
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
"realized_lineage_count": lineage_selected,
|
|
800
|
+
"final_recursive_lineage_count": sum(
|
|
801
|
+
cell_by_action[
|
|
802
|
+
value.action_sha256
|
|
803
|
+
].recursive_lineage
|
|
804
|
+
for value in selected
|
|
805
|
+
),
|
|
806
|
+
"lineage_deficit_refill_count": (
|
|
807
|
+
lineage_quota - lineage_selected
|
|
808
|
+
),
|
|
809
|
+
"lineage_partition": (
|
|
810
|
+
"pilot_floor_then_recursive_score_lane_competition"
|
|
811
|
+
if self.allow_recursive_score_lane_spillover
|
|
812
|
+
else (
|
|
813
|
+
"exact_maximum_then_nonrecursive_score_lanes"
|
|
814
|
+
)
|
|
815
|
+
),
|
|
816
|
+
"lineage_member_scorer_id": (
|
|
817
|
+
self.lineage_member_scorer_id
|
|
818
|
+
),
|
|
819
|
+
"coverage_strength_hex": (
|
|
820
|
+
self.coverage_strength.hex()
|
|
821
|
+
),
|
|
822
|
+
"selection_trace": selection_trace,
|
|
823
|
+
"hard_feasibility": feasibility_record,
|
|
824
|
+
"candidate_outcomes_observed": False,
|
|
825
|
+
"workload_model_provider_branches": False,
|
|
826
|
+
}
|
|
827
|
+
),
|
|
828
|
+
)
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
__all__ = [
|
|
832
|
+
"MaterializedActionSemanticCell",
|
|
833
|
+
"MaterializedActionSemanticCellBatch",
|
|
834
|
+
"MaterializedActionSemanticCellProjectionPort",
|
|
835
|
+
"SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_ID",
|
|
836
|
+
"SEMANTIC_COVERAGE_SCORE_PORTFOLIO_POLICY_VERSION",
|
|
837
|
+
"SemanticCoverageScorePortfolioPolicy",
|
|
838
|
+
]
|