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,834 @@
|
|
|
1
|
+
"""Benchmark-neutral, receipt-bound reflection after a terminal generation.
|
|
2
|
+
|
|
3
|
+
The optimizer seals a complete generation before invoking a feedback
|
|
4
|
+
interceptor. This module uses that boundary to run at most one optional
|
|
5
|
+
reflection call after a configured terminal generation. Earlier generations
|
|
6
|
+
reserve no calls. The terminal call may revise one planner-selected memory
|
|
7
|
+
entry and can inspect any explicitly named ``(generation, slot_id)`` outcomes.
|
|
8
|
+
|
|
9
|
+
Nothing in this module knows a benchmark's metrics, actions, planner type, or
|
|
10
|
+
generation count. Those semantics enter through an injected
|
|
11
|
+
``ReflectionInsightContract``, a declarative source scope, and a predecessor
|
|
12
|
+
resolver. Provider failures are represented by an authenticated incomplete
|
|
13
|
+
receipt and do not erase the already-sealed optimization outcomes.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import hashlib
|
|
19
|
+
import json
|
|
20
|
+
import re
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from typing import Protocol, runtime_checkable
|
|
23
|
+
|
|
24
|
+
from agent_evolve.application.agentic_evolution import (
|
|
25
|
+
AgenticEvolutionEngine,
|
|
26
|
+
InvocationOutcome,
|
|
27
|
+
ReflectionCallExecutionError,
|
|
28
|
+
ReflectionCallReceipt,
|
|
29
|
+
ReflectionCallStatus,
|
|
30
|
+
ReflectionPublicationResult,
|
|
31
|
+
)
|
|
32
|
+
from agent_evolve.application.budgeted_optimizer import (
|
|
33
|
+
GenerationPlan,
|
|
34
|
+
GenerationReceipt,
|
|
35
|
+
OptimizerState,
|
|
36
|
+
validate_generation_receipt_integrity,
|
|
37
|
+
)
|
|
38
|
+
from agent_evolve.application.generation_feedback import (
|
|
39
|
+
GenerationFeedbackContext,
|
|
40
|
+
GenerationFeedbackReservation,
|
|
41
|
+
GenerationFeedbackResult,
|
|
42
|
+
)
|
|
43
|
+
from agent_evolve.application.insight_memory import (
|
|
44
|
+
InsightLifecycleState,
|
|
45
|
+
InsightMemoryBank,
|
|
46
|
+
InsightMemoryEntry,
|
|
47
|
+
InsightOrigin,
|
|
48
|
+
)
|
|
49
|
+
from agent_evolve.domain.ids import OperatorInvocationId
|
|
50
|
+
from agent_evolve.domain.insight import InsightRef
|
|
51
|
+
from agent_evolve.domain.patch import require_sha256
|
|
52
|
+
from agent_evolve.ports.agentic_generator import ReflectionInsightContract
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
56
|
+
_SOURCE_SCOPE_DOMAIN = b"agent-evolve:post-evolution-reflection-source-scope:v1\x00"
|
|
57
|
+
_SPEC_DOMAIN = b"agent-evolve:post-evolution-reflection-spec:v1\x00"
|
|
58
|
+
_AUTHORITY_DOMAIN = b"agent-evolve:post-evolution-reflection-authority:v1\x00"
|
|
59
|
+
_RECEIPT_DOMAIN = b"agent-evolve:post-evolution-reflection-receipt:v1\x00"
|
|
60
|
+
|
|
61
|
+
POST_EVOLUTION_REFLECTION_DEFINITION_SHA256 = hashlib.sha256(
|
|
62
|
+
b"agent-evolve:post-evolution-reflection:v1;terminal-only-one-call;"
|
|
63
|
+
b"generation-slot-source-scope;planner-resolved-predecessor;"
|
|
64
|
+
b"injected-reflection-contract;engine-issued-request-publication-receipt;"
|
|
65
|
+
b"zero-prior-quarantined-revision;isolated-provider-failure"
|
|
66
|
+
).hexdigest()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _canonical_json(value: object) -> bytes:
|
|
70
|
+
return json.dumps(
|
|
71
|
+
value,
|
|
72
|
+
ensure_ascii=True,
|
|
73
|
+
allow_nan=False,
|
|
74
|
+
separators=(",", ":"),
|
|
75
|
+
sort_keys=True,
|
|
76
|
+
).encode("ascii")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _hash(domain: bytes, record: object) -> str:
|
|
80
|
+
return hashlib.sha256(domain + _canonical_json(record)).hexdigest()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _ref_record(reference: InsightRef) -> dict[str, object]:
|
|
84
|
+
return {
|
|
85
|
+
"insight_id": reference.insight_id.value,
|
|
86
|
+
"version": reference.version,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass(frozen=True, slots=True, order=True)
|
|
91
|
+
class PostEvolutionReflectionSource:
|
|
92
|
+
"""One exact outcome coordinate in the sealed generation ledger."""
|
|
93
|
+
|
|
94
|
+
generation: int
|
|
95
|
+
slot_id: str
|
|
96
|
+
|
|
97
|
+
def __post_init__(self) -> None:
|
|
98
|
+
if type(self.generation) is not int or self.generation <= 0:
|
|
99
|
+
raise ValueError("reflection source generation must be positive")
|
|
100
|
+
if (
|
|
101
|
+
type(self.slot_id) is not str
|
|
102
|
+
or not self.slot_id
|
|
103
|
+
or self.slot_id != self.slot_id.strip()
|
|
104
|
+
):
|
|
105
|
+
raise ValueError("reflection source slot_id must be canonical")
|
|
106
|
+
|
|
107
|
+
def to_record(self) -> dict[str, object]:
|
|
108
|
+
return {"generation": self.generation, "slot_id": self.slot_id}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _validated_receipts(
|
|
112
|
+
receipts: tuple[GenerationReceipt, ...],
|
|
113
|
+
) -> tuple[GenerationReceipt, ...]:
|
|
114
|
+
if type(receipts) is not tuple or not receipts:
|
|
115
|
+
raise ValueError("reflection sources require sealed generation receipts")
|
|
116
|
+
if any(type(receipt) is not GenerationReceipt for receipt in receipts):
|
|
117
|
+
raise TypeError("source receipts must be exact GenerationReceipt values")
|
|
118
|
+
for receipt in receipts:
|
|
119
|
+
validate_generation_receipt_integrity(receipt)
|
|
120
|
+
generations = tuple(receipt.generation for receipt in receipts)
|
|
121
|
+
if generations != tuple(range(1, len(receipts) + 1)):
|
|
122
|
+
raise ValueError("source receipts must be contiguous and ordered")
|
|
123
|
+
return receipts
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass(frozen=True, slots=True)
|
|
127
|
+
class PostEvolutionReflectionSourceScope:
|
|
128
|
+
"""Ordered, versioned selection of outcomes from sealed receipts.
|
|
129
|
+
|
|
130
|
+
Slot identifiers only need to be unique within a generation. Pairing each
|
|
131
|
+
identifier with its generation therefore permits stable scopes even when a
|
|
132
|
+
generic planner intentionally reuses role names across generations.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
sources: tuple[PostEvolutionReflectionSource, ...]
|
|
136
|
+
policy_id: str = "explicit_generation_slot_scope"
|
|
137
|
+
policy_version: int = 1
|
|
138
|
+
policy_definition_sha256: str = POST_EVOLUTION_REFLECTION_DEFINITION_SHA256
|
|
139
|
+
scope_sha256: str = field(init=False)
|
|
140
|
+
|
|
141
|
+
def __post_init__(self) -> None:
|
|
142
|
+
if type(self.policy_id) is not str or _TOKEN.fullmatch(self.policy_id) is None:
|
|
143
|
+
raise ValueError("source scope policy_id must use the token grammar")
|
|
144
|
+
if type(self.policy_version) is not int or self.policy_version <= 0:
|
|
145
|
+
raise ValueError("source scope policy_version must be positive")
|
|
146
|
+
require_sha256(
|
|
147
|
+
self.policy_definition_sha256,
|
|
148
|
+
"source scope policy_definition_sha256",
|
|
149
|
+
)
|
|
150
|
+
if type(self.sources) is not tuple or not self.sources:
|
|
151
|
+
raise ValueError("source scope requires at least one source")
|
|
152
|
+
if any(
|
|
153
|
+
type(source) is not PostEvolutionReflectionSource for source in self.sources
|
|
154
|
+
):
|
|
155
|
+
raise TypeError("source scope must contain exact source coordinates")
|
|
156
|
+
for source in self.sources:
|
|
157
|
+
PostEvolutionReflectionSource.__post_init__(source)
|
|
158
|
+
if len(set(self.sources)) != len(self.sources):
|
|
159
|
+
raise ValueError("source scope cannot repeat a generation/slot pair")
|
|
160
|
+
object.__setattr__(
|
|
161
|
+
self,
|
|
162
|
+
"scope_sha256",
|
|
163
|
+
_hash(_SOURCE_SCOPE_DOMAIN, self.to_record()),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def to_record(self) -> dict[str, object]:
|
|
167
|
+
return {
|
|
168
|
+
"schema_version": 1,
|
|
169
|
+
"policy_id": self.policy_id,
|
|
170
|
+
"policy_version": self.policy_version,
|
|
171
|
+
"policy_definition_sha256": self.policy_definition_sha256,
|
|
172
|
+
"sources": [source.to_record() for source in self.sources],
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
def select(
|
|
176
|
+
self,
|
|
177
|
+
receipts: tuple[GenerationReceipt, ...],
|
|
178
|
+
) -> tuple[InvocationOutcome, ...]:
|
|
179
|
+
"""Return exact outcomes in the declared source order."""
|
|
180
|
+
|
|
181
|
+
sealed = _validated_receipts(receipts)
|
|
182
|
+
outcomes: list[InvocationOutcome] = []
|
|
183
|
+
for source in self.sources:
|
|
184
|
+
if source.generation > len(sealed):
|
|
185
|
+
raise ValueError("source scope names an unsealed generation")
|
|
186
|
+
receipt = sealed[source.generation - 1]
|
|
187
|
+
matches = tuple(
|
|
188
|
+
slot_result.outcome
|
|
189
|
+
for slot_result in receipt.slot_results
|
|
190
|
+
if slot_result.slot.slot_id == source.slot_id
|
|
191
|
+
)
|
|
192
|
+
if len(matches) != 1:
|
|
193
|
+
raise ValueError(
|
|
194
|
+
"source scope must resolve each generation/slot pair exactly once"
|
|
195
|
+
)
|
|
196
|
+
outcome = matches[0]
|
|
197
|
+
if type(outcome) is not InvocationOutcome:
|
|
198
|
+
raise TypeError("source scope resolved a foreign invocation outcome")
|
|
199
|
+
outcomes.append(outcome)
|
|
200
|
+
return tuple(outcomes)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@runtime_checkable
|
|
204
|
+
class PostEvolutionPredecessorResolver(Protocol):
|
|
205
|
+
"""Resolve the memory entry selected by a benchmark-owned planner.
|
|
206
|
+
|
|
207
|
+
Composition invokes the resolver only after ``planner.plan`` has completed
|
|
208
|
+
for the terminal generation. A resolver may therefore read a planner's
|
|
209
|
+
frozen memory-assignment receipt without coupling this generic policy to
|
|
210
|
+
the planner's concrete type.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
def __call__(self, planner: object) -> InsightRef: ...
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@dataclass(frozen=True, slots=True)
|
|
217
|
+
class PostEvolutionReflectionSpec:
|
|
218
|
+
"""Complete benchmark-injected policy for one terminal reflection."""
|
|
219
|
+
|
|
220
|
+
terminal_generation: int
|
|
221
|
+
source_scope: PostEvolutionReflectionSourceScope
|
|
222
|
+
insight_contract: ReflectionInsightContract
|
|
223
|
+
policy_id: str = "post_evolution_atomic_revision"
|
|
224
|
+
policy_version: int = 1
|
|
225
|
+
policy_definition_sha256: str = POST_EVOLUTION_REFLECTION_DEFINITION_SHA256
|
|
226
|
+
label: str = "post_evolution_reflection"
|
|
227
|
+
spec_sha256: str = field(init=False)
|
|
228
|
+
|
|
229
|
+
def __post_init__(self) -> None:
|
|
230
|
+
if type(self.terminal_generation) is not int or self.terminal_generation <= 0:
|
|
231
|
+
raise ValueError("terminal_generation must be positive")
|
|
232
|
+
if type(self.source_scope) is not PostEvolutionReflectionSourceScope:
|
|
233
|
+
raise TypeError("reflection source_scope must be exact")
|
|
234
|
+
PostEvolutionReflectionSourceScope.__post_init__(self.source_scope)
|
|
235
|
+
if any(
|
|
236
|
+
source.generation > self.terminal_generation
|
|
237
|
+
for source in self.source_scope.sources
|
|
238
|
+
):
|
|
239
|
+
raise ValueError("reflection source cannot follow the terminal generation")
|
|
240
|
+
if type(self.insight_contract) is not ReflectionInsightContract:
|
|
241
|
+
raise TypeError("reflection insight_contract must be exact")
|
|
242
|
+
ReflectionInsightContract.__post_init__(self.insight_contract)
|
|
243
|
+
if type(self.policy_id) is not str or _TOKEN.fullmatch(self.policy_id) is None:
|
|
244
|
+
raise ValueError("reflection policy_id must use the token grammar")
|
|
245
|
+
if type(self.policy_version) is not int or self.policy_version <= 0:
|
|
246
|
+
raise ValueError("reflection policy_version must be positive")
|
|
247
|
+
require_sha256(
|
|
248
|
+
self.policy_definition_sha256,
|
|
249
|
+
"reflection policy_definition_sha256",
|
|
250
|
+
)
|
|
251
|
+
if (
|
|
252
|
+
type(self.label) is not str
|
|
253
|
+
or not self.label
|
|
254
|
+
or self.label != self.label.strip()
|
|
255
|
+
):
|
|
256
|
+
raise ValueError("reflection label must be canonical non-empty text")
|
|
257
|
+
object.__setattr__(self, "spec_sha256", _hash(_SPEC_DOMAIN, self.to_record()))
|
|
258
|
+
|
|
259
|
+
def to_record(self) -> dict[str, object]:
|
|
260
|
+
return {
|
|
261
|
+
"schema_version": 1,
|
|
262
|
+
"terminal_generation": self.terminal_generation,
|
|
263
|
+
"source_scope_sha256": self.source_scope.scope_sha256,
|
|
264
|
+
"insight_contract_sha256": self.insight_contract.identity_sha256,
|
|
265
|
+
"policy_id": self.policy_id,
|
|
266
|
+
"policy_version": self.policy_version,
|
|
267
|
+
"policy_definition_sha256": self.policy_definition_sha256,
|
|
268
|
+
"label": self.label,
|
|
269
|
+
"requested_cardinality": {"min": 0, "max": 1},
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@dataclass(frozen=True, slots=True)
|
|
274
|
+
class PostEvolutionReflectionAuthority:
|
|
275
|
+
"""Pre-provider commitment to exact sealed evidence and one revision."""
|
|
276
|
+
|
|
277
|
+
spec_sha256: str
|
|
278
|
+
reservation_hash: str
|
|
279
|
+
terminal_generation: int
|
|
280
|
+
generation_receipt_sha256s: tuple[str, ...]
|
|
281
|
+
source_scope_sha256: str
|
|
282
|
+
sources: tuple[PostEvolutionReflectionSource, ...]
|
|
283
|
+
source_operator_invocation_ids: tuple[OperatorInvocationId, ...]
|
|
284
|
+
revision_predecessor: InsightRef
|
|
285
|
+
revision_predecessor_content_sha256: str
|
|
286
|
+
insight_contract_sha256: str
|
|
287
|
+
reflection_label: str
|
|
288
|
+
authority_sha256: str = ""
|
|
289
|
+
|
|
290
|
+
def __post_init__(self) -> None:
|
|
291
|
+
for name in (
|
|
292
|
+
"spec_sha256",
|
|
293
|
+
"reservation_hash",
|
|
294
|
+
"source_scope_sha256",
|
|
295
|
+
"revision_predecessor_content_sha256",
|
|
296
|
+
"insight_contract_sha256",
|
|
297
|
+
):
|
|
298
|
+
require_sha256(getattr(self, name), f"reflection authority {name}")
|
|
299
|
+
if type(self.terminal_generation) is not int or self.terminal_generation <= 0:
|
|
300
|
+
raise ValueError("authority terminal_generation must be positive")
|
|
301
|
+
if (
|
|
302
|
+
type(self.generation_receipt_sha256s) is not tuple
|
|
303
|
+
or len(self.generation_receipt_sha256s) != self.terminal_generation
|
|
304
|
+
):
|
|
305
|
+
raise ValueError("authority requires every terminal generation receipt")
|
|
306
|
+
for value in self.generation_receipt_sha256s:
|
|
307
|
+
require_sha256(value, "reflection source generation receipt")
|
|
308
|
+
if type(self.sources) is not tuple or not self.sources:
|
|
309
|
+
raise ValueError("reflection authority requires source coordinates")
|
|
310
|
+
if any(
|
|
311
|
+
type(value) is not PostEvolutionReflectionSource for value in self.sources
|
|
312
|
+
):
|
|
313
|
+
raise TypeError("reflection authority sources must be exact")
|
|
314
|
+
for value in self.sources:
|
|
315
|
+
PostEvolutionReflectionSource.__post_init__(value)
|
|
316
|
+
if len(set(self.sources)) != len(self.sources):
|
|
317
|
+
raise ValueError("reflection authority sources cannot repeat")
|
|
318
|
+
if any(value.generation > self.terminal_generation for value in self.sources):
|
|
319
|
+
raise ValueError("reflection authority source follows terminal generation")
|
|
320
|
+
if type(self.source_operator_invocation_ids) is not tuple or any(
|
|
321
|
+
type(value) is not OperatorInvocationId
|
|
322
|
+
for value in self.source_operator_invocation_ids
|
|
323
|
+
):
|
|
324
|
+
raise TypeError("reflection source operator IDs must be exact")
|
|
325
|
+
for value in self.source_operator_invocation_ids:
|
|
326
|
+
OperatorInvocationId.__post_init__(value)
|
|
327
|
+
if len(self.sources) != len(self.source_operator_invocation_ids):
|
|
328
|
+
raise ValueError("reflection source coordinates/operator IDs differ")
|
|
329
|
+
if len(set(self.source_operator_invocation_ids)) != len(
|
|
330
|
+
self.source_operator_invocation_ids
|
|
331
|
+
):
|
|
332
|
+
raise ValueError("reflection source operator IDs cannot repeat")
|
|
333
|
+
if type(self.revision_predecessor) is not InsightRef:
|
|
334
|
+
raise TypeError("reflection revision_predecessor must be exact")
|
|
335
|
+
InsightRef.__post_init__(self.revision_predecessor)
|
|
336
|
+
if (
|
|
337
|
+
type(self.reflection_label) is not str
|
|
338
|
+
or not self.reflection_label
|
|
339
|
+
or self.reflection_label != self.reflection_label.strip()
|
|
340
|
+
):
|
|
341
|
+
raise ValueError("authority reflection_label must be canonical")
|
|
342
|
+
expected = _hash(_AUTHORITY_DOMAIN, self.to_record())
|
|
343
|
+
if self.authority_sha256:
|
|
344
|
+
require_sha256(self.authority_sha256, "reflection authority_sha256")
|
|
345
|
+
if self.authority_sha256 != expected:
|
|
346
|
+
raise ValueError("reflection authority hash does not authenticate data")
|
|
347
|
+
else:
|
|
348
|
+
object.__setattr__(self, "authority_sha256", expected)
|
|
349
|
+
|
|
350
|
+
def to_record(self) -> dict[str, object]:
|
|
351
|
+
return {
|
|
352
|
+
"schema_version": 1,
|
|
353
|
+
"spec_sha256": self.spec_sha256,
|
|
354
|
+
"reservation_hash": self.reservation_hash,
|
|
355
|
+
"terminal_generation": self.terminal_generation,
|
|
356
|
+
"generation_receipt_sha256s": list(self.generation_receipt_sha256s),
|
|
357
|
+
"source_scope_sha256": self.source_scope_sha256,
|
|
358
|
+
"sources": [source.to_record() for source in self.sources],
|
|
359
|
+
"source_operator_invocation_ids": [
|
|
360
|
+
value.value for value in self.source_operator_invocation_ids
|
|
361
|
+
],
|
|
362
|
+
"revision_predecessor": _ref_record(self.revision_predecessor),
|
|
363
|
+
"revision_predecessor_content_sha256": (
|
|
364
|
+
self.revision_predecessor_content_sha256
|
|
365
|
+
),
|
|
366
|
+
"insight_contract_sha256": self.insight_contract_sha256,
|
|
367
|
+
"reflection_label": self.reflection_label,
|
|
368
|
+
"requested_cardinality": {"min": 0, "max": 1},
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
@dataclass(frozen=True, slots=True)
|
|
373
|
+
class PostEvolutionReflectionReceipt:
|
|
374
|
+
"""Authenticated completion or isolated failure for the terminal call."""
|
|
375
|
+
|
|
376
|
+
authority: PostEvolutionReflectionAuthority
|
|
377
|
+
call_receipt: ReflectionCallReceipt
|
|
378
|
+
reflection_status: str
|
|
379
|
+
failure_type: str | None
|
|
380
|
+
receipt_sha256: str = ""
|
|
381
|
+
|
|
382
|
+
def __post_init__(self) -> None:
|
|
383
|
+
if type(self.authority) is not PostEvolutionReflectionAuthority:
|
|
384
|
+
raise TypeError("reflection receipt authority must be exact")
|
|
385
|
+
PostEvolutionReflectionAuthority.__post_init__(self.authority)
|
|
386
|
+
if type(self.call_receipt) is not ReflectionCallReceipt:
|
|
387
|
+
raise TypeError("reflection call_receipt must be exact")
|
|
388
|
+
ReflectionCallReceipt.__post_init__(self.call_receipt)
|
|
389
|
+
authority = self.authority
|
|
390
|
+
request = self.call_receipt.request
|
|
391
|
+
if (
|
|
392
|
+
request.label != authority.reflection_label
|
|
393
|
+
or request.operation != "extract_insights"
|
|
394
|
+
or request.min_insights != 0
|
|
395
|
+
or request.max_insights != 1
|
|
396
|
+
or request.insight_contract_sha256 != authority.insight_contract_sha256
|
|
397
|
+
or request.revision_predecessors != (authority.revision_predecessor,)
|
|
398
|
+
or request.revision_predecessor_content_sha256s
|
|
399
|
+
!= (authority.revision_predecessor_content_sha256,)
|
|
400
|
+
or request.source_receipt_sha256s != authority.generation_receipt_sha256s
|
|
401
|
+
or request.source_operator_invocation_ids
|
|
402
|
+
!= authority.source_operator_invocation_ids
|
|
403
|
+
or len(request.source_outcome_sha256s) != len(authority.sources)
|
|
404
|
+
):
|
|
405
|
+
raise ValueError("engine reflection request differs from its authority")
|
|
406
|
+
publications = self.call_receipt.publications
|
|
407
|
+
if self.reflection_status == "sealed_complete":
|
|
408
|
+
if (
|
|
409
|
+
self.failure_type is not None
|
|
410
|
+
or self.call_receipt.status is not ReflectionCallStatus.COMPLETED
|
|
411
|
+
or len(publications) > 1
|
|
412
|
+
):
|
|
413
|
+
raise ValueError("completed reflection has invalid call evidence")
|
|
414
|
+
if publications:
|
|
415
|
+
publication = publications[0]
|
|
416
|
+
predecessor = authority.revision_predecessor
|
|
417
|
+
if (
|
|
418
|
+
publication.revision_predecessor != predecessor
|
|
419
|
+
or publication.reference.insight_id != predecessor.insight_id
|
|
420
|
+
or publication.reference.version != predecessor.version + 1
|
|
421
|
+
or publication.lifecycle_state
|
|
422
|
+
is not InsightLifecycleState.QUARANTINED
|
|
423
|
+
or publication.origin is not InsightOrigin.REFLECTION
|
|
424
|
+
or publication.initial_score != 0.0
|
|
425
|
+
):
|
|
426
|
+
raise ValueError("reflection publication is not one fresh revision")
|
|
427
|
+
elif self.reflection_status == "incomplete":
|
|
428
|
+
if (
|
|
429
|
+
type(self.failure_type) is not str
|
|
430
|
+
or not self.failure_type
|
|
431
|
+
or self.call_receipt.status is not ReflectionCallStatus.FAILED
|
|
432
|
+
or self.call_receipt.failure_type != self.failure_type
|
|
433
|
+
or publications
|
|
434
|
+
):
|
|
435
|
+
raise ValueError("incomplete reflection lacks exact failure evidence")
|
|
436
|
+
else:
|
|
437
|
+
raise ValueError("reflection_status must be sealed_complete or incomplete")
|
|
438
|
+
expected = _hash(_RECEIPT_DOMAIN, self.to_record())
|
|
439
|
+
if self.receipt_sha256:
|
|
440
|
+
require_sha256(self.receipt_sha256, "reflection receipt_sha256")
|
|
441
|
+
if self.receipt_sha256 != expected:
|
|
442
|
+
raise ValueError("reflection receipt hash does not authenticate data")
|
|
443
|
+
else:
|
|
444
|
+
object.__setattr__(self, "receipt_sha256", expected)
|
|
445
|
+
|
|
446
|
+
@property
|
|
447
|
+
def publication_outcome(self) -> str:
|
|
448
|
+
if self.reflection_status == "incomplete":
|
|
449
|
+
return "failed"
|
|
450
|
+
return (
|
|
451
|
+
"completed_revision"
|
|
452
|
+
if self.call_receipt.publications
|
|
453
|
+
else "completed_abstention"
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
def to_record(self) -> dict[str, object]:
|
|
457
|
+
return {
|
|
458
|
+
"schema_version": 1,
|
|
459
|
+
"authority_sha256": self.authority.authority_sha256,
|
|
460
|
+
"reflection_call_receipt_sha256": self.call_receipt.receipt_sha256,
|
|
461
|
+
"reflection_call_id": self.call_receipt.call_id.value,
|
|
462
|
+
"reflection_request_sha256": self.call_receipt.request.request_sha256,
|
|
463
|
+
"reflection_status": self.reflection_status,
|
|
464
|
+
"publication_outcome": self.publication_outcome,
|
|
465
|
+
"failure_type": self.failure_type,
|
|
466
|
+
"publication_sha256s": [
|
|
467
|
+
value.publication_sha256 for value in self.call_receipt.publications
|
|
468
|
+
],
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
class PostEvolutionReflectionInterceptor:
|
|
473
|
+
"""Reserve zero early calls and exactly one terminal reflection call."""
|
|
474
|
+
|
|
475
|
+
def __init__(
|
|
476
|
+
self,
|
|
477
|
+
*,
|
|
478
|
+
engine: AgenticEvolutionEngine,
|
|
479
|
+
planner: object,
|
|
480
|
+
memory: InsightMemoryBank,
|
|
481
|
+
spec: PostEvolutionReflectionSpec,
|
|
482
|
+
predecessor_resolver: PostEvolutionPredecessorResolver,
|
|
483
|
+
) -> None:
|
|
484
|
+
if type(engine) is not AgenticEvolutionEngine:
|
|
485
|
+
raise TypeError("post-evolution reflection engine must be exact")
|
|
486
|
+
if type(memory) is not InsightMemoryBank:
|
|
487
|
+
raise TypeError("post-evolution reflection memory must be exact")
|
|
488
|
+
if engine.memory is not memory:
|
|
489
|
+
raise ValueError("post-evolution reflection memory differs from engine")
|
|
490
|
+
if not callable(getattr(planner, "plan", None)):
|
|
491
|
+
raise TypeError("post-evolution reflection planner must implement plan")
|
|
492
|
+
if type(spec) is not PostEvolutionReflectionSpec:
|
|
493
|
+
raise TypeError("post-evolution reflection spec must be exact")
|
|
494
|
+
PostEvolutionReflectionSpec.__post_init__(spec)
|
|
495
|
+
if not callable(predecessor_resolver):
|
|
496
|
+
raise TypeError("predecessor_resolver must be callable")
|
|
497
|
+
self.engine = engine
|
|
498
|
+
self.planner = planner
|
|
499
|
+
self.memory = memory
|
|
500
|
+
self.spec = spec
|
|
501
|
+
self.predecessor_resolver = predecessor_resolver
|
|
502
|
+
self.policy_id = spec.policy_id
|
|
503
|
+
self.policy_version = spec.policy_version
|
|
504
|
+
self.invoked_generations: list[int] = []
|
|
505
|
+
self.reflected_entries: tuple[InsightMemoryEntry, ...] = ()
|
|
506
|
+
self.reflection_result: ReflectionPublicationResult | None = None
|
|
507
|
+
self.reflection_authority: PostEvolutionReflectionAuthority | None = None
|
|
508
|
+
self.reflection_receipt: PostEvolutionReflectionReceipt | None = None
|
|
509
|
+
self.reflection_failure_type: str | None = None
|
|
510
|
+
self._reservations: dict[int, GenerationFeedbackReservation] = {}
|
|
511
|
+
self._completed_generations: set[int] = set()
|
|
512
|
+
self._terminal_predecessor: tuple[InsightRef, str] | None = None
|
|
513
|
+
|
|
514
|
+
def _resolve_predecessor(self) -> tuple[InsightRef, InsightMemoryEntry]:
|
|
515
|
+
reference = self.predecessor_resolver(self.planner)
|
|
516
|
+
if type(reference) is not InsightRef:
|
|
517
|
+
raise TypeError("predecessor_resolver must return an exact InsightRef")
|
|
518
|
+
InsightRef.__post_init__(reference)
|
|
519
|
+
entry = self.memory.entries_for((reference,))[0]
|
|
520
|
+
if type(entry) is not InsightMemoryEntry:
|
|
521
|
+
raise TypeError("predecessor resolver selected a foreign memory entry")
|
|
522
|
+
InsightMemoryEntry.__post_init__(entry)
|
|
523
|
+
return reference, entry
|
|
524
|
+
|
|
525
|
+
def _reservation(
|
|
526
|
+
self,
|
|
527
|
+
*,
|
|
528
|
+
generation: int,
|
|
529
|
+
) -> GenerationFeedbackReservation:
|
|
530
|
+
terminal = self.spec.terminal_generation
|
|
531
|
+
if type(generation) is not int or not 1 <= generation <= terminal:
|
|
532
|
+
raise ValueError("reflection reservation generation is outside its run")
|
|
533
|
+
if generation < terminal:
|
|
534
|
+
metadata = tuple(
|
|
535
|
+
sorted(
|
|
536
|
+
(
|
|
537
|
+
("reflection_spec_sha256", self.spec.spec_sha256),
|
|
538
|
+
("stage", "sealed_no_op"),
|
|
539
|
+
)
|
|
540
|
+
)
|
|
541
|
+
)
|
|
542
|
+
logical_calls = 0
|
|
543
|
+
else:
|
|
544
|
+
predecessor, entry = self._resolve_predecessor()
|
|
545
|
+
frozen = (predecessor, entry.draft.content_sha256)
|
|
546
|
+
if self._terminal_predecessor is not None:
|
|
547
|
+
raise RuntimeError("terminal reflection predecessor was resolved twice")
|
|
548
|
+
self._terminal_predecessor = frozen
|
|
549
|
+
metadata = tuple(
|
|
550
|
+
sorted(
|
|
551
|
+
(
|
|
552
|
+
(
|
|
553
|
+
"reflection_contract_sha256",
|
|
554
|
+
self.spec.insight_contract.identity_sha256,
|
|
555
|
+
),
|
|
556
|
+
("reflection_spec_sha256", self.spec.spec_sha256),
|
|
557
|
+
(
|
|
558
|
+
"revision_predecessor",
|
|
559
|
+
f"{predecessor.insight_id.value}@{predecessor.version}",
|
|
560
|
+
),
|
|
561
|
+
(
|
|
562
|
+
"revision_predecessor_content_sha256",
|
|
563
|
+
entry.draft.content_sha256,
|
|
564
|
+
),
|
|
565
|
+
("source_scope_sha256", self.spec.source_scope.scope_sha256),
|
|
566
|
+
("stage", "post_terminal_generation"),
|
|
567
|
+
)
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
logical_calls = 1
|
|
571
|
+
return GenerationFeedbackReservation(
|
|
572
|
+
policy_id=self.policy_id,
|
|
573
|
+
policy_version=self.policy_version,
|
|
574
|
+
logical_llm_calls=logical_calls,
|
|
575
|
+
metadata=metadata,
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
def reserve(
|
|
579
|
+
self,
|
|
580
|
+
*,
|
|
581
|
+
state: OptimizerState,
|
|
582
|
+
plan: GenerationPlan,
|
|
583
|
+
) -> GenerationFeedbackReservation:
|
|
584
|
+
if type(state) is not OptimizerState:
|
|
585
|
+
raise TypeError("reflection reservation state must be exact")
|
|
586
|
+
if type(plan) is not GenerationPlan:
|
|
587
|
+
raise TypeError("reflection reservation plan must be exact")
|
|
588
|
+
if state.generation + 1 != plan.generation:
|
|
589
|
+
raise ValueError("reflection reservation observed the wrong generation")
|
|
590
|
+
if plan.generation in self._reservations:
|
|
591
|
+
raise RuntimeError("reflection generation was reserved twice")
|
|
592
|
+
reservation = self._reservation(generation=plan.generation)
|
|
593
|
+
self._reservations[plan.generation] = reservation
|
|
594
|
+
return reservation
|
|
595
|
+
|
|
596
|
+
async def after_generation(
|
|
597
|
+
self,
|
|
598
|
+
context: GenerationFeedbackContext,
|
|
599
|
+
) -> GenerationFeedbackResult:
|
|
600
|
+
if type(context) is not GenerationFeedbackContext:
|
|
601
|
+
raise TypeError("post-evolution reflection context must be exact")
|
|
602
|
+
GenerationFeedbackContext.__post_init__(context)
|
|
603
|
+
generation = context.plan.generation
|
|
604
|
+
if generation in self._completed_generations:
|
|
605
|
+
raise RuntimeError("reflection feedback generation was completed twice")
|
|
606
|
+
expected_reservation = self._reservations.get(generation)
|
|
607
|
+
if context.reservation != expected_reservation:
|
|
608
|
+
raise ValueError("reflection context differs from its frozen reservation")
|
|
609
|
+
self._completed_generations.add(generation)
|
|
610
|
+
self.invoked_generations.append(generation)
|
|
611
|
+
terminal = self.spec.terminal_generation
|
|
612
|
+
if generation < terminal:
|
|
613
|
+
if context.reservation.logical_llm_calls != 0:
|
|
614
|
+
raise ValueError("early reflection reservation must be zero")
|
|
615
|
+
return GenerationFeedbackResult(
|
|
616
|
+
logical_llm_calls_used=0,
|
|
617
|
+
metadata=tuple(
|
|
618
|
+
sorted(
|
|
619
|
+
(
|
|
620
|
+
("reflection_spec_sha256", self.spec.spec_sha256),
|
|
621
|
+
("reflection_status", "not_due"),
|
|
622
|
+
)
|
|
623
|
+
)
|
|
624
|
+
),
|
|
625
|
+
)
|
|
626
|
+
if generation != terminal:
|
|
627
|
+
raise ValueError("reflection interceptor received a foreign generation")
|
|
628
|
+
if context.reservation.logical_llm_calls != 1:
|
|
629
|
+
raise ValueError("terminal reflection must reserve exactly one call")
|
|
630
|
+
receipts = context.state.generation_receipts
|
|
631
|
+
if (
|
|
632
|
+
type(receipts) is not tuple
|
|
633
|
+
or len(receipts) != terminal
|
|
634
|
+
or receipts[-1] != context.generation_receipt
|
|
635
|
+
):
|
|
636
|
+
raise ValueError("terminal reflection requires every sealed receipt")
|
|
637
|
+
_validated_receipts(receipts)
|
|
638
|
+
outcomes = self.spec.source_scope.select(receipts)
|
|
639
|
+
frozen_predecessor = self._terminal_predecessor
|
|
640
|
+
if frozen_predecessor is None:
|
|
641
|
+
raise RuntimeError("terminal predecessor was not frozen after planning")
|
|
642
|
+
predecessor, predecessor_content_sha256 = frozen_predecessor
|
|
643
|
+
current_entry = self.memory.entries_for((predecessor,))[0]
|
|
644
|
+
if current_entry.draft.content_sha256 != predecessor_content_sha256:
|
|
645
|
+
raise ValueError("revision predecessor content changed after reservation")
|
|
646
|
+
generation_receipt_sha256s = tuple(receipt.receipt_hash for receipt in receipts)
|
|
647
|
+
authority = PostEvolutionReflectionAuthority(
|
|
648
|
+
spec_sha256=self.spec.spec_sha256,
|
|
649
|
+
reservation_hash=context.reservation.reservation_hash,
|
|
650
|
+
terminal_generation=terminal,
|
|
651
|
+
generation_receipt_sha256s=generation_receipt_sha256s,
|
|
652
|
+
source_scope_sha256=self.spec.source_scope.scope_sha256,
|
|
653
|
+
sources=self.spec.source_scope.sources,
|
|
654
|
+
source_operator_invocation_ids=tuple(
|
|
655
|
+
outcome.prepared.operator_invocation_id for outcome in outcomes
|
|
656
|
+
),
|
|
657
|
+
revision_predecessor=predecessor,
|
|
658
|
+
revision_predecessor_content_sha256=predecessor_content_sha256,
|
|
659
|
+
insight_contract_sha256=self.spec.insight_contract.identity_sha256,
|
|
660
|
+
reflection_label=self.spec.label,
|
|
661
|
+
)
|
|
662
|
+
# Persist the authority before crossing the provider boundary so even a
|
|
663
|
+
# failed logical call remains attributable to its admitted evidence.
|
|
664
|
+
self.reflection_authority = authority
|
|
665
|
+
try:
|
|
666
|
+
result = await self.engine.reflect_with_receipt(
|
|
667
|
+
outcomes,
|
|
668
|
+
label=self.spec.label,
|
|
669
|
+
max_insights=1,
|
|
670
|
+
min_insights=0,
|
|
671
|
+
insight_contract=self.spec.insight_contract,
|
|
672
|
+
revision_predecessors=(predecessor,),
|
|
673
|
+
source_receipt_sha256s=generation_receipt_sha256s,
|
|
674
|
+
)
|
|
675
|
+
except ReflectionCallExecutionError as exc:
|
|
676
|
+
self.reflection_failure_type = exc.failure_type
|
|
677
|
+
receipt = PostEvolutionReflectionReceipt(
|
|
678
|
+
authority=authority,
|
|
679
|
+
call_receipt=exc.receipt,
|
|
680
|
+
reflection_status="incomplete",
|
|
681
|
+
failure_type=exc.failure_type,
|
|
682
|
+
)
|
|
683
|
+
self.reflection_receipt = receipt
|
|
684
|
+
return self._feedback_result(receipt)
|
|
685
|
+
if type(result) is not ReflectionPublicationResult:
|
|
686
|
+
raise TypeError("receipt-bearing reflection returned a foreign result")
|
|
687
|
+
ReflectionPublicationResult.__post_init__(result)
|
|
688
|
+
self.reflection_result = result
|
|
689
|
+
self.reflected_entries = result.entries
|
|
690
|
+
receipt = PostEvolutionReflectionReceipt(
|
|
691
|
+
authority=authority,
|
|
692
|
+
call_receipt=result.receipt,
|
|
693
|
+
reflection_status="sealed_complete",
|
|
694
|
+
failure_type=None,
|
|
695
|
+
)
|
|
696
|
+
self.reflection_receipt = receipt
|
|
697
|
+
return self._feedback_result(receipt)
|
|
698
|
+
|
|
699
|
+
def _feedback_result(
|
|
700
|
+
self,
|
|
701
|
+
receipt: PostEvolutionReflectionReceipt,
|
|
702
|
+
) -> GenerationFeedbackResult:
|
|
703
|
+
metadata = [
|
|
704
|
+
("reflected_entry_count", str(len(receipt.call_receipt.publications))),
|
|
705
|
+
(
|
|
706
|
+
"reflection_authority_sha256",
|
|
707
|
+
receipt.authority.authority_sha256,
|
|
708
|
+
),
|
|
709
|
+
("reflection_call_id", receipt.call_receipt.call_id.value),
|
|
710
|
+
(
|
|
711
|
+
"reflection_call_receipt_sha256",
|
|
712
|
+
receipt.call_receipt.receipt_sha256,
|
|
713
|
+
),
|
|
714
|
+
(
|
|
715
|
+
"reflection_max_output_tokens",
|
|
716
|
+
str(receipt.call_receipt.request.max_output_tokens),
|
|
717
|
+
),
|
|
718
|
+
("reflection_prompt_sha256", receipt.call_receipt.request.prompt_sha256),
|
|
719
|
+
(
|
|
720
|
+
"reflection_publication_outcome",
|
|
721
|
+
receipt.publication_outcome,
|
|
722
|
+
),
|
|
723
|
+
("reflection_receipt_sha256", receipt.receipt_sha256),
|
|
724
|
+
(
|
|
725
|
+
"reflection_request_sha256",
|
|
726
|
+
receipt.call_receipt.request.request_sha256,
|
|
727
|
+
),
|
|
728
|
+
("reflection_spec_sha256", self.spec.spec_sha256),
|
|
729
|
+
("reflection_status", receipt.reflection_status),
|
|
730
|
+
(
|
|
731
|
+
"reflection_temperature",
|
|
732
|
+
(
|
|
733
|
+
"none"
|
|
734
|
+
if receipt.call_receipt.request.temperature is None
|
|
735
|
+
else float(receipt.call_receipt.request.temperature).hex()
|
|
736
|
+
),
|
|
737
|
+
),
|
|
738
|
+
(
|
|
739
|
+
"terminal_generation_receipt_sha256",
|
|
740
|
+
receipt.authority.generation_receipt_sha256s[-1],
|
|
741
|
+
),
|
|
742
|
+
]
|
|
743
|
+
if receipt.failure_type is not None:
|
|
744
|
+
metadata.append(("reflection_failure_type", receipt.failure_type))
|
|
745
|
+
if receipt.call_receipt.telemetry_sha256 is not None:
|
|
746
|
+
metadata.append(
|
|
747
|
+
(
|
|
748
|
+
"reflection_telemetry_sha256",
|
|
749
|
+
receipt.call_receipt.telemetry_sha256,
|
|
750
|
+
)
|
|
751
|
+
)
|
|
752
|
+
return GenerationFeedbackResult(
|
|
753
|
+
logical_llm_calls_used=1,
|
|
754
|
+
metadata=tuple(sorted(metadata)),
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
class PostEvolutionReflectionFactory:
|
|
759
|
+
"""Build the interceptor against composition-owned runtime identities."""
|
|
760
|
+
|
|
761
|
+
def __init__(
|
|
762
|
+
self,
|
|
763
|
+
*,
|
|
764
|
+
spec: PostEvolutionReflectionSpec,
|
|
765
|
+
predecessor_resolver: PostEvolutionPredecessorResolver,
|
|
766
|
+
) -> None:
|
|
767
|
+
if type(spec) is not PostEvolutionReflectionSpec:
|
|
768
|
+
raise TypeError("post-evolution reflection factory spec must be exact")
|
|
769
|
+
PostEvolutionReflectionSpec.__post_init__(spec)
|
|
770
|
+
if not callable(predecessor_resolver):
|
|
771
|
+
raise TypeError("predecessor_resolver must be callable")
|
|
772
|
+
self.spec = spec
|
|
773
|
+
self.predecessor_resolver = predecessor_resolver
|
|
774
|
+
self.interceptor: PostEvolutionReflectionInterceptor | None = None
|
|
775
|
+
self.runtime_identities: (
|
|
776
|
+
tuple[object, object, object, object, object] | None
|
|
777
|
+
) = None
|
|
778
|
+
|
|
779
|
+
def build(self, *, benchmark, engine, id_factory, memory, planner):
|
|
780
|
+
if self.interceptor is not None:
|
|
781
|
+
raise RuntimeError("post-evolution reflection factory is single-use")
|
|
782
|
+
if type(engine) is not AgenticEvolutionEngine:
|
|
783
|
+
raise TypeError("reflection factory engine must be exact")
|
|
784
|
+
if type(memory) is not InsightMemoryBank:
|
|
785
|
+
raise TypeError("reflection factory memory must be exact")
|
|
786
|
+
if engine.ids is not id_factory or engine.memory is not memory:
|
|
787
|
+
raise ValueError("reflection factory received foreign engine identities")
|
|
788
|
+
problem = getattr(benchmark, "problem", None)
|
|
789
|
+
if problem is not None and engine.problem is not problem:
|
|
790
|
+
raise ValueError("reflection factory benchmark differs from engine")
|
|
791
|
+
if not callable(getattr(planner, "plan", None)):
|
|
792
|
+
raise TypeError("reflection factory planner must implement plan")
|
|
793
|
+
for attribute, expected in (
|
|
794
|
+
("benchmark", benchmark),
|
|
795
|
+
("engine", engine),
|
|
796
|
+
("ids", id_factory),
|
|
797
|
+
("id_factory", id_factory),
|
|
798
|
+
("memory", memory),
|
|
799
|
+
):
|
|
800
|
+
if (
|
|
801
|
+
hasattr(planner, attribute)
|
|
802
|
+
and getattr(planner, attribute) is not expected
|
|
803
|
+
):
|
|
804
|
+
raise ValueError(
|
|
805
|
+
f"reflection factory planner has a foreign {attribute} identity"
|
|
806
|
+
)
|
|
807
|
+
self.runtime_identities = (
|
|
808
|
+
benchmark,
|
|
809
|
+
engine,
|
|
810
|
+
id_factory,
|
|
811
|
+
memory,
|
|
812
|
+
planner,
|
|
813
|
+
)
|
|
814
|
+
self.interceptor = PostEvolutionReflectionInterceptor(
|
|
815
|
+
engine=engine,
|
|
816
|
+
planner=planner,
|
|
817
|
+
memory=memory,
|
|
818
|
+
spec=self.spec,
|
|
819
|
+
predecessor_resolver=self.predecessor_resolver,
|
|
820
|
+
)
|
|
821
|
+
return self.interceptor
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
__all__ = [
|
|
825
|
+
"POST_EVOLUTION_REFLECTION_DEFINITION_SHA256",
|
|
826
|
+
"PostEvolutionPredecessorResolver",
|
|
827
|
+
"PostEvolutionReflectionAuthority",
|
|
828
|
+
"PostEvolutionReflectionFactory",
|
|
829
|
+
"PostEvolutionReflectionInterceptor",
|
|
830
|
+
"PostEvolutionReflectionReceipt",
|
|
831
|
+
"PostEvolutionReflectionSource",
|
|
832
|
+
"PostEvolutionReflectionSourceScope",
|
|
833
|
+
"PostEvolutionReflectionSpec",
|
|
834
|
+
]
|