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,659 @@
|
|
|
1
|
+
"""Frozen, outcome-blind consequence scorers for materialized actions.
|
|
2
|
+
|
|
3
|
+
Feature construction is an injected port. This module owns only the
|
|
4
|
+
authenticated feature-vector boundary and deterministic application of frozen
|
|
5
|
+
standardized linear models. It deliberately has no workload, objective,
|
|
6
|
+
model-provider, prompt, or configuration-schema branches.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from enum import Enum
|
|
13
|
+
import hashlib
|
|
14
|
+
import json
|
|
15
|
+
import math
|
|
16
|
+
import re
|
|
17
|
+
from typing import Protocol, runtime_checkable
|
|
18
|
+
|
|
19
|
+
from agent_evolve.application.prequential_score_portfolio import (
|
|
20
|
+
MaterializedActionScore,
|
|
21
|
+
MaterializedActionScoreBatch,
|
|
22
|
+
)
|
|
23
|
+
from agent_evolve.application.residual_portfolio_evolution import (
|
|
24
|
+
MaterializedActionProposalBatch,
|
|
25
|
+
ResidualPortfolioDecisionRequest,
|
|
26
|
+
)
|
|
27
|
+
from agent_evolve.domain.patch import require_sha256
|
|
28
|
+
from agent_evolve.domain.typed_json import (
|
|
29
|
+
FrozenJsonObject,
|
|
30
|
+
freeze_json,
|
|
31
|
+
typed_json_sha256,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
FROZEN_HURDLE_SCORE_VERSION = 1
|
|
36
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
37
|
+
_FEATURE_BATCH_DOMAIN = (
|
|
38
|
+
b"agent-evolve:materialized-action-feature-batch:v1\x00"
|
|
39
|
+
)
|
|
40
|
+
_LINEAR_MODEL_DOMAIN = b"agent-evolve:frozen-standardized-linear-model:v1\x00"
|
|
41
|
+
_SCORER_DOMAIN = b"agent-evolve:frozen-hurdle-action-scorer:v1\x00"
|
|
42
|
+
_SCORER_EVIDENCE_DOMAIN = (
|
|
43
|
+
b"agent-evolve:frozen-hurdle-action-score-evidence:v1\x00"
|
|
44
|
+
)
|
|
45
|
+
_WINSORIZED_SCORER_DOMAIN = (
|
|
46
|
+
b"agent-evolve:winsorized-frozen-hurdle-action-scorer:v1\x00"
|
|
47
|
+
)
|
|
48
|
+
_WINSORIZED_SCORER_EVIDENCE_DOMAIN = (
|
|
49
|
+
b"agent-evolve:winsorized-frozen-hurdle-score-evidence:v1\x00"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _canonical_json(value: object) -> bytes:
|
|
54
|
+
return json.dumps(
|
|
55
|
+
value,
|
|
56
|
+
allow_nan=False,
|
|
57
|
+
ensure_ascii=True,
|
|
58
|
+
separators=(",", ":"),
|
|
59
|
+
sort_keys=True,
|
|
60
|
+
).encode("ascii", errors="strict")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
64
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _token(value: str, *, name: str) -> None:
|
|
68
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
69
|
+
raise ValueError(f"{name} must use the closed token grammar")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _finite_tuple(
|
|
73
|
+
values: tuple[float, ...],
|
|
74
|
+
*,
|
|
75
|
+
name: str,
|
|
76
|
+
nonzero: bool = False,
|
|
77
|
+
) -> None:
|
|
78
|
+
if type(values) is not tuple or not values:
|
|
79
|
+
raise ValueError(f"{name} must be a non-empty exact tuple")
|
|
80
|
+
for value in values:
|
|
81
|
+
if type(value) is not float or not math.isfinite(value):
|
|
82
|
+
raise TypeError(f"{name} must contain finite exact floats")
|
|
83
|
+
if nonzero and value <= 0.0:
|
|
84
|
+
raise ValueError(f"{name} must contain positive values")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass(frozen=True, slots=True)
|
|
88
|
+
class MaterializedActionFeatureVector:
|
|
89
|
+
"""One canonical feature vector for one sealed materialized action."""
|
|
90
|
+
|
|
91
|
+
action_sha256: str
|
|
92
|
+
values: tuple[float, ...]
|
|
93
|
+
|
|
94
|
+
def __post_init__(self) -> None:
|
|
95
|
+
require_sha256(self.action_sha256, "action_sha256")
|
|
96
|
+
_finite_tuple(self.values, name="feature values")
|
|
97
|
+
|
|
98
|
+
def to_record(self) -> dict[str, object]:
|
|
99
|
+
self.__post_init__()
|
|
100
|
+
return {
|
|
101
|
+
"action_sha256": self.action_sha256,
|
|
102
|
+
"values_hex": [value.hex() for value in self.values],
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass(frozen=True, slots=True)
|
|
107
|
+
class MaterializedActionFeatureBatch:
|
|
108
|
+
"""Authenticated complete features for one sealed proposal universe."""
|
|
109
|
+
|
|
110
|
+
projection_id: str
|
|
111
|
+
projection_version: int
|
|
112
|
+
projection_definition_sha256: str
|
|
113
|
+
residual_request_sha256: str
|
|
114
|
+
proposal_sha256s: tuple[str, ...]
|
|
115
|
+
feature_names: tuple[str, ...]
|
|
116
|
+
vectors: tuple[MaterializedActionFeatureVector, ...]
|
|
117
|
+
candidate_outcomes_observed: bool
|
|
118
|
+
evidence: FrozenJsonObject
|
|
119
|
+
batch_sha256: str = field(init=False)
|
|
120
|
+
|
|
121
|
+
def __post_init__(self) -> None:
|
|
122
|
+
_token(self.projection_id, name="projection_id")
|
|
123
|
+
if type(self.projection_version) is not int or self.projection_version <= 0:
|
|
124
|
+
raise ValueError("projection_version must be positive")
|
|
125
|
+
require_sha256(
|
|
126
|
+
self.projection_definition_sha256,
|
|
127
|
+
"projection_definition_sha256",
|
|
128
|
+
)
|
|
129
|
+
require_sha256(
|
|
130
|
+
self.residual_request_sha256,
|
|
131
|
+
"residual_request_sha256",
|
|
132
|
+
)
|
|
133
|
+
if (
|
|
134
|
+
type(self.proposal_sha256s) is not tuple
|
|
135
|
+
or not self.proposal_sha256s
|
|
136
|
+
or self.proposal_sha256s
|
|
137
|
+
!= tuple(sorted(set(self.proposal_sha256s)))
|
|
138
|
+
):
|
|
139
|
+
raise ValueError(
|
|
140
|
+
"proposal_sha256s must be non-empty, unique, and canonical"
|
|
141
|
+
)
|
|
142
|
+
for value in self.proposal_sha256s:
|
|
143
|
+
require_sha256(value, "proposal_sha256")
|
|
144
|
+
if (
|
|
145
|
+
type(self.feature_names) is not tuple
|
|
146
|
+
or not self.feature_names
|
|
147
|
+
or self.feature_names != tuple(dict.fromkeys(self.feature_names))
|
|
148
|
+
):
|
|
149
|
+
raise ValueError("feature_names must be non-empty and unique")
|
|
150
|
+
for value in self.feature_names:
|
|
151
|
+
_token(value, name="feature name")
|
|
152
|
+
if type(self.vectors) is not tuple or not self.vectors:
|
|
153
|
+
raise ValueError("vectors must be a non-empty exact tuple")
|
|
154
|
+
for vector in self.vectors:
|
|
155
|
+
if type(vector) is not MaterializedActionFeatureVector:
|
|
156
|
+
raise TypeError("vectors must contain exact feature vectors")
|
|
157
|
+
vector.__post_init__()
|
|
158
|
+
if len(vector.values) != len(self.feature_names):
|
|
159
|
+
raise ValueError("feature vector width differs from feature_names")
|
|
160
|
+
action_ids = tuple(value.action_sha256 for value in self.vectors)
|
|
161
|
+
if action_ids != tuple(sorted(set(action_ids))):
|
|
162
|
+
raise ValueError("feature vectors must be unique and canonical")
|
|
163
|
+
if type(self.candidate_outcomes_observed) is not bool:
|
|
164
|
+
raise TypeError(
|
|
165
|
+
"candidate_outcomes_observed must be an exact bool"
|
|
166
|
+
)
|
|
167
|
+
if self.candidate_outcomes_observed:
|
|
168
|
+
raise ValueError("prequential features cannot observe current outcomes")
|
|
169
|
+
if (
|
|
170
|
+
type(self.evidence) is not FrozenJsonObject
|
|
171
|
+
or freeze_json(self.evidence) is not self.evidence
|
|
172
|
+
):
|
|
173
|
+
raise TypeError("feature evidence must be an exact frozen object")
|
|
174
|
+
object.__setattr__(
|
|
175
|
+
self,
|
|
176
|
+
"batch_sha256",
|
|
177
|
+
_hash(_FEATURE_BATCH_DOMAIN, self._unsigned_record()),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
181
|
+
return {
|
|
182
|
+
"schema_version": 1,
|
|
183
|
+
"projection": {
|
|
184
|
+
"projection_id": self.projection_id,
|
|
185
|
+
"projection_version": self.projection_version,
|
|
186
|
+
"definition_sha256": self.projection_definition_sha256,
|
|
187
|
+
},
|
|
188
|
+
"residual_request_sha256": self.residual_request_sha256,
|
|
189
|
+
"proposal_sha256s": list(self.proposal_sha256s),
|
|
190
|
+
"feature_names": list(self.feature_names),
|
|
191
|
+
"vectors": [value.to_record() for value in self.vectors],
|
|
192
|
+
"candidate_outcomes_observed": self.candidate_outcomes_observed,
|
|
193
|
+
"evidence_sha256": typed_json_sha256(self.evidence),
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
def to_record(self) -> dict[str, object]:
|
|
197
|
+
self.__post_init__()
|
|
198
|
+
return {**self._unsigned_record(), "batch_sha256": self.batch_sha256}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@runtime_checkable
|
|
202
|
+
class MaterializedActionFeatureProjectionPort(Protocol):
|
|
203
|
+
"""Project complete sealed proposals using strictly prior evidence."""
|
|
204
|
+
|
|
205
|
+
projection_id: str
|
|
206
|
+
projection_version: int
|
|
207
|
+
definition_sha256: str
|
|
208
|
+
feature_names: tuple[str, ...]
|
|
209
|
+
|
|
210
|
+
async def project(
|
|
211
|
+
self,
|
|
212
|
+
request: ResidualPortfolioDecisionRequest,
|
|
213
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
214
|
+
) -> MaterializedActionFeatureBatch: ...
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@dataclass(frozen=True, slots=True)
|
|
218
|
+
class FrozenStandardizedLinearModel:
|
|
219
|
+
"""Immutable standardized linear predictor with authenticated identity."""
|
|
220
|
+
|
|
221
|
+
model_id: str
|
|
222
|
+
family: str
|
|
223
|
+
feature_names: tuple[str, ...]
|
|
224
|
+
means: tuple[float, ...]
|
|
225
|
+
scales: tuple[float, ...]
|
|
226
|
+
coefficients: tuple[float, ...]
|
|
227
|
+
definition_sha256: str = field(init=False)
|
|
228
|
+
|
|
229
|
+
def __post_init__(self) -> None:
|
|
230
|
+
_token(self.model_id, name="model_id")
|
|
231
|
+
_token(self.family, name="family")
|
|
232
|
+
if (
|
|
233
|
+
type(self.feature_names) is not tuple
|
|
234
|
+
or not self.feature_names
|
|
235
|
+
or self.feature_names != tuple(dict.fromkeys(self.feature_names))
|
|
236
|
+
):
|
|
237
|
+
raise ValueError("feature_names must be non-empty and unique")
|
|
238
|
+
for value in self.feature_names:
|
|
239
|
+
_token(value, name="feature name")
|
|
240
|
+
_finite_tuple(self.means, name="means")
|
|
241
|
+
_finite_tuple(self.scales, name="scales", nonzero=True)
|
|
242
|
+
_finite_tuple(self.coefficients, name="coefficients")
|
|
243
|
+
width = len(self.feature_names)
|
|
244
|
+
if len(self.means) != width or len(self.scales) != width:
|
|
245
|
+
raise ValueError("standardizer width differs from feature ABI")
|
|
246
|
+
if len(self.coefficients) != width + 1:
|
|
247
|
+
raise ValueError(
|
|
248
|
+
"coefficients must contain one intercept plus feature weights"
|
|
249
|
+
)
|
|
250
|
+
object.__setattr__(
|
|
251
|
+
self,
|
|
252
|
+
"definition_sha256",
|
|
253
|
+
_hash(_LINEAR_MODEL_DOMAIN, self._unsigned_record()),
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
257
|
+
return {
|
|
258
|
+
"schema_version": 1,
|
|
259
|
+
"model_id": self.model_id,
|
|
260
|
+
"family": self.family,
|
|
261
|
+
"feature_names": list(self.feature_names),
|
|
262
|
+
"mean_hex": [value.hex() for value in self.means],
|
|
263
|
+
"scale_hex": [value.hex() for value in self.scales],
|
|
264
|
+
"coefficients_hex": [value.hex() for value in self.coefficients],
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
def predict(self, values: tuple[float, ...]) -> float:
|
|
268
|
+
self.__post_init__()
|
|
269
|
+
_finite_tuple(values, name="prediction features")
|
|
270
|
+
if len(values) != len(self.feature_names):
|
|
271
|
+
raise ValueError("prediction vector differs from feature ABI")
|
|
272
|
+
result = self.coefficients[0] + math.fsum(
|
|
273
|
+
coefficient * ((value - mean) / scale)
|
|
274
|
+
for value, mean, scale, coefficient in zip(
|
|
275
|
+
values,
|
|
276
|
+
self.means,
|
|
277
|
+
self.scales,
|
|
278
|
+
self.coefficients[1:],
|
|
279
|
+
strict=True,
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
if not math.isfinite(result):
|
|
283
|
+
raise RuntimeError("frozen linear prediction became non-finite")
|
|
284
|
+
return float(result)
|
|
285
|
+
|
|
286
|
+
def to_record(self) -> dict[str, object]:
|
|
287
|
+
self.__post_init__()
|
|
288
|
+
return {
|
|
289
|
+
**self._unsigned_record(),
|
|
290
|
+
"definition_sha256": self.definition_sha256,
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class FrozenHurdleScoreKind(str, Enum):
|
|
295
|
+
POSITIVE_PROBABILITY = "positive_probability"
|
|
296
|
+
EXPECTED_POSITIVE_MAGNITUDE = "expected_positive_magnitude"
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass(frozen=True, slots=True)
|
|
300
|
+
class FrozenHurdleMaterializedActionScorer:
|
|
301
|
+
"""Apply a frozen positive/magnitude hurdle model before evaluation."""
|
|
302
|
+
|
|
303
|
+
scorer_id: str
|
|
304
|
+
projection: MaterializedActionFeatureProjectionPort = field(
|
|
305
|
+
repr=False,
|
|
306
|
+
compare=False,
|
|
307
|
+
)
|
|
308
|
+
positive_model: FrozenStandardizedLinearModel
|
|
309
|
+
magnitude_model: FrozenStandardizedLinearModel
|
|
310
|
+
score_kind: FrozenHurdleScoreKind
|
|
311
|
+
source_fit_sha256: str
|
|
312
|
+
scorer_version: int = FROZEN_HURDLE_SCORE_VERSION
|
|
313
|
+
definition_sha256: str = field(init=False)
|
|
314
|
+
|
|
315
|
+
def __post_init__(self) -> None:
|
|
316
|
+
_token(self.scorer_id, name="scorer_id")
|
|
317
|
+
if type(self.scorer_version) is not int or self.scorer_version <= 0:
|
|
318
|
+
raise ValueError("scorer_version must be positive")
|
|
319
|
+
require_sha256(self.source_fit_sha256, "source_fit_sha256")
|
|
320
|
+
if not isinstance(
|
|
321
|
+
self.projection,
|
|
322
|
+
MaterializedActionFeatureProjectionPort,
|
|
323
|
+
):
|
|
324
|
+
raise TypeError("projection must implement its runtime port")
|
|
325
|
+
_token(self.projection.projection_id, name="projection_id")
|
|
326
|
+
if (
|
|
327
|
+
type(self.projection.projection_version) is not int
|
|
328
|
+
or self.projection.projection_version <= 0
|
|
329
|
+
):
|
|
330
|
+
raise ValueError("projection_version must be positive")
|
|
331
|
+
require_sha256(
|
|
332
|
+
self.projection.definition_sha256,
|
|
333
|
+
"projection definition_sha256",
|
|
334
|
+
)
|
|
335
|
+
if type(self.positive_model) is not FrozenStandardizedLinearModel:
|
|
336
|
+
raise TypeError("positive_model must be exact")
|
|
337
|
+
if type(self.magnitude_model) is not FrozenStandardizedLinearModel:
|
|
338
|
+
raise TypeError("magnitude_model must be exact")
|
|
339
|
+
self.positive_model.__post_init__()
|
|
340
|
+
self.magnitude_model.__post_init__()
|
|
341
|
+
if type(self.score_kind) is not FrozenHurdleScoreKind:
|
|
342
|
+
raise TypeError("score_kind must be exact")
|
|
343
|
+
feature_names = self.projection.feature_names
|
|
344
|
+
if (
|
|
345
|
+
feature_names != self.positive_model.feature_names
|
|
346
|
+
or feature_names != self.magnitude_model.feature_names
|
|
347
|
+
):
|
|
348
|
+
raise ValueError("projection and frozen models use different feature ABIs")
|
|
349
|
+
object.__setattr__(
|
|
350
|
+
self,
|
|
351
|
+
"definition_sha256",
|
|
352
|
+
_hash(
|
|
353
|
+
_SCORER_DOMAIN,
|
|
354
|
+
{
|
|
355
|
+
"schema_version": 1,
|
|
356
|
+
"scorer_id": self.scorer_id,
|
|
357
|
+
"scorer_version": self.scorer_version,
|
|
358
|
+
"score_kind": self.score_kind.value,
|
|
359
|
+
"source_fit_sha256": self.source_fit_sha256,
|
|
360
|
+
"projection": {
|
|
361
|
+
"projection_id": self.projection.projection_id,
|
|
362
|
+
"projection_version": (
|
|
363
|
+
self.projection.projection_version
|
|
364
|
+
),
|
|
365
|
+
"definition_sha256": (
|
|
366
|
+
self.projection.definition_sha256
|
|
367
|
+
),
|
|
368
|
+
},
|
|
369
|
+
"positive_model_sha256": (
|
|
370
|
+
self.positive_model.definition_sha256
|
|
371
|
+
),
|
|
372
|
+
"magnitude_model_sha256": (
|
|
373
|
+
self.magnitude_model.definition_sha256
|
|
374
|
+
),
|
|
375
|
+
"logit_clip": [-30, 30],
|
|
376
|
+
"log_magnitude_clip": [-30, 30],
|
|
377
|
+
"candidate_outcomes_observed": False,
|
|
378
|
+
"workload_model_provider_branches": False,
|
|
379
|
+
},
|
|
380
|
+
),
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
@staticmethod
|
|
384
|
+
def _sigmoid(value: float) -> float:
|
|
385
|
+
clipped = min(30.0, max(-30.0, value))
|
|
386
|
+
return 1.0 / (1.0 + math.exp(-clipped))
|
|
387
|
+
|
|
388
|
+
async def score(
|
|
389
|
+
self,
|
|
390
|
+
request: ResidualPortfolioDecisionRequest,
|
|
391
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
392
|
+
) -> MaterializedActionScoreBatch:
|
|
393
|
+
self.__post_init__()
|
|
394
|
+
if type(request) is not ResidualPortfolioDecisionRequest:
|
|
395
|
+
raise TypeError("request must be exact")
|
|
396
|
+
request.__post_init__()
|
|
397
|
+
if type(proposals) is not tuple or not proposals:
|
|
398
|
+
raise ValueError("proposals must be a non-empty exact tuple")
|
|
399
|
+
proposal_sha256s = tuple(
|
|
400
|
+
sorted(value.proposal_sha256 for value in proposals)
|
|
401
|
+
)
|
|
402
|
+
action_sha256s = tuple(
|
|
403
|
+
sorted(
|
|
404
|
+
action.action_sha256
|
|
405
|
+
for proposal in proposals
|
|
406
|
+
for action in proposal.actions
|
|
407
|
+
)
|
|
408
|
+
)
|
|
409
|
+
features = await self.projection.project(request, proposals)
|
|
410
|
+
if type(features) is not MaterializedActionFeatureBatch:
|
|
411
|
+
raise TypeError("feature projection returned a foreign batch")
|
|
412
|
+
features.__post_init__()
|
|
413
|
+
if (
|
|
414
|
+
features.projection_id,
|
|
415
|
+
features.projection_version,
|
|
416
|
+
features.projection_definition_sha256,
|
|
417
|
+
) != (
|
|
418
|
+
self.projection.projection_id,
|
|
419
|
+
self.projection.projection_version,
|
|
420
|
+
self.projection.definition_sha256,
|
|
421
|
+
):
|
|
422
|
+
raise ValueError("feature batch differs from its projection")
|
|
423
|
+
if features.residual_request_sha256 != request.request_sha256:
|
|
424
|
+
raise ValueError("feature batch targets another residual request")
|
|
425
|
+
if features.proposal_sha256s != proposal_sha256s:
|
|
426
|
+
raise ValueError("feature batch targets another proposal universe")
|
|
427
|
+
if features.feature_names != self.positive_model.feature_names:
|
|
428
|
+
raise ValueError("feature batch differs from the frozen model ABI")
|
|
429
|
+
if tuple(value.action_sha256 for value in features.vectors) != (
|
|
430
|
+
action_sha256s
|
|
431
|
+
):
|
|
432
|
+
raise ValueError("feature batch must exactly cover sealed actions")
|
|
433
|
+
|
|
434
|
+
scores: list[MaterializedActionScore] = []
|
|
435
|
+
for vector in features.vectors:
|
|
436
|
+
probability = self._sigmoid(
|
|
437
|
+
self.positive_model.predict(vector.values)
|
|
438
|
+
)
|
|
439
|
+
if self.score_kind is FrozenHurdleScoreKind.POSITIVE_PROBABILITY:
|
|
440
|
+
value = probability
|
|
441
|
+
else:
|
|
442
|
+
log_magnitude = self.magnitude_model.predict(vector.values)
|
|
443
|
+
magnitude = max(
|
|
444
|
+
0.0,
|
|
445
|
+
math.expm1(min(30.0, max(-30.0, log_magnitude))),
|
|
446
|
+
)
|
|
447
|
+
value = probability * magnitude
|
|
448
|
+
scores.append(
|
|
449
|
+
MaterializedActionScore(
|
|
450
|
+
action_sha256=vector.action_sha256,
|
|
451
|
+
value=float(value),
|
|
452
|
+
)
|
|
453
|
+
)
|
|
454
|
+
evidence_sha256 = _hash(
|
|
455
|
+
_SCORER_EVIDENCE_DOMAIN,
|
|
456
|
+
{
|
|
457
|
+
"scorer_definition_sha256": self.definition_sha256,
|
|
458
|
+
"source_fit_sha256": self.source_fit_sha256,
|
|
459
|
+
"feature_batch_sha256": features.batch_sha256,
|
|
460
|
+
"candidate_outcomes_observed": False,
|
|
461
|
+
},
|
|
462
|
+
)
|
|
463
|
+
return MaterializedActionScoreBatch(
|
|
464
|
+
scorer_id=self.scorer_id,
|
|
465
|
+
scorer_version=self.scorer_version,
|
|
466
|
+
scorer_definition_sha256=self.definition_sha256,
|
|
467
|
+
residual_request_sha256=request.request_sha256,
|
|
468
|
+
proposal_sha256s=proposal_sha256s,
|
|
469
|
+
scores=tuple(scores),
|
|
470
|
+
candidate_outcomes_observed=False,
|
|
471
|
+
evidence_sha256=evidence_sha256,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
@dataclass(frozen=True, slots=True)
|
|
476
|
+
class WinsorizedFrozenHurdleMaterializedActionScorer(
|
|
477
|
+
FrozenHurdleMaterializedActionScorer
|
|
478
|
+
):
|
|
479
|
+
"""Apply independently standardized models with bounded source z-scores."""
|
|
480
|
+
|
|
481
|
+
winsorization_limit: float = 3.0
|
|
482
|
+
|
|
483
|
+
def __post_init__(self) -> None:
|
|
484
|
+
FrozenHurdleMaterializedActionScorer.__post_init__(self)
|
|
485
|
+
if (
|
|
486
|
+
type(self.winsorization_limit) is not float
|
|
487
|
+
or not math.isfinite(self.winsorization_limit)
|
|
488
|
+
or self.winsorization_limit <= 0.0
|
|
489
|
+
):
|
|
490
|
+
raise ValueError(
|
|
491
|
+
"winsorization_limit must be a positive finite float"
|
|
492
|
+
)
|
|
493
|
+
object.__setattr__(
|
|
494
|
+
self,
|
|
495
|
+
"definition_sha256",
|
|
496
|
+
_hash(
|
|
497
|
+
_WINSORIZED_SCORER_DOMAIN,
|
|
498
|
+
{
|
|
499
|
+
"schema_version": 1,
|
|
500
|
+
"scorer_id": self.scorer_id,
|
|
501
|
+
"scorer_version": self.scorer_version,
|
|
502
|
+
"score_kind": self.score_kind.value,
|
|
503
|
+
"source_fit_sha256": self.source_fit_sha256,
|
|
504
|
+
"projection": {
|
|
505
|
+
"projection_id": self.projection.projection_id,
|
|
506
|
+
"projection_version": (
|
|
507
|
+
self.projection.projection_version
|
|
508
|
+
),
|
|
509
|
+
"definition_sha256": (
|
|
510
|
+
self.projection.definition_sha256
|
|
511
|
+
),
|
|
512
|
+
},
|
|
513
|
+
"positive_model_sha256": (
|
|
514
|
+
self.positive_model.definition_sha256
|
|
515
|
+
),
|
|
516
|
+
"magnitude_model_sha256": (
|
|
517
|
+
self.magnitude_model.definition_sha256
|
|
518
|
+
),
|
|
519
|
+
"winsorization_limit_hex": (
|
|
520
|
+
self.winsorization_limit.hex()
|
|
521
|
+
),
|
|
522
|
+
"standardization": (
|
|
523
|
+
"independent_frozen_standardizer_per_hurdle_model"
|
|
524
|
+
),
|
|
525
|
+
"candidate_outcomes_observed": False,
|
|
526
|
+
"workload_model_provider_branches": False,
|
|
527
|
+
},
|
|
528
|
+
),
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
def _winsorized_linear(
|
|
532
|
+
self,
|
|
533
|
+
model: FrozenStandardizedLinearModel,
|
|
534
|
+
values: tuple[float, ...],
|
|
535
|
+
) -> float:
|
|
536
|
+
result = model.coefficients[0] + math.fsum(
|
|
537
|
+
coefficient
|
|
538
|
+
* min(
|
|
539
|
+
self.winsorization_limit,
|
|
540
|
+
max(
|
|
541
|
+
-self.winsorization_limit,
|
|
542
|
+
(value - mean) / scale,
|
|
543
|
+
),
|
|
544
|
+
)
|
|
545
|
+
for value, mean, scale, coefficient in zip(
|
|
546
|
+
values,
|
|
547
|
+
model.means,
|
|
548
|
+
model.scales,
|
|
549
|
+
model.coefficients[1:],
|
|
550
|
+
strict=True,
|
|
551
|
+
)
|
|
552
|
+
)
|
|
553
|
+
if not math.isfinite(result):
|
|
554
|
+
raise RuntimeError("winsorized hurdle prediction became non-finite")
|
|
555
|
+
return float(result)
|
|
556
|
+
|
|
557
|
+
async def score(
|
|
558
|
+
self,
|
|
559
|
+
request: ResidualPortfolioDecisionRequest,
|
|
560
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
561
|
+
) -> MaterializedActionScoreBatch:
|
|
562
|
+
self.__post_init__()
|
|
563
|
+
if type(request) is not ResidualPortfolioDecisionRequest:
|
|
564
|
+
raise TypeError("request must be exact")
|
|
565
|
+
request.__post_init__()
|
|
566
|
+
if type(proposals) is not tuple or not proposals:
|
|
567
|
+
raise ValueError("proposals must be a non-empty exact tuple")
|
|
568
|
+
proposal_sha256s = tuple(
|
|
569
|
+
sorted(value.proposal_sha256 for value in proposals)
|
|
570
|
+
)
|
|
571
|
+
action_sha256s = tuple(
|
|
572
|
+
sorted(
|
|
573
|
+
action.action_sha256
|
|
574
|
+
for proposal in proposals
|
|
575
|
+
for action in proposal.actions
|
|
576
|
+
)
|
|
577
|
+
)
|
|
578
|
+
features = await self.projection.project(request, proposals)
|
|
579
|
+
if type(features) is not MaterializedActionFeatureBatch:
|
|
580
|
+
raise TypeError("feature projection returned a foreign batch")
|
|
581
|
+
features.__post_init__()
|
|
582
|
+
if (
|
|
583
|
+
features.projection_id,
|
|
584
|
+
features.projection_version,
|
|
585
|
+
features.projection_definition_sha256,
|
|
586
|
+
) != (
|
|
587
|
+
self.projection.projection_id,
|
|
588
|
+
self.projection.projection_version,
|
|
589
|
+
self.projection.definition_sha256,
|
|
590
|
+
):
|
|
591
|
+
raise ValueError("feature batch differs from its projection")
|
|
592
|
+
if (
|
|
593
|
+
features.residual_request_sha256 != request.request_sha256
|
|
594
|
+
or features.proposal_sha256s != proposal_sha256s
|
|
595
|
+
or features.feature_names != self.positive_model.feature_names
|
|
596
|
+
or tuple(value.action_sha256 for value in features.vectors)
|
|
597
|
+
!= action_sha256s
|
|
598
|
+
):
|
|
599
|
+
raise ValueError("feature batch differs from sealed universe")
|
|
600
|
+
|
|
601
|
+
scores: list[MaterializedActionScore] = []
|
|
602
|
+
for vector in features.vectors:
|
|
603
|
+
probability = self._sigmoid(
|
|
604
|
+
self._winsorized_linear(
|
|
605
|
+
self.positive_model,
|
|
606
|
+
vector.values,
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
if self.score_kind is FrozenHurdleScoreKind.POSITIVE_PROBABILITY:
|
|
610
|
+
value = probability
|
|
611
|
+
else:
|
|
612
|
+
log_magnitude = self._winsorized_linear(
|
|
613
|
+
self.magnitude_model,
|
|
614
|
+
vector.values,
|
|
615
|
+
)
|
|
616
|
+
magnitude = max(
|
|
617
|
+
0.0,
|
|
618
|
+
math.expm1(
|
|
619
|
+
min(30.0, max(-30.0, log_magnitude))
|
|
620
|
+
),
|
|
621
|
+
)
|
|
622
|
+
value = probability * magnitude
|
|
623
|
+
scores.append(
|
|
624
|
+
MaterializedActionScore(
|
|
625
|
+
action_sha256=vector.action_sha256,
|
|
626
|
+
value=float(value),
|
|
627
|
+
)
|
|
628
|
+
)
|
|
629
|
+
evidence_sha256 = _hash(
|
|
630
|
+
_WINSORIZED_SCORER_EVIDENCE_DOMAIN,
|
|
631
|
+
{
|
|
632
|
+
"scorer_definition_sha256": self.definition_sha256,
|
|
633
|
+
"source_fit_sha256": self.source_fit_sha256,
|
|
634
|
+
"feature_batch_sha256": features.batch_sha256,
|
|
635
|
+
"candidate_outcomes_observed": False,
|
|
636
|
+
},
|
|
637
|
+
)
|
|
638
|
+
return MaterializedActionScoreBatch(
|
|
639
|
+
scorer_id=self.scorer_id,
|
|
640
|
+
scorer_version=self.scorer_version,
|
|
641
|
+
scorer_definition_sha256=self.definition_sha256,
|
|
642
|
+
residual_request_sha256=request.request_sha256,
|
|
643
|
+
proposal_sha256s=proposal_sha256s,
|
|
644
|
+
scores=tuple(scores),
|
|
645
|
+
candidate_outcomes_observed=False,
|
|
646
|
+
evidence_sha256=evidence_sha256,
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
__all__ = [
|
|
651
|
+
"FROZEN_HURDLE_SCORE_VERSION",
|
|
652
|
+
"FrozenHurdleMaterializedActionScorer",
|
|
653
|
+
"FrozenHurdleScoreKind",
|
|
654
|
+
"FrozenStandardizedLinearModel",
|
|
655
|
+
"MaterializedActionFeatureBatch",
|
|
656
|
+
"MaterializedActionFeatureProjectionPort",
|
|
657
|
+
"MaterializedActionFeatureVector",
|
|
658
|
+
"WinsorizedFrozenHurdleMaterializedActionScorer",
|
|
659
|
+
]
|