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,827 @@
|
|
|
1
|
+
"""Provider- and workload-neutral contextual allocation contract."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import re
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
|
|
10
|
+
from agent_evolve.domain.patch import require_sha256
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
|
|
14
|
+
_CONTRACT_DOMAIN = b"agent-evolve:contextual-portfolio-allocation-contract:v1\x00"
|
|
15
|
+
_REALIZATION_DOMAIN = b"agent-evolve:contextual-portfolio-allocation-realization:v1\x00"
|
|
16
|
+
_CAPABILITY_WITNESS_DOMAIN = (
|
|
17
|
+
b"agent-evolve:contextual-arm-count-capability-witness:v1\x00"
|
|
18
|
+
)
|
|
19
|
+
_CAPABILITY_DOMAIN = b"agent-evolve:contextual-arm-count-capability:v1\x00"
|
|
20
|
+
_JOINT_VECTOR_DOMAIN = b"agent-evolve:contextual-joint-count-vector:v1\x00"
|
|
21
|
+
_LANE_JOINT_CAPABILITY_DOMAIN = (
|
|
22
|
+
b"agent-evolve:contextual-lane-joint-count-capability:v1\x00"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _canonical_json(value: object) -> bytes:
|
|
27
|
+
return json.dumps(
|
|
28
|
+
value,
|
|
29
|
+
allow_nan=False,
|
|
30
|
+
ensure_ascii=True,
|
|
31
|
+
separators=(",", ":"),
|
|
32
|
+
sort_keys=True,
|
|
33
|
+
).encode("ascii", errors="strict")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _require_token(value: str, *, name: str) -> None:
|
|
37
|
+
if type(value) is not str or _TOKEN.fullmatch(value) is None:
|
|
38
|
+
raise ValueError(f"{name} must use the closed token grammar")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _validate_counts(
|
|
42
|
+
values: tuple[tuple[str, int], ...],
|
|
43
|
+
*,
|
|
44
|
+
name: str,
|
|
45
|
+
expected_slots: int,
|
|
46
|
+
) -> None:
|
|
47
|
+
if type(values) is not tuple or not values:
|
|
48
|
+
raise ValueError(f"{name} must be a non-empty exact tuple")
|
|
49
|
+
for arm_id, count in values:
|
|
50
|
+
_require_token(arm_id, name=f"{name}.arm_id")
|
|
51
|
+
if type(count) is not int or count < 0:
|
|
52
|
+
raise ValueError(f"{name} counts must be non-negative")
|
|
53
|
+
if values != tuple(sorted(values)) or len({value[0] for value in values}) != len(
|
|
54
|
+
values
|
|
55
|
+
):
|
|
56
|
+
raise ValueError(f"{name} must use canonical unique arms")
|
|
57
|
+
if sum(value[1] for value in values) != expected_slots:
|
|
58
|
+
raise ValueError(f"{name} must allocate every evaluation slot")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True, slots=True)
|
|
62
|
+
class ContextualArmCountCapabilityWitness:
|
|
63
|
+
"""One prior, actually realized stage-level arm-count vector.
|
|
64
|
+
|
|
65
|
+
A witness says only that an allocation was realizable under an earlier
|
|
66
|
+
prior-wave candidate set. It is deliberately weaker than a promise about
|
|
67
|
+
the current wave. Keeping that distinction explicit lets a controller use
|
|
68
|
+
the evidence conservatively without smuggling workload rules into the
|
|
69
|
+
application layer.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
controller_wave_index: int
|
|
73
|
+
evaluation_slots: int
|
|
74
|
+
realized_target_counts: tuple[tuple[str, int], ...]
|
|
75
|
+
allocation_realization_sha256s: tuple[str, ...]
|
|
76
|
+
witness_sha256: str = field(init=False)
|
|
77
|
+
|
|
78
|
+
def __post_init__(self) -> None:
|
|
79
|
+
if (
|
|
80
|
+
type(self.controller_wave_index) is not int
|
|
81
|
+
or self.controller_wave_index <= 0
|
|
82
|
+
):
|
|
83
|
+
raise ValueError("controller_wave_index must be positive")
|
|
84
|
+
if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
|
|
85
|
+
raise ValueError("evaluation_slots must be positive")
|
|
86
|
+
_validate_counts(
|
|
87
|
+
self.realized_target_counts,
|
|
88
|
+
name="realized_target_counts",
|
|
89
|
+
expected_slots=self.evaluation_slots,
|
|
90
|
+
)
|
|
91
|
+
if (
|
|
92
|
+
type(self.allocation_realization_sha256s) is not tuple
|
|
93
|
+
or not self.allocation_realization_sha256s
|
|
94
|
+
or self.allocation_realization_sha256s
|
|
95
|
+
!= tuple(sorted(set(self.allocation_realization_sha256s)))
|
|
96
|
+
):
|
|
97
|
+
raise ValueError(
|
|
98
|
+
"allocation realization hashes must be non-empty and canonical"
|
|
99
|
+
)
|
|
100
|
+
for value in self.allocation_realization_sha256s:
|
|
101
|
+
require_sha256(value, "allocation_realization_sha256")
|
|
102
|
+
object.__setattr__(
|
|
103
|
+
self,
|
|
104
|
+
"witness_sha256",
|
|
105
|
+
hashlib.sha256(
|
|
106
|
+
_CAPABILITY_WITNESS_DOMAIN + _canonical_json(self._unsigned_record())
|
|
107
|
+
).hexdigest(),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
111
|
+
return {
|
|
112
|
+
"schema_version": 1,
|
|
113
|
+
"controller_wave_index": self.controller_wave_index,
|
|
114
|
+
"evaluation_slots": self.evaluation_slots,
|
|
115
|
+
"realized_target_counts": [
|
|
116
|
+
list(value) for value in self.realized_target_counts
|
|
117
|
+
],
|
|
118
|
+
"allocation_realization_sha256s": list(self.allocation_realization_sha256s),
|
|
119
|
+
"interpretation": "prior_realized_witness_not_current_capacity_promise",
|
|
120
|
+
"objective_values_consulted": False,
|
|
121
|
+
"workload_identifiers_consulted": False,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
def to_record(self) -> dict[str, object]:
|
|
125
|
+
self.__post_init__()
|
|
126
|
+
return {**self._unsigned_record(), "witness_sha256": self.witness_sha256}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@dataclass(frozen=True, slots=True)
|
|
130
|
+
class ContextualArmCountCapability:
|
|
131
|
+
"""A workload-blind empirical feasible-count set for one arm kind."""
|
|
132
|
+
|
|
133
|
+
kind: str
|
|
134
|
+
evaluation_slots: int
|
|
135
|
+
arm_ids: tuple[str, ...]
|
|
136
|
+
witnesses: tuple[ContextualArmCountCapabilityWitness, ...]
|
|
137
|
+
capability_sha256: str = field(init=False)
|
|
138
|
+
|
|
139
|
+
def __post_init__(self) -> None:
|
|
140
|
+
if self.kind not in {"source", "operator"}:
|
|
141
|
+
raise ValueError("kind must be source or operator")
|
|
142
|
+
if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
|
|
143
|
+
raise ValueError("evaluation_slots must be positive")
|
|
144
|
+
if type(self.arm_ids) is not tuple or not self.arm_ids:
|
|
145
|
+
raise ValueError("arm_ids must be a non-empty exact tuple")
|
|
146
|
+
for value in self.arm_ids:
|
|
147
|
+
_require_token(value, name="arm_id")
|
|
148
|
+
if self.arm_ids != tuple(sorted(set(self.arm_ids))):
|
|
149
|
+
raise ValueError("arm_ids must be unique and canonical")
|
|
150
|
+
if (
|
|
151
|
+
type(self.witnesses) is not tuple
|
|
152
|
+
or not self.witnesses
|
|
153
|
+
or any(
|
|
154
|
+
type(value) is not ContextualArmCountCapabilityWitness
|
|
155
|
+
for value in self.witnesses
|
|
156
|
+
)
|
|
157
|
+
):
|
|
158
|
+
raise ValueError("witnesses must contain exact capability witnesses")
|
|
159
|
+
for value in self.witnesses:
|
|
160
|
+
value.__post_init__()
|
|
161
|
+
if value.evaluation_slots != self.evaluation_slots:
|
|
162
|
+
raise ValueError("capability witness has a different stage width")
|
|
163
|
+
if tuple(arm_id for arm_id, _ in value.realized_target_counts) != (
|
|
164
|
+
self.arm_ids
|
|
165
|
+
):
|
|
166
|
+
raise ValueError("capability witness has different arms")
|
|
167
|
+
if tuple(value.witness_sha256 for value in self.witnesses) != tuple(
|
|
168
|
+
sorted({value.witness_sha256 for value in self.witnesses})
|
|
169
|
+
):
|
|
170
|
+
raise ValueError("capability witnesses must be unique and canonical")
|
|
171
|
+
object.__setattr__(
|
|
172
|
+
self,
|
|
173
|
+
"capability_sha256",
|
|
174
|
+
hashlib.sha256(
|
|
175
|
+
_CAPABILITY_DOMAIN + _canonical_json(self._unsigned_record())
|
|
176
|
+
).hexdigest(),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def feasible_count_vectors(self) -> tuple[tuple[tuple[str, int], ...], ...]:
|
|
181
|
+
"""Return unique witnessed vectors in deterministic count order."""
|
|
182
|
+
|
|
183
|
+
return tuple(sorted({value.realized_target_counts for value in self.witnesses}))
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def allocation_realization_sha256s(self) -> tuple[str, ...]:
|
|
187
|
+
return tuple(
|
|
188
|
+
sorted(
|
|
189
|
+
{
|
|
190
|
+
receipt
|
|
191
|
+
for witness in self.witnesses
|
|
192
|
+
for receipt in witness.allocation_realization_sha256s
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
198
|
+
return {
|
|
199
|
+
"schema_version": 1,
|
|
200
|
+
"kind": self.kind,
|
|
201
|
+
"evaluation_slots": self.evaluation_slots,
|
|
202
|
+
"arm_ids": list(self.arm_ids),
|
|
203
|
+
"witnesses": [value.to_record() for value in self.witnesses],
|
|
204
|
+
"feasible_count_vectors": [
|
|
205
|
+
[list(value) for value in vector]
|
|
206
|
+
for vector in self.feasible_count_vectors
|
|
207
|
+
],
|
|
208
|
+
"current_capacity_guaranteed": False,
|
|
209
|
+
"objective_values_consulted": False,
|
|
210
|
+
"workload_identifiers_consulted": False,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
def to_record(self) -> dict[str, object]:
|
|
214
|
+
self.__post_init__()
|
|
215
|
+
return {
|
|
216
|
+
**self._unsigned_record(),
|
|
217
|
+
"capability_sha256": self.capability_sha256,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@dataclass(frozen=True, slots=True)
|
|
222
|
+
class ContextualJointCountVector:
|
|
223
|
+
"""One prospectively witnessed source x operator marginal pair.
|
|
224
|
+
|
|
225
|
+
The vector deliberately carries only arm counts and immutable finite-option
|
|
226
|
+
identities. Objective values, ranks, model outputs, and workload names are
|
|
227
|
+
outside this port. A lane capability may retain one canonical witness for
|
|
228
|
+
each distinct marginal pair even when many option subsets realize it.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
source_target_counts: tuple[tuple[str, int], ...]
|
|
232
|
+
operator_target_counts: tuple[tuple[str, int], ...]
|
|
233
|
+
feasibility_witness_option_identity_sha256s: tuple[str, ...]
|
|
234
|
+
vector_sha256: str = field(init=False)
|
|
235
|
+
|
|
236
|
+
def __post_init__(self) -> None:
|
|
237
|
+
slots = sum(value[1] for value in self.source_target_counts)
|
|
238
|
+
if slots <= 0:
|
|
239
|
+
raise ValueError("joint count vector must cover positive capacity")
|
|
240
|
+
_validate_counts(
|
|
241
|
+
self.source_target_counts,
|
|
242
|
+
name="source_target_counts",
|
|
243
|
+
expected_slots=slots,
|
|
244
|
+
)
|
|
245
|
+
_validate_counts(
|
|
246
|
+
self.operator_target_counts,
|
|
247
|
+
name="operator_target_counts",
|
|
248
|
+
expected_slots=slots,
|
|
249
|
+
)
|
|
250
|
+
witnesses = self.feasibility_witness_option_identity_sha256s
|
|
251
|
+
if (
|
|
252
|
+
type(witnesses) is not tuple
|
|
253
|
+
or len(witnesses) != slots
|
|
254
|
+
or witnesses != tuple(sorted(set(witnesses)))
|
|
255
|
+
):
|
|
256
|
+
raise ValueError(
|
|
257
|
+
"joint count vector requires one canonical unique witness per slot"
|
|
258
|
+
)
|
|
259
|
+
for value in witnesses:
|
|
260
|
+
require_sha256(value, "feasibility_witness_option_identity_sha256")
|
|
261
|
+
object.__setattr__(
|
|
262
|
+
self,
|
|
263
|
+
"vector_sha256",
|
|
264
|
+
hashlib.sha256(
|
|
265
|
+
_JOINT_VECTOR_DOMAIN + _canonical_json(self._unsigned_record())
|
|
266
|
+
).hexdigest(),
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def evaluation_slots(self) -> int:
|
|
271
|
+
return sum(value[1] for value in self.source_target_counts)
|
|
272
|
+
|
|
273
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
274
|
+
return {
|
|
275
|
+
"schema_version": 1,
|
|
276
|
+
"source_target_counts": [
|
|
277
|
+
list(value) for value in self.source_target_counts
|
|
278
|
+
],
|
|
279
|
+
"operator_target_counts": [
|
|
280
|
+
list(value) for value in self.operator_target_counts
|
|
281
|
+
],
|
|
282
|
+
"feasibility_witness_option_identity_sha256s": list(
|
|
283
|
+
self.feasibility_witness_option_identity_sha256s
|
|
284
|
+
),
|
|
285
|
+
"objective_values_consulted": False,
|
|
286
|
+
"workload_identifiers_consulted": False,
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
def to_record(self) -> dict[str, object]:
|
|
290
|
+
self.__post_init__()
|
|
291
|
+
return {**self._unsigned_record(), "vector_sha256": self.vector_sha256}
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
@dataclass(frozen=True, slots=True)
|
|
295
|
+
class ContextualLaneJointCountCapability:
|
|
296
|
+
"""Exact finite-contract marginal capability for one concurrent lane."""
|
|
297
|
+
|
|
298
|
+
slice_id: str
|
|
299
|
+
finite_contract_identity_sha256: str
|
|
300
|
+
structural_constraint_sha256: str
|
|
301
|
+
evaluation_slots: int
|
|
302
|
+
source_arm_ids: tuple[str, ...]
|
|
303
|
+
operator_arm_ids: tuple[str, ...]
|
|
304
|
+
feasible_vectors: tuple[ContextualJointCountVector, ...]
|
|
305
|
+
minimum_single_path_interventions: int = 0
|
|
306
|
+
minimum_disjoint_parent_patch_pairs: int = 0
|
|
307
|
+
capability_sha256: str = field(init=False)
|
|
308
|
+
|
|
309
|
+
def __post_init__(self) -> None:
|
|
310
|
+
_require_token(self.slice_id, name="slice_id")
|
|
311
|
+
require_sha256(
|
|
312
|
+
self.finite_contract_identity_sha256,
|
|
313
|
+
"finite_contract_identity_sha256",
|
|
314
|
+
)
|
|
315
|
+
require_sha256(
|
|
316
|
+
self.structural_constraint_sha256,
|
|
317
|
+
"structural_constraint_sha256",
|
|
318
|
+
)
|
|
319
|
+
if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
|
|
320
|
+
raise ValueError("evaluation_slots must be positive")
|
|
321
|
+
if (
|
|
322
|
+
type(self.minimum_single_path_interventions) is not int
|
|
323
|
+
or not 0
|
|
324
|
+
<= self.minimum_single_path_interventions
|
|
325
|
+
<= self.evaluation_slots
|
|
326
|
+
):
|
|
327
|
+
raise ValueError(
|
|
328
|
+
"minimum_single_path_interventions must lie in lane capacity"
|
|
329
|
+
)
|
|
330
|
+
maximum_pairs = self.evaluation_slots * (self.evaluation_slots - 1) // 2
|
|
331
|
+
if (
|
|
332
|
+
type(self.minimum_disjoint_parent_patch_pairs) is not int
|
|
333
|
+
or not 0
|
|
334
|
+
<= self.minimum_disjoint_parent_patch_pairs
|
|
335
|
+
<= maximum_pairs
|
|
336
|
+
):
|
|
337
|
+
raise ValueError(
|
|
338
|
+
"minimum_disjoint_parent_patch_pairs must lie in lane pair capacity"
|
|
339
|
+
)
|
|
340
|
+
for name in ("source_arm_ids", "operator_arm_ids"):
|
|
341
|
+
values = getattr(self, name)
|
|
342
|
+
if type(values) is not tuple or not values:
|
|
343
|
+
raise ValueError(f"{name} must be a non-empty exact tuple")
|
|
344
|
+
for value in values:
|
|
345
|
+
_require_token(value, name=name)
|
|
346
|
+
if values != tuple(sorted(set(values))):
|
|
347
|
+
raise ValueError(f"{name} must be unique and canonical")
|
|
348
|
+
if (
|
|
349
|
+
type(self.feasible_vectors) is not tuple
|
|
350
|
+
or not self.feasible_vectors
|
|
351
|
+
or any(
|
|
352
|
+
type(value) is not ContextualJointCountVector
|
|
353
|
+
for value in self.feasible_vectors
|
|
354
|
+
)
|
|
355
|
+
):
|
|
356
|
+
raise ValueError("feasible_vectors must contain exact joint vectors")
|
|
357
|
+
for value in self.feasible_vectors:
|
|
358
|
+
value.__post_init__()
|
|
359
|
+
if value.evaluation_slots != self.evaluation_slots:
|
|
360
|
+
raise ValueError("joint vector has a different lane capacity")
|
|
361
|
+
if tuple(arm_id for arm_id, _ in value.source_target_counts) != (
|
|
362
|
+
self.source_arm_ids
|
|
363
|
+
):
|
|
364
|
+
raise ValueError("joint vector has different source arms")
|
|
365
|
+
if tuple(arm_id for arm_id, _ in value.operator_target_counts) != (
|
|
366
|
+
self.operator_arm_ids
|
|
367
|
+
):
|
|
368
|
+
raise ValueError("joint vector has different operator arms")
|
|
369
|
+
vector_hashes = tuple(value.vector_sha256 for value in self.feasible_vectors)
|
|
370
|
+
if vector_hashes != tuple(sorted(set(vector_hashes))):
|
|
371
|
+
raise ValueError("joint vectors must be unique and hash-canonical")
|
|
372
|
+
marginal_pairs = tuple(
|
|
373
|
+
(value.source_target_counts, value.operator_target_counts)
|
|
374
|
+
for value in self.feasible_vectors
|
|
375
|
+
)
|
|
376
|
+
if len(set(marginal_pairs)) != len(marginal_pairs):
|
|
377
|
+
raise ValueError("joint capability repeats one marginal pair")
|
|
378
|
+
object.__setattr__(
|
|
379
|
+
self,
|
|
380
|
+
"capability_sha256",
|
|
381
|
+
hashlib.sha256(
|
|
382
|
+
_LANE_JOINT_CAPABILITY_DOMAIN
|
|
383
|
+
+ _canonical_json(self._unsigned_record())
|
|
384
|
+
).hexdigest(),
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
def resolve_vector(self, vector_sha256: str) -> ContextualJointCountVector:
|
|
388
|
+
require_sha256(vector_sha256, "vector_sha256")
|
|
389
|
+
try:
|
|
390
|
+
return next(
|
|
391
|
+
value
|
|
392
|
+
for value in self.feasible_vectors
|
|
393
|
+
if value.vector_sha256 == vector_sha256
|
|
394
|
+
)
|
|
395
|
+
except StopIteration as error:
|
|
396
|
+
raise ValueError(
|
|
397
|
+
"joint vector is absent from this lane capability"
|
|
398
|
+
) from error
|
|
399
|
+
|
|
400
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
401
|
+
record: dict[str, object] = {
|
|
402
|
+
"schema_version": (
|
|
403
|
+
3
|
|
404
|
+
if self.minimum_disjoint_parent_patch_pairs
|
|
405
|
+
else 2
|
|
406
|
+
if self.minimum_single_path_interventions
|
|
407
|
+
else 1
|
|
408
|
+
),
|
|
409
|
+
"slice_id": self.slice_id,
|
|
410
|
+
"finite_contract_identity_sha256": self.finite_contract_identity_sha256,
|
|
411
|
+
"structural_constraint_sha256": self.structural_constraint_sha256,
|
|
412
|
+
"evaluation_slots": self.evaluation_slots,
|
|
413
|
+
"source_arm_ids": list(self.source_arm_ids),
|
|
414
|
+
"operator_arm_ids": list(self.operator_arm_ids),
|
|
415
|
+
"feasible_vectors": [value.to_record() for value in self.feasible_vectors],
|
|
416
|
+
"current_capacity_guaranteed": True,
|
|
417
|
+
"objective_values_consulted": False,
|
|
418
|
+
"workload_identifiers_consulted": False,
|
|
419
|
+
}
|
|
420
|
+
if self.minimum_single_path_interventions:
|
|
421
|
+
record["minimum_single_path_interventions"] = (
|
|
422
|
+
self.minimum_single_path_interventions
|
|
423
|
+
)
|
|
424
|
+
record["intervention_axis"] = (
|
|
425
|
+
"exact_parent_relative_changed_json_path_count"
|
|
426
|
+
)
|
|
427
|
+
if self.minimum_disjoint_parent_patch_pairs:
|
|
428
|
+
record["minimum_disjoint_parent_patch_pairs"] = (
|
|
429
|
+
self.minimum_disjoint_parent_patch_pairs
|
|
430
|
+
)
|
|
431
|
+
record["offspring_opportunity_axis"] = (
|
|
432
|
+
"pairwise_disjoint_parent_relative_patch_pairs"
|
|
433
|
+
)
|
|
434
|
+
return record
|
|
435
|
+
|
|
436
|
+
def to_record(self) -> dict[str, object]:
|
|
437
|
+
self.__post_init__()
|
|
438
|
+
return {**self._unsigned_record(), "capability_sha256": self.capability_sha256}
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
@dataclass(frozen=True, slots=True)
|
|
442
|
+
class ContextualPortfolioAllocationContract:
|
|
443
|
+
"""Exact request-local exposure targets from a prior-only controller."""
|
|
444
|
+
|
|
445
|
+
campaign_scope_sha256: str
|
|
446
|
+
query_sha256: str
|
|
447
|
+
decision_sha256: str
|
|
448
|
+
campaign_generation: int
|
|
449
|
+
controller_wave_index: int
|
|
450
|
+
phase_id: str
|
|
451
|
+
slice_id: str
|
|
452
|
+
evaluation_slots: int
|
|
453
|
+
source_target_counts: tuple[tuple[str, int], ...]
|
|
454
|
+
operator_target_counts: tuple[tuple[str, int], ...]
|
|
455
|
+
minimum_single_path_interventions: int = 0
|
|
456
|
+
minimum_disjoint_parent_patch_pairs: int = 0
|
|
457
|
+
feasibility_witness_option_identity_sha256s: tuple[str, ...] = ()
|
|
458
|
+
contract_sha256: str = field(init=False)
|
|
459
|
+
|
|
460
|
+
def __post_init__(self) -> None:
|
|
461
|
+
for name in (
|
|
462
|
+
"campaign_scope_sha256",
|
|
463
|
+
"query_sha256",
|
|
464
|
+
"decision_sha256",
|
|
465
|
+
):
|
|
466
|
+
require_sha256(getattr(self, name), name)
|
|
467
|
+
for name in ("campaign_generation", "controller_wave_index"):
|
|
468
|
+
value = getattr(self, name)
|
|
469
|
+
if type(value) is not int or value <= 0:
|
|
470
|
+
raise ValueError(f"{name} must be positive")
|
|
471
|
+
_require_token(self.phase_id, name="phase_id")
|
|
472
|
+
_require_token(self.slice_id, name="slice_id")
|
|
473
|
+
if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
|
|
474
|
+
raise ValueError("evaluation_slots must be positive")
|
|
475
|
+
if (
|
|
476
|
+
type(self.minimum_single_path_interventions) is not int
|
|
477
|
+
or not 0
|
|
478
|
+
<= self.minimum_single_path_interventions
|
|
479
|
+
<= self.evaluation_slots
|
|
480
|
+
):
|
|
481
|
+
raise ValueError(
|
|
482
|
+
"minimum_single_path_interventions must lie in allocation capacity"
|
|
483
|
+
)
|
|
484
|
+
maximum_pairs = self.evaluation_slots * (self.evaluation_slots - 1) // 2
|
|
485
|
+
if (
|
|
486
|
+
type(self.minimum_disjoint_parent_patch_pairs) is not int
|
|
487
|
+
or not 0
|
|
488
|
+
<= self.minimum_disjoint_parent_patch_pairs
|
|
489
|
+
<= maximum_pairs
|
|
490
|
+
):
|
|
491
|
+
raise ValueError(
|
|
492
|
+
"minimum_disjoint_parent_patch_pairs must lie in allocation pair "
|
|
493
|
+
"capacity"
|
|
494
|
+
)
|
|
495
|
+
_validate_counts(
|
|
496
|
+
self.source_target_counts,
|
|
497
|
+
name="source_target_counts",
|
|
498
|
+
expected_slots=self.evaluation_slots,
|
|
499
|
+
)
|
|
500
|
+
_validate_counts(
|
|
501
|
+
self.operator_target_counts,
|
|
502
|
+
name="operator_target_counts",
|
|
503
|
+
expected_slots=self.evaluation_slots,
|
|
504
|
+
)
|
|
505
|
+
witnesses = self.feasibility_witness_option_identity_sha256s
|
|
506
|
+
if type(witnesses) is not tuple:
|
|
507
|
+
raise TypeError(
|
|
508
|
+
"feasibility_witness_option_identity_sha256s must be an exact tuple"
|
|
509
|
+
)
|
|
510
|
+
if witnesses:
|
|
511
|
+
if len(witnesses) != self.evaluation_slots or witnesses != tuple(
|
|
512
|
+
sorted(set(witnesses))
|
|
513
|
+
):
|
|
514
|
+
raise ValueError(
|
|
515
|
+
"allocation feasibility witness must contain one canonical "
|
|
516
|
+
"unique option identity per evaluation slot"
|
|
517
|
+
)
|
|
518
|
+
for value in witnesses:
|
|
519
|
+
require_sha256(value, "feasibility_witness_option_identity_sha256")
|
|
520
|
+
object.__setattr__(
|
|
521
|
+
self,
|
|
522
|
+
"contract_sha256",
|
|
523
|
+
hashlib.sha256(
|
|
524
|
+
_CONTRACT_DOMAIN + _canonical_json(self._unsigned_record())
|
|
525
|
+
).hexdigest(),
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
529
|
+
record: dict[str, object] = {
|
|
530
|
+
"schema_version": (
|
|
531
|
+
4
|
|
532
|
+
if self.feasibility_witness_option_identity_sha256s
|
|
533
|
+
else 3
|
|
534
|
+
if self.minimum_disjoint_parent_patch_pairs
|
|
535
|
+
else 2
|
|
536
|
+
if self.minimum_single_path_interventions
|
|
537
|
+
else 1
|
|
538
|
+
),
|
|
539
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
540
|
+
"query_sha256": self.query_sha256,
|
|
541
|
+
"decision_sha256": self.decision_sha256,
|
|
542
|
+
"campaign_generation": self.campaign_generation,
|
|
543
|
+
"controller_wave_index": self.controller_wave_index,
|
|
544
|
+
"phase_id": self.phase_id,
|
|
545
|
+
"slice_id": self.slice_id,
|
|
546
|
+
"evaluation_slots": self.evaluation_slots,
|
|
547
|
+
"source_target_counts": [
|
|
548
|
+
list(value) for value in self.source_target_counts
|
|
549
|
+
],
|
|
550
|
+
"operator_target_counts": [
|
|
551
|
+
list(value) for value in self.operator_target_counts
|
|
552
|
+
],
|
|
553
|
+
}
|
|
554
|
+
if self.minimum_single_path_interventions:
|
|
555
|
+
record["minimum_single_path_interventions"] = (
|
|
556
|
+
self.minimum_single_path_interventions
|
|
557
|
+
)
|
|
558
|
+
record["intervention_axis"] = (
|
|
559
|
+
"exact_parent_relative_changed_json_path_count"
|
|
560
|
+
)
|
|
561
|
+
if self.minimum_disjoint_parent_patch_pairs:
|
|
562
|
+
record["minimum_disjoint_parent_patch_pairs"] = (
|
|
563
|
+
self.minimum_disjoint_parent_patch_pairs
|
|
564
|
+
)
|
|
565
|
+
record["offspring_opportunity_axis"] = (
|
|
566
|
+
"pairwise_disjoint_parent_relative_patch_pairs"
|
|
567
|
+
)
|
|
568
|
+
if self.feasibility_witness_option_identity_sha256s:
|
|
569
|
+
record["feasibility_witness_option_identity_sha256s"] = list(
|
|
570
|
+
self.feasibility_witness_option_identity_sha256s
|
|
571
|
+
)
|
|
572
|
+
record["feasibility_witness_semantics"] = (
|
|
573
|
+
"current_finite_contract_exact_joint_count_and_structural_witness"
|
|
574
|
+
)
|
|
575
|
+
return record
|
|
576
|
+
|
|
577
|
+
def to_record(self) -> dict[str, object]:
|
|
578
|
+
self.__post_init__()
|
|
579
|
+
return {**self._unsigned_record(), "contract_sha256": self.contract_sha256}
|
|
580
|
+
|
|
581
|
+
def target_count(self, *, kind: str, arm_id: str) -> int:
|
|
582
|
+
if kind not in {"source", "operator"}:
|
|
583
|
+
raise ValueError("kind must be source or operator")
|
|
584
|
+
_require_token(arm_id, name="arm_id")
|
|
585
|
+
values = (
|
|
586
|
+
self.source_target_counts
|
|
587
|
+
if kind == "source"
|
|
588
|
+
else self.operator_target_counts
|
|
589
|
+
)
|
|
590
|
+
try:
|
|
591
|
+
return dict(values)[arm_id]
|
|
592
|
+
except KeyError as error:
|
|
593
|
+
raise ValueError("arm is absent from this allocation contract") from error
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
@dataclass(frozen=True, slots=True)
|
|
597
|
+
class ContextualPortfolioAllocationRealization:
|
|
598
|
+
"""Objective-blind requested-to-realized exposure evidence.
|
|
599
|
+
|
|
600
|
+
This is an inward-facing application port: an integration may solve a
|
|
601
|
+
workload-specific finite feasibility problem, but the controller receives
|
|
602
|
+
only canonical arm counts and the identity of the prospective contract.
|
|
603
|
+
Candidate fields, objective values, workload IDs, model IDs, and provider
|
|
604
|
+
metadata are deliberately absent.
|
|
605
|
+
"""
|
|
606
|
+
|
|
607
|
+
campaign_scope_sha256: str
|
|
608
|
+
query_sha256: str
|
|
609
|
+
decision_sha256: str
|
|
610
|
+
contract_sha256: str
|
|
611
|
+
controller_wave_index: int
|
|
612
|
+
slice_id: str
|
|
613
|
+
requested_source_target_counts: tuple[tuple[str, int], ...]
|
|
614
|
+
requested_operator_target_counts: tuple[tuple[str, int], ...]
|
|
615
|
+
realized_source_target_counts: tuple[tuple[str, int], ...]
|
|
616
|
+
realized_operator_target_counts: tuple[tuple[str, int], ...]
|
|
617
|
+
requested_minimum_single_path_interventions: int = 0
|
|
618
|
+
realized_single_path_interventions: int = 0
|
|
619
|
+
requested_minimum_disjoint_parent_patch_pairs: int = 0
|
|
620
|
+
realized_disjoint_parent_patch_pairs: int = 0
|
|
621
|
+
realization_sha256: str = field(init=False)
|
|
622
|
+
|
|
623
|
+
def __post_init__(self) -> None:
|
|
624
|
+
for name in (
|
|
625
|
+
"campaign_scope_sha256",
|
|
626
|
+
"query_sha256",
|
|
627
|
+
"decision_sha256",
|
|
628
|
+
"contract_sha256",
|
|
629
|
+
):
|
|
630
|
+
require_sha256(getattr(self, name), name)
|
|
631
|
+
if (
|
|
632
|
+
type(self.controller_wave_index) is not int
|
|
633
|
+
or self.controller_wave_index <= 0
|
|
634
|
+
):
|
|
635
|
+
raise ValueError("controller_wave_index must be positive")
|
|
636
|
+
_require_token(self.slice_id, name="slice_id")
|
|
637
|
+
slots = sum(value[1] for value in self.requested_source_target_counts)
|
|
638
|
+
if slots <= 0:
|
|
639
|
+
raise ValueError("allocation realization must cover positive capacity")
|
|
640
|
+
for name in (
|
|
641
|
+
"requested_source_target_counts",
|
|
642
|
+
"requested_operator_target_counts",
|
|
643
|
+
"realized_source_target_counts",
|
|
644
|
+
"realized_operator_target_counts",
|
|
645
|
+
):
|
|
646
|
+
_validate_counts(
|
|
647
|
+
getattr(self, name),
|
|
648
|
+
name=name,
|
|
649
|
+
expected_slots=slots,
|
|
650
|
+
)
|
|
651
|
+
if tuple(value[0] for value in self.requested_source_target_counts) != tuple(
|
|
652
|
+
value[0] for value in self.realized_source_target_counts
|
|
653
|
+
):
|
|
654
|
+
raise ValueError("realized source arms differ from requested arms")
|
|
655
|
+
if tuple(value[0] for value in self.requested_operator_target_counts) != tuple(
|
|
656
|
+
value[0] for value in self.realized_operator_target_counts
|
|
657
|
+
):
|
|
658
|
+
raise ValueError("realized operator arms differ from requested arms")
|
|
659
|
+
if (
|
|
660
|
+
type(self.requested_minimum_single_path_interventions) is not int
|
|
661
|
+
or not 0
|
|
662
|
+
<= self.requested_minimum_single_path_interventions
|
|
663
|
+
<= slots
|
|
664
|
+
):
|
|
665
|
+
raise ValueError(
|
|
666
|
+
"requested minimum single-path interventions is invalid"
|
|
667
|
+
)
|
|
668
|
+
if (
|
|
669
|
+
type(self.realized_single_path_interventions) is not int
|
|
670
|
+
or not 0 <= self.realized_single_path_interventions <= slots
|
|
671
|
+
):
|
|
672
|
+
raise ValueError("realized single-path interventions is invalid")
|
|
673
|
+
if self.realized_single_path_interventions < (
|
|
674
|
+
self.requested_minimum_single_path_interventions
|
|
675
|
+
):
|
|
676
|
+
raise ValueError("realized portfolio violated its single-path floor")
|
|
677
|
+
maximum_pairs = slots * (slots - 1) // 2
|
|
678
|
+
if (
|
|
679
|
+
type(self.requested_minimum_disjoint_parent_patch_pairs) is not int
|
|
680
|
+
or not 0
|
|
681
|
+
<= self.requested_minimum_disjoint_parent_patch_pairs
|
|
682
|
+
<= maximum_pairs
|
|
683
|
+
):
|
|
684
|
+
raise ValueError(
|
|
685
|
+
"requested minimum disjoint parent-patch pairs is invalid"
|
|
686
|
+
)
|
|
687
|
+
if (
|
|
688
|
+
type(self.realized_disjoint_parent_patch_pairs) is not int
|
|
689
|
+
or not 0 <= self.realized_disjoint_parent_patch_pairs <= maximum_pairs
|
|
690
|
+
):
|
|
691
|
+
raise ValueError("realized disjoint parent-patch pair count is invalid")
|
|
692
|
+
if self.realized_disjoint_parent_patch_pairs < (
|
|
693
|
+
self.requested_minimum_disjoint_parent_patch_pairs
|
|
694
|
+
):
|
|
695
|
+
raise ValueError(
|
|
696
|
+
"realized portfolio violated its disjoint parent-pair floor"
|
|
697
|
+
)
|
|
698
|
+
object.__setattr__(
|
|
699
|
+
self,
|
|
700
|
+
"realization_sha256",
|
|
701
|
+
hashlib.sha256(
|
|
702
|
+
_REALIZATION_DOMAIN + _canonical_json(self._unsigned_record())
|
|
703
|
+
).hexdigest(),
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
@staticmethod
|
|
707
|
+
def _l1(
|
|
708
|
+
requested: tuple[tuple[str, int], ...],
|
|
709
|
+
realized: tuple[tuple[str, int], ...],
|
|
710
|
+
) -> int:
|
|
711
|
+
return sum(
|
|
712
|
+
abs(left[1] - right[1])
|
|
713
|
+
for left, right in zip(requested, realized, strict=True)
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
@property
|
|
717
|
+
def source_l1_deviation(self) -> int:
|
|
718
|
+
return self._l1(
|
|
719
|
+
self.requested_source_target_counts,
|
|
720
|
+
self.realized_source_target_counts,
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
@property
|
|
724
|
+
def operator_l1_deviation(self) -> int:
|
|
725
|
+
return self._l1(
|
|
726
|
+
self.requested_operator_target_counts,
|
|
727
|
+
self.realized_operator_target_counts,
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
@property
|
|
731
|
+
def exact(self) -> bool:
|
|
732
|
+
return self.source_l1_deviation == 0 and self.operator_l1_deviation == 0
|
|
733
|
+
|
|
734
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
735
|
+
intervention_bound = self.requested_minimum_single_path_interventions > 0
|
|
736
|
+
offspring_opportunity_bound = (
|
|
737
|
+
self.requested_minimum_disjoint_parent_patch_pairs > 0
|
|
738
|
+
)
|
|
739
|
+
record: dict[str, object] = {
|
|
740
|
+
"schema_version": (
|
|
741
|
+
3 if offspring_opportunity_bound else 2 if intervention_bound else 1
|
|
742
|
+
),
|
|
743
|
+
"campaign_scope_sha256": self.campaign_scope_sha256,
|
|
744
|
+
"query_sha256": self.query_sha256,
|
|
745
|
+
"decision_sha256": self.decision_sha256,
|
|
746
|
+
"contract_sha256": self.contract_sha256,
|
|
747
|
+
"controller_wave_index": self.controller_wave_index,
|
|
748
|
+
"slice_id": self.slice_id,
|
|
749
|
+
"requested_source_target_counts": [
|
|
750
|
+
list(value) for value in self.requested_source_target_counts
|
|
751
|
+
],
|
|
752
|
+
"requested_operator_target_counts": [
|
|
753
|
+
list(value) for value in self.requested_operator_target_counts
|
|
754
|
+
],
|
|
755
|
+
"realized_source_target_counts": [
|
|
756
|
+
list(value) for value in self.realized_source_target_counts
|
|
757
|
+
],
|
|
758
|
+
"realized_operator_target_counts": [
|
|
759
|
+
list(value) for value in self.realized_operator_target_counts
|
|
760
|
+
],
|
|
761
|
+
"source_l1_deviation": self.source_l1_deviation,
|
|
762
|
+
"operator_l1_deviation": self.operator_l1_deviation,
|
|
763
|
+
"exact": self.exact,
|
|
764
|
+
"objective_values_consulted": False,
|
|
765
|
+
"workload_identifiers_consulted": False,
|
|
766
|
+
}
|
|
767
|
+
if intervention_bound:
|
|
768
|
+
record["requested_minimum_single_path_interventions"] = (
|
|
769
|
+
self.requested_minimum_single_path_interventions
|
|
770
|
+
)
|
|
771
|
+
record["realized_single_path_interventions"] = (
|
|
772
|
+
self.realized_single_path_interventions
|
|
773
|
+
)
|
|
774
|
+
record["intervention_axis"] = (
|
|
775
|
+
"exact_parent_relative_changed_json_path_count"
|
|
776
|
+
)
|
|
777
|
+
if offspring_opportunity_bound:
|
|
778
|
+
record["requested_minimum_disjoint_parent_patch_pairs"] = (
|
|
779
|
+
self.requested_minimum_disjoint_parent_patch_pairs
|
|
780
|
+
)
|
|
781
|
+
record["realized_disjoint_parent_patch_pairs"] = (
|
|
782
|
+
self.realized_disjoint_parent_patch_pairs
|
|
783
|
+
)
|
|
784
|
+
record["offspring_opportunity_axis"] = (
|
|
785
|
+
"pairwise_disjoint_parent_relative_patch_pairs"
|
|
786
|
+
)
|
|
787
|
+
return record
|
|
788
|
+
|
|
789
|
+
def to_record(self) -> dict[str, object]:
|
|
790
|
+
self.__post_init__()
|
|
791
|
+
return {
|
|
792
|
+
**self._unsigned_record(),
|
|
793
|
+
"realization_sha256": self.realization_sha256,
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
def require_contract(
|
|
797
|
+
self,
|
|
798
|
+
contract: ContextualPortfolioAllocationContract,
|
|
799
|
+
) -> None:
|
|
800
|
+
if type(contract) is not ContextualPortfolioAllocationContract:
|
|
801
|
+
raise TypeError("contract must be exact")
|
|
802
|
+
contract.__post_init__()
|
|
803
|
+
if (
|
|
804
|
+
self.campaign_scope_sha256 != contract.campaign_scope_sha256
|
|
805
|
+
or self.query_sha256 != contract.query_sha256
|
|
806
|
+
or self.decision_sha256 != contract.decision_sha256
|
|
807
|
+
or self.contract_sha256 != contract.contract_sha256
|
|
808
|
+
or self.controller_wave_index != contract.controller_wave_index
|
|
809
|
+
or self.slice_id != contract.slice_id
|
|
810
|
+
or self.requested_source_target_counts != contract.source_target_counts
|
|
811
|
+
or self.requested_operator_target_counts != contract.operator_target_counts
|
|
812
|
+
or self.requested_minimum_single_path_interventions
|
|
813
|
+
!= contract.minimum_single_path_interventions
|
|
814
|
+
or self.requested_minimum_disjoint_parent_patch_pairs
|
|
815
|
+
!= contract.minimum_disjoint_parent_patch_pairs
|
|
816
|
+
):
|
|
817
|
+
raise ValueError("allocation realization differs from its contract")
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
__all__ = [
|
|
821
|
+
"ContextualArmCountCapability",
|
|
822
|
+
"ContextualArmCountCapabilityWitness",
|
|
823
|
+
"ContextualJointCountVector",
|
|
824
|
+
"ContextualLaneJointCountCapability",
|
|
825
|
+
"ContextualPortfolioAllocationContract",
|
|
826
|
+
"ContextualPortfolioAllocationRealization",
|
|
827
|
+
]
|