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,368 @@
|
|
|
1
|
+
"""Outcome-blind structural reservations inside a model-proposed slate.
|
|
2
|
+
|
|
3
|
+
The model normally chooses a K-member proposal from a larger finite action
|
|
4
|
+
contract. Complete K8 outcome panels show that this truncation can remove the
|
|
5
|
+
useful action before the evaluator allocator ever sees it. This policy
|
|
6
|
+
reserves two *proposal* positions for archive novelty and structural coverage.
|
|
7
|
+
The reservations do not force an evaluator slot and are not quality rankings;
|
|
8
|
+
the downstream allocator retains authority over the evaluated subset.
|
|
9
|
+
|
|
10
|
+
All inputs are sealed before provider dispatch. The policy reads no objective
|
|
11
|
+
value, evaluator outcome, workload identifier, model profile, action name, or
|
|
12
|
+
free-form memory text.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import hashlib
|
|
18
|
+
import json
|
|
19
|
+
import math
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from enum import Enum
|
|
22
|
+
|
|
23
|
+
from agent_evolve.domain.patch import require_sha256
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
POLICY_ID = "structural_proposal_support_reservation"
|
|
27
|
+
POLICY_VERSION = 1
|
|
28
|
+
POLICY_DEFINITION_SHA256 = hashlib.sha256(
|
|
29
|
+
b"agent-evolve:structural-proposal-support-reservation:v1;"
|
|
30
|
+
b"reservation-count=2;roles=archive-novelty,structural-coverage;"
|
|
31
|
+
b"first=lexicographic(novelty,coverage);"
|
|
32
|
+
b"second=prefer-distinct-family-and-locus-then-family-then-locus;"
|
|
33
|
+
b"proposal-reservation-only=true;evaluator-slot-authority=false;"
|
|
34
|
+
b"objective-values=false;outcomes=false;workload-and-model-fields=false"
|
|
35
|
+
).hexdigest()
|
|
36
|
+
|
|
37
|
+
_DECISION_DOMAIN = b"agent-evolve:proposal-support-reservation:decision:v1\x00"
|
|
38
|
+
_RESERVATION_COUNT = 2
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _canonical_json(value: object) -> bytes:
|
|
42
|
+
return json.dumps(
|
|
43
|
+
value,
|
|
44
|
+
allow_nan=False,
|
|
45
|
+
ensure_ascii=True,
|
|
46
|
+
separators=(",", ":"),
|
|
47
|
+
sort_keys=True,
|
|
48
|
+
).encode("ascii", errors="strict")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _finite_unit(value: float, *, name: str) -> None:
|
|
52
|
+
if type(value) is not float or not math.isfinite(value):
|
|
53
|
+
raise TypeError(f"{name} must be a finite canonical float")
|
|
54
|
+
if not 0.0 <= value <= 1.0:
|
|
55
|
+
raise ValueError(f"{name} must lie in [0, 1]")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True, slots=True)
|
|
59
|
+
class ProposalSupportCandidate:
|
|
60
|
+
"""One pre-provider structural row from the common candidate universe."""
|
|
61
|
+
|
|
62
|
+
option_id: str
|
|
63
|
+
option_identity_sha256: str
|
|
64
|
+
family: str
|
|
65
|
+
locus_key: str
|
|
66
|
+
phenotype_identity_sha256: str
|
|
67
|
+
frozen_archive_snapshot_sha256: str
|
|
68
|
+
structural_evidence_receipt_sha256: str
|
|
69
|
+
archive_novelty_score: float
|
|
70
|
+
structural_coverage_score: float
|
|
71
|
+
|
|
72
|
+
def __post_init__(self) -> None:
|
|
73
|
+
for name in ("option_id", "family", "locus_key"):
|
|
74
|
+
value = getattr(self, name)
|
|
75
|
+
if type(value) is not str or not value:
|
|
76
|
+
raise ValueError(f"{name} must be a non-empty string")
|
|
77
|
+
for name in (
|
|
78
|
+
"option_identity_sha256",
|
|
79
|
+
"phenotype_identity_sha256",
|
|
80
|
+
"frozen_archive_snapshot_sha256",
|
|
81
|
+
"structural_evidence_receipt_sha256",
|
|
82
|
+
):
|
|
83
|
+
require_sha256(getattr(self, name), name)
|
|
84
|
+
_finite_unit(self.archive_novelty_score, name="archive_novelty_score")
|
|
85
|
+
_finite_unit(
|
|
86
|
+
self.structural_coverage_score,
|
|
87
|
+
name="structural_coverage_score",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def to_record(self) -> dict[str, object]:
|
|
91
|
+
self.__post_init__()
|
|
92
|
+
return {
|
|
93
|
+
"option_id": self.option_id,
|
|
94
|
+
"option_identity_sha256": self.option_identity_sha256,
|
|
95
|
+
"family": self.family,
|
|
96
|
+
"locus_key": self.locus_key,
|
|
97
|
+
"phenotype_identity_sha256": self.phenotype_identity_sha256,
|
|
98
|
+
"frozen_archive_snapshot_sha256": (
|
|
99
|
+
self.frozen_archive_snapshot_sha256
|
|
100
|
+
),
|
|
101
|
+
"structural_evidence_receipt_sha256": (
|
|
102
|
+
self.structural_evidence_receipt_sha256
|
|
103
|
+
),
|
|
104
|
+
"archive_novelty_score_hex": self.archive_novelty_score.hex(),
|
|
105
|
+
"structural_coverage_score_hex": (
|
|
106
|
+
self.structural_coverage_score.hex()
|
|
107
|
+
),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ProposalSupportRole(str, Enum):
|
|
112
|
+
"""Why one action is protected in the proposal rather than the evaluator."""
|
|
113
|
+
|
|
114
|
+
ARCHIVE_NOVELTY = "archive_novelty"
|
|
115
|
+
STRUCTURAL_COVERAGE = "structural_coverage"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@dataclass(frozen=True, slots=True)
|
|
119
|
+
class ProposalSupportReservation:
|
|
120
|
+
"""One selected proposal-only reservation and its exact structural row."""
|
|
121
|
+
|
|
122
|
+
role: ProposalSupportRole
|
|
123
|
+
candidate: ProposalSupportCandidate
|
|
124
|
+
|
|
125
|
+
def __post_init__(self) -> None:
|
|
126
|
+
if type(self.role) is not ProposalSupportRole:
|
|
127
|
+
raise TypeError("role must be an exact ProposalSupportRole")
|
|
128
|
+
if type(self.candidate) is not ProposalSupportCandidate:
|
|
129
|
+
raise TypeError("candidate must be an exact ProposalSupportCandidate")
|
|
130
|
+
self.candidate.__post_init__()
|
|
131
|
+
|
|
132
|
+
def to_record(self) -> dict[str, object]:
|
|
133
|
+
self.__post_init__()
|
|
134
|
+
return {"role": self.role.value, "candidate": self.candidate.to_record()}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _select_reservations(
|
|
138
|
+
candidates: tuple[ProposalSupportCandidate, ...],
|
|
139
|
+
) -> tuple[ProposalSupportReservation, ProposalSupportReservation]:
|
|
140
|
+
first = min(
|
|
141
|
+
candidates,
|
|
142
|
+
key=lambda value: (
|
|
143
|
+
-value.archive_novelty_score,
|
|
144
|
+
-value.structural_coverage_score,
|
|
145
|
+
value.option_id,
|
|
146
|
+
),
|
|
147
|
+
)
|
|
148
|
+
remaining = tuple(value for value in candidates if value != first)
|
|
149
|
+
preference_pools = (
|
|
150
|
+
tuple(
|
|
151
|
+
value
|
|
152
|
+
for value in remaining
|
|
153
|
+
if value.family != first.family and value.locus_key != first.locus_key
|
|
154
|
+
),
|
|
155
|
+
tuple(value for value in remaining if value.family != first.family),
|
|
156
|
+
tuple(value for value in remaining if value.locus_key != first.locus_key),
|
|
157
|
+
remaining,
|
|
158
|
+
)
|
|
159
|
+
second_pool = next(value for value in preference_pools if value)
|
|
160
|
+
second = min(
|
|
161
|
+
second_pool,
|
|
162
|
+
key=lambda value: (
|
|
163
|
+
-value.structural_coverage_score,
|
|
164
|
+
-value.archive_novelty_score,
|
|
165
|
+
value.option_id,
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
return (
|
|
169
|
+
ProposalSupportReservation(ProposalSupportRole.ARCHIVE_NOVELTY, first),
|
|
170
|
+
ProposalSupportReservation(ProposalSupportRole.STRUCTURAL_COVERAGE, second),
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
175
|
+
class ProposalSupportDecision:
|
|
176
|
+
"""Replayable proposal-reservation decision over one exact common pool."""
|
|
177
|
+
|
|
178
|
+
request_sha256: str
|
|
179
|
+
common_candidate_pool_decision_sha256: str
|
|
180
|
+
model_selection_size: int
|
|
181
|
+
candidates: tuple[ProposalSupportCandidate, ...]
|
|
182
|
+
reservations: tuple[ProposalSupportReservation, ...]
|
|
183
|
+
policy_id: str = POLICY_ID
|
|
184
|
+
policy_version: int = POLICY_VERSION
|
|
185
|
+
policy_definition_sha256: str = POLICY_DEFINITION_SHA256
|
|
186
|
+
decision_sha256: str = field(init=False, default="")
|
|
187
|
+
|
|
188
|
+
def __post_init__(self) -> None:
|
|
189
|
+
require_sha256(self.request_sha256, "request_sha256")
|
|
190
|
+
require_sha256(
|
|
191
|
+
self.common_candidate_pool_decision_sha256,
|
|
192
|
+
"common_candidate_pool_decision_sha256",
|
|
193
|
+
)
|
|
194
|
+
require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
|
|
195
|
+
if (
|
|
196
|
+
self.policy_id != POLICY_ID
|
|
197
|
+
or self.policy_version != POLICY_VERSION
|
|
198
|
+
or self.policy_definition_sha256 != POLICY_DEFINITION_SHA256
|
|
199
|
+
):
|
|
200
|
+
raise ValueError("proposal-support policy identity drifted")
|
|
201
|
+
if type(self.model_selection_size) is not int or self.model_selection_size < 4:
|
|
202
|
+
raise ValueError("model_selection_size must be an exact integer >= 4")
|
|
203
|
+
if type(self.candidates) is not tuple or len(self.candidates) < (
|
|
204
|
+
_RESERVATION_COUNT
|
|
205
|
+
):
|
|
206
|
+
raise ValueError("candidates must contain at least two exact rows")
|
|
207
|
+
if any(type(value) is not ProposalSupportCandidate for value in self.candidates):
|
|
208
|
+
raise TypeError("candidates must contain exact structural rows")
|
|
209
|
+
for value in self.candidates:
|
|
210
|
+
value.__post_init__()
|
|
211
|
+
if self.candidates != tuple(
|
|
212
|
+
sorted(self.candidates, key=lambda value: value.option_id)
|
|
213
|
+
):
|
|
214
|
+
raise ValueError("candidates must preserve canonical option order")
|
|
215
|
+
if len({value.option_id for value in self.candidates}) != len(self.candidates):
|
|
216
|
+
raise ValueError("candidates cannot repeat an option")
|
|
217
|
+
if len(self.candidates) < self.model_selection_size:
|
|
218
|
+
raise ValueError("model selection exceeds the candidate universe")
|
|
219
|
+
snapshots = {
|
|
220
|
+
value.frozen_archive_snapshot_sha256 for value in self.candidates
|
|
221
|
+
}
|
|
222
|
+
if len(snapshots) != 1:
|
|
223
|
+
raise ValueError("proposal-support candidates must share one archive cutoff")
|
|
224
|
+
if type(self.reservations) is not tuple or len(self.reservations) != (
|
|
225
|
+
_RESERVATION_COUNT
|
|
226
|
+
):
|
|
227
|
+
raise ValueError("reservations must contain the exact two roles")
|
|
228
|
+
if any(
|
|
229
|
+
type(value) is not ProposalSupportReservation
|
|
230
|
+
for value in self.reservations
|
|
231
|
+
):
|
|
232
|
+
raise TypeError("reservations must contain exact reservation rows")
|
|
233
|
+
for value in self.reservations:
|
|
234
|
+
value.__post_init__()
|
|
235
|
+
if tuple(value.role for value in self.reservations) != tuple(
|
|
236
|
+
ProposalSupportRole
|
|
237
|
+
):
|
|
238
|
+
raise ValueError("reservations must preserve the closed role order")
|
|
239
|
+
if len({value.candidate.option_id for value in self.reservations}) != (
|
|
240
|
+
_RESERVATION_COUNT
|
|
241
|
+
):
|
|
242
|
+
raise ValueError("proposal-support reservations must be distinct")
|
|
243
|
+
if self.reservations != _select_reservations(self.candidates):
|
|
244
|
+
raise ValueError("reservations differ from the structural policy")
|
|
245
|
+
computed = hashlib.sha256(
|
|
246
|
+
_DECISION_DOMAIN + _canonical_json(self._unsigned_record())
|
|
247
|
+
).hexdigest()
|
|
248
|
+
if self.decision_sha256 not in ("", computed):
|
|
249
|
+
raise ValueError("decision_sha256 does not authenticate the decision")
|
|
250
|
+
object.__setattr__(self, "decision_sha256", computed)
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def required_option_ids(self) -> tuple[str, ...]:
|
|
254
|
+
self.__post_init__()
|
|
255
|
+
return tuple(
|
|
256
|
+
sorted(value.candidate.option_id for value in self.reservations)
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def membership_constraint_effective(self) -> bool:
|
|
261
|
+
self.__post_init__()
|
|
262
|
+
return len(self.candidates) > self.model_selection_size
|
|
263
|
+
|
|
264
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
265
|
+
return {
|
|
266
|
+
"schema_version": 1,
|
|
267
|
+
"request_sha256": self.request_sha256,
|
|
268
|
+
"common_candidate_pool_decision_sha256": (
|
|
269
|
+
self.common_candidate_pool_decision_sha256
|
|
270
|
+
),
|
|
271
|
+
"model_selection_size": self.model_selection_size,
|
|
272
|
+
"candidates": [value.to_record() for value in self.candidates],
|
|
273
|
+
"reservations": [value.to_record() for value in self.reservations],
|
|
274
|
+
"required_option_ids": [
|
|
275
|
+
value.candidate.option_id for value in self.reservations
|
|
276
|
+
],
|
|
277
|
+
"policy": {
|
|
278
|
+
"policy_id": self.policy_id,
|
|
279
|
+
"policy_version": self.policy_version,
|
|
280
|
+
"definition_sha256": self.policy_definition_sha256,
|
|
281
|
+
},
|
|
282
|
+
"evaluator_slot_authority": False,
|
|
283
|
+
"objective_or_outcome_values_consulted": False,
|
|
284
|
+
"workload_or_model_fields_consulted": False,
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
def to_record(self) -> dict[str, object]:
|
|
288
|
+
self.__post_init__()
|
|
289
|
+
return {**self._unsigned_record(), "decision_sha256": self.decision_sha256}
|
|
290
|
+
|
|
291
|
+
def to_prompt_record(self) -> dict[str, object]:
|
|
292
|
+
self.__post_init__()
|
|
293
|
+
return {
|
|
294
|
+
"schema_version": 1,
|
|
295
|
+
"decision_sha256": self.decision_sha256,
|
|
296
|
+
"required_option_ids": list(self.required_option_ids),
|
|
297
|
+
"reservation_roles": [value.role.value for value in self.reservations],
|
|
298
|
+
"reservations_are_quality_rankings": False,
|
|
299
|
+
"reservations_force_evaluator_slots": False,
|
|
300
|
+
"model_may_rank_reserved_options_anywhere": True,
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
def __eq__(self, other: object) -> bool:
|
|
304
|
+
return (
|
|
305
|
+
type(other) is ProposalSupportDecision
|
|
306
|
+
and self.decision_sha256 == other.decision_sha256
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
__hash__ = None
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
@dataclass(frozen=True, slots=True)
|
|
313
|
+
class StructuralProposalSupportPolicy:
|
|
314
|
+
"""Reserve two structurally complementary candidates in the model slate."""
|
|
315
|
+
|
|
316
|
+
policy_id: str = POLICY_ID
|
|
317
|
+
policy_version: int = POLICY_VERSION
|
|
318
|
+
definition_sha256: str = POLICY_DEFINITION_SHA256
|
|
319
|
+
|
|
320
|
+
def __post_init__(self) -> None:
|
|
321
|
+
if (
|
|
322
|
+
self.policy_id != POLICY_ID
|
|
323
|
+
or self.policy_version != POLICY_VERSION
|
|
324
|
+
or self.definition_sha256 != POLICY_DEFINITION_SHA256
|
|
325
|
+
):
|
|
326
|
+
raise ValueError("proposal-support policy identity drifted")
|
|
327
|
+
|
|
328
|
+
def select(
|
|
329
|
+
self,
|
|
330
|
+
*,
|
|
331
|
+
request_sha256: str,
|
|
332
|
+
common_candidate_pool_decision_sha256: str,
|
|
333
|
+
model_selection_size: int,
|
|
334
|
+
candidates: tuple[ProposalSupportCandidate, ...],
|
|
335
|
+
) -> ProposalSupportDecision:
|
|
336
|
+
self.__post_init__()
|
|
337
|
+
canonical = tuple(sorted(candidates, key=lambda value: value.option_id))
|
|
338
|
+
return ProposalSupportDecision(
|
|
339
|
+
request_sha256=request_sha256,
|
|
340
|
+
common_candidate_pool_decision_sha256=(
|
|
341
|
+
common_candidate_pool_decision_sha256
|
|
342
|
+
),
|
|
343
|
+
model_selection_size=model_selection_size,
|
|
344
|
+
candidates=canonical,
|
|
345
|
+
reservations=_select_reservations(canonical),
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def to_record(self) -> dict[str, object]:
|
|
349
|
+
self.__post_init__()
|
|
350
|
+
return {
|
|
351
|
+
"policy_id": self.policy_id,
|
|
352
|
+
"policy_version": self.policy_version,
|
|
353
|
+
"definition_sha256": self.definition_sha256,
|
|
354
|
+
"reservation_count": _RESERVATION_COUNT,
|
|
355
|
+
"evaluator_slot_authority": False,
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
__all__ = [
|
|
360
|
+
"POLICY_DEFINITION_SHA256",
|
|
361
|
+
"POLICY_ID",
|
|
362
|
+
"POLICY_VERSION",
|
|
363
|
+
"ProposalSupportCandidate",
|
|
364
|
+
"ProposalSupportDecision",
|
|
365
|
+
"ProposalSupportReservation",
|
|
366
|
+
"ProposalSupportRole",
|
|
367
|
+
"StructuralProposalSupportPolicy",
|
|
368
|
+
]
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"""Outcome-blind, replayable random portfolios over sealed finite options.
|
|
2
|
+
|
|
3
|
+
The policy is a reusable scientific control for ranked portfolio evolution. It
|
|
4
|
+
uses only the request identity, option families, and exact parent-relative
|
|
5
|
+
patch paths. It never reads objective values, option prose, card payloads, or
|
|
6
|
+
previous outcomes. A task-keyed deterministic shuffle plus bounded
|
|
7
|
+
backtracking finds a portfolio whose member patches are pairwise disjoint and
|
|
8
|
+
whose family count satisfies the request contract.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import hashlib
|
|
14
|
+
import json
|
|
15
|
+
import random
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from decimal import Decimal
|
|
18
|
+
|
|
19
|
+
from agent_evolve.domain.ids import CandidateId
|
|
20
|
+
from agent_evolve.domain.patch import ArrayIndex, JsonPath, ObjectKey, require_sha256
|
|
21
|
+
from agent_evolve.policies.variation.typed_patch import derive_patch
|
|
22
|
+
from agent_evolve.ports.agentic_generator import (
|
|
23
|
+
AgenticCallTelemetry,
|
|
24
|
+
MetricEffectDirection,
|
|
25
|
+
MetricEffectPrediction,
|
|
26
|
+
)
|
|
27
|
+
from agent_evolve.ports.portfolio_selection import (
|
|
28
|
+
PortfolioMemberDraft,
|
|
29
|
+
PortfolioSelectionRequest,
|
|
30
|
+
PortfolioSelectionResult,
|
|
31
|
+
resolve_ranked_portfolio_decision,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
POLICY_ID = "deterministic_random_feasible_portfolio"
|
|
36
|
+
POLICY_VERSION = 1
|
|
37
|
+
_POLICY_DEFINITION = {
|
|
38
|
+
"schema_id": "agent_evolve_random_feasible_portfolio_v1",
|
|
39
|
+
"entropy": "sha256(base_seed, call_id, finite_contract_identity_sha256)",
|
|
40
|
+
"ordering": "python_random_shuffle_then_bounded_depth_first_search",
|
|
41
|
+
"admitted_option_fields": ["family", "child_configuration"],
|
|
42
|
+
"admitted_request_fields": [
|
|
43
|
+
"portfolio_size",
|
|
44
|
+
"min_distinct_families",
|
|
45
|
+
"required_metric_ids",
|
|
46
|
+
"require_supporting_cards",
|
|
47
|
+
"card_keys",
|
|
48
|
+
"call_id",
|
|
49
|
+
"finite_contract_identity_sha256",
|
|
50
|
+
],
|
|
51
|
+
"path_constraint": "all_member_patch_paths_pairwise_nonoverlapping",
|
|
52
|
+
"predictions": "all_unknown",
|
|
53
|
+
"forbidden_inputs": [
|
|
54
|
+
"objective_values",
|
|
55
|
+
"prior_outcomes",
|
|
56
|
+
"option_descriptions",
|
|
57
|
+
"option_metadata",
|
|
58
|
+
"card_payloads",
|
|
59
|
+
"card_scores",
|
|
60
|
+
],
|
|
61
|
+
}
|
|
62
|
+
POLICY_DEFINITION_SHA256 = hashlib.sha256(
|
|
63
|
+
b"agent-evolve:random-feasible-portfolio-policy:v1\x00"
|
|
64
|
+
+ json.dumps(
|
|
65
|
+
_POLICY_DEFINITION,
|
|
66
|
+
ensure_ascii=True,
|
|
67
|
+
allow_nan=False,
|
|
68
|
+
separators=(",", ":"),
|
|
69
|
+
sort_keys=True,
|
|
70
|
+
).encode("ascii")
|
|
71
|
+
).hexdigest()
|
|
72
|
+
_PARENT_ID = CandidateId("candidate_0000000000000001")
|
|
73
|
+
_CHILD_ID = CandidateId("candidate_0000000000000002")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _paths_overlap(first: JsonPath, second: JsonPath) -> bool:
|
|
77
|
+
return first.is_prefix_of(second) or second.is_prefix_of(first)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _path_text(path: JsonPath) -> str:
|
|
81
|
+
parts = ["$"]
|
|
82
|
+
for segment in path.segments:
|
|
83
|
+
if type(segment) is ObjectKey:
|
|
84
|
+
parts.append(f".{segment.value}")
|
|
85
|
+
elif type(segment) is ArrayIndex:
|
|
86
|
+
parts.append(f"[{segment.value}]")
|
|
87
|
+
else: # pragma: no cover - JsonPath validates the closed segment union.
|
|
88
|
+
raise AssertionError("unsupported JSON-path segment")
|
|
89
|
+
return "".join(parts)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True, slots=True)
|
|
93
|
+
class _OptionRow:
|
|
94
|
+
option_id: str
|
|
95
|
+
family: str
|
|
96
|
+
paths: tuple[JsonPath, ...]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _option_rows(request: PortfolioSelectionRequest) -> tuple[_OptionRow, ...]:
|
|
100
|
+
parent = request.finite_variation_contract.parent_configuration
|
|
101
|
+
rows: list[_OptionRow] = []
|
|
102
|
+
for option in request.finite_variation_contract.options:
|
|
103
|
+
patch = derive_patch(
|
|
104
|
+
parent,
|
|
105
|
+
option.child_configuration,
|
|
106
|
+
base_candidate_id=_PARENT_ID,
|
|
107
|
+
target_candidate_id=_CHILD_ID,
|
|
108
|
+
)
|
|
109
|
+
paths = tuple(
|
|
110
|
+
sorted(
|
|
111
|
+
{operation.path for operation in patch.operations},
|
|
112
|
+
key=_path_text,
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
if not paths:
|
|
116
|
+
raise ValueError("finite option materialized no parent-relative path")
|
|
117
|
+
rows.append(_OptionRow(option.option_id, option.family, paths))
|
|
118
|
+
return tuple(rows)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _disjoint(paths: tuple[JsonPath, ...], selected: tuple[_OptionRow, ...]) -> bool:
|
|
122
|
+
return not any(
|
|
123
|
+
_paths_overlap(path, previous)
|
|
124
|
+
for row in selected
|
|
125
|
+
for path in paths
|
|
126
|
+
for previous in row.paths
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _select_rows(
|
|
131
|
+
request: PortfolioSelectionRequest,
|
|
132
|
+
*,
|
|
133
|
+
seed: int,
|
|
134
|
+
) -> tuple[_OptionRow, ...]:
|
|
135
|
+
rows = list(_option_rows(request))
|
|
136
|
+
entropy = hashlib.sha256(
|
|
137
|
+
b"agent-evolve:random-feasible-portfolio-entropy:v1\x00"
|
|
138
|
+
+ seed.to_bytes(16, "big", signed=True)
|
|
139
|
+
+ request.call_id.value.encode("ascii", errors="strict")
|
|
140
|
+
+ bytes.fromhex(request.finite_variation_contract.identity_sha256)
|
|
141
|
+
).digest()
|
|
142
|
+
random.Random(int.from_bytes(entropy, "big", signed=False)).shuffle(rows)
|
|
143
|
+
required_families = request.min_distinct_families or 1
|
|
144
|
+
target_size = request.portfolio_size
|
|
145
|
+
|
|
146
|
+
def search(
|
|
147
|
+
start: int,
|
|
148
|
+
selected: tuple[_OptionRow, ...],
|
|
149
|
+
families: frozenset[str],
|
|
150
|
+
) -> tuple[_OptionRow, ...] | None:
|
|
151
|
+
if len(selected) == target_size:
|
|
152
|
+
return selected if len(families) >= required_families else None
|
|
153
|
+
remaining_slots = target_size - len(selected)
|
|
154
|
+
if len(rows) - start < remaining_slots:
|
|
155
|
+
return None
|
|
156
|
+
possible_families = families | frozenset(row.family for row in rows[start:])
|
|
157
|
+
if len(possible_families) < required_families:
|
|
158
|
+
return None
|
|
159
|
+
for index in range(start, len(rows)):
|
|
160
|
+
row = rows[index]
|
|
161
|
+
if not _disjoint(row.paths, selected):
|
|
162
|
+
continue
|
|
163
|
+
result = search(
|
|
164
|
+
index + 1,
|
|
165
|
+
(*selected, row),
|
|
166
|
+
families | {row.family},
|
|
167
|
+
)
|
|
168
|
+
if result is not None:
|
|
169
|
+
return result
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
selected = search(0, (), frozenset())
|
|
173
|
+
if selected is None:
|
|
174
|
+
raise ValueError(
|
|
175
|
+
"sealed finite contract has no path-disjoint portfolio satisfying "
|
|
176
|
+
"the requested size and family constraints"
|
|
177
|
+
)
|
|
178
|
+
return selected
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass(frozen=True, slots=True)
|
|
182
|
+
class DeterministicRandomFeasiblePortfolioPolicy:
|
|
183
|
+
"""Select a path-disjoint random portfolio without observing outcomes."""
|
|
184
|
+
|
|
185
|
+
seed: int
|
|
186
|
+
policy_id: str = field(init=False, default=POLICY_ID)
|
|
187
|
+
policy_version: int = field(init=False, default=POLICY_VERSION)
|
|
188
|
+
policy_definition_sha256: str = field(
|
|
189
|
+
init=False,
|
|
190
|
+
default=POLICY_DEFINITION_SHA256,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
def __post_init__(self) -> None:
|
|
194
|
+
if type(self.seed) is not int or not -(1 << 127) <= self.seed < (1 << 127):
|
|
195
|
+
raise ValueError("seed must be an exact signed int128")
|
|
196
|
+
require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
|
|
197
|
+
|
|
198
|
+
async def select(
|
|
199
|
+
self,
|
|
200
|
+
request: PortfolioSelectionRequest,
|
|
201
|
+
) -> PortfolioSelectionResult:
|
|
202
|
+
if type(request) is not PortfolioSelectionRequest:
|
|
203
|
+
raise TypeError("request must be an exact PortfolioSelectionRequest")
|
|
204
|
+
request.__post_init__()
|
|
205
|
+
rows = _select_rows(request, seed=self.seed)
|
|
206
|
+
card_keys = tuple(card.card_key for card in request.cards)
|
|
207
|
+
supporting = (card_keys[0],) if request.require_supporting_cards else ()
|
|
208
|
+
predictions = tuple(
|
|
209
|
+
MetricEffectPrediction(metric_id, MetricEffectDirection.UNKNOWN)
|
|
210
|
+
for metric_id in request.required_metric_ids
|
|
211
|
+
)
|
|
212
|
+
drafts = tuple(
|
|
213
|
+
PortfolioMemberDraft(
|
|
214
|
+
option_id=row.option_id,
|
|
215
|
+
supporting_card_keys=supporting,
|
|
216
|
+
effect_predictions=predictions,
|
|
217
|
+
design_rationale=(
|
|
218
|
+
"Outcome-blind deterministic random control selected this "
|
|
219
|
+
"sealed option under exact family and path constraints."
|
|
220
|
+
),
|
|
221
|
+
)
|
|
222
|
+
for row in rows
|
|
223
|
+
)
|
|
224
|
+
decision = resolve_ranked_portfolio_decision(
|
|
225
|
+
request,
|
|
226
|
+
drafts,
|
|
227
|
+
policy_id=self.policy_id,
|
|
228
|
+
policy_version=self.policy_version,
|
|
229
|
+
policy_definition_sha256=self.policy_definition_sha256,
|
|
230
|
+
)
|
|
231
|
+
telemetry = AgenticCallTelemetry(
|
|
232
|
+
requested_model="provider-free-random-policy",
|
|
233
|
+
resolved_model="provider-free-random-policy",
|
|
234
|
+
resolved_provider="local-deterministic-control",
|
|
235
|
+
provider_response_id=None,
|
|
236
|
+
finish_reason="policy_completed",
|
|
237
|
+
input_tokens=0,
|
|
238
|
+
output_tokens=0,
|
|
239
|
+
reasoning_tokens=0,
|
|
240
|
+
cache_read_tokens=0,
|
|
241
|
+
cache_write_tokens=0,
|
|
242
|
+
cost_usd=Decimal("0"),
|
|
243
|
+
latency_ns=0,
|
|
244
|
+
attempt_count=1,
|
|
245
|
+
)
|
|
246
|
+
return PortfolioSelectionResult(decision=decision, telemetry=telemetry)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
__all__ = [
|
|
250
|
+
"DeterministicRandomFeasiblePortfolioPolicy",
|
|
251
|
+
"POLICY_DEFINITION_SHA256",
|
|
252
|
+
"POLICY_ID",
|
|
253
|
+
"POLICY_VERSION",
|
|
254
|
+
]
|