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,385 @@
|
|
|
1
|
+
"""Opportunity-aware routing over frozen residual portfolio continuations.
|
|
2
|
+
|
|
3
|
+
The existing portfolio-race gate estimates which precommitted completion best
|
|
4
|
+
matches the observed pilot lanes. This decorator adds a separate question:
|
|
5
|
+
did the pilot expose enough absolute opportunity to keep spending on the
|
|
6
|
+
current market at all?
|
|
7
|
+
|
|
8
|
+
All candidate branches still exist before current outcomes are observed. A
|
|
9
|
+
weak pilot can therefore hand off only to a pre-generated renewal branch; it
|
|
10
|
+
cannot trigger an unlogged provider call or outcome-conditioned candidate
|
|
11
|
+
construction. Later campaign stages may use the resulting authenticated
|
|
12
|
+
evidence to open a fresh proposal market through the ordinary expert ports.
|
|
13
|
+
|
|
14
|
+
The policy is workload-, objective-, model-, provider-, prompt-, and
|
|
15
|
+
configuration-blind. Its absolute gain reference must be bound to an
|
|
16
|
+
authenticated prior-evidence digest so that a caller cannot silently tune the
|
|
17
|
+
threshold after seeing the current pilot.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import hashlib
|
|
23
|
+
import json
|
|
24
|
+
import math
|
|
25
|
+
import re
|
|
26
|
+
from dataclasses import dataclass, field
|
|
27
|
+
|
|
28
|
+
from agent_evolve.application.precommitted_portfolio_racing import (
|
|
29
|
+
EvidenceAdaptivePortfolioRaceGate,
|
|
30
|
+
PortfolioRaceGateDecision,
|
|
31
|
+
PrecommittedPortfolioRacePlan,
|
|
32
|
+
)
|
|
33
|
+
from agent_evolve.application.sequential_lineage_allocation import (
|
|
34
|
+
SequentialAllocationGateDecisionPort,
|
|
35
|
+
SequentialAllocationPlanPort,
|
|
36
|
+
SequentialPilotOutcomeBatch,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.domain.patch import require_sha256
|
|
39
|
+
from agent_evolve.domain.typed_json import freeze_json, thaw_json
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_ID = (
|
|
43
|
+
"causal_opportunity_portfolio_race_gate"
|
|
44
|
+
)
|
|
45
|
+
CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_VERSION = 2
|
|
46
|
+
|
|
47
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
48
|
+
_DEFINITION_DOMAIN = (
|
|
49
|
+
b"agent-evolve:causal-opportunity-portfolio-race-gate:v2\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 _require_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 _resolve_frozen_route(
|
|
73
|
+
plan: PrecommittedPortfolioRacePlan,
|
|
74
|
+
requested_branch_id: str,
|
|
75
|
+
) -> tuple[str, tuple[str, ...]]:
|
|
76
|
+
"""Resolve a configured source branch to its frozen equivalent.
|
|
77
|
+
|
|
78
|
+
A disagreement planner may outcome-blindly collapse source branches that
|
|
79
|
+
produce the same complete action slate, either before or after the common
|
|
80
|
+
pilot is inserted. The planner authenticates that exact equivalence in
|
|
81
|
+
``outcome_blind_route_resolution``. The gate may consume that proof, but
|
|
82
|
+
it must never guess a substitute for a non-equivalent missing route.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
_require_token(requested_branch_id, name="requested_branch_id")
|
|
86
|
+
if requested_branch_id in plan.frozen_branch_ids:
|
|
87
|
+
return requested_branch_id, ("identity",)
|
|
88
|
+
raw_plan_evidence = thaw_json(plan.evidence)
|
|
89
|
+
if type(raw_plan_evidence) is not dict:
|
|
90
|
+
raise TypeError("portfolio plan evidence must have an object root")
|
|
91
|
+
raw_design = raw_plan_evidence.get("disagreement_design")
|
|
92
|
+
if type(raw_design) is not dict:
|
|
93
|
+
raise ValueError(
|
|
94
|
+
"configured route is absent and the plan has no disagreement proof"
|
|
95
|
+
)
|
|
96
|
+
raw_design_evidence = raw_design.get("evidence")
|
|
97
|
+
if type(raw_design_evidence) is not dict:
|
|
98
|
+
raise ValueError(
|
|
99
|
+
"configured route is absent and disagreement evidence is missing"
|
|
100
|
+
)
|
|
101
|
+
raw_rows = raw_design_evidence.get(
|
|
102
|
+
"outcome_blind_route_resolution"
|
|
103
|
+
)
|
|
104
|
+
if type(raw_rows) is not list:
|
|
105
|
+
raise ValueError(
|
|
106
|
+
"configured route is absent and has no authenticated resolution"
|
|
107
|
+
)
|
|
108
|
+
matches = tuple(
|
|
109
|
+
value
|
|
110
|
+
for value in raw_rows
|
|
111
|
+
if type(value) is dict
|
|
112
|
+
and value.get("source_branch_id") == requested_branch_id
|
|
113
|
+
)
|
|
114
|
+
if len(matches) != 1:
|
|
115
|
+
raise ValueError(
|
|
116
|
+
"configured route lacks one unambiguous authenticated resolution"
|
|
117
|
+
)
|
|
118
|
+
row = matches[0]
|
|
119
|
+
representative = row.get("representative_branch_id")
|
|
120
|
+
raw_path = row.get("equivalence_path")
|
|
121
|
+
if type(representative) is not str:
|
|
122
|
+
raise TypeError("resolved representative_branch_id must be a string")
|
|
123
|
+
_require_token(representative, name="representative_branch_id")
|
|
124
|
+
if (
|
|
125
|
+
type(raw_path) is not list
|
|
126
|
+
or not raw_path
|
|
127
|
+
or any(type(value) is not str for value in raw_path)
|
|
128
|
+
):
|
|
129
|
+
raise ValueError("route resolution needs an equivalence proof path")
|
|
130
|
+
path = tuple(raw_path)
|
|
131
|
+
allowed = {
|
|
132
|
+
"identity",
|
|
133
|
+
"identical_complete_action_set_before_pilot",
|
|
134
|
+
"identical_complete_action_set_after_frozen_pilot",
|
|
135
|
+
}
|
|
136
|
+
if any(value not in allowed for value in path):
|
|
137
|
+
raise ValueError("route resolution uses an unknown equivalence proof")
|
|
138
|
+
if representative not in plan.frozen_branch_ids:
|
|
139
|
+
raise ValueError(
|
|
140
|
+
"authenticated route representative is absent from the frozen plan"
|
|
141
|
+
)
|
|
142
|
+
return representative, path
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass(frozen=True, slots=True)
|
|
146
|
+
class CausalOpportunityPortfolioRaceGate:
|
|
147
|
+
"""Route weak, sparse, and productive pilots to frozen continuations.
|
|
148
|
+
|
|
149
|
+
``reference_gain_scale`` is a robust positive-gain scale derived only from
|
|
150
|
+
strictly prior authenticated outcomes. ``minimum_peak_gain_ratio`` tests
|
|
151
|
+
whether the best pilot clears a declared fraction of that scale.
|
|
152
|
+
``minimum_positive_fraction`` separates a sparse market from a productive
|
|
153
|
+
one after the absolute opportunity check passes.
|
|
154
|
+
|
|
155
|
+
The productive route delegates to the existing lane-aware race gate. The
|
|
156
|
+
weak and sparse routes select explicit precommitted branch IDs. This
|
|
157
|
+
separation is intentional: opportunity detection and within-market
|
|
158
|
+
conversion are different control problems.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
renewal_branch_id: str
|
|
162
|
+
exploration_branch_id: str
|
|
163
|
+
reference_gain_scale: float
|
|
164
|
+
reference_gain_evidence_sha256: str
|
|
165
|
+
minimum_peak_gain_ratio: float = 0.5
|
|
166
|
+
minimum_positive_fraction: float = 0.5
|
|
167
|
+
minimum_pilot_count: int = 2
|
|
168
|
+
base_gate: EvidenceAdaptivePortfolioRaceGate = field(
|
|
169
|
+
default_factory=EvidenceAdaptivePortfolioRaceGate,
|
|
170
|
+
repr=False,
|
|
171
|
+
compare=False,
|
|
172
|
+
)
|
|
173
|
+
gate_id: str = CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_ID
|
|
174
|
+
gate_version: int = CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_VERSION
|
|
175
|
+
definition_sha256: str = field(init=False)
|
|
176
|
+
|
|
177
|
+
def __post_init__(self) -> None:
|
|
178
|
+
_require_token(self.renewal_branch_id, name="renewal_branch_id")
|
|
179
|
+
_require_token(
|
|
180
|
+
self.exploration_branch_id,
|
|
181
|
+
name="exploration_branch_id",
|
|
182
|
+
)
|
|
183
|
+
if self.renewal_branch_id == self.exploration_branch_id:
|
|
184
|
+
raise ValueError(
|
|
185
|
+
"renewal and exploration branches must be distinct"
|
|
186
|
+
)
|
|
187
|
+
if (
|
|
188
|
+
type(self.reference_gain_scale) is not float
|
|
189
|
+
or not math.isfinite(self.reference_gain_scale)
|
|
190
|
+
or self.reference_gain_scale <= 0.0
|
|
191
|
+
):
|
|
192
|
+
raise ValueError(
|
|
193
|
+
"reference_gain_scale must be finite and positive"
|
|
194
|
+
)
|
|
195
|
+
require_sha256(
|
|
196
|
+
self.reference_gain_evidence_sha256,
|
|
197
|
+
"reference_gain_evidence_sha256",
|
|
198
|
+
)
|
|
199
|
+
if (
|
|
200
|
+
type(self.minimum_peak_gain_ratio) is not float
|
|
201
|
+
or not math.isfinite(self.minimum_peak_gain_ratio)
|
|
202
|
+
or self.minimum_peak_gain_ratio < 0.0
|
|
203
|
+
):
|
|
204
|
+
raise ValueError(
|
|
205
|
+
"minimum_peak_gain_ratio must be finite and non-negative"
|
|
206
|
+
)
|
|
207
|
+
if (
|
|
208
|
+
type(self.minimum_positive_fraction) is not float
|
|
209
|
+
or not math.isfinite(self.minimum_positive_fraction)
|
|
210
|
+
or not 0.0 <= self.minimum_positive_fraction <= 1.0
|
|
211
|
+
):
|
|
212
|
+
raise ValueError(
|
|
213
|
+
"minimum_positive_fraction must lie in [0, 1]"
|
|
214
|
+
)
|
|
215
|
+
if (
|
|
216
|
+
type(self.minimum_pilot_count) is not int
|
|
217
|
+
or self.minimum_pilot_count <= 0
|
|
218
|
+
):
|
|
219
|
+
raise ValueError("minimum_pilot_count must be positive")
|
|
220
|
+
if type(self.base_gate) is not EvidenceAdaptivePortfolioRaceGate:
|
|
221
|
+
raise TypeError("base_gate must be an exact evidence-adaptive gate")
|
|
222
|
+
self.base_gate.__post_init__()
|
|
223
|
+
_require_token(self.gate_id, name="gate_id")
|
|
224
|
+
if self.gate_version != CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_VERSION:
|
|
225
|
+
raise ValueError("gate_version is immutable")
|
|
226
|
+
object.__setattr__(
|
|
227
|
+
self,
|
|
228
|
+
"definition_sha256",
|
|
229
|
+
_hash(
|
|
230
|
+
_DEFINITION_DOMAIN,
|
|
231
|
+
{
|
|
232
|
+
"schema_version": 1,
|
|
233
|
+
"gate_id": self.gate_id,
|
|
234
|
+
"gate_version": self.gate_version,
|
|
235
|
+
"renewal_branch_id": self.renewal_branch_id,
|
|
236
|
+
"exploration_branch_id": self.exploration_branch_id,
|
|
237
|
+
"reference_gain_scale_hex": (
|
|
238
|
+
self.reference_gain_scale.hex()
|
|
239
|
+
),
|
|
240
|
+
"reference_gain_evidence_sha256": (
|
|
241
|
+
self.reference_gain_evidence_sha256
|
|
242
|
+
),
|
|
243
|
+
"minimum_peak_gain_ratio_hex": (
|
|
244
|
+
self.minimum_peak_gain_ratio.hex()
|
|
245
|
+
),
|
|
246
|
+
"minimum_positive_fraction_hex": (
|
|
247
|
+
self.minimum_positive_fraction.hex()
|
|
248
|
+
),
|
|
249
|
+
"minimum_pilot_count": self.minimum_pilot_count,
|
|
250
|
+
"base_gate": {
|
|
251
|
+
"gate_id": self.base_gate.gate_id,
|
|
252
|
+
"gate_version": self.base_gate.gate_version,
|
|
253
|
+
"definition_sha256": (
|
|
254
|
+
self.base_gate.definition_sha256
|
|
255
|
+
),
|
|
256
|
+
},
|
|
257
|
+
"routing_order": (
|
|
258
|
+
"insufficient_pilot_then_weak_absolute_opportunity_"
|
|
259
|
+
"then_sparse_positive_support_then_lane_adaptation"
|
|
260
|
+
),
|
|
261
|
+
"missing_route_resolution": (
|
|
262
|
+
"authenticated_exact_action_set_equivalence_only"
|
|
263
|
+
),
|
|
264
|
+
"candidate_branches_frozen_before_outcomes": True,
|
|
265
|
+
"outcome_conditioned_regeneration": False,
|
|
266
|
+
"only_pilot_outcomes_observed": True,
|
|
267
|
+
"workload_model_provider_branches": False,
|
|
268
|
+
},
|
|
269
|
+
),
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
def decide(
|
|
273
|
+
self,
|
|
274
|
+
plan: SequentialAllocationPlanPort,
|
|
275
|
+
outcomes: SequentialPilotOutcomeBatch,
|
|
276
|
+
) -> SequentialAllocationGateDecisionPort:
|
|
277
|
+
self.__post_init__()
|
|
278
|
+
if type(plan) is not PrecommittedPortfolioRacePlan:
|
|
279
|
+
raise TypeError(
|
|
280
|
+
"causal opportunity gate requires an exact portfolio plan"
|
|
281
|
+
)
|
|
282
|
+
plan.__post_init__()
|
|
283
|
+
if type(outcomes) is not SequentialPilotOutcomeBatch:
|
|
284
|
+
raise TypeError("outcomes must be exact")
|
|
285
|
+
outcomes.__post_init__()
|
|
286
|
+
|
|
287
|
+
base_decision = self.base_gate.decide(plan, outcomes)
|
|
288
|
+
if type(base_decision) is not PortfolioRaceGateDecision:
|
|
289
|
+
raise TypeError("base gate returned a foreign decision")
|
|
290
|
+
base_decision.__post_init__()
|
|
291
|
+
|
|
292
|
+
pilot_count = len(outcomes.outcomes)
|
|
293
|
+
positive_count = sum(
|
|
294
|
+
value.positive_marginal_utility
|
|
295
|
+
for value in outcomes.outcomes
|
|
296
|
+
)
|
|
297
|
+
maximum_gain = max(
|
|
298
|
+
(
|
|
299
|
+
value.marginal_archive_gain
|
|
300
|
+
for value in outcomes.outcomes
|
|
301
|
+
),
|
|
302
|
+
default=0.0,
|
|
303
|
+
)
|
|
304
|
+
peak_gain_ratio = maximum_gain / self.reference_gain_scale
|
|
305
|
+
positive_fraction = (
|
|
306
|
+
0.0 if pilot_count == 0 else positive_count / pilot_count
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
if pilot_count < self.minimum_pilot_count:
|
|
310
|
+
requested_branch_id = base_decision.selected_branch_id
|
|
311
|
+
route = "insufficient_pilot_base_gate"
|
|
312
|
+
elif (
|
|
313
|
+
positive_count == 0
|
|
314
|
+
or peak_gain_ratio < self.minimum_peak_gain_ratio
|
|
315
|
+
):
|
|
316
|
+
requested_branch_id = self.renewal_branch_id
|
|
317
|
+
route = "weak_opportunity_renewal"
|
|
318
|
+
elif positive_fraction < self.minimum_positive_fraction:
|
|
319
|
+
requested_branch_id = self.exploration_branch_id
|
|
320
|
+
route = "sparse_opportunity_exploration"
|
|
321
|
+
else:
|
|
322
|
+
requested_branch_id = base_decision.selected_branch_id
|
|
323
|
+
route = "productive_market_lane_adaptation"
|
|
324
|
+
|
|
325
|
+
selected_branch_id, route_equivalence_path = _resolve_frozen_route(
|
|
326
|
+
plan,
|
|
327
|
+
requested_branch_id,
|
|
328
|
+
)
|
|
329
|
+
selected = plan.branch_for(selected_branch_id)
|
|
330
|
+
return PortfolioRaceGateDecision(
|
|
331
|
+
gate_id=self.gate_id,
|
|
332
|
+
gate_version=self.gate_version,
|
|
333
|
+
gate_definition_sha256=self.definition_sha256,
|
|
334
|
+
plan_sha256=plan.plan_sha256,
|
|
335
|
+
pilot_outcome_batch_sha256=outcomes.batch_sha256,
|
|
336
|
+
selected_branch_id=selected_branch_id,
|
|
337
|
+
selected_requirement_sha256=(
|
|
338
|
+
selected.requirement.requirement_sha256
|
|
339
|
+
),
|
|
340
|
+
positive_pilot_count=positive_count,
|
|
341
|
+
pilot_count=pilot_count,
|
|
342
|
+
branch_scores=base_decision.branch_scores,
|
|
343
|
+
evidence=freeze_json(
|
|
344
|
+
{
|
|
345
|
+
"route": route,
|
|
346
|
+
"requested_branch_id": requested_branch_id,
|
|
347
|
+
"resolved_branch_id": selected_branch_id,
|
|
348
|
+
"route_equivalence_path": list(
|
|
349
|
+
route_equivalence_path
|
|
350
|
+
),
|
|
351
|
+
"maximum_pilot_marginal_gain_hex": maximum_gain.hex(),
|
|
352
|
+
"reference_gain_scale_hex": (
|
|
353
|
+
self.reference_gain_scale.hex()
|
|
354
|
+
),
|
|
355
|
+
"reference_gain_evidence_sha256": (
|
|
356
|
+
self.reference_gain_evidence_sha256
|
|
357
|
+
),
|
|
358
|
+
"peak_gain_ratio_hex": peak_gain_ratio.hex(),
|
|
359
|
+
"minimum_peak_gain_ratio_hex": (
|
|
360
|
+
self.minimum_peak_gain_ratio.hex()
|
|
361
|
+
),
|
|
362
|
+
"positive_pilot_count": positive_count,
|
|
363
|
+
"pilot_count": pilot_count,
|
|
364
|
+
"positive_fraction_hex": positive_fraction.hex(),
|
|
365
|
+
"minimum_positive_fraction_hex": (
|
|
366
|
+
self.minimum_positive_fraction.hex()
|
|
367
|
+
),
|
|
368
|
+
"minimum_pilot_count": self.minimum_pilot_count,
|
|
369
|
+
"base_gate_decision": base_decision.to_record(
|
|
370
|
+
include_evidence=True
|
|
371
|
+
),
|
|
372
|
+
"selected_branch_frozen_before_pilot": True,
|
|
373
|
+
"outcome_conditioned_regeneration": False,
|
|
374
|
+
"only_pilot_outcomes_observed": True,
|
|
375
|
+
"workload_model_provider_branches": False,
|
|
376
|
+
}
|
|
377
|
+
),
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
__all__ = [
|
|
382
|
+
"CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_ID",
|
|
383
|
+
"CAUSAL_OPPORTUNITY_PORTFOLIO_GATE_VERSION",
|
|
384
|
+
"CausalOpportunityPortfolioRaceGate",
|
|
385
|
+
]
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""Transactional composition for independent campaign outcome projections."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
from agent_evolve.application.campaign_execution import CampaignStageRequest
|
|
8
|
+
from agent_evolve.application.portfolio_campaign_runtime import (
|
|
9
|
+
CampaignPortfolioOutcomePreparation,
|
|
10
|
+
CampaignPortfolioOutcomeUpdater,
|
|
11
|
+
)
|
|
12
|
+
from agent_evolve.application.portfolio_evolution import (
|
|
13
|
+
PortfolioVariationWaveRequest,
|
|
14
|
+
PortfolioVariationWaveResult,
|
|
15
|
+
)
|
|
16
|
+
from agent_evolve.domain.typed_json import (
|
|
17
|
+
FrozenJsonObject,
|
|
18
|
+
freeze_json,
|
|
19
|
+
typed_json_sha256,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _object(value: dict[str, object]) -> FrozenJsonObject:
|
|
24
|
+
result = freeze_json(value)
|
|
25
|
+
if type(result) is not FrozenJsonObject: # pragma: no cover - closed root.
|
|
26
|
+
raise AssertionError("composite outcome evidence did not freeze to an object")
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(slots=True)
|
|
31
|
+
class CompositeCampaignPortfolioOutcomeUpdater:
|
|
32
|
+
"""Stage several zero-call updaters behind one atomic runtime port.
|
|
33
|
+
|
|
34
|
+
Each component receives the memory projection produced by its predecessor.
|
|
35
|
+
No component is published until every preparation succeeds. Abort proceeds
|
|
36
|
+
in reverse order; commit proceeds in declaration order.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
updaters: tuple[CampaignPortfolioOutcomeUpdater, ...]
|
|
40
|
+
_prepared: dict[
|
|
41
|
+
str,
|
|
42
|
+
tuple[
|
|
43
|
+
CampaignPortfolioOutcomePreparation,
|
|
44
|
+
tuple[
|
|
45
|
+
tuple[
|
|
46
|
+
CampaignPortfolioOutcomeUpdater,
|
|
47
|
+
CampaignPortfolioOutcomePreparation,
|
|
48
|
+
],
|
|
49
|
+
...,
|
|
50
|
+
],
|
|
51
|
+
],
|
|
52
|
+
] = field(init=False, default_factory=dict, repr=False)
|
|
53
|
+
|
|
54
|
+
def __post_init__(self) -> None:
|
|
55
|
+
if type(self.updaters) is not tuple or len(self.updaters) < 2:
|
|
56
|
+
raise ValueError("composite outcome updater requires at least two components")
|
|
57
|
+
if any(
|
|
58
|
+
not isinstance(value, CampaignPortfolioOutcomeUpdater)
|
|
59
|
+
for value in self.updaters
|
|
60
|
+
):
|
|
61
|
+
raise TypeError("every component must implement the outcome updater port")
|
|
62
|
+
|
|
63
|
+
async def prepare_update(
|
|
64
|
+
self,
|
|
65
|
+
request: CampaignStageRequest,
|
|
66
|
+
waves: tuple[PortfolioVariationWaveRequest, ...],
|
|
67
|
+
results: tuple[PortfolioVariationWaveResult, ...],
|
|
68
|
+
prior_memory: FrozenJsonObject,
|
|
69
|
+
) -> CampaignPortfolioOutcomePreparation:
|
|
70
|
+
self.__post_init__()
|
|
71
|
+
staged: list[
|
|
72
|
+
tuple[CampaignPortfolioOutcomeUpdater, CampaignPortfolioOutcomePreparation]
|
|
73
|
+
] = []
|
|
74
|
+
memory = prior_memory
|
|
75
|
+
try:
|
|
76
|
+
for updater in self.updaters:
|
|
77
|
+
preparation = await updater.prepare_update(
|
|
78
|
+
request,
|
|
79
|
+
waves,
|
|
80
|
+
results,
|
|
81
|
+
memory,
|
|
82
|
+
)
|
|
83
|
+
if type(preparation) is not CampaignPortfolioOutcomePreparation:
|
|
84
|
+
raise TypeError(
|
|
85
|
+
"composite component returned a foreign preparation"
|
|
86
|
+
)
|
|
87
|
+
preparation.__post_init__()
|
|
88
|
+
staged.append((updater, preparation))
|
|
89
|
+
memory = preparation.updated_memory
|
|
90
|
+
except BaseException:
|
|
91
|
+
for updater, preparation in reversed(staged):
|
|
92
|
+
updater.abort_update(preparation)
|
|
93
|
+
raise
|
|
94
|
+
outer = CampaignPortfolioOutcomePreparation(
|
|
95
|
+
request_sha256=request.request_sha256,
|
|
96
|
+
generation=request.step.generation,
|
|
97
|
+
wave_request_sha256s=tuple(
|
|
98
|
+
value.selection_request.request_sha256 for value in waves
|
|
99
|
+
),
|
|
100
|
+
result_receipt_sha256s=tuple(
|
|
101
|
+
value.receipt.receipt_sha256 for value in results
|
|
102
|
+
),
|
|
103
|
+
prior_memory_sha256=typed_json_sha256(prior_memory),
|
|
104
|
+
updated_memory=memory,
|
|
105
|
+
evidence=_object(
|
|
106
|
+
{
|
|
107
|
+
"schema_version": 1,
|
|
108
|
+
"composition": "sequential_prepare_atomic_publish",
|
|
109
|
+
"component_preparations": [
|
|
110
|
+
value.to_record() for _updater, value in staged
|
|
111
|
+
],
|
|
112
|
+
"component_count": len(staged),
|
|
113
|
+
"provider_calls": 0,
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
)
|
|
117
|
+
if outer.preparation_sha256 in self._prepared:
|
|
118
|
+
for updater, preparation in reversed(staged):
|
|
119
|
+
updater.abort_update(preparation)
|
|
120
|
+
raise ValueError("composite outcome preparation is already pending")
|
|
121
|
+
self._prepared[outer.preparation_sha256] = (outer, tuple(staged))
|
|
122
|
+
return outer
|
|
123
|
+
|
|
124
|
+
def commit_update(self, preparation: CampaignPortfolioOutcomePreparation) -> None:
|
|
125
|
+
if type(preparation) is not CampaignPortfolioOutcomePreparation:
|
|
126
|
+
raise TypeError("preparation must be exact")
|
|
127
|
+
preparation.__post_init__()
|
|
128
|
+
pending = self._prepared.pop(preparation.preparation_sha256, None)
|
|
129
|
+
if pending is None or pending[0] != preparation:
|
|
130
|
+
raise ValueError("composite outcome preparation is foreign or not pending")
|
|
131
|
+
for updater, component in pending[1]:
|
|
132
|
+
updater.commit_update(component)
|
|
133
|
+
|
|
134
|
+
def abort_update(self, preparation: CampaignPortfolioOutcomePreparation) -> None:
|
|
135
|
+
if type(preparation) is not CampaignPortfolioOutcomePreparation:
|
|
136
|
+
raise TypeError("preparation must be exact")
|
|
137
|
+
preparation.__post_init__()
|
|
138
|
+
pending = self._prepared.pop(preparation.preparation_sha256, None)
|
|
139
|
+
if pending is None or pending[0] != preparation:
|
|
140
|
+
raise ValueError("composite outcome preparation is foreign or not pending")
|
|
141
|
+
for updater, component in reversed(pending[1]):
|
|
142
|
+
updater.abort_update(component)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
__all__ = ["CompositeCampaignPortfolioOutcomeUpdater"]
|