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,950 @@
|
|
|
1
|
+
"""Public bridge from :class:`AgenticBenchmark` to campaign workload ports.
|
|
2
|
+
|
|
3
|
+
The campaign application owns chronology, budgets, and runtime preflight. A
|
|
4
|
+
benchmark owns candidate semantics, a finite variation catalog, seed
|
|
5
|
+
configurations, evaluator-resource facts, and prompt evidence. This module is
|
|
6
|
+
the narrow adapter between those two boundaries.
|
|
7
|
+
|
|
8
|
+
Construction and :meth:`EvolutionCampaign.prepare` are deliberately
|
|
9
|
+
provider- and evaluator-free. The selected finite catalog is materialized
|
|
10
|
+
only when ``CampaignCatalogPort.bind`` is called for a concrete parent after
|
|
11
|
+
preparation. Evidence memory, context, and cards are likewise delegated to
|
|
12
|
+
injected projections rather than embedding workload rules in the campaign
|
|
13
|
+
orchestrator.
|
|
14
|
+
|
|
15
|
+
Library integrations should import :class:`AgenticCampaignWorkloadConfig` and
|
|
16
|
+
:class:`AgenticCampaignEvidenceProjections` from the top-level
|
|
17
|
+
``agent_evolve`` facade. This implementation module remains importable for
|
|
18
|
+
type-directed tooling, but it is not the intended composition root.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import hashlib
|
|
24
|
+
import json
|
|
25
|
+
import re
|
|
26
|
+
from collections.abc import Callable
|
|
27
|
+
from dataclasses import dataclass
|
|
28
|
+
|
|
29
|
+
from pydantic import BaseModel
|
|
30
|
+
|
|
31
|
+
from agent_evolve.agentic import (
|
|
32
|
+
AgenticBenchmark,
|
|
33
|
+
FiniteVariationContract,
|
|
34
|
+
OptionPhenotypeBinding,
|
|
35
|
+
PhenotypeIdentity,
|
|
36
|
+
eligible_finite_variation_view,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.application.evolution_campaign import (
|
|
39
|
+
BenchmarkSessionRequest,
|
|
40
|
+
CampaignBenchmarkSession,
|
|
41
|
+
CampaignSeed,
|
|
42
|
+
CampaignSeedBatch,
|
|
43
|
+
CampaignWorkloadPorts,
|
|
44
|
+
ParentVariationBinding,
|
|
45
|
+
)
|
|
46
|
+
from agent_evolve.domain.typed_json import (
|
|
47
|
+
FrozenJsonObject,
|
|
48
|
+
freeze_json,
|
|
49
|
+
thaw_json,
|
|
50
|
+
typed_json_sha256,
|
|
51
|
+
)
|
|
52
|
+
from agent_evolve.workload_prompt import (
|
|
53
|
+
WORKLOAD_PROMPT_EXTENSION_CONTEXT_KEY,
|
|
54
|
+
WorkloadPromptExtensionView,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,127}$")
|
|
59
|
+
_CONFIG_DOMAIN = b"agent-evolve:agentic-campaign-workload-config:v1\x00"
|
|
60
|
+
_PORT_DOMAIN = b"agent-evolve:agentic-campaign-workload-port:v1\x00"
|
|
61
|
+
_PORT_ADAPTER_IMPLEMENTATION_REVISION = 2
|
|
62
|
+
_BINDING_KEY_DOMAIN = (
|
|
63
|
+
b"agent-evolve:agentic-campaign-workload-binding-key:v1\x00"
|
|
64
|
+
)
|
|
65
|
+
_OPTION_PHENOTYPE_SET_DOMAIN = (
|
|
66
|
+
b"agent-evolve:agentic-campaign-option-phenotype-set:v1\x00"
|
|
67
|
+
)
|
|
68
|
+
_ISSUED_BINDING_DOMAIN = (
|
|
69
|
+
b"agent-evolve:agentic-campaign-issued-binding:v1\x00"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _canonical_bytes(value: object) -> bytes:
|
|
74
|
+
return json.dumps(
|
|
75
|
+
value,
|
|
76
|
+
allow_nan=False,
|
|
77
|
+
ensure_ascii=True,
|
|
78
|
+
separators=(",", ":"),
|
|
79
|
+
sort_keys=True,
|
|
80
|
+
).encode("ascii")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _sha256(domain: bytes, value: object) -> str:
|
|
84
|
+
return hashlib.sha256(domain + _canonical_bytes(value)).hexdigest()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _require_sha256(value: object, *, name: str) -> str:
|
|
88
|
+
if (
|
|
89
|
+
type(value) is not str
|
|
90
|
+
or len(value) != 64
|
|
91
|
+
or any(character not in "0123456789abcdef" for character in value)
|
|
92
|
+
):
|
|
93
|
+
raise ValueError(f"{name} must be a lowercase SHA-256 digest")
|
|
94
|
+
return value
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _require_token(value: object, *, name: str) -> str:
|
|
98
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
99
|
+
raise ValueError(f"{name} must use the closed campaign-token grammar")
|
|
100
|
+
return value
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _require_object(value: object, *, name: str) -> FrozenJsonObject:
|
|
104
|
+
if type(value) is not FrozenJsonObject or freeze_json(value) is not value:
|
|
105
|
+
raise TypeError(f"{name} must be an exact frozen typed-JSON object")
|
|
106
|
+
return value
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
MemoryProjection = Callable[
|
|
110
|
+
[AgenticBenchmark, CampaignBenchmarkSession, CampaignSeedBatch],
|
|
111
|
+
FrozenJsonObject,
|
|
112
|
+
]
|
|
113
|
+
ContextProjection = Callable[
|
|
114
|
+
[
|
|
115
|
+
AgenticBenchmark,
|
|
116
|
+
CampaignBenchmarkSession,
|
|
117
|
+
FrozenJsonObject,
|
|
118
|
+
ParentVariationBinding,
|
|
119
|
+
FrozenJsonObject,
|
|
120
|
+
],
|
|
121
|
+
FrozenJsonObject,
|
|
122
|
+
]
|
|
123
|
+
CardProjection = Callable[
|
|
124
|
+
[
|
|
125
|
+
AgenticBenchmark,
|
|
126
|
+
CampaignBenchmarkSession,
|
|
127
|
+
FrozenJsonObject,
|
|
128
|
+
ParentVariationBinding,
|
|
129
|
+
FrozenJsonObject,
|
|
130
|
+
],
|
|
131
|
+
tuple[FrozenJsonObject, ...],
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass(frozen=True, slots=True)
|
|
136
|
+
class AgenticCampaignEvidenceProjections:
|
|
137
|
+
"""Injected workload evidence projections with an immutable identity."""
|
|
138
|
+
|
|
139
|
+
projection_id: str
|
|
140
|
+
projection_version: int
|
|
141
|
+
definition_sha256: str
|
|
142
|
+
initialize_memory: MemoryProjection
|
|
143
|
+
context: ContextProjection
|
|
144
|
+
cards: CardProjection
|
|
145
|
+
|
|
146
|
+
def __post_init__(self) -> None:
|
|
147
|
+
_require_token(self.projection_id, name="projection_id")
|
|
148
|
+
if type(self.projection_version) is not int or self.projection_version <= 0:
|
|
149
|
+
raise ValueError("projection_version must be a positive exact integer")
|
|
150
|
+
_require_sha256(self.definition_sha256, name="definition_sha256")
|
|
151
|
+
for name in ("initialize_memory", "context", "cards"):
|
|
152
|
+
if not callable(getattr(self, name)):
|
|
153
|
+
raise TypeError(f"{name} must be callable")
|
|
154
|
+
|
|
155
|
+
def to_record(self) -> dict[str, object]:
|
|
156
|
+
self.__post_init__()
|
|
157
|
+
return {
|
|
158
|
+
"projection_id": self.projection_id,
|
|
159
|
+
"projection_version": self.projection_version,
|
|
160
|
+
"definition_sha256": self.definition_sha256,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@dataclass(frozen=True, slots=True)
|
|
165
|
+
class AgenticCampaignWorkloadConfig:
|
|
166
|
+
"""Complete configuration for one benchmark-owned campaign boundary.
|
|
167
|
+
|
|
168
|
+
``evaluator_preflight_receipt`` and ``resource_lease_receipt`` are facts
|
|
169
|
+
acquired outside this adapter. Supplying those immutable receipts keeps
|
|
170
|
+
preparation free of evaluator work while still making resource admission
|
|
171
|
+
replay-identifiable.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
workload_id: str
|
|
175
|
+
workload_version: int
|
|
176
|
+
definition_sha256: str
|
|
177
|
+
benchmark: AgenticBenchmark
|
|
178
|
+
seeds: tuple[CampaignSeed, ...]
|
|
179
|
+
finite_catalog_id: str
|
|
180
|
+
evaluator_concurrency_cap: int
|
|
181
|
+
evaluator_preflight_receipt: FrozenJsonObject
|
|
182
|
+
resource_lease_receipt: FrozenJsonObject
|
|
183
|
+
evidence: AgenticCampaignEvidenceProjections
|
|
184
|
+
prompt_extension: WorkloadPromptExtensionView | None = None
|
|
185
|
+
|
|
186
|
+
def __post_init__(self) -> None:
|
|
187
|
+
_require_token(self.workload_id, name="workload_id")
|
|
188
|
+
if type(self.workload_version) is not int or self.workload_version <= 0:
|
|
189
|
+
raise ValueError("workload_version must be a positive exact integer")
|
|
190
|
+
_require_sha256(self.definition_sha256, name="definition_sha256")
|
|
191
|
+
if type(self.benchmark) is not AgenticBenchmark:
|
|
192
|
+
raise TypeError("benchmark must be an exact AgenticBenchmark")
|
|
193
|
+
self.benchmark.validate_binding()
|
|
194
|
+
if type(self.seeds) is not tuple or not self.seeds:
|
|
195
|
+
raise ValueError("seeds must be a non-empty exact tuple")
|
|
196
|
+
if any(type(seed) is not CampaignSeed for seed in self.seeds):
|
|
197
|
+
raise TypeError("seeds must contain exact CampaignSeed values")
|
|
198
|
+
if len({seed.seed_id for seed in self.seeds}) != len(self.seeds):
|
|
199
|
+
raise ValueError("seed IDs must be unique")
|
|
200
|
+
if len({seed.configuration_sha256 for seed in self.seeds}) != len(self.seeds):
|
|
201
|
+
raise ValueError("seed configurations must be unique")
|
|
202
|
+
for seed in self.seeds:
|
|
203
|
+
CampaignSeed.__post_init__(seed)
|
|
204
|
+
self._validate_seed_schema(seed)
|
|
205
|
+
_require_token(self.finite_catalog_id, name="finite_catalog_id")
|
|
206
|
+
identities = self.benchmark.finite_variation_catalog_identities
|
|
207
|
+
if sum(identity[0] == self.finite_catalog_id for identity in identities) != 1:
|
|
208
|
+
raise ValueError(
|
|
209
|
+
"finite_catalog_id must identify exactly one benchmark catalog"
|
|
210
|
+
)
|
|
211
|
+
if (
|
|
212
|
+
type(self.evaluator_concurrency_cap) is not int
|
|
213
|
+
or self.evaluator_concurrency_cap <= 0
|
|
214
|
+
):
|
|
215
|
+
raise ValueError("evaluator_concurrency_cap must be positive")
|
|
216
|
+
_require_object(
|
|
217
|
+
self.evaluator_preflight_receipt,
|
|
218
|
+
name="evaluator_preflight_receipt",
|
|
219
|
+
)
|
|
220
|
+
_require_object(
|
|
221
|
+
self.resource_lease_receipt,
|
|
222
|
+
name="resource_lease_receipt",
|
|
223
|
+
)
|
|
224
|
+
if type(self.evidence) is not AgenticCampaignEvidenceProjections:
|
|
225
|
+
raise TypeError("evidence must be exact AgenticCampaignEvidenceProjections")
|
|
226
|
+
AgenticCampaignEvidenceProjections.__post_init__(self.evidence)
|
|
227
|
+
if self.prompt_extension is not None:
|
|
228
|
+
if type(self.prompt_extension) is not WorkloadPromptExtensionView:
|
|
229
|
+
raise TypeError(
|
|
230
|
+
"prompt_extension must be an exact "
|
|
231
|
+
"WorkloadPromptExtensionView or None"
|
|
232
|
+
)
|
|
233
|
+
WorkloadPromptExtensionView.__post_init__(self.prompt_extension)
|
|
234
|
+
# Force construction now so an unsupported benchmark fact fails before
|
|
235
|
+
# a campaign can acquire a session.
|
|
236
|
+
self._benchmark_record()
|
|
237
|
+
|
|
238
|
+
def _validate_seed_schema(self, seed: CampaignSeed) -> None:
|
|
239
|
+
candidate_model = self.benchmark.problem.candidate_model
|
|
240
|
+
if not isinstance(candidate_model, type) or not issubclass(
|
|
241
|
+
candidate_model, BaseModel
|
|
242
|
+
):
|
|
243
|
+
raise TypeError("benchmark candidate_model must be a Pydantic model")
|
|
244
|
+
parsed = candidate_model.model_validate(
|
|
245
|
+
thaw_json(seed.configuration),
|
|
246
|
+
strict=True,
|
|
247
|
+
by_alias=False,
|
|
248
|
+
by_name=True,
|
|
249
|
+
)
|
|
250
|
+
round_trip = freeze_json(parsed.model_dump(mode="python", by_alias=False))
|
|
251
|
+
if type(round_trip) is not FrozenJsonObject:
|
|
252
|
+
raise TypeError("candidate_model did not publish an object")
|
|
253
|
+
if typed_json_sha256(round_trip) != seed.configuration_sha256:
|
|
254
|
+
raise ValueError(
|
|
255
|
+
f"seed {seed.seed_id!r} is not canonical under candidate_model"
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def selected_catalog_identity(self) -> tuple[str, int, str]:
|
|
260
|
+
return next(
|
|
261
|
+
identity
|
|
262
|
+
for identity in self.benchmark.finite_variation_catalog_identities
|
|
263
|
+
if identity[0] == self.finite_catalog_id
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def _benchmark_record(self) -> dict[str, object]:
|
|
267
|
+
self.benchmark.validate_binding()
|
|
268
|
+
candidate_model = self.benchmark.problem.candidate_model
|
|
269
|
+
candidate_schema = freeze_json(
|
|
270
|
+
candidate_model.model_json_schema(by_alias=False)
|
|
271
|
+
)
|
|
272
|
+
if type(candidate_schema) is not FrozenJsonObject:
|
|
273
|
+
raise TypeError("candidate schema must be an object")
|
|
274
|
+
evaluator_identity = (
|
|
275
|
+
None
|
|
276
|
+
if self.benchmark.detailed_evaluator is None
|
|
277
|
+
else self.benchmark.detailed_evaluator.evaluator_identity.to_record()
|
|
278
|
+
)
|
|
279
|
+
relation_identity = (
|
|
280
|
+
None
|
|
281
|
+
if self.benchmark.outcome_relation is None
|
|
282
|
+
else self.benchmark.outcome_relation.to_record()
|
|
283
|
+
)
|
|
284
|
+
optimization_semantics = self.benchmark.optimization_semantics
|
|
285
|
+
action_semantics = self.benchmark.action_semantics
|
|
286
|
+
selected_id, selected_version, selected_definition = (
|
|
287
|
+
self.selected_catalog_identity
|
|
288
|
+
)
|
|
289
|
+
record: dict[str, object] = {
|
|
290
|
+
"schema_version": 1,
|
|
291
|
+
"workload_id": self.workload_id,
|
|
292
|
+
"workload_version": self.workload_version,
|
|
293
|
+
"definition_sha256": self.definition_sha256,
|
|
294
|
+
"objectives": [
|
|
295
|
+
{"name": objective.name, "goal": objective.goal}
|
|
296
|
+
for objective in self.benchmark.objectives
|
|
297
|
+
],
|
|
298
|
+
"candidate_schema_sha256": typed_json_sha256(candidate_schema),
|
|
299
|
+
"reward_binding_sha256": self.benchmark.reward.binding_sha256,
|
|
300
|
+
"evaluator_identity": evaluator_identity,
|
|
301
|
+
"outcome_relation": relation_identity,
|
|
302
|
+
"phenotype_identity": {
|
|
303
|
+
"policy_id": self.benchmark.phenotype_identity.policy_id,
|
|
304
|
+
"policy_version": self.benchmark.phenotype_identity.policy_version,
|
|
305
|
+
},
|
|
306
|
+
"optimization_semantics_identity": (
|
|
307
|
+
None
|
|
308
|
+
if optimization_semantics is None
|
|
309
|
+
else list(optimization_semantics.identity)
|
|
310
|
+
),
|
|
311
|
+
"action_semantics_identity": (
|
|
312
|
+
None if action_semantics is None else list(action_semantics.identity)
|
|
313
|
+
),
|
|
314
|
+
"selected_finite_catalog": {
|
|
315
|
+
"catalog_id": selected_id,
|
|
316
|
+
"catalog_version": selected_version,
|
|
317
|
+
"definition_sha256": selected_definition,
|
|
318
|
+
},
|
|
319
|
+
"finite_catalog_identities": [
|
|
320
|
+
{
|
|
321
|
+
"catalog_id": catalog_id,
|
|
322
|
+
"catalog_version": catalog_version,
|
|
323
|
+
"definition_sha256": definition_sha256,
|
|
324
|
+
}
|
|
325
|
+
for catalog_id, catalog_version, definition_sha256 in (
|
|
326
|
+
self.benchmark.finite_variation_catalog_identities
|
|
327
|
+
)
|
|
328
|
+
],
|
|
329
|
+
}
|
|
330
|
+
if self.benchmark.objective_resolution is not None:
|
|
331
|
+
policy = self.benchmark.objective_resolution
|
|
332
|
+
record["objective_resolution"] = {
|
|
333
|
+
"policy_id": policy.policy_id,
|
|
334
|
+
"policy_version": policy.policy_version,
|
|
335
|
+
"definition_sha256": policy.definition_sha256,
|
|
336
|
+
}
|
|
337
|
+
if self.prompt_extension is not None:
|
|
338
|
+
record["workload_prompt_extension"] = (
|
|
339
|
+
self.prompt_extension.to_binding_record()
|
|
340
|
+
)
|
|
341
|
+
return record
|
|
342
|
+
|
|
343
|
+
@property
|
|
344
|
+
def benchmark_record(self) -> FrozenJsonObject:
|
|
345
|
+
value = freeze_json(self._benchmark_record())
|
|
346
|
+
if type(value) is not FrozenJsonObject: # pragma: no cover
|
|
347
|
+
raise AssertionError("benchmark record did not freeze as an object")
|
|
348
|
+
return value
|
|
349
|
+
|
|
350
|
+
def to_record(self) -> dict[str, object]:
|
|
351
|
+
self.__post_init__()
|
|
352
|
+
record: dict[str, object] = {
|
|
353
|
+
"schema_version": 1,
|
|
354
|
+
"benchmark": thaw_json(self.benchmark_record),
|
|
355
|
+
"benchmark_sha256": typed_json_sha256(self.benchmark_record),
|
|
356
|
+
"seeds": [seed.to_record() for seed in self.seeds],
|
|
357
|
+
"finite_catalog_id": self.finite_catalog_id,
|
|
358
|
+
"evaluator_concurrency_cap": self.evaluator_concurrency_cap,
|
|
359
|
+
"evaluator_preflight_receipt_sha256": typed_json_sha256(
|
|
360
|
+
self.evaluator_preflight_receipt
|
|
361
|
+
),
|
|
362
|
+
"resource_lease_receipt_sha256": typed_json_sha256(
|
|
363
|
+
self.resource_lease_receipt
|
|
364
|
+
),
|
|
365
|
+
"evidence": self.evidence.to_record(),
|
|
366
|
+
}
|
|
367
|
+
if self.prompt_extension is not None:
|
|
368
|
+
record["workload_prompt_extension"] = (
|
|
369
|
+
self.prompt_extension.to_binding_record()
|
|
370
|
+
)
|
|
371
|
+
return record
|
|
372
|
+
|
|
373
|
+
@property
|
|
374
|
+
def configuration_sha256(self) -> str:
|
|
375
|
+
return _sha256(_CONFIG_DOMAIN, self.to_record())
|
|
376
|
+
|
|
377
|
+
def build_ports(self) -> CampaignWorkloadPorts:
|
|
378
|
+
"""Create the four campaign ports without opening or evaluating anything."""
|
|
379
|
+
|
|
380
|
+
self.__post_init__()
|
|
381
|
+
registry = _AuthenticatedBindingRegistry(self)
|
|
382
|
+
return CampaignWorkloadPorts(
|
|
383
|
+
benchmark=_AgenticBenchmarkSessionPort(self, registry),
|
|
384
|
+
seeds=_AgenticSeedPort(self, registry),
|
|
385
|
+
catalog=_AgenticCatalogPort(self, registry),
|
|
386
|
+
evidence=_AgenticEvidencePort(self, registry),
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _port_definition(config: AgenticCampaignWorkloadConfig, role: str) -> str:
|
|
391
|
+
return _sha256(
|
|
392
|
+
_PORT_DOMAIN,
|
|
393
|
+
{
|
|
394
|
+
"schema_version": 1,
|
|
395
|
+
"adapter": "agentic_benchmark_campaign_workload",
|
|
396
|
+
"adapter_implementation_revision": _PORT_ADAPTER_IMPLEMENTATION_REVISION,
|
|
397
|
+
"role": role,
|
|
398
|
+
"configuration_sha256": config.configuration_sha256,
|
|
399
|
+
},
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def _benchmark_option_phenotype_bindings(
|
|
404
|
+
benchmark: AgenticBenchmark,
|
|
405
|
+
contract: FiniteVariationContract,
|
|
406
|
+
) -> tuple[OptionPhenotypeBinding, ...]:
|
|
407
|
+
"""Project every child through the benchmark's declared phenotype law."""
|
|
408
|
+
|
|
409
|
+
benchmark.validate_binding()
|
|
410
|
+
policy = benchmark.phenotype_identity
|
|
411
|
+
expected_policy = (policy.policy_id, policy.policy_version)
|
|
412
|
+
bindings = []
|
|
413
|
+
for option in contract.options:
|
|
414
|
+
identity = policy.identify(thaw_json(option.child_configuration))
|
|
415
|
+
if type(identity) is not PhenotypeIdentity:
|
|
416
|
+
raise TypeError(
|
|
417
|
+
"benchmark phenotype policy must return exact PhenotypeIdentity"
|
|
418
|
+
)
|
|
419
|
+
PhenotypeIdentity.__post_init__(identity)
|
|
420
|
+
if (identity.policy_id, identity.policy_version) != expected_policy:
|
|
421
|
+
raise ValueError("phenotype policy returned a foreign identity law")
|
|
422
|
+
bindings.append(
|
|
423
|
+
OptionPhenotypeBinding(
|
|
424
|
+
option_id=option.option_id,
|
|
425
|
+
option_identity_sha256=option.identity_sha256,
|
|
426
|
+
phenotype_identity_sha256=identity.value_sha256,
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
return tuple(bindings)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
@dataclass(frozen=True, slots=True)
|
|
433
|
+
class _BaseBindingKey:
|
|
434
|
+
"""Exact immutable authority key before a novelty cutoff is applied."""
|
|
435
|
+
|
|
436
|
+
configuration_sha256: str
|
|
437
|
+
benchmark_sha256: str
|
|
438
|
+
phenotype_policy_id: str
|
|
439
|
+
phenotype_policy_version: int
|
|
440
|
+
catalog_id: str
|
|
441
|
+
catalog_version: int
|
|
442
|
+
catalog_definition_sha256: str
|
|
443
|
+
parent_configuration_sha256: str
|
|
444
|
+
|
|
445
|
+
def to_record(self) -> dict[str, object]:
|
|
446
|
+
return {
|
|
447
|
+
"configuration_sha256": self.configuration_sha256,
|
|
448
|
+
"benchmark_sha256": self.benchmark_sha256,
|
|
449
|
+
"phenotype_policy_id": self.phenotype_policy_id,
|
|
450
|
+
"phenotype_policy_version": self.phenotype_policy_version,
|
|
451
|
+
"catalog_id": self.catalog_id,
|
|
452
|
+
"catalog_version": self.catalog_version,
|
|
453
|
+
"catalog_definition_sha256": self.catalog_definition_sha256,
|
|
454
|
+
"parent_configuration_sha256": self.parent_configuration_sha256,
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
@dataclass(frozen=True, slots=True)
|
|
459
|
+
class _BaseBinding:
|
|
460
|
+
contract: FiniteVariationContract
|
|
461
|
+
option_phenotypes: tuple[OptionPhenotypeBinding, ...]
|
|
462
|
+
contract_identity_sha256: str
|
|
463
|
+
option_phenotypes_sha256: str
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
@dataclass(frozen=True, slots=True)
|
|
467
|
+
class _IssuedBinding:
|
|
468
|
+
binding: ParentVariationBinding
|
|
469
|
+
key_sha256: str
|
|
470
|
+
base_contract_identity_sha256: str
|
|
471
|
+
option_phenotypes_sha256: str
|
|
472
|
+
eligible_contract_identity_sha256: str
|
|
473
|
+
eligibility_receipt_sha256: str
|
|
474
|
+
binding_authenticator_sha256: str
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
class _AuthenticatedBindingRegistry:
|
|
478
|
+
"""Private provenance and memoization boundary shared by one port set.
|
|
479
|
+
|
|
480
|
+
Structural equality is intentionally insufficient. Evidence projections
|
|
481
|
+
accept only the exact object issued by their sibling catalog port and also
|
|
482
|
+
recheck a cryptographic fingerprint, closing both coherent forgery and
|
|
483
|
+
post-issuance mutation. The registry is private to one ``build_ports``
|
|
484
|
+
invocation, so bindings cannot cross a campaign port/session boundary.
|
|
485
|
+
"""
|
|
486
|
+
|
|
487
|
+
__slots__ = (
|
|
488
|
+
"_base_bindings",
|
|
489
|
+
"_benchmark_sha256",
|
|
490
|
+
"_bindings",
|
|
491
|
+
"_catalog_identity",
|
|
492
|
+
"_config",
|
|
493
|
+
"_configuration_sha256",
|
|
494
|
+
"_phenotype_policy_identity",
|
|
495
|
+
"_sessions",
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
def __init__(self, config: AgenticCampaignWorkloadConfig) -> None:
|
|
499
|
+
self._config = config
|
|
500
|
+
self._configuration_sha256 = config.configuration_sha256
|
|
501
|
+
self._benchmark_sha256 = typed_json_sha256(config.benchmark_record)
|
|
502
|
+
policy = config.benchmark.phenotype_identity
|
|
503
|
+
self._phenotype_policy_identity = (policy.policy_id, policy.policy_version)
|
|
504
|
+
self._catalog_identity = config.selected_catalog_identity
|
|
505
|
+
self._base_bindings: dict[_BaseBindingKey, _BaseBinding] = {}
|
|
506
|
+
self._bindings: dict[tuple[_BaseBindingKey, tuple[str, ...]], _IssuedBinding] = {}
|
|
507
|
+
self._sessions: dict[str, tuple[CampaignBenchmarkSession, str]] = {}
|
|
508
|
+
|
|
509
|
+
def issue_session(
|
|
510
|
+
self,
|
|
511
|
+
session: CampaignBenchmarkSession,
|
|
512
|
+
) -> CampaignBenchmarkSession:
|
|
513
|
+
request_sha256 = session.request_sha256
|
|
514
|
+
cached = self._sessions.get(request_sha256)
|
|
515
|
+
if cached is not None:
|
|
516
|
+
cached_session, session_sha256 = cached
|
|
517
|
+
if cached_session.session_sha256 != session_sha256:
|
|
518
|
+
raise ValueError("cached campaign session was mutated")
|
|
519
|
+
return cached_session
|
|
520
|
+
self._sessions[request_sha256] = (session, session.session_sha256)
|
|
521
|
+
return session
|
|
522
|
+
|
|
523
|
+
def require_session(self, session: CampaignBenchmarkSession) -> None:
|
|
524
|
+
cached = self._sessions.get(session.request_sha256)
|
|
525
|
+
if cached is None or cached[0] is not session:
|
|
526
|
+
raise ValueError(
|
|
527
|
+
"session was not issued by this exact campaign port set"
|
|
528
|
+
)
|
|
529
|
+
if session.session_sha256 != cached[1]:
|
|
530
|
+
raise ValueError("issued campaign session failed authentication")
|
|
531
|
+
|
|
532
|
+
def _validate_authority(self, benchmark: FrozenJsonObject) -> None:
|
|
533
|
+
if benchmark != self._config.benchmark_record:
|
|
534
|
+
raise ValueError("catalog request is bound to a foreign benchmark")
|
|
535
|
+
if self._config.configuration_sha256 != self._configuration_sha256:
|
|
536
|
+
raise ValueError("campaign workload configuration drifted after port build")
|
|
537
|
+
if typed_json_sha256(benchmark) != self._benchmark_sha256:
|
|
538
|
+
raise ValueError("campaign benchmark identity drifted after port build")
|
|
539
|
+
policy = self._config.benchmark.phenotype_identity
|
|
540
|
+
if (policy.policy_id, policy.policy_version) != (
|
|
541
|
+
self._phenotype_policy_identity
|
|
542
|
+
):
|
|
543
|
+
raise ValueError("phenotype identity policy drifted after port build")
|
|
544
|
+
if self._config.selected_catalog_identity != self._catalog_identity:
|
|
545
|
+
raise ValueError("finite catalog identity drifted after port build")
|
|
546
|
+
|
|
547
|
+
def _base_key(
|
|
548
|
+
self,
|
|
549
|
+
benchmark: FrozenJsonObject,
|
|
550
|
+
parent: FrozenJsonObject,
|
|
551
|
+
) -> _BaseBindingKey:
|
|
552
|
+
self._validate_authority(benchmark)
|
|
553
|
+
policy_id, policy_version = self._phenotype_policy_identity
|
|
554
|
+
catalog_id, catalog_version, catalog_definition_sha256 = (
|
|
555
|
+
self._catalog_identity
|
|
556
|
+
)
|
|
557
|
+
return _BaseBindingKey(
|
|
558
|
+
configuration_sha256=self._configuration_sha256,
|
|
559
|
+
benchmark_sha256=self._benchmark_sha256,
|
|
560
|
+
phenotype_policy_id=policy_id,
|
|
561
|
+
phenotype_policy_version=policy_version,
|
|
562
|
+
catalog_id=catalog_id,
|
|
563
|
+
catalog_version=catalog_version,
|
|
564
|
+
catalog_definition_sha256=catalog_definition_sha256,
|
|
565
|
+
parent_configuration_sha256=typed_json_sha256(parent),
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
@staticmethod
|
|
569
|
+
def _option_phenotypes_sha256(
|
|
570
|
+
values: tuple[OptionPhenotypeBinding, ...],
|
|
571
|
+
) -> str:
|
|
572
|
+
return _sha256(
|
|
573
|
+
_OPTION_PHENOTYPE_SET_DOMAIN,
|
|
574
|
+
[value.to_record() for value in values],
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
@staticmethod
|
|
578
|
+
def _key_sha256(
|
|
579
|
+
base_key: _BaseBindingKey,
|
|
580
|
+
known_phenotype_sha256s: tuple[str, ...],
|
|
581
|
+
) -> str:
|
|
582
|
+
return _sha256(
|
|
583
|
+
_BINDING_KEY_DOMAIN,
|
|
584
|
+
{
|
|
585
|
+
**base_key.to_record(),
|
|
586
|
+
"known_phenotype_sha256s": list(known_phenotype_sha256s),
|
|
587
|
+
},
|
|
588
|
+
)
|
|
589
|
+
|
|
590
|
+
@staticmethod
|
|
591
|
+
def _binding_authenticator(
|
|
592
|
+
*,
|
|
593
|
+
binding: ParentVariationBinding,
|
|
594
|
+
key_sha256: str,
|
|
595
|
+
base_contract_identity_sha256: str,
|
|
596
|
+
option_phenotypes_sha256: str,
|
|
597
|
+
eligibility_receipt_sha256: str,
|
|
598
|
+
) -> str:
|
|
599
|
+
return _sha256(
|
|
600
|
+
_ISSUED_BINDING_DOMAIN,
|
|
601
|
+
{
|
|
602
|
+
"key_sha256": key_sha256,
|
|
603
|
+
"base_contract_identity_sha256": (
|
|
604
|
+
base_contract_identity_sha256
|
|
605
|
+
),
|
|
606
|
+
"option_phenotypes_sha256": option_phenotypes_sha256,
|
|
607
|
+
"eligible_contract_identity_sha256": (
|
|
608
|
+
binding.contract.identity_sha256
|
|
609
|
+
),
|
|
610
|
+
"eligibility_receipt_sha256": eligibility_receipt_sha256,
|
|
611
|
+
"binding": binding.to_record(),
|
|
612
|
+
},
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
def _base_binding(
|
|
616
|
+
self,
|
|
617
|
+
key: _BaseBindingKey,
|
|
618
|
+
parent: FrozenJsonObject,
|
|
619
|
+
) -> _BaseBinding:
|
|
620
|
+
cached = self._base_bindings.get(key)
|
|
621
|
+
if cached is not None:
|
|
622
|
+
if (
|
|
623
|
+
cached.contract.identity_sha256
|
|
624
|
+
!= cached.contract_identity_sha256
|
|
625
|
+
or self._option_phenotypes_sha256(cached.option_phenotypes)
|
|
626
|
+
!= cached.option_phenotypes_sha256
|
|
627
|
+
):
|
|
628
|
+
raise ValueError("cached finite catalog authority was mutated")
|
|
629
|
+
return cached
|
|
630
|
+
contract = self._config.benchmark.bind_finite_variation(
|
|
631
|
+
self._config.finite_catalog_id,
|
|
632
|
+
thaw_json(parent),
|
|
633
|
+
)
|
|
634
|
+
option_phenotypes = _benchmark_option_phenotype_bindings(
|
|
635
|
+
self._config.benchmark,
|
|
636
|
+
contract,
|
|
637
|
+
)
|
|
638
|
+
created = _BaseBinding(
|
|
639
|
+
contract=contract,
|
|
640
|
+
option_phenotypes=option_phenotypes,
|
|
641
|
+
contract_identity_sha256=contract.identity_sha256,
|
|
642
|
+
option_phenotypes_sha256=self._option_phenotypes_sha256(
|
|
643
|
+
option_phenotypes
|
|
644
|
+
),
|
|
645
|
+
)
|
|
646
|
+
self._base_bindings[key] = created
|
|
647
|
+
return created
|
|
648
|
+
|
|
649
|
+
def bind(
|
|
650
|
+
self,
|
|
651
|
+
benchmark: FrozenJsonObject,
|
|
652
|
+
parent: FrozenJsonObject,
|
|
653
|
+
known_phenotype_sha256s: tuple[str, ...],
|
|
654
|
+
) -> ParentVariationBinding:
|
|
655
|
+
base_key = self._base_key(benchmark, parent)
|
|
656
|
+
cache_key = (base_key, known_phenotype_sha256s)
|
|
657
|
+
cached = self._bindings.get(cache_key)
|
|
658
|
+
if cached is not None:
|
|
659
|
+
self._validate_issued(cached, cached.binding)
|
|
660
|
+
return cached.binding
|
|
661
|
+
|
|
662
|
+
base = self._base_binding(base_key, parent)
|
|
663
|
+
eligibility = eligible_finite_variation_view(
|
|
664
|
+
contract=base.contract,
|
|
665
|
+
option_phenotypes=base.option_phenotypes,
|
|
666
|
+
known_phenotype_sha256s=known_phenotype_sha256s,
|
|
667
|
+
)
|
|
668
|
+
binding = ParentVariationBinding(
|
|
669
|
+
benchmark_sha256=self._benchmark_sha256,
|
|
670
|
+
parent_configuration_sha256=base_key.parent_configuration_sha256,
|
|
671
|
+
known_phenotype_sha256s=known_phenotype_sha256s,
|
|
672
|
+
contract=eligibility.contract,
|
|
673
|
+
eligibility_receipt=eligibility.receipt,
|
|
674
|
+
)
|
|
675
|
+
key_sha256 = self._key_sha256(base_key, known_phenotype_sha256s)
|
|
676
|
+
receipt_sha256 = eligibility.receipt.receipt_sha256
|
|
677
|
+
issued = _IssuedBinding(
|
|
678
|
+
binding=binding,
|
|
679
|
+
key_sha256=key_sha256,
|
|
680
|
+
base_contract_identity_sha256=base.contract_identity_sha256,
|
|
681
|
+
option_phenotypes_sha256=base.option_phenotypes_sha256,
|
|
682
|
+
eligible_contract_identity_sha256=eligibility.contract.identity_sha256,
|
|
683
|
+
eligibility_receipt_sha256=receipt_sha256,
|
|
684
|
+
binding_authenticator_sha256=self._binding_authenticator(
|
|
685
|
+
binding=binding,
|
|
686
|
+
key_sha256=key_sha256,
|
|
687
|
+
base_contract_identity_sha256=base.contract_identity_sha256,
|
|
688
|
+
option_phenotypes_sha256=base.option_phenotypes_sha256,
|
|
689
|
+
eligibility_receipt_sha256=receipt_sha256,
|
|
690
|
+
),
|
|
691
|
+
)
|
|
692
|
+
self._bindings[cache_key] = issued
|
|
693
|
+
return binding
|
|
694
|
+
|
|
695
|
+
def require_issued(
|
|
696
|
+
self,
|
|
697
|
+
benchmark: FrozenJsonObject,
|
|
698
|
+
parent: FrozenJsonObject,
|
|
699
|
+
variation: ParentVariationBinding,
|
|
700
|
+
) -> None:
|
|
701
|
+
base_key = self._base_key(benchmark, parent)
|
|
702
|
+
cache_key = (base_key, variation.known_phenotype_sha256s)
|
|
703
|
+
issued = self._bindings.get(cache_key)
|
|
704
|
+
if issued is None or issued.binding is not variation:
|
|
705
|
+
raise ValueError(
|
|
706
|
+
"variation is not the selected catalog's exact eligible view "
|
|
707
|
+
"issued by this campaign port set"
|
|
708
|
+
)
|
|
709
|
+
self._validate_issued(issued, variation)
|
|
710
|
+
|
|
711
|
+
def _validate_issued(
|
|
712
|
+
self,
|
|
713
|
+
issued: _IssuedBinding,
|
|
714
|
+
variation: ParentVariationBinding,
|
|
715
|
+
) -> None:
|
|
716
|
+
ParentVariationBinding.__post_init__(variation)
|
|
717
|
+
receipt = variation.eligibility_receipt
|
|
718
|
+
if receipt is None:
|
|
719
|
+
raise ValueError("issued variation omitted its eligibility receipt")
|
|
720
|
+
if (
|
|
721
|
+
variation.contract.identity_sha256
|
|
722
|
+
!= issued.eligible_contract_identity_sha256
|
|
723
|
+
or receipt.base_contract_identity_sha256
|
|
724
|
+
!= issued.base_contract_identity_sha256
|
|
725
|
+
or self._option_phenotypes_sha256(receipt.option_phenotypes)
|
|
726
|
+
!= issued.option_phenotypes_sha256
|
|
727
|
+
or receipt.receipt_sha256 != issued.eligibility_receipt_sha256
|
|
728
|
+
or self._binding_authenticator(
|
|
729
|
+
binding=variation,
|
|
730
|
+
key_sha256=issued.key_sha256,
|
|
731
|
+
base_contract_identity_sha256=(
|
|
732
|
+
issued.base_contract_identity_sha256
|
|
733
|
+
),
|
|
734
|
+
option_phenotypes_sha256=issued.option_phenotypes_sha256,
|
|
735
|
+
eligibility_receipt_sha256=issued.eligibility_receipt_sha256,
|
|
736
|
+
)
|
|
737
|
+
!= issued.binding_authenticator_sha256
|
|
738
|
+
):
|
|
739
|
+
raise ValueError("issued variation authority failed authentication")
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
@dataclass(frozen=True, slots=True)
|
|
743
|
+
class _AgenticBenchmarkSessionPort:
|
|
744
|
+
config: AgenticCampaignWorkloadConfig
|
|
745
|
+
registry: _AuthenticatedBindingRegistry
|
|
746
|
+
port_id = "agentic_benchmark_session"
|
|
747
|
+
port_version = 1
|
|
748
|
+
|
|
749
|
+
@property
|
|
750
|
+
def definition_sha256(self) -> str:
|
|
751
|
+
return _port_definition(self.config, "benchmark")
|
|
752
|
+
|
|
753
|
+
def open(self, request: BenchmarkSessionRequest) -> CampaignBenchmarkSession:
|
|
754
|
+
if type(request) is not BenchmarkSessionRequest:
|
|
755
|
+
raise TypeError("request must be an exact BenchmarkSessionRequest")
|
|
756
|
+
BenchmarkSessionRequest.__post_init__(request)
|
|
757
|
+
self.config.benchmark.validate_binding()
|
|
758
|
+
return self.registry.issue_session(
|
|
759
|
+
CampaignBenchmarkSession(
|
|
760
|
+
request_sha256=request.request_sha256,
|
|
761
|
+
benchmark=self.config.benchmark_record,
|
|
762
|
+
evaluator_concurrency_cap=self.config.evaluator_concurrency_cap,
|
|
763
|
+
preflight_receipt=self.config.evaluator_preflight_receipt,
|
|
764
|
+
resource_lease=self.config.resource_lease_receipt,
|
|
765
|
+
)
|
|
766
|
+
)
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@dataclass(frozen=True, slots=True)
|
|
770
|
+
class _AgenticSeedPort:
|
|
771
|
+
config: AgenticCampaignWorkloadConfig
|
|
772
|
+
registry: _AuthenticatedBindingRegistry
|
|
773
|
+
port_id = "agentic_benchmark_seeds"
|
|
774
|
+
port_version = 1
|
|
775
|
+
|
|
776
|
+
@property
|
|
777
|
+
def definition_sha256(self) -> str:
|
|
778
|
+
return _port_definition(self.config, "seeds")
|
|
779
|
+
|
|
780
|
+
def load(self, session: CampaignBenchmarkSession) -> CampaignSeedBatch:
|
|
781
|
+
_validate_session(self.config, session)
|
|
782
|
+
self.registry.require_session(session)
|
|
783
|
+
return CampaignSeedBatch(
|
|
784
|
+
session_sha256=session.session_sha256,
|
|
785
|
+
seeds=self.config.seeds,
|
|
786
|
+
)
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
@dataclass(frozen=True, slots=True)
|
|
790
|
+
class _AgenticCatalogPort:
|
|
791
|
+
config: AgenticCampaignWorkloadConfig
|
|
792
|
+
registry: _AuthenticatedBindingRegistry
|
|
793
|
+
port_id = "agentic_benchmark_catalog"
|
|
794
|
+
port_version = 1
|
|
795
|
+
|
|
796
|
+
@property
|
|
797
|
+
def definition_sha256(self) -> str:
|
|
798
|
+
return _port_definition(self.config, "catalog")
|
|
799
|
+
|
|
800
|
+
def bind(
|
|
801
|
+
self,
|
|
802
|
+
benchmark: FrozenJsonObject,
|
|
803
|
+
parent: FrozenJsonObject,
|
|
804
|
+
known_phenotype_sha256s: tuple[str, ...],
|
|
805
|
+
) -> ParentVariationBinding:
|
|
806
|
+
if benchmark != self.config.benchmark_record:
|
|
807
|
+
raise ValueError("catalog request is bound to a foreign benchmark")
|
|
808
|
+
_require_object(parent, name="parent")
|
|
809
|
+
if type(known_phenotype_sha256s) is not tuple:
|
|
810
|
+
raise TypeError("known_phenotype_sha256s must be an exact tuple")
|
|
811
|
+
for value in known_phenotype_sha256s:
|
|
812
|
+
_require_sha256(value, name="known_phenotype_sha256")
|
|
813
|
+
if known_phenotype_sha256s != tuple(sorted(set(known_phenotype_sha256s))):
|
|
814
|
+
raise ValueError("known phenotype hashes must be unique and canonical")
|
|
815
|
+
return self.registry.bind(benchmark, parent, known_phenotype_sha256s)
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
@dataclass(frozen=True, slots=True)
|
|
819
|
+
class _AgenticEvidencePort:
|
|
820
|
+
config: AgenticCampaignWorkloadConfig
|
|
821
|
+
registry: _AuthenticatedBindingRegistry
|
|
822
|
+
port_id = "agentic_benchmark_evidence"
|
|
823
|
+
port_version = 1
|
|
824
|
+
|
|
825
|
+
@property
|
|
826
|
+
def definition_sha256(self) -> str:
|
|
827
|
+
return _port_definition(self.config, "evidence")
|
|
828
|
+
|
|
829
|
+
def initialize_memory(
|
|
830
|
+
self,
|
|
831
|
+
session: CampaignBenchmarkSession,
|
|
832
|
+
seeds: CampaignSeedBatch,
|
|
833
|
+
) -> FrozenJsonObject:
|
|
834
|
+
_validate_session(self.config, session)
|
|
835
|
+
self.registry.require_session(session)
|
|
836
|
+
if type(seeds) is not CampaignSeedBatch:
|
|
837
|
+
raise TypeError("seeds must be an exact CampaignSeedBatch")
|
|
838
|
+
CampaignSeedBatch.__post_init__(seeds)
|
|
839
|
+
if seeds.session_sha256 != session.session_sha256:
|
|
840
|
+
raise ValueError("seed batch is bound to a foreign session")
|
|
841
|
+
if seeds.seeds != self.config.seeds:
|
|
842
|
+
raise ValueError("evidence seed batch differs from workload seeds")
|
|
843
|
+
result = self.config.evidence.initialize_memory(
|
|
844
|
+
self.config.benchmark,
|
|
845
|
+
session,
|
|
846
|
+
seeds,
|
|
847
|
+
)
|
|
848
|
+
return _require_object(result, name="initialized memory")
|
|
849
|
+
|
|
850
|
+
def context(
|
|
851
|
+
self,
|
|
852
|
+
session: CampaignBenchmarkSession,
|
|
853
|
+
parent: FrozenJsonObject,
|
|
854
|
+
variation: ParentVariationBinding,
|
|
855
|
+
memory: FrozenJsonObject,
|
|
856
|
+
) -> FrozenJsonObject:
|
|
857
|
+
self._validate_projection_request(session, parent, variation, memory)
|
|
858
|
+
result = self.config.evidence.context(
|
|
859
|
+
self.config.benchmark,
|
|
860
|
+
session,
|
|
861
|
+
parent,
|
|
862
|
+
variation,
|
|
863
|
+
memory,
|
|
864
|
+
)
|
|
865
|
+
context = _require_object(result, name="evidence context")
|
|
866
|
+
extension = self.config.prompt_extension
|
|
867
|
+
if extension is None:
|
|
868
|
+
return context
|
|
869
|
+
mutable_context = thaw_json(context)
|
|
870
|
+
if type(mutable_context) is not dict: # pragma: no cover - exact guard above
|
|
871
|
+
raise AssertionError("evidence context did not thaw as an object")
|
|
872
|
+
if WORKLOAD_PROMPT_EXTENSION_CONTEXT_KEY in mutable_context:
|
|
873
|
+
raise ValueError(
|
|
874
|
+
"evidence projection used the reserved workload prompt "
|
|
875
|
+
"extension context key"
|
|
876
|
+
)
|
|
877
|
+
mutable_context[WORKLOAD_PROMPT_EXTENSION_CONTEXT_KEY] = (
|
|
878
|
+
extension.to_prompt_record()
|
|
879
|
+
)
|
|
880
|
+
attached = freeze_json(mutable_context)
|
|
881
|
+
return _require_object(attached, name="extended evidence context")
|
|
882
|
+
|
|
883
|
+
def cards(
|
|
884
|
+
self,
|
|
885
|
+
session: CampaignBenchmarkSession,
|
|
886
|
+
parent: FrozenJsonObject,
|
|
887
|
+
variation: ParentVariationBinding,
|
|
888
|
+
memory: FrozenJsonObject,
|
|
889
|
+
) -> tuple[FrozenJsonObject, ...]:
|
|
890
|
+
self._validate_projection_request(session, parent, variation, memory)
|
|
891
|
+
result = self.config.evidence.cards(
|
|
892
|
+
self.config.benchmark,
|
|
893
|
+
session,
|
|
894
|
+
parent,
|
|
895
|
+
variation,
|
|
896
|
+
memory,
|
|
897
|
+
)
|
|
898
|
+
if type(result) is not tuple or any(
|
|
899
|
+
type(card) is not FrozenJsonObject for card in result
|
|
900
|
+
):
|
|
901
|
+
raise TypeError("evidence cards must be an exact tuple of frozen objects")
|
|
902
|
+
for card in result:
|
|
903
|
+
_require_object(card, name="evidence card")
|
|
904
|
+
return result
|
|
905
|
+
|
|
906
|
+
def _validate_projection_request(
|
|
907
|
+
self,
|
|
908
|
+
session: CampaignBenchmarkSession,
|
|
909
|
+
parent: FrozenJsonObject,
|
|
910
|
+
variation: ParentVariationBinding,
|
|
911
|
+
memory: FrozenJsonObject,
|
|
912
|
+
) -> None:
|
|
913
|
+
_validate_session(self.config, session)
|
|
914
|
+
self.registry.require_session(session)
|
|
915
|
+
_require_object(parent, name="parent")
|
|
916
|
+
_require_object(memory, name="memory")
|
|
917
|
+
if type(variation) is not ParentVariationBinding:
|
|
918
|
+
raise TypeError("variation must be an exact ParentVariationBinding")
|
|
919
|
+
ParentVariationBinding.__post_init__(variation)
|
|
920
|
+
if variation.benchmark_sha256 != typed_json_sha256(session.benchmark):
|
|
921
|
+
raise ValueError("variation is bound to a foreign benchmark")
|
|
922
|
+
if variation.parent_configuration_sha256 != typed_json_sha256(parent):
|
|
923
|
+
raise ValueError("variation is bound to a foreign parent")
|
|
924
|
+
self.registry.require_issued(session.benchmark, parent, variation)
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
def _validate_session(
|
|
928
|
+
config: AgenticCampaignWorkloadConfig,
|
|
929
|
+
session: CampaignBenchmarkSession,
|
|
930
|
+
) -> None:
|
|
931
|
+
if type(session) is not CampaignBenchmarkSession:
|
|
932
|
+
raise TypeError("session must be an exact CampaignBenchmarkSession")
|
|
933
|
+
CampaignBenchmarkSession.__post_init__(session)
|
|
934
|
+
if session.benchmark != config.benchmark_record:
|
|
935
|
+
raise ValueError("session is bound to a foreign benchmark")
|
|
936
|
+
if session.evaluator_concurrency_cap != config.evaluator_concurrency_cap:
|
|
937
|
+
raise ValueError("session evaluator concurrency changed")
|
|
938
|
+
if session.preflight_receipt != config.evaluator_preflight_receipt:
|
|
939
|
+
raise ValueError("session preflight receipt changed")
|
|
940
|
+
if session.resource_lease != config.resource_lease_receipt:
|
|
941
|
+
raise ValueError("session resource lease changed")
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
__all__ = [
|
|
945
|
+
"AgenticCampaignEvidenceProjections",
|
|
946
|
+
"AgenticCampaignWorkloadConfig",
|
|
947
|
+
"CardProjection",
|
|
948
|
+
"ContextProjection",
|
|
949
|
+
"MemoryProjection",
|
|
950
|
+
]
|