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,674 @@
|
|
|
1
|
+
"""Pydantic-AI adapter for compact hierarchical residual proposals.
|
|
2
|
+
|
|
3
|
+
The model selects a parent and one or two opaque atomic option IDs. The
|
|
4
|
+
application-layer reachability schema owns eligibility and trusted engine code
|
|
5
|
+
materializes the resulting configuration after this adapter returns. Queueing,
|
|
6
|
+
retry, backoff, and model routing remain injected through ``LowLevelRunner``.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
import hashlib
|
|
13
|
+
import json
|
|
14
|
+
import math
|
|
15
|
+
import re
|
|
16
|
+
from typing import Annotated, Any, ClassVar, Literal, cast
|
|
17
|
+
|
|
18
|
+
from pydantic import (
|
|
19
|
+
BaseModel,
|
|
20
|
+
ConfigDict,
|
|
21
|
+
Field,
|
|
22
|
+
StringConstraints,
|
|
23
|
+
create_model,
|
|
24
|
+
model_validator,
|
|
25
|
+
)
|
|
26
|
+
from pydantic_core import PydanticCustomError
|
|
27
|
+
|
|
28
|
+
from agent_evolve.application.residual_reachability import (
|
|
29
|
+
CrossParentFiniteActionSchema,
|
|
30
|
+
HierarchicalResidualPlan,
|
|
31
|
+
ResidualProposalRole,
|
|
32
|
+
)
|
|
33
|
+
from agent_evolve.domain.ids import LLMCallId
|
|
34
|
+
from agent_evolve.domain.llm_task_queue import ValidationIssueReasonCode
|
|
35
|
+
from agent_evolve.domain.patch import require_sha256
|
|
36
|
+
from agent_evolve.domain.typed_json import FrozenJsonObject, freeze_json, thaw_json
|
|
37
|
+
from agent_evolve.integrations.pydantic_ai.agentic_generator import (
|
|
38
|
+
AttemptedStructuredGenerationResponse,
|
|
39
|
+
LowLevelRunner,
|
|
40
|
+
)
|
|
41
|
+
from agent_evolve.ports.agentic_generator import AgenticCallTelemetry
|
|
42
|
+
from agent_evolve.ports.portfolio_selection import (
|
|
43
|
+
pairwise_disjoint_parent_patch_pairs,
|
|
44
|
+
)
|
|
45
|
+
from agent_evolve.ports.structured_generator import (
|
|
46
|
+
MAX_OUTPUT_TOKENS,
|
|
47
|
+
StructuredGenerationRequest,
|
|
48
|
+
StructuredGenerationResponse,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
HIERARCHICAL_RESIDUAL_PROPOSAL_TOOL_NAME = "propose_residual_plans"
|
|
53
|
+
HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_ID = (
|
|
54
|
+
"pydantic_ai_hierarchical_residual_proposal"
|
|
55
|
+
)
|
|
56
|
+
HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_VERSION = 2
|
|
57
|
+
HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_DEFINITION_SHA256 = hashlib.sha256(
|
|
58
|
+
b"agent-evolve:pydantic-ai-hierarchical-residual-proposal:v2;"
|
|
59
|
+
b"model-output=parent-id-plus-radius-one-or-two-atomic-id-tuple;"
|
|
60
|
+
b"consequence=p10-p50-p90-parent-relative-metric-deltas-plus-confidence-"
|
|
61
|
+
b"and-probability-valid;"
|
|
62
|
+
b"engine-materialization-only=true;cross-parent-schema=true;"
|
|
63
|
+
b"workload-model-provider-branches=false"
|
|
64
|
+
).hexdigest()
|
|
65
|
+
|
|
66
|
+
_STRICT = ConfigDict(
|
|
67
|
+
extra="forbid",
|
|
68
|
+
strict=True,
|
|
69
|
+
populate_by_name=True,
|
|
70
|
+
validate_default=True,
|
|
71
|
+
)
|
|
72
|
+
_OPERATION = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
73
|
+
_Rationale = Annotated[
|
|
74
|
+
str,
|
|
75
|
+
StringConstraints(
|
|
76
|
+
strict=True,
|
|
77
|
+
strip_whitespace=True,
|
|
78
|
+
min_length=1,
|
|
79
|
+
max_length=16_384,
|
|
80
|
+
),
|
|
81
|
+
]
|
|
82
|
+
_DECISION_DOMAIN = b"agent-evolve:hierarchical-residual-proposal-decision:v2\x00"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _canonical_bytes(value: object) -> bytes:
|
|
86
|
+
return json.dumps(
|
|
87
|
+
value,
|
|
88
|
+
allow_nan=False,
|
|
89
|
+
ensure_ascii=True,
|
|
90
|
+
separators=(",", ":"),
|
|
91
|
+
sort_keys=True,
|
|
92
|
+
).encode("ascii", errors="strict")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _hash(value: object) -> str:
|
|
96
|
+
return hashlib.sha256(_DECISION_DOMAIN + _canonical_bytes(value)).hexdigest()
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@dataclass(frozen=True, slots=True)
|
|
100
|
+
class HierarchicalResidualProposalRequest:
|
|
101
|
+
"""Provider-neutral request for one proposal expert."""
|
|
102
|
+
|
|
103
|
+
call_id: LLMCallId
|
|
104
|
+
operation: str
|
|
105
|
+
instruction: str
|
|
106
|
+
context: FrozenJsonObject
|
|
107
|
+
action_schema: CrossParentFiniteActionSchema
|
|
108
|
+
proposal_count: int
|
|
109
|
+
allowed_radii: tuple[int, ...]
|
|
110
|
+
allowed_roles: tuple[ResidualProposalRole, ...]
|
|
111
|
+
required_metric_ids: tuple[str, ...]
|
|
112
|
+
minimum_distinct_parents: int
|
|
113
|
+
expert_id: str
|
|
114
|
+
expert_definition_sha256: str
|
|
115
|
+
max_output_tokens: int
|
|
116
|
+
temperature: float
|
|
117
|
+
|
|
118
|
+
def __post_init__(self) -> None:
|
|
119
|
+
if type(self.call_id) is not LLMCallId:
|
|
120
|
+
raise TypeError("call_id must be an exact LLMCallId")
|
|
121
|
+
LLMCallId.__post_init__(self.call_id)
|
|
122
|
+
if type(self.operation) is not str or _OPERATION.fullmatch(self.operation) is None:
|
|
123
|
+
raise ValueError("operation must use the closed token grammar")
|
|
124
|
+
if type(self.instruction) is not str or not self.instruction.strip():
|
|
125
|
+
raise ValueError("instruction must be non-empty")
|
|
126
|
+
if len(self.instruction.encode("utf-8")) > 32_768:
|
|
127
|
+
raise ValueError("instruction exceeds its byte limit")
|
|
128
|
+
if type(self.context) is not FrozenJsonObject:
|
|
129
|
+
raise TypeError("context must be an exact FrozenJsonObject")
|
|
130
|
+
if freeze_json(self.context) is not self.context:
|
|
131
|
+
raise TypeError("context must already be frozen typed JSON")
|
|
132
|
+
if type(self.action_schema) is not CrossParentFiniteActionSchema:
|
|
133
|
+
raise TypeError("action_schema must be exact")
|
|
134
|
+
self.action_schema.__post_init__()
|
|
135
|
+
if type(self.proposal_count) is not int or not 1 <= self.proposal_count <= 32:
|
|
136
|
+
raise ValueError("proposal_count must lie in [1, 32]")
|
|
137
|
+
if (
|
|
138
|
+
type(self.allowed_radii) is not tuple
|
|
139
|
+
or not self.allowed_radii
|
|
140
|
+
or self.allowed_radii != tuple(sorted(set(self.allowed_radii)))
|
|
141
|
+
or not set(self.allowed_radii).issubset({1, 2})
|
|
142
|
+
):
|
|
143
|
+
raise ValueError("allowed_radii must be a canonical subset of {1, 2}")
|
|
144
|
+
if (
|
|
145
|
+
type(self.allowed_roles) is not tuple
|
|
146
|
+
or not self.allowed_roles
|
|
147
|
+
or any(type(value) is not ResidualProposalRole for value in self.allowed_roles)
|
|
148
|
+
):
|
|
149
|
+
raise TypeError("allowed_roles must contain exact role values")
|
|
150
|
+
if self.allowed_roles != tuple(
|
|
151
|
+
sorted(set(self.allowed_roles), key=lambda value: value.value)
|
|
152
|
+
):
|
|
153
|
+
raise ValueError("allowed_roles must be unique and canonical")
|
|
154
|
+
if (
|
|
155
|
+
type(self.required_metric_ids) is not tuple
|
|
156
|
+
or not self.required_metric_ids
|
|
157
|
+
or self.required_metric_ids != tuple(sorted(set(self.required_metric_ids)))
|
|
158
|
+
):
|
|
159
|
+
raise ValueError("required_metric_ids must be non-empty and canonical")
|
|
160
|
+
if (
|
|
161
|
+
type(self.minimum_distinct_parents) is not int
|
|
162
|
+
or not 1 <= self.minimum_distinct_parents <= self.proposal_count
|
|
163
|
+
or self.minimum_distinct_parents > len(self.action_schema.bindings)
|
|
164
|
+
):
|
|
165
|
+
raise ValueError("minimum_distinct_parents is infeasible")
|
|
166
|
+
if type(self.expert_id) is not str or _OPERATION.fullmatch(self.expert_id) is None:
|
|
167
|
+
raise ValueError("expert_id must use the closed token grammar")
|
|
168
|
+
require_sha256(self.expert_definition_sha256, "expert_definition_sha256")
|
|
169
|
+
if (
|
|
170
|
+
type(self.max_output_tokens) is not int
|
|
171
|
+
or not 1 <= self.max_output_tokens <= MAX_OUTPUT_TOKENS
|
|
172
|
+
):
|
|
173
|
+
raise ValueError("max_output_tokens is outside the generic bound")
|
|
174
|
+
if type(self.temperature) is not float or not math.isfinite(self.temperature):
|
|
175
|
+
raise TypeError("temperature must be a finite exact float")
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
def request_sha256(self) -> str:
|
|
179
|
+
self.__post_init__()
|
|
180
|
+
return _hash(
|
|
181
|
+
{
|
|
182
|
+
"schema_version": 1,
|
|
183
|
+
"call_id": self.call_id.value,
|
|
184
|
+
"operation": self.operation,
|
|
185
|
+
"instruction": self.instruction,
|
|
186
|
+
"context": thaw_json(self.context),
|
|
187
|
+
"action_schema_sha256": self.action_schema.schema_sha256,
|
|
188
|
+
"proposal_count": self.proposal_count,
|
|
189
|
+
"allowed_radii": list(self.allowed_radii),
|
|
190
|
+
"allowed_roles": [value.value for value in self.allowed_roles],
|
|
191
|
+
"required_metric_ids": list(self.required_metric_ids),
|
|
192
|
+
"minimum_distinct_parents": self.minimum_distinct_parents,
|
|
193
|
+
"expert_id": self.expert_id,
|
|
194
|
+
"expert_definition_sha256": self.expert_definition_sha256,
|
|
195
|
+
"max_output_tokens": self.max_output_tokens,
|
|
196
|
+
"temperature_hex": self.temperature.hex(),
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class _ResidualMemberBase(BaseModel):
|
|
202
|
+
model_config = _STRICT
|
|
203
|
+
|
|
204
|
+
available_option_ids_by_parent: ClassVar[dict[str, frozenset[str]]] = {}
|
|
205
|
+
compatible_radius_two_by_parent: ClassVar[
|
|
206
|
+
dict[str, frozenset[tuple[str, str]]]
|
|
207
|
+
] = {}
|
|
208
|
+
allowed_radii: ClassVar[frozenset[int]] = frozenset()
|
|
209
|
+
required_metric_ids: ClassVar[frozenset[str]] = frozenset()
|
|
210
|
+
|
|
211
|
+
@model_validator(mode="after")
|
|
212
|
+
def _validate_member(self) -> "_ResidualMemberBase":
|
|
213
|
+
parent_id = cast(Any, self).parent_candidate_id
|
|
214
|
+
option_ids = tuple(cast(Any, self).component_option_ids)
|
|
215
|
+
if len(option_ids) not in type(self).allowed_radii:
|
|
216
|
+
raise PydanticCustomError(
|
|
217
|
+
ValidationIssueReasonCode.RESIDUAL_RADIUS_CONTRACT_VIOLATION.value,
|
|
218
|
+
"component tuple has a forbidden radius",
|
|
219
|
+
)
|
|
220
|
+
if len(set(option_ids)) != len(option_ids):
|
|
221
|
+
raise PydanticCustomError(
|
|
222
|
+
ValidationIssueReasonCode.RESIDUAL_OPTION_CONTRACT_VIOLATION.value,
|
|
223
|
+
"component option IDs cannot repeat",
|
|
224
|
+
)
|
|
225
|
+
if not set(option_ids).issubset(
|
|
226
|
+
type(self).available_option_ids_by_parent[parent_id]
|
|
227
|
+
):
|
|
228
|
+
raise PydanticCustomError(
|
|
229
|
+
ValidationIssueReasonCode.RESIDUAL_OPTION_CONTRACT_VIOLATION.value,
|
|
230
|
+
"a component is unavailable for the selected parent",
|
|
231
|
+
)
|
|
232
|
+
if len(option_ids) == 2 and tuple(sorted(option_ids)) not in type(
|
|
233
|
+
self
|
|
234
|
+
).compatible_radius_two_by_parent[parent_id]:
|
|
235
|
+
raise PydanticCustomError(
|
|
236
|
+
ValidationIssueReasonCode.RESIDUAL_OPTION_CONTRACT_VIOLATION.value,
|
|
237
|
+
"radius-two components are not a safe disjoint "
|
|
238
|
+
"parent-relative pair",
|
|
239
|
+
)
|
|
240
|
+
metrics = tuple(item.metric_id for item in cast(Any, self).effect_predictions)
|
|
241
|
+
if len(set(metrics)) != len(metrics) or set(metrics) != type(self).required_metric_ids:
|
|
242
|
+
raise PydanticCustomError(
|
|
243
|
+
ValidationIssueReasonCode.RESIDUAL_METRIC_CONTRACT_VIOLATION.value,
|
|
244
|
+
"effect predictions must cover each requested metric once",
|
|
245
|
+
)
|
|
246
|
+
return self
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class _ResidualMetricPredictionBase(BaseModel):
|
|
250
|
+
model_config = _STRICT
|
|
251
|
+
|
|
252
|
+
@model_validator(mode="after")
|
|
253
|
+
def _validate_quantiles(self) -> "_ResidualMetricPredictionBase":
|
|
254
|
+
p10 = cast(float, cast(Any, self).p10_delta)
|
|
255
|
+
p50 = cast(float, cast(Any, self).p50_delta)
|
|
256
|
+
p90 = cast(float, cast(Any, self).p90_delta)
|
|
257
|
+
if not all(math.isfinite(value) for value in (p10, p50, p90)):
|
|
258
|
+
raise PydanticCustomError(
|
|
259
|
+
ValidationIssueReasonCode.RESIDUAL_QUANTILE_ORDER_VIOLATION.value,
|
|
260
|
+
"effect quantiles must be finite",
|
|
261
|
+
)
|
|
262
|
+
if not p10 <= p50 <= p90:
|
|
263
|
+
raise PydanticCustomError(
|
|
264
|
+
ValidationIssueReasonCode.RESIDUAL_QUANTILE_ORDER_VIOLATION.value,
|
|
265
|
+
"effect quantiles must satisfy p10 <= p50 <= p90",
|
|
266
|
+
)
|
|
267
|
+
return self
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class _ResidualOutputBase(BaseModel):
|
|
271
|
+
model_config = _STRICT
|
|
272
|
+
|
|
273
|
+
proposal_count: ClassVar[int] = 1
|
|
274
|
+
minimum_distinct_parents: ClassVar[int] = 1
|
|
275
|
+
|
|
276
|
+
@model_validator(mode="after")
|
|
277
|
+
def _validate_output(self) -> "_ResidualOutputBase":
|
|
278
|
+
members = tuple(cast(Any, self).members)
|
|
279
|
+
if len(members) != type(self).proposal_count:
|
|
280
|
+
raise ValueError("members must have the exact requested size")
|
|
281
|
+
identities = tuple(
|
|
282
|
+
(value.parent_candidate_id, tuple(sorted(value.component_option_ids)))
|
|
283
|
+
for value in members
|
|
284
|
+
)
|
|
285
|
+
if len(set(identities)) != len(identities):
|
|
286
|
+
raise PydanticCustomError(
|
|
287
|
+
ValidationIssueReasonCode.RESIDUAL_PLAN_DIVERSITY_VIOLATION.value,
|
|
288
|
+
"members cannot repeat a parent-relative plan",
|
|
289
|
+
)
|
|
290
|
+
if len({value.parent_candidate_id for value in members}) < type(self).minimum_distinct_parents:
|
|
291
|
+
raise PydanticCustomError(
|
|
292
|
+
ValidationIssueReasonCode.RESIDUAL_PLAN_DIVERSITY_VIOLATION.value,
|
|
293
|
+
"members do not cover enough distinct parents",
|
|
294
|
+
)
|
|
295
|
+
return self
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def hierarchical_residual_output_type(
|
|
299
|
+
request: HierarchicalResidualProposalRequest,
|
|
300
|
+
) -> type[BaseModel]:
|
|
301
|
+
request.__post_init__()
|
|
302
|
+
parent_ids = tuple(
|
|
303
|
+
value.parent_candidate_id.value for value in request.action_schema.bindings
|
|
304
|
+
)
|
|
305
|
+
option_ids = request.action_schema.option_ids
|
|
306
|
+
role_ids = tuple(value.value for value in request.allowed_roles)
|
|
307
|
+
metric_ids = request.required_metric_ids
|
|
308
|
+
parent_literal = Literal.__getitem__(parent_ids)
|
|
309
|
+
option_literal = Literal.__getitem__(option_ids)
|
|
310
|
+
role_literal = Literal.__getitem__(role_ids)
|
|
311
|
+
metric_literal = Literal.__getitem__(metric_ids)
|
|
312
|
+
prediction_type = create_model(
|
|
313
|
+
"ResidualMetricPrediction",
|
|
314
|
+
__base__=_ResidualMetricPredictionBase,
|
|
315
|
+
__module__=__name__,
|
|
316
|
+
metric_id=(metric_literal, ...),
|
|
317
|
+
p10_delta=(float, ...),
|
|
318
|
+
p50_delta=(float, ...),
|
|
319
|
+
p90_delta=(float, ...),
|
|
320
|
+
confidence=(float, Field(ge=0.0, le=1.0, strict=True)),
|
|
321
|
+
)
|
|
322
|
+
member_type = create_model(
|
|
323
|
+
"HierarchicalResidualMember",
|
|
324
|
+
__base__=_ResidualMemberBase,
|
|
325
|
+
__module__=__name__,
|
|
326
|
+
parent_candidate_id=(parent_literal, ...),
|
|
327
|
+
component_option_ids=(
|
|
328
|
+
list[option_literal],
|
|
329
|
+
Field(min_length=min(request.allowed_radii), max_length=max(request.allowed_radii)),
|
|
330
|
+
),
|
|
331
|
+
role=(role_literal, ...),
|
|
332
|
+
probability_valid=(float, Field(ge=0.0, le=1.0, strict=True)),
|
|
333
|
+
effect_predictions=(
|
|
334
|
+
list[prediction_type],
|
|
335
|
+
Field(min_length=len(metric_ids), max_length=len(metric_ids)),
|
|
336
|
+
),
|
|
337
|
+
interaction_rationale=(_Rationale, ...),
|
|
338
|
+
)
|
|
339
|
+
member_type.available_option_ids_by_parent = {
|
|
340
|
+
value.parent_candidate_id.value: frozenset(
|
|
341
|
+
option.option_id for option in value.contract.options
|
|
342
|
+
)
|
|
343
|
+
for value in request.action_schema.bindings
|
|
344
|
+
}
|
|
345
|
+
member_type.compatible_radius_two_by_parent = {
|
|
346
|
+
value.parent_candidate_id.value: (
|
|
347
|
+
frozenset(
|
|
348
|
+
pairwise_disjoint_parent_patch_pairs(
|
|
349
|
+
value.contract,
|
|
350
|
+
tuple(option.option_id for option in value.contract.options),
|
|
351
|
+
)
|
|
352
|
+
)
|
|
353
|
+
if 2 in request.allowed_radii
|
|
354
|
+
else frozenset()
|
|
355
|
+
)
|
|
356
|
+
for value in request.action_schema.bindings
|
|
357
|
+
}
|
|
358
|
+
member_type.allowed_radii = frozenset(request.allowed_radii)
|
|
359
|
+
member_type.required_metric_ids = frozenset(metric_ids)
|
|
360
|
+
output_type = create_model(
|
|
361
|
+
"HierarchicalResidualProposalSlate",
|
|
362
|
+
__base__=_ResidualOutputBase,
|
|
363
|
+
__module__=__name__,
|
|
364
|
+
members=(
|
|
365
|
+
list[member_type],
|
|
366
|
+
Field(min_length=request.proposal_count, max_length=request.proposal_count),
|
|
367
|
+
),
|
|
368
|
+
slate_rationale=(_Rationale, ...),
|
|
369
|
+
)
|
|
370
|
+
output_type.proposal_count = request.proposal_count
|
|
371
|
+
output_type.minimum_distinct_parents = request.minimum_distinct_parents
|
|
372
|
+
return output_type
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def render_hierarchical_residual_prompt(
|
|
376
|
+
request: HierarchicalResidualProposalRequest,
|
|
377
|
+
) -> str:
|
|
378
|
+
request.__post_init__()
|
|
379
|
+
contract = {
|
|
380
|
+
"schema_version": 1,
|
|
381
|
+
"request_sha256": request.request_sha256,
|
|
382
|
+
"expert_id": request.expert_id,
|
|
383
|
+
"context": thaw_json(request.context),
|
|
384
|
+
"cross_parent_action_schema": request.action_schema.prompt_record(),
|
|
385
|
+
"constraints": {
|
|
386
|
+
"proposal_count": request.proposal_count,
|
|
387
|
+
"allowed_radii": list(request.allowed_radii),
|
|
388
|
+
"allowed_roles": [value.value for value in request.allowed_roles],
|
|
389
|
+
"required_metric_ids": list(request.required_metric_ids),
|
|
390
|
+
"minimum_distinct_parents": request.minimum_distinct_parents,
|
|
391
|
+
"distinct_parent_relative_plans": True,
|
|
392
|
+
"select_only_available_option_ids_for_parent": True,
|
|
393
|
+
"do_not_return_configurations": True,
|
|
394
|
+
"effect_forecast_contract": {
|
|
395
|
+
"deltas_are_parent_relative_in_raw_metric_units": True,
|
|
396
|
+
"quantiles": ["p10_delta", "p50_delta", "p90_delta"],
|
|
397
|
+
"ordered_quantiles_required": True,
|
|
398
|
+
"confidence_and_probability_valid_range": [0.0, 1.0],
|
|
399
|
+
"future_evaluator_outcomes_are_unknown": True,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
}
|
|
403
|
+
return "\n".join(
|
|
404
|
+
(
|
|
405
|
+
request.instruction,
|
|
406
|
+
"",
|
|
407
|
+
"HIERARCHICAL RESIDUAL PROPOSAL CONTRACT",
|
|
408
|
+
json.dumps(
|
|
409
|
+
contract,
|
|
410
|
+
allow_nan=False,
|
|
411
|
+
ensure_ascii=True,
|
|
412
|
+
separators=(",", ":"),
|
|
413
|
+
sort_keys=True,
|
|
414
|
+
),
|
|
415
|
+
"Return exactly the requested best-first proposal slate. Select only "
|
|
416
|
+
"a supplied parent ID and atomic option IDs available for that parent. "
|
|
417
|
+
"The trusted engine will materialize and validate each tuple. Forecast "
|
|
418
|
+
"parent-relative p10/p50/p90 metric deltas in the raw metric units; "
|
|
419
|
+
"do not collapse magnitude into direction labels.",
|
|
420
|
+
)
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
@dataclass(frozen=True, slots=True)
|
|
425
|
+
class HierarchicalResidualMetricForecast:
|
|
426
|
+
"""Provider-neutral magnitude forecast for one objective metric."""
|
|
427
|
+
|
|
428
|
+
metric_id: str
|
|
429
|
+
p10_delta: float
|
|
430
|
+
p50_delta: float
|
|
431
|
+
p90_delta: float
|
|
432
|
+
confidence: float
|
|
433
|
+
|
|
434
|
+
def __post_init__(self) -> None:
|
|
435
|
+
if type(self.metric_id) is not str or not self.metric_id:
|
|
436
|
+
raise ValueError("metric_id must be non-empty")
|
|
437
|
+
for name in ("p10_delta", "p50_delta", "p90_delta", "confidence"):
|
|
438
|
+
value = getattr(self, name)
|
|
439
|
+
if type(value) is not float or not math.isfinite(value):
|
|
440
|
+
raise TypeError(f"{name} must be a finite exact float")
|
|
441
|
+
if not self.p10_delta <= self.p50_delta <= self.p90_delta:
|
|
442
|
+
raise ValueError("forecast quantiles must be ordered")
|
|
443
|
+
if not 0.0 <= self.confidence <= 1.0:
|
|
444
|
+
raise ValueError("confidence must lie in [0,1]")
|
|
445
|
+
|
|
446
|
+
@property
|
|
447
|
+
def direction(self) -> str:
|
|
448
|
+
self.__post_init__()
|
|
449
|
+
if self.p10_delta == self.p50_delta == self.p90_delta == 0.0:
|
|
450
|
+
return "unchanged"
|
|
451
|
+
if self.p90_delta < 0.0:
|
|
452
|
+
return "decrease"
|
|
453
|
+
if self.p10_delta > 0.0:
|
|
454
|
+
return "increase"
|
|
455
|
+
return "unknown"
|
|
456
|
+
|
|
457
|
+
def to_record(self) -> dict[str, object]:
|
|
458
|
+
self.__post_init__()
|
|
459
|
+
return {
|
|
460
|
+
"metric_id": self.metric_id,
|
|
461
|
+
"p10_delta_hex": self.p10_delta.hex(),
|
|
462
|
+
"p50_delta_hex": self.p50_delta.hex(),
|
|
463
|
+
"p90_delta_hex": self.p90_delta.hex(),
|
|
464
|
+
"confidence_hex": self.confidence.hex(),
|
|
465
|
+
"direction": self.direction,
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
@dataclass(frozen=True, slots=True)
|
|
470
|
+
class HierarchicalResidualProposalSelection:
|
|
471
|
+
request_sha256: str
|
|
472
|
+
decision_sha256: str
|
|
473
|
+
plans: tuple[HierarchicalResidualPlan, ...]
|
|
474
|
+
rationales: tuple[str, ...]
|
|
475
|
+
probability_valid: tuple[float, ...]
|
|
476
|
+
effect_predictions: tuple[
|
|
477
|
+
tuple[HierarchicalResidualMetricForecast, ...],
|
|
478
|
+
...,
|
|
479
|
+
]
|
|
480
|
+
slate_rationale: str
|
|
481
|
+
telemetry: AgenticCallTelemetry
|
|
482
|
+
|
|
483
|
+
def __post_init__(self) -> None:
|
|
484
|
+
require_sha256(self.request_sha256, "request_sha256")
|
|
485
|
+
require_sha256(self.decision_sha256, "decision_sha256")
|
|
486
|
+
if type(self.plans) is not tuple or not self.plans:
|
|
487
|
+
raise ValueError("plans must be a non-empty exact tuple")
|
|
488
|
+
if any(type(value) is not HierarchicalResidualPlan for value in self.plans):
|
|
489
|
+
raise TypeError("plans contain a foreign value")
|
|
490
|
+
for value in self.plans:
|
|
491
|
+
HierarchicalResidualPlan.__post_init__(value)
|
|
492
|
+
if type(self.rationales) is not tuple or len(self.rationales) != len(self.plans):
|
|
493
|
+
raise ValueError("rationales must align with plans")
|
|
494
|
+
if (
|
|
495
|
+
type(self.probability_valid) is not tuple
|
|
496
|
+
or len(self.probability_valid) != len(self.plans)
|
|
497
|
+
):
|
|
498
|
+
raise ValueError("probability_valid must align with plans")
|
|
499
|
+
for value in self.probability_valid:
|
|
500
|
+
if type(value) is not float or not 0.0 <= value <= 1.0:
|
|
501
|
+
raise ValueError("probability_valid must contain probabilities")
|
|
502
|
+
if type(self.effect_predictions) is not tuple or len(self.effect_predictions) != len(self.plans):
|
|
503
|
+
raise ValueError("effect_predictions must align with plans")
|
|
504
|
+
for values in self.effect_predictions:
|
|
505
|
+
if type(values) is not tuple or not values:
|
|
506
|
+
raise ValueError("each plan must forecast at least one metric")
|
|
507
|
+
for value in values:
|
|
508
|
+
if type(value) is not HierarchicalResidualMetricForecast:
|
|
509
|
+
raise TypeError("effect_predictions contain a foreign value")
|
|
510
|
+
value.__post_init__()
|
|
511
|
+
metric_ids = tuple(value.metric_id for value in values)
|
|
512
|
+
if metric_ids != tuple(sorted(set(metric_ids))):
|
|
513
|
+
raise ValueError("effect prediction metrics must be canonical")
|
|
514
|
+
if type(self.slate_rationale) is not str or not self.slate_rationale:
|
|
515
|
+
raise ValueError("slate_rationale must be non-empty")
|
|
516
|
+
if type(self.telemetry) is not AgenticCallTelemetry:
|
|
517
|
+
raise TypeError("telemetry must be exact")
|
|
518
|
+
AgenticCallTelemetry.__post_init__(self.telemetry)
|
|
519
|
+
|
|
520
|
+
def to_record(self) -> dict[str, object]:
|
|
521
|
+
self.__post_init__()
|
|
522
|
+
return {
|
|
523
|
+
"schema_version": 1,
|
|
524
|
+
"request_sha256": self.request_sha256,
|
|
525
|
+
"decision_sha256": self.decision_sha256,
|
|
526
|
+
"plans": [value.to_record() for value in self.plans],
|
|
527
|
+
"rationales": list(self.rationales),
|
|
528
|
+
"probability_valid_hex": [
|
|
529
|
+
value.hex() for value in self.probability_valid
|
|
530
|
+
],
|
|
531
|
+
"effect_predictions": [
|
|
532
|
+
[value.to_record() for value in values]
|
|
533
|
+
for values in self.effect_predictions
|
|
534
|
+
],
|
|
535
|
+
"slate_rationale": self.slate_rationale,
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def _telemetry(
|
|
540
|
+
response: StructuredGenerationResponse[Any], attempt_count: int
|
|
541
|
+
) -> AgenticCallTelemetry:
|
|
542
|
+
return AgenticCallTelemetry(
|
|
543
|
+
requested_model=response.requested_model,
|
|
544
|
+
resolved_model=response.resolved_model,
|
|
545
|
+
resolved_provider=response.resolved_provider,
|
|
546
|
+
provider_response_id=response.provider_response_id,
|
|
547
|
+
finish_reason=response.finish_reason,
|
|
548
|
+
input_tokens=response.input_tokens,
|
|
549
|
+
output_tokens=response.output_tokens,
|
|
550
|
+
reasoning_tokens=response.reasoning_tokens,
|
|
551
|
+
cache_read_tokens=response.cache_read_tokens,
|
|
552
|
+
cache_write_tokens=response.cache_write_tokens,
|
|
553
|
+
cost_usd=response.cost_usd,
|
|
554
|
+
latency_ns=response.latency_ns,
|
|
555
|
+
attempt_count=attempt_count,
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
@dataclass(slots=True)
|
|
560
|
+
class PydanticAIHierarchicalResidualProposalPolicy:
|
|
561
|
+
generate_once: LowLevelRunner
|
|
562
|
+
|
|
563
|
+
def __post_init__(self) -> None:
|
|
564
|
+
if not callable(self.generate_once):
|
|
565
|
+
raise TypeError("generate_once must be callable")
|
|
566
|
+
|
|
567
|
+
async def select(
|
|
568
|
+
self,
|
|
569
|
+
request: HierarchicalResidualProposalRequest,
|
|
570
|
+
) -> HierarchicalResidualProposalSelection:
|
|
571
|
+
request.__post_init__()
|
|
572
|
+
output_type = hierarchical_residual_output_type(request)
|
|
573
|
+
prompt = render_hierarchical_residual_prompt(request)
|
|
574
|
+
raw = await self.generate_once(
|
|
575
|
+
StructuredGenerationRequest(
|
|
576
|
+
call_id=request.call_id,
|
|
577
|
+
operation=request.operation,
|
|
578
|
+
prompt=prompt,
|
|
579
|
+
output_type=output_type,
|
|
580
|
+
output_tool_name=HIERARCHICAL_RESIDUAL_PROPOSAL_TOOL_NAME,
|
|
581
|
+
max_output_tokens=request.max_output_tokens,
|
|
582
|
+
temperature=request.temperature,
|
|
583
|
+
)
|
|
584
|
+
)
|
|
585
|
+
if type(raw) is AttemptedStructuredGenerationResponse:
|
|
586
|
+
response = raw.response
|
|
587
|
+
attempt_count = raw.attempt_count
|
|
588
|
+
elif type(raw) is StructuredGenerationResponse:
|
|
589
|
+
response = raw
|
|
590
|
+
attempt_count = 1
|
|
591
|
+
else:
|
|
592
|
+
raise TypeError("low-level runner returned a foreign response")
|
|
593
|
+
StructuredGenerationResponse.__post_init__(response)
|
|
594
|
+
if type(response.value) is not output_type:
|
|
595
|
+
raise TypeError("response value differs from the requested output type")
|
|
596
|
+
value = cast(Any, response.value)
|
|
597
|
+
draft_record = {
|
|
598
|
+
"schema_version": 1,
|
|
599
|
+
"request_sha256": request.request_sha256,
|
|
600
|
+
"members": [member.model_dump(mode="json") for member in value.members],
|
|
601
|
+
"slate_rationale": value.slate_rationale,
|
|
602
|
+
}
|
|
603
|
+
decision_sha256 = _hash(draft_record)
|
|
604
|
+
plans = tuple(
|
|
605
|
+
HierarchicalResidualPlan(
|
|
606
|
+
parent_candidate_id=next(
|
|
607
|
+
binding.parent_candidate_id
|
|
608
|
+
for binding in request.action_schema.bindings
|
|
609
|
+
if binding.parent_candidate_id.value == member.parent_candidate_id
|
|
610
|
+
),
|
|
611
|
+
parent_contract_sha256=request.action_schema.contract_for(
|
|
612
|
+
next(
|
|
613
|
+
binding.parent_candidate_id
|
|
614
|
+
for binding in request.action_schema.bindings
|
|
615
|
+
if binding.parent_candidate_id.value
|
|
616
|
+
== member.parent_candidate_id
|
|
617
|
+
)
|
|
618
|
+
).identity_sha256,
|
|
619
|
+
action_schema_sha256=request.action_schema.schema_sha256,
|
|
620
|
+
component_option_ids=tuple(sorted(member.component_option_ids)),
|
|
621
|
+
role=ResidualProposalRole(member.role),
|
|
622
|
+
expert_id=request.expert_id,
|
|
623
|
+
expert_definition_sha256=request.expert_definition_sha256,
|
|
624
|
+
native_rank=rank,
|
|
625
|
+
decision_receipt_sha256=decision_sha256,
|
|
626
|
+
)
|
|
627
|
+
for rank, member in enumerate(value.members, start=1)
|
|
628
|
+
)
|
|
629
|
+
result = HierarchicalResidualProposalSelection(
|
|
630
|
+
request_sha256=request.request_sha256,
|
|
631
|
+
decision_sha256=decision_sha256,
|
|
632
|
+
plans=plans,
|
|
633
|
+
rationales=tuple(member.interaction_rationale for member in value.members),
|
|
634
|
+
probability_valid=tuple(
|
|
635
|
+
float(member.probability_valid)
|
|
636
|
+
for member in value.members
|
|
637
|
+
),
|
|
638
|
+
effect_predictions=tuple(
|
|
639
|
+
tuple(
|
|
640
|
+
sorted(
|
|
641
|
+
(
|
|
642
|
+
HierarchicalResidualMetricForecast(
|
|
643
|
+
metric_id=prediction.metric_id,
|
|
644
|
+
p10_delta=float(prediction.p10_delta),
|
|
645
|
+
p50_delta=float(prediction.p50_delta),
|
|
646
|
+
p90_delta=float(prediction.p90_delta),
|
|
647
|
+
confidence=float(prediction.confidence),
|
|
648
|
+
)
|
|
649
|
+
for prediction in member.effect_predictions
|
|
650
|
+
),
|
|
651
|
+
key=lambda item: item.metric_id,
|
|
652
|
+
)
|
|
653
|
+
)
|
|
654
|
+
for member in value.members
|
|
655
|
+
),
|
|
656
|
+
slate_rationale=value.slate_rationale,
|
|
657
|
+
telemetry=_telemetry(response, attempt_count),
|
|
658
|
+
)
|
|
659
|
+
result.__post_init__()
|
|
660
|
+
return result
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
__all__ = [
|
|
664
|
+
"HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_DEFINITION_SHA256",
|
|
665
|
+
"HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_ID",
|
|
666
|
+
"HIERARCHICAL_RESIDUAL_PROPOSAL_POLICY_VERSION",
|
|
667
|
+
"HIERARCHICAL_RESIDUAL_PROPOSAL_TOOL_NAME",
|
|
668
|
+
"HierarchicalResidualProposalRequest",
|
|
669
|
+
"HierarchicalResidualProposalSelection",
|
|
670
|
+
"HierarchicalResidualMetricForecast",
|
|
671
|
+
"PydanticAIHierarchicalResidualProposalPolicy",
|
|
672
|
+
"hierarchical_residual_output_type",
|
|
673
|
+
"render_hierarchical_residual_prompt",
|
|
674
|
+
]
|