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,466 @@
|
|
|
1
|
+
"""Provider-neutral contracts for prospective blinded treatment assignment.
|
|
2
|
+
|
|
3
|
+
The types in this module distinguish scientific treatments, their repeatable
|
|
4
|
+
occurrences, and provider-facing opaque slots. They authenticate exact input
|
|
5
|
+
order and both directions of the resulting bijection. The receipt's claim is
|
|
6
|
+
deliberately narrow: it establishes label/order assignment blinding, never
|
|
7
|
+
content blinding.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from enum import Enum
|
|
14
|
+
import hashlib
|
|
15
|
+
import json
|
|
16
|
+
import re
|
|
17
|
+
|
|
18
|
+
from agent_evolve.domain.patch import require_sha256
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_IDENTIFIER = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
22
|
+
_SEED_MATERIAL = re.compile(r"^[a-z0-9][a-z0-9_.:-]{0,255}$")
|
|
23
|
+
_POLICY_BINDING_DOMAIN = b"agent-evolve:treatment-assignment-policy:v1\x00"
|
|
24
|
+
_INPUT_DOMAIN = b"agent-evolve:treatment-assignment-input:v1\x00"
|
|
25
|
+
_RECEIPT_DOMAIN = b"agent-evolve:treatment-assignment-receipt:v1\x00"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _canonical_json(value: object) -> bytes:
|
|
29
|
+
return json.dumps(
|
|
30
|
+
value,
|
|
31
|
+
allow_nan=False,
|
|
32
|
+
ensure_ascii=True,
|
|
33
|
+
separators=(",", ":"),
|
|
34
|
+
sort_keys=True,
|
|
35
|
+
).encode("ascii")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
39
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _require_identifier(value: object, name: str) -> str:
|
|
43
|
+
if type(value) is not str or _IDENTIFIER.fullmatch(value) is None:
|
|
44
|
+
raise ValueError(f"{name} must use the canonical lowercase identifier grammar")
|
|
45
|
+
return value
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True, slots=True)
|
|
49
|
+
class TreatmentId:
|
|
50
|
+
"""Nominal identifier for a scientific treatment; repeats are permitted."""
|
|
51
|
+
|
|
52
|
+
value: str
|
|
53
|
+
|
|
54
|
+
def __post_init__(self) -> None:
|
|
55
|
+
_require_identifier(self.value, "treatment_id")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True, slots=True)
|
|
59
|
+
class TreatmentOccurrenceId:
|
|
60
|
+
"""Nominal identifier for one unique occurrence of a treatment."""
|
|
61
|
+
|
|
62
|
+
value: str
|
|
63
|
+
|
|
64
|
+
def __post_init__(self) -> None:
|
|
65
|
+
_require_identifier(self.value, "occurrence_id")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass(frozen=True, slots=True)
|
|
69
|
+
class OpaqueProviderSlotId:
|
|
70
|
+
"""Nominal provider-facing slot identifier with no treatment semantics."""
|
|
71
|
+
|
|
72
|
+
value: str
|
|
73
|
+
|
|
74
|
+
def __post_init__(self) -> None:
|
|
75
|
+
_require_identifier(self.value, "opaque_provider_slot_id")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True, slots=True)
|
|
79
|
+
class TreatmentOccurrence:
|
|
80
|
+
"""One canonical input occurrence, optionally bound to call/request identity."""
|
|
81
|
+
|
|
82
|
+
occurrence_id: TreatmentOccurrenceId
|
|
83
|
+
treatment_id: TreatmentId
|
|
84
|
+
call_identity: str | None = None
|
|
85
|
+
request_identity_sha256: str | None = None
|
|
86
|
+
|
|
87
|
+
def __post_init__(self) -> None:
|
|
88
|
+
if type(self.occurrence_id) is not TreatmentOccurrenceId:
|
|
89
|
+
raise TypeError("occurrence_id must be an exact TreatmentOccurrenceId")
|
|
90
|
+
if type(self.treatment_id) is not TreatmentId:
|
|
91
|
+
raise TypeError("treatment_id must be an exact TreatmentId")
|
|
92
|
+
self.occurrence_id.__post_init__()
|
|
93
|
+
self.treatment_id.__post_init__()
|
|
94
|
+
if self.call_identity is not None:
|
|
95
|
+
_require_identifier(self.call_identity, "call_identity")
|
|
96
|
+
if self.request_identity_sha256 is not None:
|
|
97
|
+
require_sha256(
|
|
98
|
+
self.request_identity_sha256,
|
|
99
|
+
"request_identity_sha256",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def to_record(self) -> dict[str, object]:
|
|
103
|
+
self.__post_init__()
|
|
104
|
+
return {
|
|
105
|
+
"schema_version": 1,
|
|
106
|
+
"occurrence_id": self.occurrence_id.value,
|
|
107
|
+
"treatment_id": self.treatment_id.value,
|
|
108
|
+
"call_identity": self.call_identity,
|
|
109
|
+
"request_identity_sha256": self.request_identity_sha256,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
114
|
+
class TreatmentAssignmentPolicyBinding:
|
|
115
|
+
"""Identified public permutation policy and domain separation label."""
|
|
116
|
+
|
|
117
|
+
policy_id: str
|
|
118
|
+
policy_version: int
|
|
119
|
+
policy_definition_sha256: str
|
|
120
|
+
permutation_domain: str
|
|
121
|
+
|
|
122
|
+
def __post_init__(self) -> None:
|
|
123
|
+
_require_identifier(self.policy_id, "policy_id")
|
|
124
|
+
if type(self.policy_version) is not int or self.policy_version <= 0:
|
|
125
|
+
raise ValueError("policy_version must be a positive exact integer")
|
|
126
|
+
require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
|
|
127
|
+
_require_identifier(self.permutation_domain, "permutation_domain")
|
|
128
|
+
|
|
129
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
130
|
+
self.__post_init__()
|
|
131
|
+
return {
|
|
132
|
+
"schema_version": 1,
|
|
133
|
+
"policy_id": self.policy_id,
|
|
134
|
+
"policy_version": self.policy_version,
|
|
135
|
+
"policy_definition_sha256": self.policy_definition_sha256,
|
|
136
|
+
"permutation_domain": self.permutation_domain,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def binding_sha256(self) -> str:
|
|
141
|
+
return _hash(_POLICY_BINDING_DOMAIN, self._unsigned_record())
|
|
142
|
+
|
|
143
|
+
def to_record(self) -> dict[str, object]:
|
|
144
|
+
return {**self._unsigned_record(), "binding_sha256": self.binding_sha256}
|
|
145
|
+
|
|
146
|
+
def __eq__(self, other: object) -> bool:
|
|
147
|
+
return (
|
|
148
|
+
type(other) is TreatmentAssignmentPolicyBinding
|
|
149
|
+
and self.binding_sha256 == other.binding_sha256
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
__hash__ = None
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
156
|
+
class TreatmentAssignmentInput:
|
|
157
|
+
"""Exact prospective input order and public seed material."""
|
|
158
|
+
|
|
159
|
+
experiment_commitment_sha256: str
|
|
160
|
+
public_seed_material: str
|
|
161
|
+
occurrences: tuple[TreatmentOccurrence, ...]
|
|
162
|
+
provider_slot_ids: tuple[OpaqueProviderSlotId, ...]
|
|
163
|
+
|
|
164
|
+
def __post_init__(self) -> None:
|
|
165
|
+
require_sha256(
|
|
166
|
+
self.experiment_commitment_sha256,
|
|
167
|
+
"experiment_commitment_sha256",
|
|
168
|
+
)
|
|
169
|
+
if (
|
|
170
|
+
type(self.public_seed_material) is not str
|
|
171
|
+
or _SEED_MATERIAL.fullmatch(self.public_seed_material) is None
|
|
172
|
+
):
|
|
173
|
+
raise ValueError(
|
|
174
|
+
"public_seed_material must use the canonical public-seed grammar"
|
|
175
|
+
)
|
|
176
|
+
if type(self.occurrences) is not tuple or not self.occurrences or any(
|
|
177
|
+
type(value) is not TreatmentOccurrence for value in self.occurrences
|
|
178
|
+
):
|
|
179
|
+
raise ValueError("occurrences must be a non-empty exact tuple")
|
|
180
|
+
if type(self.provider_slot_ids) is not tuple or any(
|
|
181
|
+
type(value) is not OpaqueProviderSlotId
|
|
182
|
+
for value in self.provider_slot_ids
|
|
183
|
+
):
|
|
184
|
+
raise TypeError("provider_slot_ids must be an exact tuple")
|
|
185
|
+
if len(self.provider_slot_ids) != len(self.occurrences):
|
|
186
|
+
raise ValueError("provider slot and occurrence counts must match exactly")
|
|
187
|
+
for value in self.occurrences:
|
|
188
|
+
value.__post_init__()
|
|
189
|
+
for value in self.provider_slot_ids:
|
|
190
|
+
value.__post_init__()
|
|
191
|
+
|
|
192
|
+
occurrence_ids = tuple(value.occurrence_id.value for value in self.occurrences)
|
|
193
|
+
slot_ids = tuple(value.value for value in self.provider_slot_ids)
|
|
194
|
+
if len(set(occurrence_ids)) != len(occurrence_ids):
|
|
195
|
+
raise ValueError("occurrence IDs cannot repeat")
|
|
196
|
+
if len(set(slot_ids)) != len(slot_ids):
|
|
197
|
+
raise ValueError("opaque provider slot IDs cannot repeat")
|
|
198
|
+
|
|
199
|
+
treatment_ids = {value.treatment_id.value for value in self.occurrences}
|
|
200
|
+
occurrence_id_set = set(occurrence_ids)
|
|
201
|
+
slot_id_set = set(slot_ids)
|
|
202
|
+
if (
|
|
203
|
+
treatment_ids & occurrence_id_set
|
|
204
|
+
or treatment_ids & slot_id_set
|
|
205
|
+
or occurrence_id_set & slot_id_set
|
|
206
|
+
):
|
|
207
|
+
raise ValueError(
|
|
208
|
+
"treatment, occurrence, and provider-slot identifier namespaces "
|
|
209
|
+
"must be disjoint"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
213
|
+
self.__post_init__()
|
|
214
|
+
return {
|
|
215
|
+
"schema_version": 1,
|
|
216
|
+
"experiment_commitment_sha256": self.experiment_commitment_sha256,
|
|
217
|
+
"public_seed_material": self.public_seed_material,
|
|
218
|
+
"occurrence_input_order": [
|
|
219
|
+
value.to_record() for value in self.occurrences
|
|
220
|
+
],
|
|
221
|
+
"provider_slot_input_order": [
|
|
222
|
+
value.value for value in self.provider_slot_ids
|
|
223
|
+
],
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def input_sha256(self) -> str:
|
|
228
|
+
return _hash(_INPUT_DOMAIN, self._unsigned_record())
|
|
229
|
+
|
|
230
|
+
def to_record(self) -> dict[str, object]:
|
|
231
|
+
return {**self._unsigned_record(), "input_sha256": self.input_sha256}
|
|
232
|
+
|
|
233
|
+
def __eq__(self, other: object) -> bool:
|
|
234
|
+
return (
|
|
235
|
+
type(other) is TreatmentAssignmentInput
|
|
236
|
+
and self.input_sha256 == other.input_sha256
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
__hash__ = None
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass(frozen=True, slots=True)
|
|
243
|
+
class TreatmentAssignment:
|
|
244
|
+
"""One authenticated edge in the occurrence/provider-slot bijection."""
|
|
245
|
+
|
|
246
|
+
occurrence_id: TreatmentOccurrenceId
|
|
247
|
+
treatment_id: TreatmentId
|
|
248
|
+
opaque_provider_slot_id: OpaqueProviderSlotId
|
|
249
|
+
occurrence_input_index: int
|
|
250
|
+
provider_slot_input_index: int
|
|
251
|
+
call_identity: str | None = None
|
|
252
|
+
request_identity_sha256: str | None = None
|
|
253
|
+
|
|
254
|
+
def __post_init__(self) -> None:
|
|
255
|
+
if type(self.occurrence_id) is not TreatmentOccurrenceId:
|
|
256
|
+
raise TypeError("occurrence_id must be an exact TreatmentOccurrenceId")
|
|
257
|
+
if type(self.treatment_id) is not TreatmentId:
|
|
258
|
+
raise TypeError("treatment_id must be an exact TreatmentId")
|
|
259
|
+
if type(self.opaque_provider_slot_id) is not OpaqueProviderSlotId:
|
|
260
|
+
raise TypeError(
|
|
261
|
+
"opaque_provider_slot_id must be an exact OpaqueProviderSlotId"
|
|
262
|
+
)
|
|
263
|
+
self.occurrence_id.__post_init__()
|
|
264
|
+
self.treatment_id.__post_init__()
|
|
265
|
+
self.opaque_provider_slot_id.__post_init__()
|
|
266
|
+
for name in ("occurrence_input_index", "provider_slot_input_index"):
|
|
267
|
+
value = getattr(self, name)
|
|
268
|
+
if type(value) is not int or value < 0:
|
|
269
|
+
raise ValueError(f"{name} must be a non-negative exact integer")
|
|
270
|
+
if self.call_identity is not None:
|
|
271
|
+
_require_identifier(self.call_identity, "call_identity")
|
|
272
|
+
if self.request_identity_sha256 is not None:
|
|
273
|
+
require_sha256(
|
|
274
|
+
self.request_identity_sha256,
|
|
275
|
+
"request_identity_sha256",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def to_record(self) -> dict[str, object]:
|
|
279
|
+
self.__post_init__()
|
|
280
|
+
return {
|
|
281
|
+
"schema_version": 1,
|
|
282
|
+
"occurrence_id": self.occurrence_id.value,
|
|
283
|
+
"treatment_id": self.treatment_id.value,
|
|
284
|
+
"opaque_provider_slot_id": self.opaque_provider_slot_id.value,
|
|
285
|
+
"occurrence_input_index": self.occurrence_input_index,
|
|
286
|
+
"provider_slot_input_index": self.provider_slot_input_index,
|
|
287
|
+
"call_identity": self.call_identity,
|
|
288
|
+
"request_identity_sha256": self.request_identity_sha256,
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class TreatmentAssignmentBlindingScope(str, Enum):
|
|
293
|
+
"""The only blinding scope this receipt is capable of establishing."""
|
|
294
|
+
|
|
295
|
+
LABEL_AND_ORDER_ONLY = "label_and_order_only"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _blinding_claim_record() -> dict[str, object]:
|
|
299
|
+
return {
|
|
300
|
+
"scope": TreatmentAssignmentBlindingScope.LABEL_AND_ORDER_ONLY.value,
|
|
301
|
+
"opaque_provider_slot_ids": True,
|
|
302
|
+
"content_blinding_claimed": False,
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
307
|
+
class ProspectiveTreatmentAssignmentReceipt:
|
|
308
|
+
"""Authenticated prospective assignment with explicit forward and inverse maps."""
|
|
309
|
+
|
|
310
|
+
policy: TreatmentAssignmentPolicyBinding
|
|
311
|
+
assignment_input_sha256: str
|
|
312
|
+
experiment_commitment_sha256: str
|
|
313
|
+
public_seed_material: str
|
|
314
|
+
occurrence_input_order: tuple[TreatmentOccurrence, ...]
|
|
315
|
+
provider_slot_input_order: tuple[OpaqueProviderSlotId, ...]
|
|
316
|
+
ordinal_permutation: tuple[int, ...]
|
|
317
|
+
inverse_ordinal_permutation: tuple[int, ...]
|
|
318
|
+
slot_to_occurrence: tuple[TreatmentAssignment, ...]
|
|
319
|
+
occurrence_to_slot: tuple[TreatmentAssignment, ...]
|
|
320
|
+
|
|
321
|
+
def __post_init__(self) -> None:
|
|
322
|
+
if type(self.policy) is not TreatmentAssignmentPolicyBinding:
|
|
323
|
+
raise TypeError("policy must be an exact TreatmentAssignmentPolicyBinding")
|
|
324
|
+
self.policy.__post_init__()
|
|
325
|
+
require_sha256(self.assignment_input_sha256, "assignment_input_sha256")
|
|
326
|
+
assignment_input = TreatmentAssignmentInput(
|
|
327
|
+
experiment_commitment_sha256=self.experiment_commitment_sha256,
|
|
328
|
+
public_seed_material=self.public_seed_material,
|
|
329
|
+
occurrences=self.occurrence_input_order,
|
|
330
|
+
provider_slot_ids=self.provider_slot_input_order,
|
|
331
|
+
)
|
|
332
|
+
if self.assignment_input_sha256 != assignment_input.input_sha256:
|
|
333
|
+
raise ValueError(
|
|
334
|
+
"assignment input commitment does not match receipt inputs"
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
count = len(self.occurrence_input_order)
|
|
338
|
+
for name in ("ordinal_permutation", "inverse_ordinal_permutation"):
|
|
339
|
+
value = getattr(self, name)
|
|
340
|
+
if type(value) is not tuple or any(
|
|
341
|
+
type(index) is not int for index in value
|
|
342
|
+
):
|
|
343
|
+
raise TypeError(f"{name} must be an exact integer tuple")
|
|
344
|
+
if len(value) != count or tuple(sorted(value)) != tuple(range(count)):
|
|
345
|
+
raise ValueError(f"{name} must be a complete exact permutation")
|
|
346
|
+
for provider_index, occurrence_index in enumerate(self.ordinal_permutation):
|
|
347
|
+
if self.inverse_ordinal_permutation[occurrence_index] != provider_index:
|
|
348
|
+
raise ValueError("ordinal permutation and inverse disagree")
|
|
349
|
+
|
|
350
|
+
for name in ("slot_to_occurrence", "occurrence_to_slot"):
|
|
351
|
+
value = getattr(self, name)
|
|
352
|
+
if type(value) is not tuple or any(
|
|
353
|
+
type(item) is not TreatmentAssignment for item in value
|
|
354
|
+
):
|
|
355
|
+
raise TypeError(f"{name} must be an exact assignment tuple")
|
|
356
|
+
if len(value) != count:
|
|
357
|
+
raise ValueError(f"{name} must cover every occurrence exactly once")
|
|
358
|
+
for item in value:
|
|
359
|
+
item.__post_init__()
|
|
360
|
+
|
|
361
|
+
expected_by_occurrence: list[TreatmentAssignment | None] = [None] * count
|
|
362
|
+
for provider_index, assignment in enumerate(self.slot_to_occurrence):
|
|
363
|
+
occurrence_index = self.ordinal_permutation[provider_index]
|
|
364
|
+
occurrence = self.occurrence_input_order[occurrence_index]
|
|
365
|
+
if (
|
|
366
|
+
assignment.provider_slot_input_index != provider_index
|
|
367
|
+
or assignment.opaque_provider_slot_id
|
|
368
|
+
!= self.provider_slot_input_order[provider_index]
|
|
369
|
+
or assignment.occurrence_input_index != occurrence_index
|
|
370
|
+
or assignment.occurrence_id != occurrence.occurrence_id
|
|
371
|
+
or assignment.treatment_id != occurrence.treatment_id
|
|
372
|
+
or assignment.call_identity != occurrence.call_identity
|
|
373
|
+
or assignment.request_identity_sha256
|
|
374
|
+
!= occurrence.request_identity_sha256
|
|
375
|
+
):
|
|
376
|
+
raise ValueError("slot-to-occurrence mapping differs from bound inputs")
|
|
377
|
+
if expected_by_occurrence[occurrence_index] is not None:
|
|
378
|
+
raise ValueError("slot-to-occurrence mapping repeats an occurrence")
|
|
379
|
+
expected_by_occurrence[occurrence_index] = assignment
|
|
380
|
+
|
|
381
|
+
if any(value is None for value in expected_by_occurrence):
|
|
382
|
+
raise ValueError("slot-to-occurrence mapping is not a complete bijection")
|
|
383
|
+
for occurrence_index, assignment in enumerate(self.occurrence_to_slot):
|
|
384
|
+
if assignment is not expected_by_occurrence[occurrence_index]:
|
|
385
|
+
if assignment != expected_by_occurrence[occurrence_index]:
|
|
386
|
+
raise ValueError(
|
|
387
|
+
"occurrence-to-slot mapping is not the exact inverse"
|
|
388
|
+
)
|
|
389
|
+
if assignment.provider_slot_input_index != self.inverse_ordinal_permutation[
|
|
390
|
+
occurrence_index
|
|
391
|
+
]:
|
|
392
|
+
raise ValueError("inverse mapping differs from inverse permutation")
|
|
393
|
+
|
|
394
|
+
if len(
|
|
395
|
+
{value.occurrence_id.value for value in self.slot_to_occurrence}
|
|
396
|
+
) != count:
|
|
397
|
+
raise ValueError("assignment repeats an occurrence ID")
|
|
398
|
+
if len(
|
|
399
|
+
{
|
|
400
|
+
value.opaque_provider_slot_id.value
|
|
401
|
+
for value in self.slot_to_occurrence
|
|
402
|
+
}
|
|
403
|
+
) != count:
|
|
404
|
+
raise ValueError("assignment repeats an opaque provider slot ID")
|
|
405
|
+
|
|
406
|
+
@property
|
|
407
|
+
def blinding_scope(self) -> TreatmentAssignmentBlindingScope:
|
|
408
|
+
return TreatmentAssignmentBlindingScope.LABEL_AND_ORDER_ONLY
|
|
409
|
+
|
|
410
|
+
@property
|
|
411
|
+
def content_blinding_claimed(self) -> bool:
|
|
412
|
+
return False
|
|
413
|
+
|
|
414
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
415
|
+
self.__post_init__()
|
|
416
|
+
return {
|
|
417
|
+
"schema_version": 1,
|
|
418
|
+
"prospective": True,
|
|
419
|
+
"policy": self.policy.to_record(),
|
|
420
|
+
"assignment_input_sha256": self.assignment_input_sha256,
|
|
421
|
+
"experiment_commitment_sha256": self.experiment_commitment_sha256,
|
|
422
|
+
"public_seed_material": self.public_seed_material,
|
|
423
|
+
"occurrence_input_order": [
|
|
424
|
+
value.to_record() for value in self.occurrence_input_order
|
|
425
|
+
],
|
|
426
|
+
"provider_slot_input_order": [
|
|
427
|
+
value.value for value in self.provider_slot_input_order
|
|
428
|
+
],
|
|
429
|
+
"ordinal_permutation": list(self.ordinal_permutation),
|
|
430
|
+
"inverse_ordinal_permutation": list(self.inverse_ordinal_permutation),
|
|
431
|
+
"slot_to_occurrence": [
|
|
432
|
+
value.to_record() for value in self.slot_to_occurrence
|
|
433
|
+
],
|
|
434
|
+
"occurrence_to_slot": [
|
|
435
|
+
value.to_record() for value in self.occurrence_to_slot
|
|
436
|
+
],
|
|
437
|
+
"blinding_claim": _blinding_claim_record(),
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
@property
|
|
441
|
+
def receipt_sha256(self) -> str:
|
|
442
|
+
return _hash(_RECEIPT_DOMAIN, self._unsigned_record())
|
|
443
|
+
|
|
444
|
+
def to_record(self) -> dict[str, object]:
|
|
445
|
+
return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
|
|
446
|
+
|
|
447
|
+
def __eq__(self, other: object) -> bool:
|
|
448
|
+
return (
|
|
449
|
+
type(other) is ProspectiveTreatmentAssignmentReceipt
|
|
450
|
+
and self.receipt_sha256 == other.receipt_sha256
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
__hash__ = None
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
__all__ = [
|
|
457
|
+
"OpaqueProviderSlotId",
|
|
458
|
+
"ProspectiveTreatmentAssignmentReceipt",
|
|
459
|
+
"TreatmentAssignment",
|
|
460
|
+
"TreatmentAssignmentBlindingScope",
|
|
461
|
+
"TreatmentAssignmentInput",
|
|
462
|
+
"TreatmentAssignmentPolicyBinding",
|
|
463
|
+
"TreatmentId",
|
|
464
|
+
"TreatmentOccurrence",
|
|
465
|
+
"TreatmentOccurrenceId",
|
|
466
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Ports for deterministic finite, parent-relative variation catalogs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
6
|
+
|
|
7
|
+
from agent_evolve.domain.finite_variation import (
|
|
8
|
+
FiniteVariationContract,
|
|
9
|
+
FiniteVariationOption,
|
|
10
|
+
)
|
|
11
|
+
from agent_evolve.domain.typed_json import FrozenJsonObject, freeze_json
|
|
12
|
+
from agent_evolve.domain.variation_space import AtomicEditOption
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@runtime_checkable
|
|
19
|
+
class AtomicVariationCatalog(Protocol):
|
|
20
|
+
"""Enumerate an immutable, deterministic option tuple for one parent."""
|
|
21
|
+
|
|
22
|
+
def options(
|
|
23
|
+
self,
|
|
24
|
+
parent: "EvolutionCandidate",
|
|
25
|
+
) -> tuple[AtomicEditOption, ...]: ...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@runtime_checkable
|
|
29
|
+
class FiniteVariationCatalog(Protocol):
|
|
30
|
+
"""Enumerate sealed full-child choices for one immutable parent.
|
|
31
|
+
|
|
32
|
+
The protocol intentionally receives configuration data rather than an
|
|
33
|
+
application-layer candidate. Benchmark adapters therefore need no import
|
|
34
|
+
from the evolutionary engine and may coordinate arbitrarily many fields in
|
|
35
|
+
one option.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
catalog_id: str
|
|
39
|
+
catalog_version: int
|
|
40
|
+
definition_sha256: str
|
|
41
|
+
|
|
42
|
+
def options(
|
|
43
|
+
self,
|
|
44
|
+
parent_configuration: FrozenJsonObject,
|
|
45
|
+
) -> tuple[FiniteVariationOption, ...]: ...
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def bind_finite_variation_catalog(
|
|
49
|
+
catalog: FiniteVariationCatalog,
|
|
50
|
+
parent_configuration: FrozenJsonObject,
|
|
51
|
+
) -> FiniteVariationContract:
|
|
52
|
+
"""Seal one catalog result and its published semantics to one parent."""
|
|
53
|
+
|
|
54
|
+
if not isinstance(catalog, FiniteVariationCatalog):
|
|
55
|
+
raise TypeError("catalog must implement FiniteVariationCatalog")
|
|
56
|
+
if type(parent_configuration) is not FrozenJsonObject:
|
|
57
|
+
raise TypeError("parent_configuration must be an exact FrozenJsonObject")
|
|
58
|
+
if freeze_json(parent_configuration) is not parent_configuration:
|
|
59
|
+
raise TypeError("parent_configuration must already be frozen typed JSON")
|
|
60
|
+
options = catalog.options(parent_configuration)
|
|
61
|
+
if type(options) is not tuple:
|
|
62
|
+
raise TypeError("finite variation catalog must return an exact tuple")
|
|
63
|
+
return FiniteVariationContract(
|
|
64
|
+
catalog_id=catalog.catalog_id,
|
|
65
|
+
catalog_version=catalog.catalog_version,
|
|
66
|
+
catalog_definition_sha256=catalog.definition_sha256,
|
|
67
|
+
parent_configuration=parent_configuration,
|
|
68
|
+
options=options,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
__all__ = [
|
|
73
|
+
"AtomicVariationCatalog",
|
|
74
|
+
"FiniteVariationCatalog",
|
|
75
|
+
"bind_finite_variation_catalog",
|
|
76
|
+
]
|