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,407 @@
|
|
|
1
|
+
"""Variation arms under measured credit: operators earn their offspring slots.
|
|
2
|
+
|
|
3
|
+
The classical crossover+mutate path becomes one arm among several. Arms --
|
|
4
|
+
rule-written or model-authored -- are chosen per offspring slot by UCB1 over
|
|
5
|
+
measured SURVIVAL (did the child outlive truncation against parents and
|
|
6
|
+
siblings?), with two guarantees that keep the mechanism honest: the
|
|
7
|
+
classical arm holds a floor slot every generation, so the comparator is
|
|
8
|
+
always inside the run; and credit is assigned at survival time, never at
|
|
9
|
+
proposal time, so an arm cannot look good by proposing loudly.
|
|
10
|
+
|
|
11
|
+
Authored arms construct through the bounded runtime, batched one process per
|
|
12
|
+
generation. Every authored child passes :func:`child_within_material` --
|
|
13
|
+
each value inherited from a parent or drawn from the (already restricted)
|
|
14
|
+
declared domain, same shape as the template -- or it is rejected, counted,
|
|
15
|
+
and its slot falls back to the classical arm. The authoring line holds: an
|
|
16
|
+
artifact reaches real evaluations only through slots it earned.
|
|
17
|
+
|
|
18
|
+
Retirement is preregistered in code, not judged post hoc: an arm with at
|
|
19
|
+
least four measured children and zero survivors, while the classical arm has
|
|
20
|
+
survivors, retires for the remainder of the run. One way, counted, recorded.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import math
|
|
26
|
+
import random
|
|
27
|
+
from dataclasses import dataclass, field
|
|
28
|
+
from typing import Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple
|
|
29
|
+
|
|
30
|
+
from agent_evolve.core.authored import AuthoredArtifact
|
|
31
|
+
from agent_evolve.policies.genetic import (
|
|
32
|
+
Locus,
|
|
33
|
+
crossover,
|
|
34
|
+
loci_of,
|
|
35
|
+
locus_domain,
|
|
36
|
+
mutate,
|
|
37
|
+
read_locus,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
"ArmCredit",
|
|
42
|
+
"CreditTable",
|
|
43
|
+
"VariationArm",
|
|
44
|
+
"OperatorPortfolio",
|
|
45
|
+
"child_within_material",
|
|
46
|
+
"segment_arm",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
Config = Dict[str, Any]
|
|
50
|
+
|
|
51
|
+
#: A rule arm's constructor: (parent_a, parent_b, candidate_model,
|
|
52
|
+
#: restriction, rng) -> child. Classical and rule arms run in-process; they
|
|
53
|
+
#: are trusted code shipped with the package.
|
|
54
|
+
RuleConstruct = Callable[[Config, Config, Any, Any, random.Random], Config]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class ArmCredit:
|
|
59
|
+
proposed: int = 0
|
|
60
|
+
measured: int = 0
|
|
61
|
+
survived: int = 0
|
|
62
|
+
rejected_out_of_domain: int = 0
|
|
63
|
+
runtime_failures: int = 0
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class CreditTable:
|
|
67
|
+
"""Per-arm outcomes, and the UCB1 view over them."""
|
|
68
|
+
|
|
69
|
+
def __init__(self) -> None:
|
|
70
|
+
self.arms: Dict[str, ArmCredit] = {}
|
|
71
|
+
|
|
72
|
+
def arm(self, name: str) -> ArmCredit:
|
|
73
|
+
return self.arms.setdefault(name, ArmCredit())
|
|
74
|
+
|
|
75
|
+
def total_measured(self) -> int:
|
|
76
|
+
return sum(credit.measured for credit in self.arms.values())
|
|
77
|
+
|
|
78
|
+
def ucb(self, name: str, *, c: float = 1.4) -> float:
|
|
79
|
+
credit = self.arm(name)
|
|
80
|
+
if credit.measured == 0:
|
|
81
|
+
return float("inf") # every arm gets its first hearing
|
|
82
|
+
rate = credit.survived / credit.measured
|
|
83
|
+
total = max(2, self.total_measured())
|
|
84
|
+
return rate + c * math.sqrt(math.log(total) / credit.measured)
|
|
85
|
+
|
|
86
|
+
def as_flat_counters(self) -> Dict[str, int]:
|
|
87
|
+
out: Dict[str, int] = {}
|
|
88
|
+
for name, credit in sorted(self.arms.items()):
|
|
89
|
+
for fieldname in ("proposed", "measured", "survived",
|
|
90
|
+
"rejected_out_of_domain", "runtime_failures"):
|
|
91
|
+
out[f"{name}__{fieldname}"] = getattr(credit, fieldname)
|
|
92
|
+
return out
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass(frozen=True)
|
|
96
|
+
class VariationArm:
|
|
97
|
+
"""One way to construct a child. ``artifact`` only for authored arms."""
|
|
98
|
+
|
|
99
|
+
name: str
|
|
100
|
+
kind: str # "classical" | "rule" | "authored"
|
|
101
|
+
construct: Optional[RuleConstruct] = None # in-process arms only
|
|
102
|
+
artifact: Optional[AuthoredArtifact] = None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def classical_arm() -> VariationArm:
|
|
106
|
+
"""Uniform-mask crossover + rate-1/n mutation: the loop's own operators.
|
|
107
|
+
|
|
108
|
+
Note one composition limit, stated rather than hidden: under a portfolio
|
|
109
|
+
the chooser still picks the parents, but the classical arm draws its own
|
|
110
|
+
mask instead of the chooser's -- mask-level guidance and arm-level credit
|
|
111
|
+
do not compose yet.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
def construct(parent_a: Config, parent_b: Config, candidate_model: Any,
|
|
115
|
+
restriction: Any, rng: random.Random) -> Config:
|
|
116
|
+
child = crossover(parent_a, parent_b, rng=rng)
|
|
117
|
+
return mutate(child, candidate_model, restriction=restriction, rng=rng)
|
|
118
|
+
|
|
119
|
+
return VariationArm(name="classical", kind="classical", construct=construct)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def segment_arm() -> VariationArm:
|
|
123
|
+
"""Contiguous-block recombination: the shipped rule comparator.
|
|
124
|
+
|
|
125
|
+
Uniform masks shred building blocks that live in adjacent loci; a
|
|
126
|
+
contiguous cut preserves them. This is the classic alternative any
|
|
127
|
+
authored operator should at minimum out-survive before its story is
|
|
128
|
+
believed.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def construct(parent_a: Config, parent_b: Config, candidate_model: Any,
|
|
132
|
+
restriction: Any, rng: random.Random) -> Config:
|
|
133
|
+
loci = loci_of(parent_a)
|
|
134
|
+
n = len(loci)
|
|
135
|
+
start = rng.randrange(n)
|
|
136
|
+
length = 1 + rng.randrange(max(1, n // 2))
|
|
137
|
+
mask = tuple(start <= i < start + length for i in range(n))
|
|
138
|
+
child = crossover(parent_a, parent_b, mask=mask)
|
|
139
|
+
return mutate(child, candidate_model, restriction=restriction, rng=rng)
|
|
140
|
+
|
|
141
|
+
return VariationArm(name="segment", kind="rule", construct=construct)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def child_within_material(
|
|
145
|
+
child: Any,
|
|
146
|
+
parent_a: Config,
|
|
147
|
+
parent_b: Config,
|
|
148
|
+
domains: Mapping[str, Tuple[Any, ...]],
|
|
149
|
+
) -> bool:
|
|
150
|
+
"""May this authored child enter the run at all?
|
|
151
|
+
|
|
152
|
+
Shape must equal the parents' shape, and every locus value must be
|
|
153
|
+
inherited from a parent at that locus or drawn from the provided
|
|
154
|
+
(already restricted) declared domain. This is the widened authoring
|
|
155
|
+
line: an operator may construct any candidate the schema and its parents
|
|
156
|
+
can express, and nothing else.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
if not isinstance(child, dict):
|
|
160
|
+
return False
|
|
161
|
+
if set(child.keys()) != set(parent_a.keys()):
|
|
162
|
+
return False
|
|
163
|
+
try:
|
|
164
|
+
child_loci = loci_of(child)
|
|
165
|
+
except Exception:
|
|
166
|
+
return False
|
|
167
|
+
if child_loci != loci_of(parent_a):
|
|
168
|
+
return False
|
|
169
|
+
for locus in child_loci:
|
|
170
|
+
value = read_locus(child, locus)
|
|
171
|
+
if value == read_locus(parent_a, locus):
|
|
172
|
+
continue
|
|
173
|
+
if value == read_locus(parent_b, locus):
|
|
174
|
+
continue
|
|
175
|
+
domain = domains.get(str(locus), ())
|
|
176
|
+
if domain and value in domain:
|
|
177
|
+
continue
|
|
178
|
+
return False
|
|
179
|
+
return True
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class PortfolioTelemetry:
|
|
183
|
+
"""Portfolio-level counters; per-arm credit is appended at harvest."""
|
|
184
|
+
|
|
185
|
+
__slots__ = ("generations", "constructed", "authored_children",
|
|
186
|
+
"rejected_out_of_domain", "runtime_failures", "retired")
|
|
187
|
+
|
|
188
|
+
def __init__(self) -> None:
|
|
189
|
+
self.generations = 0
|
|
190
|
+
self.constructed = 0
|
|
191
|
+
self.authored_children = 0
|
|
192
|
+
self.rejected_out_of_domain = 0
|
|
193
|
+
self.runtime_failures = 0
|
|
194
|
+
self.retired = 0
|
|
195
|
+
|
|
196
|
+
def as_dict(self) -> dict[str, int]:
|
|
197
|
+
return {name: getattr(self, name) for name in self.__slots__}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class OperatorPortfolio:
|
|
201
|
+
"""Chooses arms, constructs a generation, and assigns survival credit."""
|
|
202
|
+
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
arms: Sequence[VariationArm],
|
|
206
|
+
*,
|
|
207
|
+
runtime: Any = None,
|
|
208
|
+
max_authored_fraction: float = 0.5,
|
|
209
|
+
) -> None:
|
|
210
|
+
names = [arm.name for arm in arms]
|
|
211
|
+
if len(names) != len(set(names)):
|
|
212
|
+
raise ValueError(f"arm names must be unique, got {names}")
|
|
213
|
+
if not any(arm.kind == "classical" for arm in arms):
|
|
214
|
+
raise ValueError("the portfolio needs the classical arm: it is "
|
|
215
|
+
"the comparator every other arm is read against")
|
|
216
|
+
if any(arm.kind == "authored" for arm in arms) and runtime is None:
|
|
217
|
+
raise ValueError("authored arms need a runtime")
|
|
218
|
+
self.arms = tuple(arms)
|
|
219
|
+
self.runtime = runtime
|
|
220
|
+
self.max_authored_fraction = float(max_authored_fraction)
|
|
221
|
+
self.credit = CreditTable()
|
|
222
|
+
self.retired: set[str] = set()
|
|
223
|
+
self.counters = PortfolioTelemetry()
|
|
224
|
+
self.mechanism = "operator_portfolio"
|
|
225
|
+
self.authored_by = (
|
|
226
|
+
"llm" if any(arm.kind == "authored" for arm in self.arms) else "rule"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Harvest sees one flat counter map: portfolio totals + per-arm credit.
|
|
230
|
+
outer = self
|
|
231
|
+
|
|
232
|
+
class _Merged:
|
|
233
|
+
def as_dict(self) -> dict[str, int]:
|
|
234
|
+
merged = outer.counters.as_dict()
|
|
235
|
+
merged.update(outer.credit.as_flat_counters())
|
|
236
|
+
return merged
|
|
237
|
+
|
|
238
|
+
self.telemetry = _Merged()
|
|
239
|
+
|
|
240
|
+
# -- choosing -----------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
def active_arms(self) -> Tuple[VariationArm, ...]:
|
|
243
|
+
return tuple(arm for arm in self.arms if arm.name not in self.retired)
|
|
244
|
+
|
|
245
|
+
def assign(self, count: int, rng: random.Random) -> List[VariationArm]:
|
|
246
|
+
"""One arm per offspring slot; slot 0 is always classical.
|
|
247
|
+
|
|
248
|
+
Unmeasured arms rank at +inf so every arm gets its first hearing;
|
|
249
|
+
ties break toward the FEWEST proposals so far (including this
|
|
250
|
+
generation's), so first hearings rotate instead of the
|
|
251
|
+
alphabetically-first arm swallowing every slot. Deterministic; *rng*
|
|
252
|
+
is reserved for future stochastic policies.
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
del rng
|
|
256
|
+
active = self.active_arms()
|
|
257
|
+
classical = next(arm for arm in active if arm.kind == "classical")
|
|
258
|
+
out: List[VariationArm] = []
|
|
259
|
+
tally: Dict[str, int] = {}
|
|
260
|
+
authored_cap = max(0, int(self.max_authored_fraction * count + 1e-9))
|
|
261
|
+
authored_given = 0
|
|
262
|
+
|
|
263
|
+
def take(arm: VariationArm) -> None:
|
|
264
|
+
tally[arm.name] = tally.get(arm.name, 0) + 1
|
|
265
|
+
out.append(arm)
|
|
266
|
+
|
|
267
|
+
for slot in range(count):
|
|
268
|
+
if slot == 0:
|
|
269
|
+
take(classical)
|
|
270
|
+
continue
|
|
271
|
+
ranked = sorted(
|
|
272
|
+
active,
|
|
273
|
+
key=lambda arm: (
|
|
274
|
+
-self.credit.ucb(arm.name),
|
|
275
|
+
self.credit.arm(arm.name).proposed + tally.get(arm.name, 0),
|
|
276
|
+
arm.name,
|
|
277
|
+
),
|
|
278
|
+
)
|
|
279
|
+
pick = ranked[0]
|
|
280
|
+
if pick.kind == "authored" and authored_given >= authored_cap:
|
|
281
|
+
pick = next((arm for arm in ranked
|
|
282
|
+
if arm.kind != "authored"), classical)
|
|
283
|
+
if pick.kind == "authored":
|
|
284
|
+
authored_given += 1
|
|
285
|
+
take(pick)
|
|
286
|
+
return out
|
|
287
|
+
|
|
288
|
+
# -- constructing -------------------------------------------------------
|
|
289
|
+
|
|
290
|
+
def construct_generation(
|
|
291
|
+
self,
|
|
292
|
+
parent_pairs: Sequence[Tuple[Config, Config]],
|
|
293
|
+
candidate_model: Any,
|
|
294
|
+
restriction: Any,
|
|
295
|
+
rng: random.Random,
|
|
296
|
+
*,
|
|
297
|
+
generation: int,
|
|
298
|
+
) -> Tuple[List[Config], List[str]]:
|
|
299
|
+
"""Children for the generation, plus the arm that made each."""
|
|
300
|
+
|
|
301
|
+
self.counters.generations += 1
|
|
302
|
+
assignments = self.assign(len(parent_pairs), rng)
|
|
303
|
+
classical = next(arm for arm in self.arms if arm.kind == "classical")
|
|
304
|
+
|
|
305
|
+
kids: List[Optional[Config]] = [None] * len(parent_pairs)
|
|
306
|
+
origins: List[str] = [""] * len(parent_pairs)
|
|
307
|
+
authored_slots: Dict[str, List[int]] = {}
|
|
308
|
+
for slot, (arm, (parent_a, parent_b)) in enumerate(
|
|
309
|
+
zip(assignments, parent_pairs)):
|
|
310
|
+
if arm.kind == "authored":
|
|
311
|
+
authored_slots.setdefault(arm.name, []).append(slot)
|
|
312
|
+
continue
|
|
313
|
+
kids[slot] = arm.construct(parent_a, parent_b, candidate_model,
|
|
314
|
+
restriction, rng)
|
|
315
|
+
origins[slot] = arm.name
|
|
316
|
+
self.credit.arm(arm.name).proposed += 1
|
|
317
|
+
|
|
318
|
+
for name, slots in authored_slots.items():
|
|
319
|
+
arm = next(a for a in self.arms if a.name == name)
|
|
320
|
+
self._construct_authored(
|
|
321
|
+
arm, slots, parent_pairs, candidate_model, restriction,
|
|
322
|
+
rng, kids, origins, classical, generation)
|
|
323
|
+
|
|
324
|
+
self.counters.constructed += len(kids)
|
|
325
|
+
return [kid for kid in kids if kid is not None], origins
|
|
326
|
+
|
|
327
|
+
def _construct_authored(
|
|
328
|
+
self, arm, slots, parent_pairs, candidate_model, restriction,
|
|
329
|
+
rng, kids, origins, classical, generation,
|
|
330
|
+
) -> None:
|
|
331
|
+
template = parent_pairs[slots[0]][0]
|
|
332
|
+
loci = loci_of(template)
|
|
333
|
+
loci_names = [str(locus) for locus in loci]
|
|
334
|
+
domains = {
|
|
335
|
+
str(locus): list(locus_domain(candidate_model, locus,
|
|
336
|
+
restriction=restriction))
|
|
337
|
+
for locus in loci
|
|
338
|
+
}
|
|
339
|
+
calls = []
|
|
340
|
+
for slot in slots:
|
|
341
|
+
parent_a, parent_b = parent_pairs[slot]
|
|
342
|
+
calls.append([dict(parent_a), dict(parent_b), loci_names,
|
|
343
|
+
domains, generation * 1000 + slot])
|
|
344
|
+
self.credit.arm(arm.name).proposed += 1
|
|
345
|
+
|
|
346
|
+
outcome = self.runtime.call(arm.artifact, calls)
|
|
347
|
+
results: Sequence[Any]
|
|
348
|
+
if outcome.ok:
|
|
349
|
+
results = outcome.results
|
|
350
|
+
else:
|
|
351
|
+
self.counters.runtime_failures += len(slots)
|
|
352
|
+
self.credit.arm(arm.name).runtime_failures += len(slots)
|
|
353
|
+
results = [None] * len(slots)
|
|
354
|
+
|
|
355
|
+
domain_tuples = {name: tuple(values) for name, values in domains.items()}
|
|
356
|
+
for slot, child in zip(slots, results):
|
|
357
|
+
parent_a, parent_b = parent_pairs[slot]
|
|
358
|
+
if child is not None and child_within_material(
|
|
359
|
+
child, parent_a, parent_b, domain_tuples):
|
|
360
|
+
kids[slot] = dict(child)
|
|
361
|
+
origins[slot] = arm.name
|
|
362
|
+
self.counters.authored_children += 1
|
|
363
|
+
else:
|
|
364
|
+
if child is not None:
|
|
365
|
+
self.counters.rejected_out_of_domain += 1
|
|
366
|
+
self.credit.arm(arm.name).rejected_out_of_domain += 1
|
|
367
|
+
kids[slot] = classical.construct(
|
|
368
|
+
parent_a, parent_b, candidate_model, restriction, rng)
|
|
369
|
+
origins[slot] = f"{classical.name}(fallback)"
|
|
370
|
+
self.credit.arm(classical.name).proposed += 1
|
|
371
|
+
|
|
372
|
+
# -- credit and retirement ---------------------------------------------
|
|
373
|
+
|
|
374
|
+
def record_measured(self, origin: str, *, survived: bool) -> None:
|
|
375
|
+
name = origin.split("(")[0]
|
|
376
|
+
credit = self.credit.arm(name)
|
|
377
|
+
credit.measured += 1
|
|
378
|
+
if survived:
|
|
379
|
+
credit.survived += 1
|
|
380
|
+
|
|
381
|
+
def review(self) -> Tuple[str, ...]:
|
|
382
|
+
"""The preregistered retirement rule; one-way, counted."""
|
|
383
|
+
|
|
384
|
+
classical_survived = any(
|
|
385
|
+
self.credit.arm(arm.name).survived > 0
|
|
386
|
+
for arm in self.arms if arm.kind == "classical"
|
|
387
|
+
)
|
|
388
|
+
newly = []
|
|
389
|
+
for arm in self.active_arms():
|
|
390
|
+
if arm.kind == "classical":
|
|
391
|
+
continue
|
|
392
|
+
credit = self.credit.arm(arm.name)
|
|
393
|
+
if (credit.measured >= 4 and credit.survived == 0
|
|
394
|
+
and classical_survived):
|
|
395
|
+
self.retired.add(arm.name)
|
|
396
|
+
self.counters.retired += 1
|
|
397
|
+
newly.append(arm.name)
|
|
398
|
+
return tuple(newly)
|
|
399
|
+
|
|
400
|
+
def summary(self) -> Dict[str, Any]:
|
|
401
|
+
return {
|
|
402
|
+
"arms": {
|
|
403
|
+
name: [credit.proposed, credit.measured, credit.survived]
|
|
404
|
+
for name, credit in sorted(self.credit.arms.items())
|
|
405
|
+
},
|
|
406
|
+
"retired": sorted(self.retired),
|
|
407
|
+
}
|