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,651 @@
|
|
|
1
|
+
"""Workload-neutral delayed frontier, lineage, and terminal credit projection.
|
|
2
|
+
|
|
3
|
+
The service joins framework candidate lineage to previously sealed contextual
|
|
4
|
+
observations. It never reads candidate configuration fields, objective names,
|
|
5
|
+
model prose, or provider metadata. Recombination credit is selection-
|
|
6
|
+
conditioned evidence: a source receives a positive descendant verdict only
|
|
7
|
+
when at least one evaluated direct recombinant using it survives on the sealed
|
|
8
|
+
post-stage front. Unselected sources remain unobserved for that channel rather
|
|
9
|
+
than being mislabeled as failures. Every source candidate independently
|
|
10
|
+
receives post-stage frontier-survival credit. Terminal persistence is
|
|
11
|
+
adjudicated separately after successful campaign completion.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import hashlib
|
|
17
|
+
import json
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
|
+
|
|
20
|
+
from agent_evolve.application.contextual_search_controller import (
|
|
21
|
+
ContextualSearchDelayedCredit,
|
|
22
|
+
ContextualSearchObservation,
|
|
23
|
+
)
|
|
24
|
+
from agent_evolve.application.portfolio_evolution import PortfolioMemberDisposition
|
|
25
|
+
from agent_evolve.application.portfolio_recombination import (
|
|
26
|
+
PortfolioRecombinationWaveResult,
|
|
27
|
+
)
|
|
28
|
+
from agent_evolve.domain.ids import CandidateId
|
|
29
|
+
from agent_evolve.domain.patch import require_sha256
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
_POST_RECOMBINATION_BATCH_DOMAIN = (
|
|
33
|
+
b"agent-evolve:contextual-post-recombination-credit-batch:v1\x00"
|
|
34
|
+
)
|
|
35
|
+
_POST_STAGE_SURVIVAL_BATCH_DOMAIN = (
|
|
36
|
+
b"agent-evolve:contextual-post-stage-survival-credit-batch:v1\x00"
|
|
37
|
+
)
|
|
38
|
+
_PERSISTENCE_BATCH_DOMAIN = (
|
|
39
|
+
b"agent-evolve:contextual-terminal-persistence-credit-batch:v1\x00"
|
|
40
|
+
)
|
|
41
|
+
CONTEXTUAL_DELAYED_CREDIT_POLICY_ID = "sealed_multi_horizon_contextual_credit"
|
|
42
|
+
CONTEXTUAL_DELAYED_CREDIT_POLICY_VERSION = 2
|
|
43
|
+
CONTEXTUAL_DELAYED_CREDIT_DEFINITION_SHA256 = hashlib.sha256(
|
|
44
|
+
b"agent-evolve:sealed-multi-horizon-contextual-credit:v2;"
|
|
45
|
+
b"lineage=framework-candidate-ids;stage-survival=all-source-candidates-on-"
|
|
46
|
+
b"sealed-post-stage-front;descendant=selected-direct-recombinant-survives-"
|
|
47
|
+
b"sealed-post-stage-front;unselected-descendant=unobserved;"
|
|
48
|
+
b"persistence=successful-campaign-terminal-front-membership;"
|
|
49
|
+
b"availability=strictly-after-source-wave;"
|
|
50
|
+
b"workload-objective-model-provider-fields=false"
|
|
51
|
+
).hexdigest()
|
|
52
|
+
CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_ID = "sealed_contextual_stage_survival"
|
|
53
|
+
CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_VERSION = 1
|
|
54
|
+
CONTEXTUAL_POST_STAGE_SURVIVAL_DEFINITION_SHA256 = hashlib.sha256(
|
|
55
|
+
b"agent-evolve:sealed-contextual-stage-survival:v1;"
|
|
56
|
+
b"source=prior-contextual-observations;"
|
|
57
|
+
b"stage-survival=sealed-post-stage-front-membership;"
|
|
58
|
+
b"descendant=unobserved-when-no-source-descendant-attempt;"
|
|
59
|
+
b"availability=strictly-after-source-wave;"
|
|
60
|
+
b"workload-objective-model-provider-fields=false"
|
|
61
|
+
).hexdigest()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _canonical_json(value: object) -> bytes:
|
|
65
|
+
return json.dumps(
|
|
66
|
+
value,
|
|
67
|
+
allow_nan=False,
|
|
68
|
+
ensure_ascii=True,
|
|
69
|
+
separators=(",", ":"),
|
|
70
|
+
sort_keys=True,
|
|
71
|
+
).encode("ascii", errors="strict")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _canonical_candidate_ids(
|
|
75
|
+
values: tuple[CandidateId, ...],
|
|
76
|
+
*,
|
|
77
|
+
name: str,
|
|
78
|
+
allow_empty: bool = False,
|
|
79
|
+
) -> tuple[CandidateId, ...]:
|
|
80
|
+
if type(values) is not tuple or any(
|
|
81
|
+
type(value) is not CandidateId for value in values
|
|
82
|
+
):
|
|
83
|
+
raise TypeError(f"{name} must contain exact CandidateId values")
|
|
84
|
+
for value in values:
|
|
85
|
+
CandidateId.__post_init__(value)
|
|
86
|
+
if not allow_empty and not values:
|
|
87
|
+
raise ValueError(f"{name} must be non-empty")
|
|
88
|
+
if values != tuple(sorted(set(values))):
|
|
89
|
+
raise ValueError(f"{name} must be unique and canonical")
|
|
90
|
+
return values
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@dataclass(frozen=True, slots=True)
|
|
94
|
+
class ContextualPostRecombinationCreditBatch:
|
|
95
|
+
campaign_scope_sha256: str
|
|
96
|
+
source_wave_index: int
|
|
97
|
+
available_at_wave_index: int
|
|
98
|
+
recombination_receipt_sha256s: tuple[str, ...]
|
|
99
|
+
selected_source_candidate_ids: tuple[CandidateId, ...]
|
|
100
|
+
stage_surviving_source_candidate_ids: tuple[CandidateId, ...]
|
|
101
|
+
useful_descendant_candidate_ids: tuple[CandidateId, ...]
|
|
102
|
+
post_stage_front_candidate_ids: tuple[CandidateId, ...]
|
|
103
|
+
credits: tuple[ContextualSearchDelayedCredit, ...]
|
|
104
|
+
batch_sha256: str = field(init=False)
|
|
105
|
+
|
|
106
|
+
def __post_init__(self) -> None:
|
|
107
|
+
require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
|
|
108
|
+
if type(self.source_wave_index) is not int or self.source_wave_index <= 0:
|
|
109
|
+
raise ValueError("source_wave_index must be positive")
|
|
110
|
+
if (
|
|
111
|
+
type(self.available_at_wave_index) is not int
|
|
112
|
+
or self.available_at_wave_index <= self.source_wave_index
|
|
113
|
+
):
|
|
114
|
+
raise ValueError("descendant credit must become available later")
|
|
115
|
+
if (
|
|
116
|
+
type(self.recombination_receipt_sha256s) is not tuple
|
|
117
|
+
or not self.recombination_receipt_sha256s
|
|
118
|
+
or self.recombination_receipt_sha256s
|
|
119
|
+
!= tuple(sorted(set(self.recombination_receipt_sha256s)))
|
|
120
|
+
):
|
|
121
|
+
raise ValueError("recombination receipts must be non-empty and canonical")
|
|
122
|
+
for value in self.recombination_receipt_sha256s:
|
|
123
|
+
require_sha256(value, "recombination_receipt_sha256")
|
|
124
|
+
_canonical_candidate_ids(
|
|
125
|
+
self.selected_source_candidate_ids,
|
|
126
|
+
name="selected_source_candidate_ids",
|
|
127
|
+
allow_empty=True,
|
|
128
|
+
)
|
|
129
|
+
_canonical_candidate_ids(
|
|
130
|
+
self.stage_surviving_source_candidate_ids,
|
|
131
|
+
name="stage_surviving_source_candidate_ids",
|
|
132
|
+
allow_empty=True,
|
|
133
|
+
)
|
|
134
|
+
_canonical_candidate_ids(
|
|
135
|
+
self.useful_descendant_candidate_ids,
|
|
136
|
+
name="useful_descendant_candidate_ids",
|
|
137
|
+
allow_empty=True,
|
|
138
|
+
)
|
|
139
|
+
_canonical_candidate_ids(
|
|
140
|
+
self.post_stage_front_candidate_ids,
|
|
141
|
+
name="post_stage_front_candidate_ids",
|
|
142
|
+
)
|
|
143
|
+
front = set(self.post_stage_front_candidate_ids)
|
|
144
|
+
if not set(self.stage_surviving_source_candidate_ids).issubset(front):
|
|
145
|
+
raise ValueError("stage survivors escape the post-stage front")
|
|
146
|
+
if not set(self.useful_descendant_candidate_ids).issubset(front):
|
|
147
|
+
raise ValueError("useful descendants escape the post-stage front")
|
|
148
|
+
if (
|
|
149
|
+
type(self.credits) is not tuple
|
|
150
|
+
or not self.credits
|
|
151
|
+
or any(
|
|
152
|
+
type(value) is not ContextualSearchDelayedCredit
|
|
153
|
+
for value in self.credits
|
|
154
|
+
)
|
|
155
|
+
):
|
|
156
|
+
raise ValueError("credits must contain exact delayed-credit values")
|
|
157
|
+
for value in self.credits:
|
|
158
|
+
value.__post_init__()
|
|
159
|
+
if (
|
|
160
|
+
value.campaign_scope_sha256 != self.campaign_scope_sha256
|
|
161
|
+
or value.available_at_wave_index != self.available_at_wave_index
|
|
162
|
+
or value.final_front_persisted is not None
|
|
163
|
+
or value.stage_front_persisted is None
|
|
164
|
+
):
|
|
165
|
+
raise ValueError("post-recombination credit differs from its batch")
|
|
166
|
+
if tuple(value.credit_sha256 for value in self.credits) != tuple(
|
|
167
|
+
sorted({value.credit_sha256 for value in self.credits})
|
|
168
|
+
):
|
|
169
|
+
raise ValueError("post-recombination credits must be unique and canonical")
|
|
170
|
+
object.__setattr__(
|
|
171
|
+
self,
|
|
172
|
+
"batch_sha256",
|
|
173
|
+
hashlib.sha256(
|
|
174
|
+
_POST_RECOMBINATION_BATCH_DOMAIN
|
|
175
|
+
+ _canonical_json(self._unsigned_record())
|
|
176
|
+
).hexdigest(),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
180
|
+
return {
|
|
181
|
+
"schema_version": 1,
|
|
182
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
183
|
+
"source_wave_index": self.source_wave_index,
|
|
184
|
+
"available_at_wave_index": self.available_at_wave_index,
|
|
185
|
+
"recombination_receipt_sha256s": list(self.recombination_receipt_sha256s),
|
|
186
|
+
"selected_source_candidate_ids": [
|
|
187
|
+
value.value for value in self.selected_source_candidate_ids
|
|
188
|
+
],
|
|
189
|
+
"stage_surviving_source_candidate_ids": [
|
|
190
|
+
value.value for value in self.stage_surviving_source_candidate_ids
|
|
191
|
+
],
|
|
192
|
+
"useful_descendant_candidate_ids": [
|
|
193
|
+
value.value for value in self.useful_descendant_candidate_ids
|
|
194
|
+
],
|
|
195
|
+
"post_stage_front_candidate_ids": [
|
|
196
|
+
value.value for value in self.post_stage_front_candidate_ids
|
|
197
|
+
],
|
|
198
|
+
"credit_sha256s": [value.credit_sha256 for value in self.credits],
|
|
199
|
+
"policy": {
|
|
200
|
+
"policy_id": CONTEXTUAL_DELAYED_CREDIT_POLICY_ID,
|
|
201
|
+
"policy_version": CONTEXTUAL_DELAYED_CREDIT_POLICY_VERSION,
|
|
202
|
+
"definition_sha256": CONTEXTUAL_DELAYED_CREDIT_DEFINITION_SHA256,
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
def to_record(self) -> dict[str, object]:
|
|
207
|
+
self.__post_init__()
|
|
208
|
+
return {
|
|
209
|
+
**self._unsigned_record(),
|
|
210
|
+
"credits": [value.to_record() for value in self.credits],
|
|
211
|
+
"batch_sha256": self.batch_sha256,
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@dataclass(frozen=True, slots=True)
|
|
216
|
+
class ContextualPostStageSurvivalCreditBatch:
|
|
217
|
+
"""Persistence evidence when a later stage evaluates no source descendant.
|
|
218
|
+
|
|
219
|
+
A capacity broker can legitimately allocate a transition to another
|
|
220
|
+
proposal expert. The prior source candidates still acquire observable
|
|
221
|
+
post-stage frontier-survival outcomes, while descendant usefulness remains
|
|
222
|
+
unobserved rather than being mislabeled false.
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
campaign_scope_sha256: str
|
|
226
|
+
source_wave_index: int
|
|
227
|
+
available_at_wave_index: int
|
|
228
|
+
stage_request_sha256: str
|
|
229
|
+
source_observation_sha256s: tuple[str, ...]
|
|
230
|
+
stage_surviving_source_candidate_ids: tuple[CandidateId, ...]
|
|
231
|
+
post_stage_front_candidate_ids: tuple[CandidateId, ...]
|
|
232
|
+
credits: tuple[ContextualSearchDelayedCredit, ...]
|
|
233
|
+
batch_sha256: str = field(init=False)
|
|
234
|
+
|
|
235
|
+
def __post_init__(self) -> None:
|
|
236
|
+
require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
|
|
237
|
+
require_sha256(self.stage_request_sha256, "stage_request_sha256")
|
|
238
|
+
if type(self.source_wave_index) is not int or self.source_wave_index <= 0:
|
|
239
|
+
raise ValueError("source_wave_index must be positive")
|
|
240
|
+
if (
|
|
241
|
+
type(self.available_at_wave_index) is not int
|
|
242
|
+
or self.available_at_wave_index <= self.source_wave_index
|
|
243
|
+
):
|
|
244
|
+
raise ValueError("stage-survival credit must become available later")
|
|
245
|
+
if (
|
|
246
|
+
type(self.source_observation_sha256s) is not tuple
|
|
247
|
+
or not self.source_observation_sha256s
|
|
248
|
+
or self.source_observation_sha256s
|
|
249
|
+
!= tuple(sorted(set(self.source_observation_sha256s)))
|
|
250
|
+
):
|
|
251
|
+
raise ValueError("source observations must be non-empty and canonical")
|
|
252
|
+
for value in self.source_observation_sha256s:
|
|
253
|
+
require_sha256(value, "source_observation_sha256")
|
|
254
|
+
_canonical_candidate_ids(
|
|
255
|
+
self.stage_surviving_source_candidate_ids,
|
|
256
|
+
name="stage_surviving_source_candidate_ids",
|
|
257
|
+
allow_empty=True,
|
|
258
|
+
)
|
|
259
|
+
front = _canonical_candidate_ids(
|
|
260
|
+
self.post_stage_front_candidate_ids,
|
|
261
|
+
name="post_stage_front_candidate_ids",
|
|
262
|
+
)
|
|
263
|
+
if not set(self.stage_surviving_source_candidate_ids).issubset(front):
|
|
264
|
+
raise ValueError("stage survivors escape the post-stage front")
|
|
265
|
+
if (
|
|
266
|
+
type(self.credits) is not tuple
|
|
267
|
+
or not self.credits
|
|
268
|
+
or any(
|
|
269
|
+
type(value) is not ContextualSearchDelayedCredit
|
|
270
|
+
for value in self.credits
|
|
271
|
+
)
|
|
272
|
+
):
|
|
273
|
+
raise ValueError("credits must contain exact delayed-credit values")
|
|
274
|
+
for value in self.credits:
|
|
275
|
+
value.__post_init__()
|
|
276
|
+
if (
|
|
277
|
+
value.campaign_scope_sha256 != self.campaign_scope_sha256
|
|
278
|
+
or value.available_at_wave_index != self.available_at_wave_index
|
|
279
|
+
or value.stage_front_persisted is None
|
|
280
|
+
or value.final_front_persisted is not None
|
|
281
|
+
or value.useful_descendant_observed is not None
|
|
282
|
+
):
|
|
283
|
+
raise ValueError("post-stage survival credit differs from its batch")
|
|
284
|
+
credit_sources = tuple(
|
|
285
|
+
sorted(value.source_observation_sha256 for value in self.credits)
|
|
286
|
+
)
|
|
287
|
+
if credit_sources != self.source_observation_sha256s:
|
|
288
|
+
raise ValueError("post-stage credits differ from source observations")
|
|
289
|
+
if tuple(value.credit_sha256 for value in self.credits) != tuple(
|
|
290
|
+
sorted({value.credit_sha256 for value in self.credits})
|
|
291
|
+
):
|
|
292
|
+
raise ValueError("post-stage credits must be unique and canonical")
|
|
293
|
+
object.__setattr__(
|
|
294
|
+
self,
|
|
295
|
+
"batch_sha256",
|
|
296
|
+
hashlib.sha256(
|
|
297
|
+
_POST_STAGE_SURVIVAL_BATCH_DOMAIN
|
|
298
|
+
+ _canonical_json(self._unsigned_record())
|
|
299
|
+
).hexdigest(),
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
303
|
+
return {
|
|
304
|
+
"schema_version": 1,
|
|
305
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
306
|
+
"source_wave_index": self.source_wave_index,
|
|
307
|
+
"available_at_wave_index": self.available_at_wave_index,
|
|
308
|
+
"stage_request_sha256": self.stage_request_sha256,
|
|
309
|
+
"source_observation_sha256s": list(self.source_observation_sha256s),
|
|
310
|
+
"stage_surviving_source_candidate_ids": [
|
|
311
|
+
value.value for value in self.stage_surviving_source_candidate_ids
|
|
312
|
+
],
|
|
313
|
+
"post_stage_front_candidate_ids": [
|
|
314
|
+
value.value for value in self.post_stage_front_candidate_ids
|
|
315
|
+
],
|
|
316
|
+
"credit_sha256s": [value.credit_sha256 for value in self.credits],
|
|
317
|
+
"descendant_outcome": "unobserved_no_source_descendant_attempt",
|
|
318
|
+
"policy": {
|
|
319
|
+
"policy_id": CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_ID,
|
|
320
|
+
"policy_version": CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_VERSION,
|
|
321
|
+
"definition_sha256": (
|
|
322
|
+
CONTEXTUAL_POST_STAGE_SURVIVAL_DEFINITION_SHA256
|
|
323
|
+
),
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
def to_record(self) -> dict[str, object]:
|
|
328
|
+
self.__post_init__()
|
|
329
|
+
return {
|
|
330
|
+
**self._unsigned_record(),
|
|
331
|
+
"credits": [value.to_record() for value in self.credits],
|
|
332
|
+
"batch_sha256": self.batch_sha256,
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
@dataclass(frozen=True, slots=True)
|
|
337
|
+
class ContextualTerminalPersistenceCreditBatch:
|
|
338
|
+
campaign_scope_sha256: str
|
|
339
|
+
available_at_wave_index: int
|
|
340
|
+
finalization_request_sha256: str
|
|
341
|
+
terminal_front_candidate_ids: tuple[CandidateId, ...]
|
|
342
|
+
credits: tuple[ContextualSearchDelayedCredit, ...]
|
|
343
|
+
batch_sha256: str = field(init=False)
|
|
344
|
+
|
|
345
|
+
def __post_init__(self) -> None:
|
|
346
|
+
require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
|
|
347
|
+
require_sha256(
|
|
348
|
+
self.finalization_request_sha256,
|
|
349
|
+
"finalization_request_sha256",
|
|
350
|
+
)
|
|
351
|
+
if (
|
|
352
|
+
type(self.available_at_wave_index) is not int
|
|
353
|
+
or self.available_at_wave_index <= 1
|
|
354
|
+
):
|
|
355
|
+
raise ValueError("terminal credit availability must follow search")
|
|
356
|
+
_canonical_candidate_ids(
|
|
357
|
+
self.terminal_front_candidate_ids,
|
|
358
|
+
name="terminal_front_candidate_ids",
|
|
359
|
+
)
|
|
360
|
+
if (
|
|
361
|
+
type(self.credits) is not tuple
|
|
362
|
+
or not self.credits
|
|
363
|
+
or any(
|
|
364
|
+
type(value) is not ContextualSearchDelayedCredit
|
|
365
|
+
for value in self.credits
|
|
366
|
+
)
|
|
367
|
+
):
|
|
368
|
+
raise ValueError("credits must contain exact delayed-credit values")
|
|
369
|
+
for value in self.credits:
|
|
370
|
+
value.__post_init__()
|
|
371
|
+
if (
|
|
372
|
+
value.campaign_scope_sha256 != self.campaign_scope_sha256
|
|
373
|
+
or value.available_at_wave_index != self.available_at_wave_index
|
|
374
|
+
or value.stage_front_persisted is not None
|
|
375
|
+
or value.final_front_persisted is None
|
|
376
|
+
or value.useful_descendant_observed is not None
|
|
377
|
+
):
|
|
378
|
+
raise ValueError("terminal persistence credit differs from its batch")
|
|
379
|
+
if tuple(value.credit_sha256 for value in self.credits) != tuple(
|
|
380
|
+
sorted({value.credit_sha256 for value in self.credits})
|
|
381
|
+
):
|
|
382
|
+
raise ValueError("terminal credits must be unique and canonical")
|
|
383
|
+
object.__setattr__(
|
|
384
|
+
self,
|
|
385
|
+
"batch_sha256",
|
|
386
|
+
hashlib.sha256(
|
|
387
|
+
_PERSISTENCE_BATCH_DOMAIN + _canonical_json(self._unsigned_record())
|
|
388
|
+
).hexdigest(),
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
392
|
+
return {
|
|
393
|
+
"schema_version": 1,
|
|
394
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
395
|
+
"available_at_wave_index": self.available_at_wave_index,
|
|
396
|
+
"finalization_request_sha256": self.finalization_request_sha256,
|
|
397
|
+
"terminal_front_candidate_ids": [
|
|
398
|
+
value.value for value in self.terminal_front_candidate_ids
|
|
399
|
+
],
|
|
400
|
+
"credit_sha256s": [value.credit_sha256 for value in self.credits],
|
|
401
|
+
"policy": {
|
|
402
|
+
"policy_id": CONTEXTUAL_DELAYED_CREDIT_POLICY_ID,
|
|
403
|
+
"policy_version": CONTEXTUAL_DELAYED_CREDIT_POLICY_VERSION,
|
|
404
|
+
"definition_sha256": CONTEXTUAL_DELAYED_CREDIT_DEFINITION_SHA256,
|
|
405
|
+
},
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
def to_record(self) -> dict[str, object]:
|
|
409
|
+
self.__post_init__()
|
|
410
|
+
return {
|
|
411
|
+
**self._unsigned_record(),
|
|
412
|
+
"credits": [value.to_record() for value in self.credits],
|
|
413
|
+
"batch_sha256": self.batch_sha256,
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def observe_contextual_post_recombination_credit(
|
|
418
|
+
*,
|
|
419
|
+
campaign_scope_sha256: str,
|
|
420
|
+
source_wave_index: int,
|
|
421
|
+
observations: tuple[ContextualSearchObservation, ...],
|
|
422
|
+
results: tuple[PortfolioRecombinationWaveResult, ...],
|
|
423
|
+
post_stage_front_candidate_ids: tuple[CandidateId, ...],
|
|
424
|
+
) -> ContextualPostRecombinationCreditBatch:
|
|
425
|
+
"""Adjudicate source survival and selected-source descendant yield."""
|
|
426
|
+
|
|
427
|
+
require_sha256(campaign_scope_sha256, "campaign_scope_sha256")
|
|
428
|
+
if type(source_wave_index) is not int or source_wave_index <= 0:
|
|
429
|
+
raise ValueError("source_wave_index must be positive")
|
|
430
|
+
if (
|
|
431
|
+
type(observations) is not tuple
|
|
432
|
+
or not observations
|
|
433
|
+
or any(type(value) is not ContextualSearchObservation for value in observations)
|
|
434
|
+
):
|
|
435
|
+
raise ValueError("observations must contain exact contextual values")
|
|
436
|
+
observation_by_candidate: dict[CandidateId, ContextualSearchObservation] = {}
|
|
437
|
+
for value in observations:
|
|
438
|
+
value.__post_init__()
|
|
439
|
+
if (
|
|
440
|
+
value.campaign_scope_sha256 != campaign_scope_sha256
|
|
441
|
+
or value.wave_index != source_wave_index
|
|
442
|
+
):
|
|
443
|
+
raise ValueError("observation differs from the source wave")
|
|
444
|
+
if value.candidate_id is None:
|
|
445
|
+
raise ValueError("delayed credit requires candidate-bound observations")
|
|
446
|
+
if value.candidate_id in observation_by_candidate:
|
|
447
|
+
raise ValueError("contextual source wave repeats a candidate")
|
|
448
|
+
observation_by_candidate[value.candidate_id] = value
|
|
449
|
+
if (
|
|
450
|
+
type(results) is not tuple
|
|
451
|
+
or not results
|
|
452
|
+
or any(type(value) is not PortfolioRecombinationWaveResult for value in results)
|
|
453
|
+
):
|
|
454
|
+
raise ValueError("results must contain exact recombination values")
|
|
455
|
+
front = _canonical_candidate_ids(
|
|
456
|
+
post_stage_front_candidate_ids,
|
|
457
|
+
name="post_stage_front_candidate_ids",
|
|
458
|
+
)
|
|
459
|
+
front_set = set(front)
|
|
460
|
+
stage_survivors = set(observation_by_candidate) & front_set
|
|
461
|
+
selected_sources: set[CandidateId] = set()
|
|
462
|
+
useful_descendants: set[CandidateId] = set()
|
|
463
|
+
useful_by_source: dict[CandidateId, bool] = {}
|
|
464
|
+
receipts: list[str] = []
|
|
465
|
+
for result in results:
|
|
466
|
+
result.__post_init__()
|
|
467
|
+
receipts.append(result.receipt.receipt_sha256)
|
|
468
|
+
for member in result.receipt.members:
|
|
469
|
+
selected_sources.update(member.pair_ids)
|
|
470
|
+
useful = (
|
|
471
|
+
member.disposition is PortfolioMemberDisposition.SCORED
|
|
472
|
+
and member.target_candidate_id in front_set
|
|
473
|
+
)
|
|
474
|
+
if useful:
|
|
475
|
+
useful_descendants.add(member.target_candidate_id)
|
|
476
|
+
for source_id in member.pair_ids:
|
|
477
|
+
useful_by_source[source_id] = (
|
|
478
|
+
useful_by_source.get(source_id, False) or useful
|
|
479
|
+
)
|
|
480
|
+
missing = selected_sources - set(observation_by_candidate)
|
|
481
|
+
if missing:
|
|
482
|
+
raise ValueError("recombination cites a source without contextual observation")
|
|
483
|
+
credits = tuple(
|
|
484
|
+
sorted(
|
|
485
|
+
(
|
|
486
|
+
ContextualSearchDelayedCredit(
|
|
487
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
488
|
+
source_observation_sha256=(
|
|
489
|
+
observation_by_candidate[candidate_id].observation_sha256
|
|
490
|
+
),
|
|
491
|
+
available_at_wave_index=source_wave_index + 1,
|
|
492
|
+
stage_front_persisted=candidate_id in stage_survivors,
|
|
493
|
+
useful_descendant_observed=(
|
|
494
|
+
useful_by_source[candidate_id]
|
|
495
|
+
if candidate_id in selected_sources
|
|
496
|
+
else None
|
|
497
|
+
),
|
|
498
|
+
)
|
|
499
|
+
for candidate_id in sorted(observation_by_candidate)
|
|
500
|
+
),
|
|
501
|
+
key=lambda value: value.credit_sha256,
|
|
502
|
+
)
|
|
503
|
+
)
|
|
504
|
+
return ContextualPostRecombinationCreditBatch(
|
|
505
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
506
|
+
source_wave_index=source_wave_index,
|
|
507
|
+
available_at_wave_index=source_wave_index + 1,
|
|
508
|
+
recombination_receipt_sha256s=tuple(sorted(receipts)),
|
|
509
|
+
selected_source_candidate_ids=tuple(sorted(selected_sources)),
|
|
510
|
+
stage_surviving_source_candidate_ids=tuple(sorted(stage_survivors)),
|
|
511
|
+
useful_descendant_candidate_ids=tuple(sorted(useful_descendants)),
|
|
512
|
+
post_stage_front_candidate_ids=front,
|
|
513
|
+
credits=credits,
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def observe_contextual_post_stage_survival(
|
|
518
|
+
*,
|
|
519
|
+
campaign_scope_sha256: str,
|
|
520
|
+
source_wave_index: int,
|
|
521
|
+
stage_request_sha256: str,
|
|
522
|
+
observations: tuple[ContextualSearchObservation, ...],
|
|
523
|
+
post_stage_front_candidate_ids: tuple[CandidateId, ...],
|
|
524
|
+
) -> ContextualPostStageSurvivalCreditBatch:
|
|
525
|
+
"""Adjudicate source persistence when no source descendant was attempted."""
|
|
526
|
+
|
|
527
|
+
require_sha256(campaign_scope_sha256, "campaign_scope_sha256")
|
|
528
|
+
require_sha256(stage_request_sha256, "stage_request_sha256")
|
|
529
|
+
if type(source_wave_index) is not int or source_wave_index <= 0:
|
|
530
|
+
raise ValueError("source_wave_index must be positive")
|
|
531
|
+
if (
|
|
532
|
+
type(observations) is not tuple
|
|
533
|
+
or not observations
|
|
534
|
+
or any(type(value) is not ContextualSearchObservation for value in observations)
|
|
535
|
+
):
|
|
536
|
+
raise ValueError("observations must contain exact contextual values")
|
|
537
|
+
observation_by_candidate: dict[CandidateId, ContextualSearchObservation] = {}
|
|
538
|
+
for value in observations:
|
|
539
|
+
value.__post_init__()
|
|
540
|
+
if (
|
|
541
|
+
value.campaign_scope_sha256 != campaign_scope_sha256
|
|
542
|
+
or value.wave_index != source_wave_index
|
|
543
|
+
):
|
|
544
|
+
raise ValueError("observation differs from the source wave")
|
|
545
|
+
if value.candidate_id is None:
|
|
546
|
+
raise ValueError("stage-survival credit requires candidate-bound values")
|
|
547
|
+
if value.candidate_id in observation_by_candidate:
|
|
548
|
+
raise ValueError("contextual source wave repeats a candidate")
|
|
549
|
+
observation_by_candidate[value.candidate_id] = value
|
|
550
|
+
front = _canonical_candidate_ids(
|
|
551
|
+
post_stage_front_candidate_ids,
|
|
552
|
+
name="post_stage_front_candidate_ids",
|
|
553
|
+
)
|
|
554
|
+
front_set = set(front)
|
|
555
|
+
survivors = tuple(sorted(set(observation_by_candidate) & front_set))
|
|
556
|
+
credits = tuple(
|
|
557
|
+
sorted(
|
|
558
|
+
(
|
|
559
|
+
ContextualSearchDelayedCredit(
|
|
560
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
561
|
+
source_observation_sha256=value.observation_sha256,
|
|
562
|
+
available_at_wave_index=source_wave_index + 1,
|
|
563
|
+
stage_front_persisted=candidate_id in front_set,
|
|
564
|
+
)
|
|
565
|
+
for candidate_id, value in observation_by_candidate.items()
|
|
566
|
+
),
|
|
567
|
+
key=lambda value: value.credit_sha256,
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
return ContextualPostStageSurvivalCreditBatch(
|
|
571
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
572
|
+
source_wave_index=source_wave_index,
|
|
573
|
+
available_at_wave_index=source_wave_index + 1,
|
|
574
|
+
stage_request_sha256=stage_request_sha256,
|
|
575
|
+
source_observation_sha256s=tuple(
|
|
576
|
+
sorted(value.observation_sha256 for value in observations)
|
|
577
|
+
),
|
|
578
|
+
stage_surviving_source_candidate_ids=survivors,
|
|
579
|
+
post_stage_front_candidate_ids=front,
|
|
580
|
+
credits=credits,
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
def observe_contextual_terminal_persistence(
|
|
585
|
+
*,
|
|
586
|
+
campaign_scope_sha256: str,
|
|
587
|
+
available_at_wave_index: int,
|
|
588
|
+
finalization_request_sha256: str,
|
|
589
|
+
observations: tuple[ContextualSearchObservation, ...],
|
|
590
|
+
terminal_front_candidate_ids: tuple[CandidateId, ...],
|
|
591
|
+
) -> ContextualTerminalPersistenceCreditBatch:
|
|
592
|
+
"""Adjudicate candidate persistence only after successful completion."""
|
|
593
|
+
|
|
594
|
+
require_sha256(campaign_scope_sha256, "campaign_scope_sha256")
|
|
595
|
+
require_sha256(finalization_request_sha256, "finalization_request_sha256")
|
|
596
|
+
if (
|
|
597
|
+
type(observations) is not tuple
|
|
598
|
+
or not observations
|
|
599
|
+
or any(type(value) is not ContextualSearchObservation for value in observations)
|
|
600
|
+
):
|
|
601
|
+
raise ValueError("observations must contain exact contextual values")
|
|
602
|
+
terminal = _canonical_candidate_ids(
|
|
603
|
+
terminal_front_candidate_ids,
|
|
604
|
+
name="terminal_front_candidate_ids",
|
|
605
|
+
)
|
|
606
|
+
terminal_set = set(terminal)
|
|
607
|
+
for value in observations:
|
|
608
|
+
value.__post_init__()
|
|
609
|
+
if value.campaign_scope_sha256 != campaign_scope_sha256:
|
|
610
|
+
raise ValueError("terminal credit crosses campaign scopes")
|
|
611
|
+
if value.candidate_id is None:
|
|
612
|
+
raise ValueError("terminal credit requires candidate-bound observations")
|
|
613
|
+
if available_at_wave_index <= value.wave_index:
|
|
614
|
+
raise ValueError("terminal credit predates a source observation")
|
|
615
|
+
credits = tuple(
|
|
616
|
+
sorted(
|
|
617
|
+
(
|
|
618
|
+
ContextualSearchDelayedCredit(
|
|
619
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
620
|
+
source_observation_sha256=value.observation_sha256,
|
|
621
|
+
available_at_wave_index=available_at_wave_index,
|
|
622
|
+
final_front_persisted=value.candidate_id in terminal_set,
|
|
623
|
+
)
|
|
624
|
+
for value in observations
|
|
625
|
+
),
|
|
626
|
+
key=lambda value: value.credit_sha256,
|
|
627
|
+
)
|
|
628
|
+
)
|
|
629
|
+
return ContextualTerminalPersistenceCreditBatch(
|
|
630
|
+
campaign_scope_sha256=campaign_scope_sha256,
|
|
631
|
+
available_at_wave_index=available_at_wave_index,
|
|
632
|
+
finalization_request_sha256=finalization_request_sha256,
|
|
633
|
+
terminal_front_candidate_ids=terminal,
|
|
634
|
+
credits=credits,
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
__all__ = [
|
|
639
|
+
"CONTEXTUAL_DELAYED_CREDIT_DEFINITION_SHA256",
|
|
640
|
+
"CONTEXTUAL_DELAYED_CREDIT_POLICY_ID",
|
|
641
|
+
"CONTEXTUAL_DELAYED_CREDIT_POLICY_VERSION",
|
|
642
|
+
"CONTEXTUAL_POST_STAGE_SURVIVAL_DEFINITION_SHA256",
|
|
643
|
+
"CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_ID",
|
|
644
|
+
"CONTEXTUAL_POST_STAGE_SURVIVAL_POLICY_VERSION",
|
|
645
|
+
"ContextualPostRecombinationCreditBatch",
|
|
646
|
+
"ContextualPostStageSurvivalCreditBatch",
|
|
647
|
+
"ContextualTerminalPersistenceCreditBatch",
|
|
648
|
+
"observe_contextual_post_recombination_credit",
|
|
649
|
+
"observe_contextual_post_stage_survival",
|
|
650
|
+
"observe_contextual_terminal_persistence",
|
|
651
|
+
]
|