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,479 @@
|
|
|
1
|
+
"""Record and replay a generative proposer, so its evidence is checkable.
|
|
2
|
+
|
|
3
|
+
The catalogue path is auditable because the model's whole output is one token
|
|
4
|
+
from a sealed list. Generative proposal gives that up on purpose -- the model
|
|
5
|
+
authors configurations -- so the audit has to move with it. This wrapper is
|
|
6
|
+
where it moves to.
|
|
7
|
+
|
|
8
|
+
``SealedGenerativeHarness`` sits between the loop and any :class:`Harness` and
|
|
9
|
+
does one of two things:
|
|
10
|
+
|
|
11
|
+
``record`` call the delegate, hash the exact instruction, seal what came back
|
|
12
|
+
(configurations verbatim, guidance text verbatim) into a chained
|
|
13
|
+
journal, and hand the loop the delegate's answer unchanged.
|
|
14
|
+
``replay`` serve the sealed answer, after checking that the question matches.
|
|
15
|
+
No provider, no network, no credential. A prompt that has drifted
|
|
16
|
+
from the sealed one is an error, never a live call.
|
|
17
|
+
|
|
18
|
+
The prompt is hashed rather than stored because it is a *derived* quantity: the
|
|
19
|
+
loop composes it from the problem's directives and the campaign's own state, so
|
|
20
|
+
a replay that reaches a different hash has already diverged somewhere it can
|
|
21
|
+
still be diagnosed. Storing the text as well would make the journal larger and
|
|
22
|
+
prove nothing extra.
|
|
23
|
+
|
|
24
|
+
**Why replay is exact at all.** Nothing here makes a stochastic loop
|
|
25
|
+
deterministic. Replay reproduces a run only when everything outside the
|
|
26
|
+
provider is already reproducible -- a deterministic evaluator, a fixed seed, and
|
|
27
|
+
the same code. That is the standing condition on this project's benchmarks, and
|
|
28
|
+
when it does not hold the drift check fails loudly instead of quietly serving
|
|
29
|
+
the wrong answer.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
from typing import Any, Callable, Dict, List, Optional, Sequence
|
|
35
|
+
|
|
36
|
+
from agent_evolve.core.problem import ValidationOutcome
|
|
37
|
+
from agent_evolve.domain.generative_emission import (
|
|
38
|
+
GENESIS_CALL_SHA256,
|
|
39
|
+
GenerativeEmission,
|
|
40
|
+
GenerativeProposalCall,
|
|
41
|
+
SealedGuidanceCall,
|
|
42
|
+
SealedRunHeader,
|
|
43
|
+
generative_prompt_sha256,
|
|
44
|
+
)
|
|
45
|
+
from agent_evolve.domain.typed_json import freeze_json, thaw_json
|
|
46
|
+
from agent_evolve.harness.base import (
|
|
47
|
+
Harness,
|
|
48
|
+
HarnessBase,
|
|
49
|
+
HarnessContext,
|
|
50
|
+
HarnessOutputError,
|
|
51
|
+
LLMConfig,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
"SealedGenerativeHarness",
|
|
56
|
+
"SealedReplayDriftError",
|
|
57
|
+
"CANDIDATE_OPS",
|
|
58
|
+
"GUIDANCE_OPS",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
#: Operations whose output is a configuration the model authored. These are the
|
|
62
|
+
#: operator under test.
|
|
63
|
+
CANDIDATE_OPS = (
|
|
64
|
+
"generate_initial",
|
|
65
|
+
"regenerate",
|
|
66
|
+
"generate_offspring",
|
|
67
|
+
"regenerate_offspring",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
#: Operations whose output is text that re-enters a later prompt.
|
|
71
|
+
GUIDANCE_OPS = (
|
|
72
|
+
"failure_insights",
|
|
73
|
+
"constraint_instruction",
|
|
74
|
+
"performance_insights",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class SealedReplayDriftError(RuntimeError):
|
|
79
|
+
"""A replayed call is not the call that was sealed.
|
|
80
|
+
|
|
81
|
+
Raised rather than falling back to a live call. A silent fallback would let
|
|
82
|
+
a run that claims to be provider-free contact a provider, which is exactly
|
|
83
|
+
the property the seal exists to prove.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _as_outcome(value: Any) -> ValidationOutcome:
|
|
88
|
+
if isinstance(value, ValidationOutcome):
|
|
89
|
+
return value
|
|
90
|
+
if value is True or value is None:
|
|
91
|
+
return ValidationOutcome(True)
|
|
92
|
+
if value is False:
|
|
93
|
+
return ValidationOutcome(False, "validation", "validate() returned False")
|
|
94
|
+
raise TypeError("validate() must return a ValidationOutcome or a bool")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _verdict(
|
|
98
|
+
validator: Optional[Callable[[Dict[str, Any]], Any]],
|
|
99
|
+
config: Dict[str, Any],
|
|
100
|
+
) -> tuple[bool, str]:
|
|
101
|
+
"""Run the problem's own feasibility check, and never let it abort the run."""
|
|
102
|
+
|
|
103
|
+
if validator is None:
|
|
104
|
+
return True, ""
|
|
105
|
+
try:
|
|
106
|
+
outcome = _as_outcome(validator(config))
|
|
107
|
+
except ValueError as exc:
|
|
108
|
+
return False, f"ValueError: {exc}" or "ValueError"
|
|
109
|
+
except TypeError as exc:
|
|
110
|
+
return False, f"TypeError: {exc}" or "TypeError"
|
|
111
|
+
if outcome.ok:
|
|
112
|
+
return True, ""
|
|
113
|
+
return False, (outcome.message or outcome.failure_phase or "rejected by validate()")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class SealedGenerativeHarness(HarnessBase):
|
|
117
|
+
"""Seal a generative proposer's decisions by content, not by menu index.
|
|
118
|
+
|
|
119
|
+
*delegate* is the proposer actually being audited; in ``replay`` mode it is
|
|
120
|
+
never called and may be omitted entirely.
|
|
121
|
+
|
|
122
|
+
*validator* should be the problem's ``validate``. Its verdict is sealed
|
|
123
|
+
alongside each emission so the journal records what the loop was told, and a
|
|
124
|
+
replay re-runs it and requires agreement -- feasibility certification
|
|
125
|
+
survives the loss of the catalogue.
|
|
126
|
+
|
|
127
|
+
*candidate_schema_sha256* pins the support the emission was drawn from. It
|
|
128
|
+
is the field that makes a matched null checkable: a null sampling a
|
|
129
|
+
different schema is a support mismatch, and this is where that becomes
|
|
130
|
+
visible rather than assumed.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
id = "sealed_generative"
|
|
134
|
+
|
|
135
|
+
def __init__(
|
|
136
|
+
self,
|
|
137
|
+
delegate: Optional[Harness] = None,
|
|
138
|
+
*,
|
|
139
|
+
candidate_schema_sha256: str,
|
|
140
|
+
mode: str = "record",
|
|
141
|
+
validator: Optional[Callable[[Dict[str, Any]], Any]] = None,
|
|
142
|
+
sealed_calls: Sequence[Any] = (),
|
|
143
|
+
on_seal: Optional[Callable[[Dict[str, Any]], None]] = None,
|
|
144
|
+
) -> None:
|
|
145
|
+
super().__init__()
|
|
146
|
+
if mode not in ("record", "replay"):
|
|
147
|
+
raise ValueError("mode must be 'record' or 'replay'")
|
|
148
|
+
if mode == "record" and delegate is None:
|
|
149
|
+
raise ValueError("recording requires a delegate proposer to record")
|
|
150
|
+
self._delegate = delegate
|
|
151
|
+
self._mode = mode
|
|
152
|
+
self._validator = validator
|
|
153
|
+
self._schema_sha256 = candidate_schema_sha256
|
|
154
|
+
self._on_seal = on_seal
|
|
155
|
+
self._sealed: List[Any] = list(sealed_calls)
|
|
156
|
+
self._calls: List[Any] = []
|
|
157
|
+
self._previous = GENESIS_CALL_SHA256
|
|
158
|
+
self._cursor = 0
|
|
159
|
+
|
|
160
|
+
# -- lifecycle --------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
def _on_bind(self, ctx: HarnessContext, cfg: LLMConfig) -> None:
|
|
163
|
+
if self._delegate is not None:
|
|
164
|
+
self._delegate.bind(ctx, cfg)
|
|
165
|
+
if self._mode == "record" and not self._calls:
|
|
166
|
+
# The header opens the chain, before any question is asked, because
|
|
167
|
+
# it declares which questions this proposer will be asked at all.
|
|
168
|
+
self._append(
|
|
169
|
+
SealedRunHeader(
|
|
170
|
+
proposer_id=str(getattr(self._delegate, "id", "unknown")),
|
|
171
|
+
requested_model=cfg.model,
|
|
172
|
+
candidate_schema_sha256=self._schema_sha256,
|
|
173
|
+
provides_insights=bool(
|
|
174
|
+
getattr(self._delegate, "provides_insights", True)
|
|
175
|
+
),
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
elif self._mode == "replay":
|
|
179
|
+
if not self._sealed or type(self._sealed[0]) is not SealedRunHeader:
|
|
180
|
+
raise SealedReplayDriftError(
|
|
181
|
+
"the sealed journal has no run header, so the recorded "
|
|
182
|
+
"proposer's declarations cannot be recovered"
|
|
183
|
+
)
|
|
184
|
+
header = self._sealed[0]
|
|
185
|
+
if header.candidate_schema_sha256 != self._schema_sha256:
|
|
186
|
+
raise SealedReplayDriftError(
|
|
187
|
+
"the sealed run was recorded against a different candidate "
|
|
188
|
+
"schema than the one now bound"
|
|
189
|
+
)
|
|
190
|
+
self._cursor = 1
|
|
191
|
+
self._append(header)
|
|
192
|
+
|
|
193
|
+
def set_call_observer(self, observer) -> None: # noqa: ANN001 - port signature
|
|
194
|
+
super().set_call_observer(observer)
|
|
195
|
+
setter = getattr(self._delegate, "set_call_observer", None)
|
|
196
|
+
if setter is not None:
|
|
197
|
+
setter(observer)
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def calls(self) -> tuple:
|
|
201
|
+
"""The chained journal this run produced, in issue order."""
|
|
202
|
+
|
|
203
|
+
return tuple(self._calls)
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def terminal_sha256(self) -> str:
|
|
207
|
+
"""The digest that closes the chain. Publishing it dates the evidence."""
|
|
208
|
+
|
|
209
|
+
return self._previous
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def provides_insights(self) -> bool:
|
|
213
|
+
"""Whether the loop should ask this proposer for guidance at all.
|
|
214
|
+
|
|
215
|
+
In replay the answer is *read from the sealed run header*, not guessed
|
|
216
|
+
and not inferred. The loop skips guidance calls for a proposer that
|
|
217
|
+
declares it makes none -- an uninformed baseline is exactly that case --
|
|
218
|
+
so a replay that assumed ``True`` because the delegate is absent issues a
|
|
219
|
+
call the recording never made, and then reports a drift it invented
|
|
220
|
+
itself. Inferring it from which guidance calls appear does not work
|
|
221
|
+
either: a proposer that declines *failure* insights is still asked for
|
|
222
|
+
the constraint guide, so the journal holds guidance calls in both cases.
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
if self._mode == "replay":
|
|
226
|
+
return bool(self._sealed[0].provides_insights)
|
|
227
|
+
return bool(getattr(self._delegate, "provides_insights", True))
|
|
228
|
+
|
|
229
|
+
# -- the seven operations ---------------------------------------------
|
|
230
|
+
|
|
231
|
+
def generate_initial(self, n: int) -> List[Dict[str, Any]]:
|
|
232
|
+
return self._candidates(
|
|
233
|
+
"generate_initial",
|
|
234
|
+
self.directives.compose_initial(self.context, n),
|
|
235
|
+
lambda: self._delegate.generate_initial(n),
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
def regenerate(
|
|
239
|
+
self,
|
|
240
|
+
failed_str: str,
|
|
241
|
+
n: int,
|
|
242
|
+
constraint_instruction: str,
|
|
243
|
+
performance_insights: str,
|
|
244
|
+
) -> List[Dict[str, Any]]:
|
|
245
|
+
return self._candidates(
|
|
246
|
+
"regenerate",
|
|
247
|
+
self.directives.compose_regenerate(
|
|
248
|
+
self.context, failed_str, n, constraint_instruction, performance_insights
|
|
249
|
+
),
|
|
250
|
+
lambda: self._delegate.regenerate(
|
|
251
|
+
failed_str, n, constraint_instruction, performance_insights
|
|
252
|
+
),
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
def generate_offspring(
|
|
256
|
+
self,
|
|
257
|
+
pareto_str: str,
|
|
258
|
+
n: int,
|
|
259
|
+
constraint_instruction: str,
|
|
260
|
+
performance_insights: str,
|
|
261
|
+
) -> List[Dict[str, Any]]:
|
|
262
|
+
return self._candidates(
|
|
263
|
+
"generate_offspring",
|
|
264
|
+
self.directives.compose_offspring(
|
|
265
|
+
self.context, pareto_str, n, constraint_instruction, performance_insights
|
|
266
|
+
),
|
|
267
|
+
lambda: self._delegate.generate_offspring(
|
|
268
|
+
pareto_str, n, constraint_instruction, performance_insights
|
|
269
|
+
),
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
def regenerate_offspring(
|
|
273
|
+
self,
|
|
274
|
+
failed_str: str,
|
|
275
|
+
pareto_str: str,
|
|
276
|
+
n: int,
|
|
277
|
+
constraint_instruction: str,
|
|
278
|
+
performance_insights: str,
|
|
279
|
+
) -> List[Dict[str, Any]]:
|
|
280
|
+
return self._candidates(
|
|
281
|
+
"regenerate_offspring",
|
|
282
|
+
self.directives.compose_regenerate_offspring(
|
|
283
|
+
self.context,
|
|
284
|
+
failed_str,
|
|
285
|
+
pareto_str,
|
|
286
|
+
n,
|
|
287
|
+
constraint_instruction,
|
|
288
|
+
performance_insights,
|
|
289
|
+
),
|
|
290
|
+
lambda: self._delegate.regenerate_offspring(
|
|
291
|
+
failed_str, pareto_str, n, constraint_instruction, performance_insights
|
|
292
|
+
),
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
def failure_insights(self, failed_str: str, n_failed: int) -> List[str]:
|
|
296
|
+
outputs = self._guidance(
|
|
297
|
+
"failure_insights",
|
|
298
|
+
self.directives.compose_failure_insights(self.context, failed_str, n_failed),
|
|
299
|
+
lambda: self._delegate.failure_insights(failed_str, n_failed),
|
|
300
|
+
)
|
|
301
|
+
return list(outputs)
|
|
302
|
+
|
|
303
|
+
def constraint_instruction(
|
|
304
|
+
self, failed_str: str, previous: Optional[str] = None
|
|
305
|
+
) -> str:
|
|
306
|
+
outputs = self._guidance(
|
|
307
|
+
"constraint_instruction",
|
|
308
|
+
self.directives.compose_constraint_instruction(
|
|
309
|
+
self.context, failed_str, previous or ""
|
|
310
|
+
),
|
|
311
|
+
lambda: self._delegate.constraint_instruction(failed_str, previous),
|
|
312
|
+
)
|
|
313
|
+
return outputs[0] if outputs else ""
|
|
314
|
+
|
|
315
|
+
def performance_insights(
|
|
316
|
+
self, stats_str: str, pareto_str: str, previous: Optional[str] = None
|
|
317
|
+
) -> str:
|
|
318
|
+
outputs = self._guidance(
|
|
319
|
+
"performance_insights",
|
|
320
|
+
self.directives.compose_performance_insights(
|
|
321
|
+
self.context, stats_str, pareto_str, previous or ""
|
|
322
|
+
),
|
|
323
|
+
lambda: self._delegate.performance_insights(stats_str, pareto_str, previous),
|
|
324
|
+
)
|
|
325
|
+
return outputs[0] if outputs else ""
|
|
326
|
+
|
|
327
|
+
# -- sealing ----------------------------------------------------------
|
|
328
|
+
|
|
329
|
+
def _next_sealed(self, op: str, prompt_sha256: str, expected: type) -> Any:
|
|
330
|
+
if self._cursor >= len(self._sealed):
|
|
331
|
+
raise SealedReplayDriftError(
|
|
332
|
+
f"{op}: the sealed journal is exhausted at call "
|
|
333
|
+
f"{self._cursor}. The replayed run asked more of the proposer "
|
|
334
|
+
"than the recorded one did, so it is a different run."
|
|
335
|
+
)
|
|
336
|
+
call = self._sealed[self._cursor]
|
|
337
|
+
self._cursor += 1
|
|
338
|
+
if type(call) is not expected:
|
|
339
|
+
raise SealedReplayDriftError(
|
|
340
|
+
f"call {call.call_ordinal}: sealed as {type(call).__name__}, "
|
|
341
|
+
f"replayed as {expected.__name__}"
|
|
342
|
+
)
|
|
343
|
+
if call.op != op:
|
|
344
|
+
raise SealedReplayDriftError(
|
|
345
|
+
f"call {call.call_ordinal}: sealed op {call.op!r}, replayed op {op!r}"
|
|
346
|
+
)
|
|
347
|
+
if call.prompt_sha256 != prompt_sha256:
|
|
348
|
+
raise SealedReplayDriftError(
|
|
349
|
+
f"call {call.call_ordinal} ({op}): the prompt is not the sealed "
|
|
350
|
+
"prompt. Replay reconstructs the question before it trusts the "
|
|
351
|
+
"answer, and this question differs."
|
|
352
|
+
)
|
|
353
|
+
return call
|
|
354
|
+
|
|
355
|
+
def _append(self, call: Any) -> None:
|
|
356
|
+
self._calls.append(call)
|
|
357
|
+
self._previous = call.identity_sha256
|
|
358
|
+
if self._on_seal is not None:
|
|
359
|
+
self._on_seal(call.to_record())
|
|
360
|
+
|
|
361
|
+
def _candidates(
|
|
362
|
+
self,
|
|
363
|
+
op: str,
|
|
364
|
+
instruction: str,
|
|
365
|
+
live: Callable[[], List[Dict[str, Any]]],
|
|
366
|
+
) -> List[Dict[str, Any]]:
|
|
367
|
+
prompt_sha256 = generative_prompt_sha256(instruction)
|
|
368
|
+
ordinal = len(self._calls)
|
|
369
|
+
|
|
370
|
+
if self._mode == "replay":
|
|
371
|
+
sealed = self._next_sealed(op, prompt_sha256, GenerativeProposalCall)
|
|
372
|
+
if sealed.candidate_schema_sha256 != self._schema_sha256:
|
|
373
|
+
raise SealedReplayDriftError(
|
|
374
|
+
f"call {sealed.call_ordinal}: the emission was drawn from a "
|
|
375
|
+
"different candidate schema than the one now bound. The "
|
|
376
|
+
"support moved, so the decision is not the same decision."
|
|
377
|
+
)
|
|
378
|
+
configs = [thaw_json(c) for c in (e.configuration for e in sealed.emissions)]
|
|
379
|
+
self._recheck(sealed, configs)
|
|
380
|
+
call = GenerativeProposalCall(
|
|
381
|
+
call_ordinal=ordinal,
|
|
382
|
+
op=op,
|
|
383
|
+
requested_model=sealed.requested_model,
|
|
384
|
+
prompt_sha256=prompt_sha256,
|
|
385
|
+
candidate_schema_sha256=self._schema_sha256,
|
|
386
|
+
emissions=sealed.emissions,
|
|
387
|
+
previous_call_sha256=self._previous,
|
|
388
|
+
)
|
|
389
|
+
self._append(call)
|
|
390
|
+
return [dict(c) for c in configs]
|
|
391
|
+
|
|
392
|
+
configs = live()
|
|
393
|
+
if not isinstance(configs, list) or not configs:
|
|
394
|
+
# An empty answer is a failed call, and the loop already retries it.
|
|
395
|
+
# Sealing it as a success would put a call in the record that
|
|
396
|
+
# produced nothing, which is the shape of fabricated telemetry.
|
|
397
|
+
raise HarnessOutputError(f"{op}: proposer returned no candidates")
|
|
398
|
+
emissions = []
|
|
399
|
+
for config in configs:
|
|
400
|
+
accepted, reason = _verdict(self._validator, config)
|
|
401
|
+
emissions.append(
|
|
402
|
+
GenerativeEmission(
|
|
403
|
+
configuration=freeze_json(dict(config)),
|
|
404
|
+
accepted=accepted,
|
|
405
|
+
rejection_reason=reason,
|
|
406
|
+
)
|
|
407
|
+
)
|
|
408
|
+
call = GenerativeProposalCall(
|
|
409
|
+
call_ordinal=ordinal,
|
|
410
|
+
op=op,
|
|
411
|
+
requested_model=self.cfg.model,
|
|
412
|
+
prompt_sha256=prompt_sha256,
|
|
413
|
+
candidate_schema_sha256=self._schema_sha256,
|
|
414
|
+
emissions=tuple(emissions),
|
|
415
|
+
previous_call_sha256=self._previous,
|
|
416
|
+
)
|
|
417
|
+
self._append(call)
|
|
418
|
+
return configs
|
|
419
|
+
|
|
420
|
+
def _recheck(self, sealed: GenerativeProposalCall, configs: List[Any]) -> None:
|
|
421
|
+
"""Re-run the feasibility check and require the sealed verdict back.
|
|
422
|
+
|
|
423
|
+
This is what replaces the catalogue's enumeration guarantee. The
|
|
424
|
+
catalogue could promise every option was constructible because it built
|
|
425
|
+
them; a generative seal promises only that the emission still earns the
|
|
426
|
+
verdict the run acted on -- and it proves that by asking again.
|
|
427
|
+
"""
|
|
428
|
+
|
|
429
|
+
if self._validator is None:
|
|
430
|
+
return
|
|
431
|
+
for emission, config in zip(sealed.emissions, configs):
|
|
432
|
+
accepted, reason = _verdict(self._validator, config)
|
|
433
|
+
if accepted != emission.accepted:
|
|
434
|
+
raise SealedReplayDriftError(
|
|
435
|
+
f"call {sealed.call_ordinal}: a sealed emission validated as "
|
|
436
|
+
f"{'valid' if emission.accepted else 'invalid'} and now "
|
|
437
|
+
f"validates as {'valid' if accepted else 'invalid'}. The "
|
|
438
|
+
"problem's feasibility rule changed under the seal."
|
|
439
|
+
)
|
|
440
|
+
if not accepted and reason != emission.rejection_reason:
|
|
441
|
+
raise SealedReplayDriftError(
|
|
442
|
+
f"call {sealed.call_ordinal}: the rejection the proposer was "
|
|
443
|
+
"shown is not the rejection it would be shown now."
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
def _guidance(
|
|
447
|
+
self,
|
|
448
|
+
op: str,
|
|
449
|
+
instruction: str,
|
|
450
|
+
live: Callable[[], Any],
|
|
451
|
+
) -> tuple:
|
|
452
|
+
prompt_sha256 = generative_prompt_sha256(instruction)
|
|
453
|
+
ordinal = len(self._calls)
|
|
454
|
+
|
|
455
|
+
if self._mode == "replay":
|
|
456
|
+
sealed = self._next_sealed(op, prompt_sha256, SealedGuidanceCall)
|
|
457
|
+
call = SealedGuidanceCall(
|
|
458
|
+
call_ordinal=ordinal,
|
|
459
|
+
op=op,
|
|
460
|
+
requested_model=sealed.requested_model,
|
|
461
|
+
prompt_sha256=prompt_sha256,
|
|
462
|
+
outputs=sealed.outputs,
|
|
463
|
+
previous_call_sha256=self._previous,
|
|
464
|
+
)
|
|
465
|
+
self._append(call)
|
|
466
|
+
return sealed.outputs
|
|
467
|
+
|
|
468
|
+
raw = live()
|
|
469
|
+
outputs = tuple(str(x) for x in raw) if isinstance(raw, (list, tuple)) else (str(raw),)
|
|
470
|
+
call = SealedGuidanceCall(
|
|
471
|
+
call_ordinal=ordinal,
|
|
472
|
+
op=op,
|
|
473
|
+
requested_model=self.cfg.model,
|
|
474
|
+
prompt_sha256=prompt_sha256,
|
|
475
|
+
outputs=outputs,
|
|
476
|
+
previous_call_sha256=self._previous,
|
|
477
|
+
)
|
|
478
|
+
self._append(call)
|
|
479
|
+
return outputs
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Harness registry: register adapters by string id, create them by id."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Callable, Dict, List
|
|
6
|
+
|
|
7
|
+
from agent_evolve.harness.base import Harness
|
|
8
|
+
|
|
9
|
+
HarnessFactory = Callable[[], Harness]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HarnessRegistry:
|
|
13
|
+
"""Process-wide registry of harness adapters keyed by string id."""
|
|
14
|
+
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
self._factories: Dict[str, HarnessFactory] = {}
|
|
17
|
+
|
|
18
|
+
def register(self, harness_id: str, factory: HarnessFactory) -> None:
|
|
19
|
+
self._factories[harness_id] = factory
|
|
20
|
+
|
|
21
|
+
def create(self, harness_id: str, **kwargs: Any) -> Harness:
|
|
22
|
+
if harness_id not in self._factories:
|
|
23
|
+
raise KeyError(
|
|
24
|
+
f"Unknown harness '{harness_id}'. Registered: {sorted(self._factories)}"
|
|
25
|
+
)
|
|
26
|
+
factory = self._factories[harness_id]
|
|
27
|
+
try:
|
|
28
|
+
return factory(**kwargs) if kwargs else factory()
|
|
29
|
+
except TypeError:
|
|
30
|
+
# A factory that does not take the requested options still builds;
|
|
31
|
+
# the option was advisory (a seed, say), not part of the contract.
|
|
32
|
+
return factory()
|
|
33
|
+
|
|
34
|
+
def ids(self) -> List[str]:
|
|
35
|
+
return sorted(self._factories)
|
|
36
|
+
|
|
37
|
+
def clear(self) -> None:
|
|
38
|
+
self._factories.clear()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
harness_registry = HarnessRegistry()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Infrastructure adapters for AgentEvolve ports."""
|
|
2
|
+
|
|
3
|
+
from agent_evolve.infrastructure.outcome_adaptive_phase_journal import (
|
|
4
|
+
DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_DEFINITION_SHA256,
|
|
5
|
+
DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_ID,
|
|
6
|
+
DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_VERSION,
|
|
7
|
+
DurableJsonlOutcomeAdaptivePhaseCommitter,
|
|
8
|
+
)
|
|
9
|
+
from agent_evolve.infrastructure.sequential_phase_journal import (
|
|
10
|
+
DURABLE_SEQUENTIAL_PHASE_JOURNAL_DEFINITION_SHA256,
|
|
11
|
+
DURABLE_SEQUENTIAL_PHASE_JOURNAL_ID,
|
|
12
|
+
DURABLE_SEQUENTIAL_PHASE_JOURNAL_VERSION,
|
|
13
|
+
DurableJsonlSequentialPhaseCommitter,
|
|
14
|
+
)
|
|
15
|
+
from agent_evolve.infrastructure.residual_headroom_journal import (
|
|
16
|
+
DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_DEFINITION_SHA256,
|
|
17
|
+
DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_ID,
|
|
18
|
+
DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_VERSION,
|
|
19
|
+
DurableJsonlResidualHeadroomStore,
|
|
20
|
+
)
|
|
21
|
+
from agent_evolve.infrastructure.subprocess_boundary import (
|
|
22
|
+
ExplicitEnvironmentSubprocessBoundary,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_DEFINITION_SHA256",
|
|
27
|
+
"DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_ID",
|
|
28
|
+
"DURABLE_OUTCOME_ADAPTIVE_PHASE_JOURNAL_VERSION",
|
|
29
|
+
"DURABLE_SEQUENTIAL_PHASE_JOURNAL_DEFINITION_SHA256",
|
|
30
|
+
"DURABLE_SEQUENTIAL_PHASE_JOURNAL_ID",
|
|
31
|
+
"DURABLE_SEQUENTIAL_PHASE_JOURNAL_VERSION",
|
|
32
|
+
"DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_DEFINITION_SHA256",
|
|
33
|
+
"DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_ID",
|
|
34
|
+
"DURABLE_JSONL_RESIDUAL_HEADROOM_STORE_VERSION",
|
|
35
|
+
"DurableJsonlResidualHeadroomStore",
|
|
36
|
+
"DurableJsonlOutcomeAdaptivePhaseCommitter",
|
|
37
|
+
"DurableJsonlSequentialPhaseCommitter",
|
|
38
|
+
"ExplicitEnvironmentSubprocessBoundary",
|
|
39
|
+
]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Content-addressed artifact-store implementations."""
|
|
2
|
+
|
|
3
|
+
from agent_evolve.infrastructure.artifacts.filesystem import FileSystemArtifactStore
|
|
4
|
+
from agent_evolve.infrastructure.artifacts.in_memory import InMemoryArtifactStore
|
|
5
|
+
|
|
6
|
+
__all__ = ["FileSystemArtifactStore", "InMemoryArtifactStore"]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Shared verification for artifact-store adapters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import agent_evolve.domain.artifact as artifact_domain
|
|
6
|
+
from agent_evolve.domain.artifact import ArtifactRef, validate_media_type
|
|
7
|
+
from agent_evolve.domain.ids import ArtifactId
|
|
8
|
+
from agent_evolve.ports.artifact_store import ArtifactTypeError, CorruptArtifactError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def require_artifact_id(value: ArtifactId) -> None:
|
|
12
|
+
if not isinstance(value, ArtifactId):
|
|
13
|
+
raise ArtifactTypeError("artifact_id must be an ArtifactId")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def require_content_and_media_type(content: bytes, media_type: str) -> None:
|
|
17
|
+
if not isinstance(content, bytes):
|
|
18
|
+
raise ArtifactTypeError("artifact content must be immutable bytes")
|
|
19
|
+
try:
|
|
20
|
+
validate_media_type(media_type)
|
|
21
|
+
except (TypeError, ValueError) as exc:
|
|
22
|
+
raise ArtifactTypeError(f"Invalid artifact media type: {exc}") from exc
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def require_expected_media_type(expected_media_type: str | None) -> None:
|
|
26
|
+
if expected_media_type is None:
|
|
27
|
+
return
|
|
28
|
+
try:
|
|
29
|
+
validate_media_type(expected_media_type)
|
|
30
|
+
except (TypeError, ValueError) as exc:
|
|
31
|
+
raise ArtifactTypeError(f"Invalid expected media type: {exc}") from exc
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def verify_content(ref: ArtifactRef, content: bytes) -> None:
|
|
35
|
+
if not isinstance(ref, ArtifactRef):
|
|
36
|
+
raise CorruptArtifactError("Stored artifact metadata is not an ArtifactRef")
|
|
37
|
+
if not isinstance(content, bytes):
|
|
38
|
+
raise CorruptArtifactError("Stored artifact content is not immutable bytes")
|
|
39
|
+
if len(content) != ref.size_bytes:
|
|
40
|
+
raise CorruptArtifactError(
|
|
41
|
+
f"Artifact {ref.artifact_id} size does not match its metadata"
|
|
42
|
+
)
|
|
43
|
+
payload_digest = artifact_domain.content_sha256(content)
|
|
44
|
+
if payload_digest != ref.sha256_hex:
|
|
45
|
+
raise CorruptArtifactError(
|
|
46
|
+
f"Artifact {ref.artifact_id} payload does not match its SHA-256 digest"
|
|
47
|
+
)
|
|
48
|
+
identity_digest = artifact_domain.artifact_identity_sha256(
|
|
49
|
+
content,
|
|
50
|
+
media_type=ref.media_type,
|
|
51
|
+
)
|
|
52
|
+
if ref.artifact_id != ArtifactId(f"artifact_{identity_digest}"):
|
|
53
|
+
raise CorruptArtifactError(
|
|
54
|
+
f"Artifact {ref.artifact_id} ID does not match its typed payload"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def verify_expected_media_type(
|
|
59
|
+
ref: ArtifactRef,
|
|
60
|
+
expected_media_type: str | None,
|
|
61
|
+
) -> None:
|
|
62
|
+
require_expected_media_type(expected_media_type)
|
|
63
|
+
if expected_media_type is not None and ref.media_type != expected_media_type:
|
|
64
|
+
raise ArtifactTypeError(
|
|
65
|
+
f"Artifact {ref.artifact_id} has media type {ref.media_type!r}, "
|
|
66
|
+
f"not {expected_media_type!r}"
|
|
67
|
+
)
|