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,383 @@
|
|
|
1
|
+
"""Progress-aware, content-blind supervision for one provider stream.
|
|
2
|
+
|
|
3
|
+
The supervisor knows nothing about prompts, model output, schemas, or benchmark
|
|
4
|
+
semantics. A provider adapter reports only closed progress kinds/channels. A
|
|
5
|
+
first-event deadline detects requests that never begin, an idle deadline moves
|
|
6
|
+
forward whenever progress is observed, and an optional absolute deadline is a
|
|
7
|
+
separate operational fail-safe.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
from collections.abc import Awaitable, Callable
|
|
14
|
+
from contextlib import suppress
|
|
15
|
+
import time
|
|
16
|
+
from typing import Any, Protocol, TypeVar, runtime_checkable
|
|
17
|
+
|
|
18
|
+
from agent_evolve.ports.structured_generator import (
|
|
19
|
+
GenerationFailureKind,
|
|
20
|
+
StructuredGenerationError,
|
|
21
|
+
StructuredStreamChannel,
|
|
22
|
+
StructuredStreamCleanupTimeoutError,
|
|
23
|
+
StructuredStreamLivenessPolicy,
|
|
24
|
+
StructuredStreamProgress,
|
|
25
|
+
StructuredStreamProgressKind,
|
|
26
|
+
StructuredStreamProgressSink,
|
|
27
|
+
StructuredStreamTimeoutError,
|
|
28
|
+
StructuredStreamTimeoutPhase,
|
|
29
|
+
StructuredStreamRetiredError,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
ResultT = TypeVar("ResultT")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@runtime_checkable
|
|
37
|
+
class StreamProgressMarker(Protocol):
|
|
38
|
+
"""Accept only a closed content identity, never a plaintext fragment.
|
|
39
|
+
|
|
40
|
+
Every successful operation must finish by marking exactly one
|
|
41
|
+
``STREAM_COMPLETED`` event. It must be the last mark and is emitted by the
|
|
42
|
+
adapter only after its framework call has returned a typed result.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __call__(
|
|
46
|
+
self,
|
|
47
|
+
kind: StructuredStreamProgressKind,
|
|
48
|
+
channel: StructuredStreamChannel,
|
|
49
|
+
*,
|
|
50
|
+
event_content_utf8_bytes: int,
|
|
51
|
+
cumulative_content_utf8_bytes: int,
|
|
52
|
+
rolling_content_sha256: str,
|
|
53
|
+
) -> None: ...
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
StreamOperation = Callable[[StreamProgressMarker], Awaitable[ResultT]]
|
|
57
|
+
StreamRetirementOperation = Callable[[], Awaitable[None]]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@runtime_checkable
|
|
61
|
+
class ContentBlindStreamSupervisor(Protocol):
|
|
62
|
+
"""Injectable supervision port consumed by provider adapters."""
|
|
63
|
+
|
|
64
|
+
async def run(
|
|
65
|
+
self,
|
|
66
|
+
operation: StreamOperation[Any],
|
|
67
|
+
*,
|
|
68
|
+
call_id: str,
|
|
69
|
+
provider_attempt_id: str | None = None,
|
|
70
|
+
policy: StructuredStreamLivenessPolicy,
|
|
71
|
+
progress_sink: StructuredStreamProgressSink | None = None,
|
|
72
|
+
) -> Any: ...
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class AsyncioContentBlindStreamSupervisor:
|
|
76
|
+
"""Supervise one streamed operation without observing its content."""
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
*,
|
|
81
|
+
monotonic_ns: Callable[[], int] = time.monotonic_ns,
|
|
82
|
+
retirement_operation: StreamRetirementOperation | None = None,
|
|
83
|
+
) -> None:
|
|
84
|
+
if not callable(monotonic_ns):
|
|
85
|
+
raise TypeError("monotonic_ns must be callable")
|
|
86
|
+
if retirement_operation is not None and not callable(retirement_operation):
|
|
87
|
+
raise TypeError("retirement_operation must be callable or None")
|
|
88
|
+
self._monotonic_ns = monotonic_ns
|
|
89
|
+
self._retirement_operation = retirement_operation
|
|
90
|
+
self._retired = False
|
|
91
|
+
|
|
92
|
+
async def run(
|
|
93
|
+
self,
|
|
94
|
+
operation: StreamOperation[ResultT],
|
|
95
|
+
*,
|
|
96
|
+
call_id: str,
|
|
97
|
+
provider_attempt_id: str | None = None,
|
|
98
|
+
policy: StructuredStreamLivenessPolicy,
|
|
99
|
+
progress_sink: StructuredStreamProgressSink | None = None,
|
|
100
|
+
) -> ResultT:
|
|
101
|
+
if not callable(operation):
|
|
102
|
+
raise TypeError("operation must be callable")
|
|
103
|
+
if self._retired:
|
|
104
|
+
raise StructuredStreamRetiredError()
|
|
105
|
+
if type(policy) is not StructuredStreamLivenessPolicy:
|
|
106
|
+
raise TypeError("policy must be a StructuredStreamLivenessPolicy")
|
|
107
|
+
policy.__post_init__()
|
|
108
|
+
if progress_sink is not None and not callable(progress_sink):
|
|
109
|
+
raise TypeError("progress_sink must be callable or None")
|
|
110
|
+
|
|
111
|
+
started_ns = self._monotonic_ns()
|
|
112
|
+
if type(started_ns) is not int or started_ns < 0:
|
|
113
|
+
raise ValueError("monotonic_ns returned an invalid value")
|
|
114
|
+
activity = asyncio.Event()
|
|
115
|
+
sequence = 0
|
|
116
|
+
first_event_ns: int | None = None
|
|
117
|
+
last_event_ns: int | None = None
|
|
118
|
+
last_cumulative_content_utf8_bytes = 0
|
|
119
|
+
last_kind: StructuredStreamProgressKind | None = None
|
|
120
|
+
stream_completed_count = 0
|
|
121
|
+
progress_accepting = True
|
|
122
|
+
|
|
123
|
+
def mark_progress(
|
|
124
|
+
kind: StructuredStreamProgressKind,
|
|
125
|
+
channel: StructuredStreamChannel,
|
|
126
|
+
*,
|
|
127
|
+
event_content_utf8_bytes: int,
|
|
128
|
+
cumulative_content_utf8_bytes: int,
|
|
129
|
+
rolling_content_sha256: str,
|
|
130
|
+
) -> None:
|
|
131
|
+
nonlocal sequence, first_event_ns, last_event_ns, last_kind
|
|
132
|
+
nonlocal last_cumulative_content_utf8_bytes
|
|
133
|
+
nonlocal stream_completed_count
|
|
134
|
+
if not progress_accepting:
|
|
135
|
+
raise StructuredGenerationError(
|
|
136
|
+
kind=GenerationFailureKind.CANCELLED,
|
|
137
|
+
retryable=False,
|
|
138
|
+
safe_message="stream progress occurred after liveness expiry",
|
|
139
|
+
)
|
|
140
|
+
if type(kind) is not StructuredStreamProgressKind:
|
|
141
|
+
raise TypeError("stream progress kind escaped the closed domain")
|
|
142
|
+
if type(channel) is not StructuredStreamChannel:
|
|
143
|
+
raise TypeError("stream channel escaped the closed domain")
|
|
144
|
+
if stream_completed_count:
|
|
145
|
+
raise StructuredGenerationError(
|
|
146
|
+
kind=GenerationFailureKind.UNKNOWN,
|
|
147
|
+
retryable=False,
|
|
148
|
+
safe_message=(
|
|
149
|
+
"stream progress occurred after local stream completion"
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
if (
|
|
153
|
+
type(event_content_utf8_bytes) is not int
|
|
154
|
+
or event_content_utf8_bytes < 0
|
|
155
|
+
):
|
|
156
|
+
raise ValueError("stream event byte count escaped the closed domain")
|
|
157
|
+
if (
|
|
158
|
+
type(cumulative_content_utf8_bytes) is not int
|
|
159
|
+
or cumulative_content_utf8_bytes
|
|
160
|
+
!= last_cumulative_content_utf8_bytes + event_content_utf8_bytes
|
|
161
|
+
):
|
|
162
|
+
raise ValueError("stream cumulative byte count is not monotonic")
|
|
163
|
+
observed_ns = self._monotonic_ns()
|
|
164
|
+
if type(observed_ns) is not int or observed_ns < started_ns:
|
|
165
|
+
raise ValueError("monotonic stream observation moved backwards")
|
|
166
|
+
sequence += 1
|
|
167
|
+
if first_event_ns is None:
|
|
168
|
+
first_event_ns = observed_ns
|
|
169
|
+
last_event_ns = observed_ns
|
|
170
|
+
progress = StructuredStreamProgress(
|
|
171
|
+
call_id=call_id,
|
|
172
|
+
sequence=sequence,
|
|
173
|
+
kind=kind,
|
|
174
|
+
channel=channel,
|
|
175
|
+
elapsed_ns=observed_ns - started_ns,
|
|
176
|
+
event_content_utf8_bytes=event_content_utf8_bytes,
|
|
177
|
+
cumulative_content_utf8_bytes=cumulative_content_utf8_bytes,
|
|
178
|
+
rolling_content_sha256=rolling_content_sha256,
|
|
179
|
+
provider_attempt_id=provider_attempt_id,
|
|
180
|
+
)
|
|
181
|
+
if progress_sink is not None:
|
|
182
|
+
# Publication is deliberately fail closed: a scientific
|
|
183
|
+
# response cannot escape when required liveness evidence was
|
|
184
|
+
# not accepted by its injected sink.
|
|
185
|
+
progress_sink(progress)
|
|
186
|
+
last_cumulative_content_utf8_bytes = cumulative_content_utf8_bytes
|
|
187
|
+
last_kind = kind
|
|
188
|
+
if kind is StructuredStreamProgressKind.STREAM_COMPLETED:
|
|
189
|
+
stream_completed_count += 1
|
|
190
|
+
activity.set()
|
|
191
|
+
|
|
192
|
+
task = asyncio.create_task(operation(mark_progress))
|
|
193
|
+
|
|
194
|
+
async def expire_liveness(
|
|
195
|
+
phase: StructuredStreamTimeoutPhase,
|
|
196
|
+
) -> None:
|
|
197
|
+
nonlocal progress_accepting
|
|
198
|
+
progress_accepting = False
|
|
199
|
+
settled = await _cancel_and_drain(
|
|
200
|
+
task,
|
|
201
|
+
timeout_ns=policy.cleanup_policy.cancel_drain_timeout_ns,
|
|
202
|
+
)
|
|
203
|
+
if settled:
|
|
204
|
+
raise StructuredStreamTimeoutError(phase)
|
|
205
|
+
# asyncio cannot kill a cancellation-resistant coroutine. Retire
|
|
206
|
+
# this supervisor before returning so neither a retry nor a later
|
|
207
|
+
# logical call can share the abandoned attempt's transport.
|
|
208
|
+
self._retired = True
|
|
209
|
+
await _retire_bounded(
|
|
210
|
+
self._retirement_operation,
|
|
211
|
+
timeout_ns=(
|
|
212
|
+
policy.cleanup_policy.transport_retire_timeout_ns
|
|
213
|
+
),
|
|
214
|
+
)
|
|
215
|
+
raise StructuredStreamCleanupTimeoutError(phase)
|
|
216
|
+
|
|
217
|
+
try:
|
|
218
|
+
while True:
|
|
219
|
+
if task.done():
|
|
220
|
+
result = task.result()
|
|
221
|
+
if (
|
|
222
|
+
stream_completed_count != 1
|
|
223
|
+
or last_kind is not StructuredStreamProgressKind.STREAM_COMPLETED
|
|
224
|
+
):
|
|
225
|
+
raise StructuredGenerationError(
|
|
226
|
+
kind=GenerationFailureKind.UNKNOWN,
|
|
227
|
+
retryable=False,
|
|
228
|
+
safe_message=(
|
|
229
|
+
"streaming operation returned without one terminal "
|
|
230
|
+
"local completion event"
|
|
231
|
+
),
|
|
232
|
+
)
|
|
233
|
+
return result
|
|
234
|
+
|
|
235
|
+
now_ns = self._monotonic_ns()
|
|
236
|
+
deadline_ns, phase = _next_deadline(
|
|
237
|
+
started_ns=started_ns,
|
|
238
|
+
first_event_ns=first_event_ns,
|
|
239
|
+
last_event_ns=last_event_ns,
|
|
240
|
+
policy=policy,
|
|
241
|
+
)
|
|
242
|
+
remaining_ns = deadline_ns - now_ns
|
|
243
|
+
if remaining_ns <= 0:
|
|
244
|
+
await expire_liveness(phase)
|
|
245
|
+
|
|
246
|
+
observed_sequence = sequence
|
|
247
|
+
activity.clear()
|
|
248
|
+
if sequence != observed_sequence:
|
|
249
|
+
continue
|
|
250
|
+
activity_waiter = asyncio.create_task(activity.wait())
|
|
251
|
+
try:
|
|
252
|
+
done, _ = await asyncio.wait(
|
|
253
|
+
(task, activity_waiter),
|
|
254
|
+
timeout=remaining_ns / 1_000_000_000,
|
|
255
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
256
|
+
)
|
|
257
|
+
finally:
|
|
258
|
+
if not activity_waiter.done():
|
|
259
|
+
activity_waiter.cancel()
|
|
260
|
+
with suppress(BaseException):
|
|
261
|
+
await activity_waiter
|
|
262
|
+
if task in done:
|
|
263
|
+
continue
|
|
264
|
+
if activity_waiter in done:
|
|
265
|
+
continue
|
|
266
|
+
await expire_liveness(phase)
|
|
267
|
+
except asyncio.CancelledError:
|
|
268
|
+
progress_accepting = False
|
|
269
|
+
settled = await _cancel_and_drain(
|
|
270
|
+
task,
|
|
271
|
+
timeout_ns=policy.cleanup_policy.cancel_drain_timeout_ns,
|
|
272
|
+
)
|
|
273
|
+
if not settled:
|
|
274
|
+
self._retired = True
|
|
275
|
+
await _retire_bounded(
|
|
276
|
+
self._retirement_operation,
|
|
277
|
+
timeout_ns=(
|
|
278
|
+
policy.cleanup_policy.transport_retire_timeout_ns
|
|
279
|
+
),
|
|
280
|
+
)
|
|
281
|
+
raise
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _next_deadline(
|
|
285
|
+
*,
|
|
286
|
+
started_ns: int,
|
|
287
|
+
first_event_ns: int | None,
|
|
288
|
+
last_event_ns: int | None,
|
|
289
|
+
policy: StructuredStreamLivenessPolicy,
|
|
290
|
+
) -> tuple[int, StructuredStreamTimeoutPhase]:
|
|
291
|
+
"""Return the next boundary; absolute wins deterministic deadline ties."""
|
|
292
|
+
|
|
293
|
+
if first_event_ns is None:
|
|
294
|
+
candidates = [
|
|
295
|
+
(
|
|
296
|
+
started_ns + policy.first_event_timeout_ns,
|
|
297
|
+
1,
|
|
298
|
+
StructuredStreamTimeoutPhase.FIRST_EVENT,
|
|
299
|
+
)
|
|
300
|
+
]
|
|
301
|
+
else:
|
|
302
|
+
assert last_event_ns is not None
|
|
303
|
+
candidates = [
|
|
304
|
+
(
|
|
305
|
+
last_event_ns + policy.idle_timeout_ns,
|
|
306
|
+
1,
|
|
307
|
+
StructuredStreamTimeoutPhase.IDLE,
|
|
308
|
+
)
|
|
309
|
+
]
|
|
310
|
+
if policy.absolute_timeout_ns is not None:
|
|
311
|
+
candidates.append(
|
|
312
|
+
(
|
|
313
|
+
started_ns + policy.absolute_timeout_ns,
|
|
314
|
+
0,
|
|
315
|
+
StructuredStreamTimeoutPhase.ABSOLUTE,
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
deadline_ns, _, phase = min(candidates)
|
|
319
|
+
return deadline_ns, phase
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _consume_terminal(task: "asyncio.Task[object]") -> None:
|
|
323
|
+
"""Retrieve a detached task's terminal state without retaining content."""
|
|
324
|
+
|
|
325
|
+
with suppress(BaseException):
|
|
326
|
+
task.exception()
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
async def _cancel_and_drain(
|
|
330
|
+
task: "asyncio.Task[object]",
|
|
331
|
+
*,
|
|
332
|
+
timeout_ns: int,
|
|
333
|
+
) -> bool:
|
|
334
|
+
"""Cancel one stream and wait at most the frozen cleanup interval."""
|
|
335
|
+
|
|
336
|
+
if type(timeout_ns) is not int or timeout_ns <= 0:
|
|
337
|
+
raise ValueError("timeout_ns must be a positive exact integer")
|
|
338
|
+
if not task.done():
|
|
339
|
+
task.cancel()
|
|
340
|
+
done, _ = await asyncio.wait(
|
|
341
|
+
(task,),
|
|
342
|
+
timeout=timeout_ns / 1_000_000_000,
|
|
343
|
+
return_when=asyncio.ALL_COMPLETED,
|
|
344
|
+
)
|
|
345
|
+
if task in done:
|
|
346
|
+
_consume_terminal(task)
|
|
347
|
+
return True
|
|
348
|
+
task.add_done_callback(_consume_terminal)
|
|
349
|
+
return False
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
async def _retire_bounded(
|
|
353
|
+
retirement_operation: StreamRetirementOperation | None,
|
|
354
|
+
*,
|
|
355
|
+
timeout_ns: int,
|
|
356
|
+
) -> bool:
|
|
357
|
+
"""Invoke transport retirement without trusting close cancellation."""
|
|
358
|
+
|
|
359
|
+
if type(timeout_ns) is not int or timeout_ns <= 0:
|
|
360
|
+
raise ValueError("timeout_ns must be a positive exact integer")
|
|
361
|
+
if retirement_operation is None:
|
|
362
|
+
return True
|
|
363
|
+
task = asyncio.create_task(retirement_operation())
|
|
364
|
+
done, _ = await asyncio.wait(
|
|
365
|
+
(task,),
|
|
366
|
+
timeout=timeout_ns / 1_000_000_000,
|
|
367
|
+
return_when=asyncio.ALL_COMPLETED,
|
|
368
|
+
)
|
|
369
|
+
if task in done:
|
|
370
|
+
_consume_terminal(task)
|
|
371
|
+
return True
|
|
372
|
+
task.cancel()
|
|
373
|
+
task.add_done_callback(_consume_terminal)
|
|
374
|
+
return False
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
__all__ = [
|
|
378
|
+
"AsyncioContentBlindStreamSupervisor",
|
|
379
|
+
"ContentBlindStreamSupervisor",
|
|
380
|
+
"StreamOperation",
|
|
381
|
+
"StreamProgressMarker",
|
|
382
|
+
"StreamRetirementOperation",
|
|
383
|
+
]
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Deny-by-default subprocess implementation for the generic process port."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
import hashlib
|
|
7
|
+
import json
|
|
8
|
+
import math
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import stat
|
|
12
|
+
import subprocess
|
|
13
|
+
|
|
14
|
+
from agent_evolve.ports.subprocess_boundary import (
|
|
15
|
+
ChildProcessPolicy,
|
|
16
|
+
ChildProcessResult,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _canonical_sha256(value: object) -> str:
|
|
21
|
+
payload = json.dumps(
|
|
22
|
+
value,
|
|
23
|
+
ensure_ascii=True,
|
|
24
|
+
allow_nan=False,
|
|
25
|
+
sort_keys=True,
|
|
26
|
+
separators=(",", ":"),
|
|
27
|
+
).encode("ascii")
|
|
28
|
+
return hashlib.sha256(payload).hexdigest()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ExplicitEnvironmentSubprocessBoundary:
|
|
32
|
+
"""Run bounded commands with exact argv, cwd, and allowlisted environment."""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
*,
|
|
37
|
+
policy: ChildProcessPolicy,
|
|
38
|
+
working_directory: Path,
|
|
39
|
+
source_environment: Mapping[str, str] | None = None,
|
|
40
|
+
) -> None:
|
|
41
|
+
if type(policy) is not ChildProcessPolicy:
|
|
42
|
+
raise TypeError("policy must be exact ChildProcessPolicy")
|
|
43
|
+
if not isinstance(working_directory, Path) or not working_directory.is_absolute():
|
|
44
|
+
raise ValueError("working_directory must be an absolute pathlib.Path")
|
|
45
|
+
resolved_working_directory = working_directory.resolve(strict=True)
|
|
46
|
+
if not resolved_working_directory.is_dir():
|
|
47
|
+
raise ValueError("working_directory must resolve to a directory")
|
|
48
|
+
source = os.environ if source_environment is None else source_environment
|
|
49
|
+
environment: dict[str, str] = {}
|
|
50
|
+
for name in policy.inherited_environment_allowlist:
|
|
51
|
+
value = source.get(name)
|
|
52
|
+
if value is not None:
|
|
53
|
+
if type(value) is not str or "\x00" in value:
|
|
54
|
+
raise ValueError("allowlisted environment values must be strings")
|
|
55
|
+
environment[name] = value
|
|
56
|
+
environment.update(dict(policy.fixed_environment))
|
|
57
|
+
self._policy = policy
|
|
58
|
+
self._working_directory = resolved_working_directory
|
|
59
|
+
self._environment = environment
|
|
60
|
+
self._record = {
|
|
61
|
+
"schema_version": 1,
|
|
62
|
+
"policy": {
|
|
63
|
+
**policy.to_record(),
|
|
64
|
+
"identity_sha256": policy.identity_sha256,
|
|
65
|
+
},
|
|
66
|
+
"working_directory": str(resolved_working_directory),
|
|
67
|
+
"effective_environment_names": sorted(environment),
|
|
68
|
+
"effective_environment_sha256": _canonical_sha256(environment),
|
|
69
|
+
}
|
|
70
|
+
self._identity_sha256 = _canonical_sha256(self._record)
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def identity_sha256(self) -> str:
|
|
74
|
+
return self._identity_sha256
|
|
75
|
+
|
|
76
|
+
def stable_record(self) -> dict[str, object]:
|
|
77
|
+
return {
|
|
78
|
+
**self._record,
|
|
79
|
+
"identity_sha256": self._identity_sha256,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
def invocation_observation(self, executable: str) -> dict[str, object]:
|
|
83
|
+
if type(executable) is not str or not executable:
|
|
84
|
+
raise ValueError("executable must be a non-empty string")
|
|
85
|
+
invoked = Path(executable)
|
|
86
|
+
if not invoked.is_absolute():
|
|
87
|
+
raise ValueError("executable invocation path must be absolute")
|
|
88
|
+
metadata = invoked.lstat()
|
|
89
|
+
resolved = invoked.resolve(strict=True)
|
|
90
|
+
return {
|
|
91
|
+
"schema_version": 1,
|
|
92
|
+
"invoked_path": str(invoked),
|
|
93
|
+
"resolved_target": str(resolved),
|
|
94
|
+
"is_symlink": invoked.is_symlink(),
|
|
95
|
+
"lstat": {
|
|
96
|
+
"device": metadata.st_dev,
|
|
97
|
+
"inode": metadata.st_ino,
|
|
98
|
+
"mode_octal": oct(stat.S_IMODE(metadata.st_mode)),
|
|
99
|
+
"size_bytes": metadata.st_size,
|
|
100
|
+
"mtime_ns": metadata.st_mtime_ns,
|
|
101
|
+
},
|
|
102
|
+
"process_boundary_identity_sha256": self._identity_sha256,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
def run(self, argv: tuple[str, ...], *, timeout_s: float) -> ChildProcessResult:
|
|
106
|
+
if (
|
|
107
|
+
type(argv) is not tuple
|
|
108
|
+
or not argv
|
|
109
|
+
or any(type(item) is not str or not item or "\x00" in item for item in argv)
|
|
110
|
+
):
|
|
111
|
+
raise ValueError("argv must be a non-empty exact tuple of safe strings")
|
|
112
|
+
if (
|
|
113
|
+
isinstance(timeout_s, bool)
|
|
114
|
+
or not isinstance(timeout_s, (int, float))
|
|
115
|
+
or not math.isfinite(float(timeout_s))
|
|
116
|
+
or float(timeout_s) <= 0.0
|
|
117
|
+
):
|
|
118
|
+
raise ValueError("timeout_s must be finite and positive")
|
|
119
|
+
completed = subprocess.run(
|
|
120
|
+
argv,
|
|
121
|
+
check=False,
|
|
122
|
+
capture_output=True,
|
|
123
|
+
text=True,
|
|
124
|
+
timeout=float(timeout_s),
|
|
125
|
+
cwd=self._working_directory,
|
|
126
|
+
env=dict(self._environment),
|
|
127
|
+
shell=False,
|
|
128
|
+
)
|
|
129
|
+
return ChildProcessResult(
|
|
130
|
+
returncode=completed.returncode,
|
|
131
|
+
stdout=completed.stdout,
|
|
132
|
+
stderr=completed.stderr,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
__all__ = ["ExplicitEnvironmentSubprocessBoundary"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Concrete integrations (harness adapters). The core never imports from here."""
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Optional direct and dependency-isolated BoTorch acquisition integrations."""
|
|
2
|
+
|
|
3
|
+
from agent_evolve.integrations.botorch.subprocess_qlognehvi import (
|
|
4
|
+
FiniteAcquisitionSubprocessError,
|
|
5
|
+
IsolatedBotorchQLogNehviFiniteAcquisition,
|
|
6
|
+
build_isolated_botorch_qlognehvi,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def __getattr__(name: str) -> object:
|
|
11
|
+
# Keep torch and BoTorch optional in the main agent runtime. The direct
|
|
12
|
+
# policy is imported only by users (and the isolated worker) that request it.
|
|
13
|
+
if name != "BotorchQLogNehviFiniteAcquisition":
|
|
14
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
15
|
+
from agent_evolve.integrations.botorch.finite_qlognehvi import (
|
|
16
|
+
BotorchQLogNehviFiniteAcquisition,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
globals()[name] = BotorchQLogNehviFiniteAcquisition
|
|
20
|
+
return BotorchQLogNehviFiniteAcquisition
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"BotorchQLogNehviFiniteAcquisition",
|
|
25
|
+
"FiniteAcquisitionSubprocessError",
|
|
26
|
+
"IsolatedBotorchQLogNehviFiniteAcquisition",
|
|
27
|
+
"build_isolated_botorch_qlognehvi",
|
|
28
|
+
]
|