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,112 @@
|
|
|
1
|
+
"""Apply a benchmark decision-metric projection to sealed candidates."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
9
|
+
from agent_evolve.core.optimization_semantics import MetricRole
|
|
10
|
+
from agent_evolve.domain.patch import require_sha256
|
|
11
|
+
from agent_evolve.ports.decision_metric_projection import DecisionMetricProjection
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True, slots=True)
|
|
15
|
+
class ProjectedDecisionMetrics:
|
|
16
|
+
"""Canonical finite values extracted under one immutable projection."""
|
|
17
|
+
|
|
18
|
+
projection_definition_sha256: str
|
|
19
|
+
values: tuple[tuple[str, float], ...]
|
|
20
|
+
|
|
21
|
+
def __post_init__(self) -> None:
|
|
22
|
+
require_sha256(
|
|
23
|
+
self.projection_definition_sha256,
|
|
24
|
+
"projection_definition_sha256",
|
|
25
|
+
)
|
|
26
|
+
if type(self.values) is not tuple or not self.values:
|
|
27
|
+
raise ValueError("values must be a non-empty exact tuple")
|
|
28
|
+
metric_ids: list[str] = []
|
|
29
|
+
for value in self.values:
|
|
30
|
+
if type(value) is not tuple or len(value) != 2:
|
|
31
|
+
raise TypeError("values must contain exact metric/value pairs")
|
|
32
|
+
metric_id, number = value
|
|
33
|
+
if type(metric_id) is not str or not metric_id:
|
|
34
|
+
raise TypeError("projected metric IDs must be non-empty strings")
|
|
35
|
+
if type(number) is not float or not math.isfinite(number):
|
|
36
|
+
raise TypeError("projected metric values must be finite floats")
|
|
37
|
+
metric_ids.append(metric_id)
|
|
38
|
+
if tuple(metric_ids) != tuple(sorted(set(metric_ids))):
|
|
39
|
+
raise ValueError("projected metric values must be unique and canonical")
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def metric_map(self) -> dict[str, float]:
|
|
43
|
+
self.__post_init__()
|
|
44
|
+
return dict(self.values)
|
|
45
|
+
|
|
46
|
+
def to_record(self) -> dict[str, object]:
|
|
47
|
+
self.__post_init__()
|
|
48
|
+
return {
|
|
49
|
+
"projection_definition_sha256": self.projection_definition_sha256,
|
|
50
|
+
"values": [
|
|
51
|
+
{"metric_id": metric_id, "value_hex": value.hex()}
|
|
52
|
+
for metric_id, value in self.values
|
|
53
|
+
],
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def project_candidate_decision_metrics(
|
|
58
|
+
candidate: EvolutionCandidate,
|
|
59
|
+
projection: DecisionMetricProjection,
|
|
60
|
+
) -> ProjectedDecisionMetrics:
|
|
61
|
+
"""Extract canonical objectives and sealed violation/constraint values."""
|
|
62
|
+
|
|
63
|
+
if type(candidate) is not EvolutionCandidate:
|
|
64
|
+
raise TypeError("candidate must be exact EvolutionCandidate")
|
|
65
|
+
EvolutionCandidate.__post_init__(candidate)
|
|
66
|
+
if type(projection) is not DecisionMetricProjection:
|
|
67
|
+
raise TypeError("projection must be exact DecisionMetricProjection")
|
|
68
|
+
projection.__post_init__()
|
|
69
|
+
if not candidate.valid:
|
|
70
|
+
raise ValueError("decision metrics require a valid evaluated candidate")
|
|
71
|
+
|
|
72
|
+
objectives = candidate.objective_map
|
|
73
|
+
detailed_values: dict[str, float] | None = None
|
|
74
|
+
values: list[tuple[str, float]] = []
|
|
75
|
+
for binding in projection.metrics:
|
|
76
|
+
if binding.role is MetricRole.OBJECTIVE:
|
|
77
|
+
if binding.value_name not in objectives:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
"decision projection objective is absent from the candidate: "
|
|
80
|
+
f"{binding.value_name}"
|
|
81
|
+
)
|
|
82
|
+
value = objectives[binding.value_name]
|
|
83
|
+
else:
|
|
84
|
+
detailed = candidate.detailed_evaluation
|
|
85
|
+
if detailed is None or not detailed.success:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
"violation/constraint projection requires successful detailed "
|
|
88
|
+
"evaluation evidence"
|
|
89
|
+
)
|
|
90
|
+
if detailed_values is None:
|
|
91
|
+
detailed_values = dict(detailed.violations)
|
|
92
|
+
if binding.value_name not in detailed_values:
|
|
93
|
+
raise ValueError(
|
|
94
|
+
"decision projection violation/constraint is absent from "
|
|
95
|
+
f"detailed evidence: {binding.value_name}"
|
|
96
|
+
)
|
|
97
|
+
value = detailed_values[binding.value_name]
|
|
98
|
+
if type(value) is not float or not math.isfinite(value):
|
|
99
|
+
raise TypeError(
|
|
100
|
+
"candidate decision metrics must be finite canonical floats"
|
|
101
|
+
)
|
|
102
|
+
values.append((binding.metric_id, value))
|
|
103
|
+
return ProjectedDecisionMetrics(
|
|
104
|
+
projection_definition_sha256=projection.definition_sha256,
|
|
105
|
+
values=tuple(values),
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
__all__ = [
|
|
110
|
+
"ProjectedDecisionMetrics",
|
|
111
|
+
"project_candidate_decision_metrics",
|
|
112
|
+
]
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Structural action semantics derived from any sealed finite contract.
|
|
2
|
+
|
|
3
|
+
Benchmarks may expose a richer, human-authored action glossary through the
|
|
4
|
+
public inverted API. This module supplies the portable fallback: exact
|
|
5
|
+
parent-to-child patch paths and option-family membership are enough to state
|
|
6
|
+
what coordinates an action touches without inventing workload knowledge.
|
|
7
|
+
The option descriptions remain the authoritative prompt-visible semantics.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import hashlib
|
|
13
|
+
import re
|
|
14
|
+
|
|
15
|
+
from agent_evolve.core.action_semantics import (
|
|
16
|
+
ActionAxisSemantics,
|
|
17
|
+
ActionSpaceSemantics,
|
|
18
|
+
)
|
|
19
|
+
from agent_evolve.domain.finite_variation import (
|
|
20
|
+
FiniteVariationContract,
|
|
21
|
+
validate_finite_variation_contract,
|
|
22
|
+
)
|
|
23
|
+
from agent_evolve.domain.ids import CandidateId
|
|
24
|
+
from agent_evolve.domain.patch import ArrayIndex, JsonPath, ObjectKey
|
|
25
|
+
from agent_evolve.policies.variation.typed_patch import derive_patch
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DERIVED_ACTION_SEMANTICS_ID = "derived_finite_contract_action_space"
|
|
29
|
+
DERIVED_ACTION_SEMANTICS_VERSION = 1
|
|
30
|
+
_SAFE_PATH_KEY = re.compile(r"^[^\.\[\]\s]+$")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _render_path(path: JsonPath) -> str:
|
|
34
|
+
path.__post_init__()
|
|
35
|
+
if not path.segments:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
"root-replacement finite actions require explicit benchmark action semantics"
|
|
38
|
+
)
|
|
39
|
+
rendered = "$"
|
|
40
|
+
for segment in path.segments:
|
|
41
|
+
if type(segment) is ObjectKey:
|
|
42
|
+
if _SAFE_PATH_KEY.fullmatch(segment.value) is None:
|
|
43
|
+
raise ValueError(
|
|
44
|
+
"finite-action path cannot use the canonical prompt path grammar; "
|
|
45
|
+
"provide explicit benchmark action semantics"
|
|
46
|
+
)
|
|
47
|
+
rendered += "." + segment.value
|
|
48
|
+
elif type(segment) is ArrayIndex:
|
|
49
|
+
rendered += f"[{segment.value}]"
|
|
50
|
+
else: # pragma: no cover - JsonPath validation closes the union.
|
|
51
|
+
raise AssertionError("unsupported typed path segment")
|
|
52
|
+
return rendered
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def derive_action_space_semantics(
|
|
56
|
+
contract: FiniteVariationContract,
|
|
57
|
+
) -> ActionSpaceSemantics:
|
|
58
|
+
"""Derive a hash-bound structural glossary for one parent-bound palette.
|
|
59
|
+
|
|
60
|
+
The derivation reads sealed children only in trusted code. Provider-visible
|
|
61
|
+
output contains canonical coordinate paths and family membership, never a
|
|
62
|
+
child configuration or an inferred causal interpretation.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
validate_finite_variation_contract(contract)
|
|
66
|
+
families_by_path: dict[str, set[str]] = {}
|
|
67
|
+
base_id = CandidateId("candidate_derived_action_semantics_parent")
|
|
68
|
+
child_id = CandidateId("candidate_derived_action_semantics_child")
|
|
69
|
+
for option in contract.options:
|
|
70
|
+
patch = derive_patch(
|
|
71
|
+
contract.parent_configuration,
|
|
72
|
+
option.child_configuration,
|
|
73
|
+
base_candidate_id=base_id,
|
|
74
|
+
target_candidate_id=child_id,
|
|
75
|
+
)
|
|
76
|
+
if not patch.operations: # pragma: no cover - contract already forbids this.
|
|
77
|
+
raise ValueError("finite action does not change its parent")
|
|
78
|
+
for operation in patch.operations:
|
|
79
|
+
families_by_path.setdefault(_render_path(operation.path), set()).add(
|
|
80
|
+
option.family
|
|
81
|
+
)
|
|
82
|
+
axes = tuple(
|
|
83
|
+
sorted(
|
|
84
|
+
(
|
|
85
|
+
ActionAxisSemantics(
|
|
86
|
+
axis_id=(
|
|
87
|
+
"coordinate_"
|
|
88
|
+
+ hashlib.sha256(path.encode("utf-8")).hexdigest()[:20]
|
|
89
|
+
),
|
|
90
|
+
configuration_paths=(path,),
|
|
91
|
+
option_families=tuple(sorted(families)),
|
|
92
|
+
definition=(
|
|
93
|
+
"A configuration coordinate changed by at least one sealed "
|
|
94
|
+
f"finite action: {path}. Exact option descriptions are "
|
|
95
|
+
"authoritative for its domain meaning."
|
|
96
|
+
),
|
|
97
|
+
independence=(
|
|
98
|
+
"No coordinate independence is assumed; one sealed finite "
|
|
99
|
+
"action may jointly change multiple declared coordinates."
|
|
100
|
+
),
|
|
101
|
+
excluded_interpretations=(
|
|
102
|
+
"Do not infer geometry, ordering, causality, or units from "
|
|
103
|
+
"the canonical path alone.",
|
|
104
|
+
),
|
|
105
|
+
)
|
|
106
|
+
for path, families in families_by_path.items()
|
|
107
|
+
),
|
|
108
|
+
key=lambda value: value.axis_id,
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
return ActionSpaceSemantics(
|
|
112
|
+
semantics_id=DERIVED_ACTION_SEMANTICS_ID,
|
|
113
|
+
semantics_version=DERIVED_ACTION_SEMANTICS_VERSION,
|
|
114
|
+
catalog_identities=(
|
|
115
|
+
(
|
|
116
|
+
contract.catalog_id,
|
|
117
|
+
contract.catalog_version,
|
|
118
|
+
contract.catalog_definition_sha256,
|
|
119
|
+
),
|
|
120
|
+
),
|
|
121
|
+
axes=axes,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
__all__ = [
|
|
126
|
+
"DERIVED_ACTION_SEMANTICS_ID",
|
|
127
|
+
"DERIVED_ACTION_SEMANTICS_VERSION",
|
|
128
|
+
"derive_action_space_semantics",
|
|
129
|
+
]
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"""Immutable evaluator evidence sealed by the agentic engine.
|
|
2
|
+
|
|
3
|
+
An adapter owns domain semantics and returns :class:`DetailedEvaluationPayload`.
|
|
4
|
+
It never sees the engine's injected phenotype policy. The engine measures the
|
|
5
|
+
around-port wall time, binds its phenotype identity, and caches that complete
|
|
6
|
+
physical-evaluation record. Candidate occurrence identity deliberately lives
|
|
7
|
+
outside this module because multiple configurations may share one phenotype.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import hashlib
|
|
13
|
+
import json
|
|
14
|
+
import math
|
|
15
|
+
import re
|
|
16
|
+
from dataclasses import dataclass, replace
|
|
17
|
+
from enum import Enum
|
|
18
|
+
from numbers import Real
|
|
19
|
+
from typing import Protocol, runtime_checkable
|
|
20
|
+
|
|
21
|
+
from agent_evolve.core.problem import ObjectiveSpec, normalize_objective_values
|
|
22
|
+
from agent_evolve.domain.artifact import ArtifactRef
|
|
23
|
+
from agent_evolve.domain.outcome import FailureRecord
|
|
24
|
+
from agent_evolve.domain.typed_json import (
|
|
25
|
+
FrozenJsonValue,
|
|
26
|
+
canonical_typed_json_bytes,
|
|
27
|
+
freeze_json,
|
|
28
|
+
thaw_json,
|
|
29
|
+
)
|
|
30
|
+
from agent_evolve.policies.selection.phenotype_recourse import PhenotypeIdentity
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
34
|
+
_SHA256 = re.compile(r"^[0-9a-f]{64}$")
|
|
35
|
+
_HASH_DOMAIN = b"agent-evolve:detailed-evaluation:v1\x00"
|
|
36
|
+
_MAX_OBSERVED_VALUE_BYTES = 8_192
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _finite_nonnegative(value: Real, *, name: str) -> float:
|
|
40
|
+
if isinstance(value, bool) or not isinstance(value, Real):
|
|
41
|
+
raise TypeError(f"{name} must be a real number")
|
|
42
|
+
number = float(value)
|
|
43
|
+
if not math.isfinite(number) or number < 0:
|
|
44
|
+
raise ValueError(f"{name} must be finite and non-negative")
|
|
45
|
+
return number
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _named_finite_values(
|
|
49
|
+
values: tuple[tuple[str, float], ...],
|
|
50
|
+
*,
|
|
51
|
+
name: str,
|
|
52
|
+
nonnegative: bool,
|
|
53
|
+
require_sorted: bool,
|
|
54
|
+
) -> None:
|
|
55
|
+
if type(values) is not tuple:
|
|
56
|
+
raise TypeError(f"{name} must be an exact tuple")
|
|
57
|
+
names: list[str] = []
|
|
58
|
+
for item in values:
|
|
59
|
+
if type(item) is not tuple or len(item) != 2:
|
|
60
|
+
raise TypeError(f"{name} must contain exact name/value pairs")
|
|
61
|
+
key, value = item
|
|
62
|
+
if type(key) is not str or _TOKEN.fullmatch(key) is None:
|
|
63
|
+
raise ValueError(f"{name} names must use the closed token grammar")
|
|
64
|
+
if type(value) is not float:
|
|
65
|
+
raise TypeError(f"{name} values must be canonical floats")
|
|
66
|
+
if not math.isfinite(value) or (nonnegative and value < 0):
|
|
67
|
+
qualifier = "finite non-negative" if nonnegative else "finite"
|
|
68
|
+
raise ValueError(f"{name} values must be {qualifier}")
|
|
69
|
+
names.append(key)
|
|
70
|
+
if len(set(names)) != len(names):
|
|
71
|
+
raise ValueError(f"{name} names must be unique")
|
|
72
|
+
if require_sorted and names != sorted(names):
|
|
73
|
+
raise ValueError(f"{name} names must be canonically ordered")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class EvaluationCheckStatus(str, Enum):
|
|
77
|
+
PASS = "pass"
|
|
78
|
+
FAIL = "fail"
|
|
79
|
+
NOT_APPLICABLE = "not_applicable"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass(frozen=True, slots=True)
|
|
83
|
+
class EvaluationCheck:
|
|
84
|
+
"""One compact, receipt-addressable evaluator fact."""
|
|
85
|
+
|
|
86
|
+
name: str
|
|
87
|
+
status: EvaluationCheckStatus
|
|
88
|
+
observed_value: FrozenJsonValue
|
|
89
|
+
receipt_locator: str
|
|
90
|
+
|
|
91
|
+
def __post_init__(self) -> None:
|
|
92
|
+
if type(self.name) is not str or _TOKEN.fullmatch(self.name) is None:
|
|
93
|
+
raise ValueError("check name must use the closed token grammar")
|
|
94
|
+
if type(self.status) is not EvaluationCheckStatus:
|
|
95
|
+
raise TypeError("check status must be an EvaluationCheckStatus")
|
|
96
|
+
frozen = freeze_json(self.observed_value)
|
|
97
|
+
if frozen is not self.observed_value:
|
|
98
|
+
raise TypeError("observed_value must already be frozen typed JSON")
|
|
99
|
+
if len(canonical_typed_json_bytes(frozen)) > _MAX_OBSERVED_VALUE_BYTES:
|
|
100
|
+
raise ValueError("observed_value exceeds the compact evidence limit")
|
|
101
|
+
if (
|
|
102
|
+
type(self.receipt_locator) is not str
|
|
103
|
+
or not self.receipt_locator.strip()
|
|
104
|
+
or self.receipt_locator != self.receipt_locator.strip()
|
|
105
|
+
or len(self.receipt_locator.encode("utf-8")) > 512
|
|
106
|
+
):
|
|
107
|
+
raise ValueError("receipt_locator must be compact canonical text")
|
|
108
|
+
|
|
109
|
+
def to_record(self) -> dict[str, object]:
|
|
110
|
+
return {
|
|
111
|
+
"name": self.name,
|
|
112
|
+
"status": self.status.value,
|
|
113
|
+
"observed_value": thaw_json(self.observed_value),
|
|
114
|
+
"receipt_locator": self.receipt_locator,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@dataclass(frozen=True, slots=True)
|
|
119
|
+
class EvaluationTimings:
|
|
120
|
+
"""Non-additive timing observations for one physical evaluation."""
|
|
121
|
+
|
|
122
|
+
total_wall_seconds: float
|
|
123
|
+
active_wall_seconds: float | None = None
|
|
124
|
+
resource_queue_wall_seconds: float | None = None
|
|
125
|
+
|
|
126
|
+
def __post_init__(self) -> None:
|
|
127
|
+
_finite_nonnegative(self.total_wall_seconds, name="total_wall_seconds")
|
|
128
|
+
if type(self.total_wall_seconds) is not float:
|
|
129
|
+
raise TypeError("total_wall_seconds must be a canonical float")
|
|
130
|
+
for name in ("active_wall_seconds", "resource_queue_wall_seconds"):
|
|
131
|
+
value = getattr(self, name)
|
|
132
|
+
if value is not None:
|
|
133
|
+
_finite_nonnegative(value, name=name)
|
|
134
|
+
if type(value) is not float:
|
|
135
|
+
raise TypeError(f"{name} must be a canonical float or None")
|
|
136
|
+
|
|
137
|
+
def to_record(self) -> dict[str, float | None]:
|
|
138
|
+
return {
|
|
139
|
+
"total_wall_seconds": self.total_wall_seconds,
|
|
140
|
+
"active_wall_seconds": self.active_wall_seconds,
|
|
141
|
+
"resource_queue_wall_seconds": self.resource_queue_wall_seconds,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass(frozen=True, slots=True)
|
|
146
|
+
class EvaluatorIdentity:
|
|
147
|
+
"""Stable evaluator implementation/task context used in cache identity."""
|
|
148
|
+
|
|
149
|
+
evaluator_id: str
|
|
150
|
+
evaluator_version: int
|
|
151
|
+
evaluator_context_sha256: str
|
|
152
|
+
|
|
153
|
+
def __post_init__(self) -> None:
|
|
154
|
+
if type(self.evaluator_id) is not str or _TOKEN.fullmatch(
|
|
155
|
+
self.evaluator_id
|
|
156
|
+
) is None:
|
|
157
|
+
raise ValueError("evaluator_id must use the closed token grammar")
|
|
158
|
+
if type(self.evaluator_version) is not int or self.evaluator_version <= 0:
|
|
159
|
+
raise ValueError("evaluator_version must be a positive exact integer")
|
|
160
|
+
if (
|
|
161
|
+
type(self.evaluator_context_sha256) is not str
|
|
162
|
+
or _SHA256.fullmatch(self.evaluator_context_sha256) is None
|
|
163
|
+
):
|
|
164
|
+
raise ValueError(
|
|
165
|
+
"evaluator_context_sha256 must be a lowercase SHA-256 digest"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def to_record(self) -> dict[str, object]:
|
|
169
|
+
return {
|
|
170
|
+
"evaluator_id": self.evaluator_id,
|
|
171
|
+
"evaluator_version": self.evaluator_version,
|
|
172
|
+
"evaluator_context_sha256": self.evaluator_context_sha256,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _artifact_record(value: ArtifactRef | None) -> dict[str, object] | None:
|
|
177
|
+
if value is None:
|
|
178
|
+
return None
|
|
179
|
+
return {
|
|
180
|
+
"artifact_id": value.artifact_id.value,
|
|
181
|
+
"sha256_hex": value.sha256_hex,
|
|
182
|
+
"size_bytes": value.size_bytes,
|
|
183
|
+
"media_type": value.media_type,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _failure_record(value: FailureRecord | None) -> dict[str, object] | None:
|
|
188
|
+
if value is None:
|
|
189
|
+
return None
|
|
190
|
+
return {
|
|
191
|
+
"category": value.category.value,
|
|
192
|
+
"code": value.code.value,
|
|
193
|
+
"message": value.message,
|
|
194
|
+
"retryable": value.retryable,
|
|
195
|
+
"exception_type": value.exception_type,
|
|
196
|
+
"diagnostics_artifact_id": (
|
|
197
|
+
None
|
|
198
|
+
if value.diagnostics_artifact_id is None
|
|
199
|
+
else value.diagnostics_artifact_id.value
|
|
200
|
+
),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@dataclass(frozen=True, slots=True)
|
|
205
|
+
class DetailedEvaluationPayload:
|
|
206
|
+
"""Adapter-authored evidence before engine identity and timing binding."""
|
|
207
|
+
|
|
208
|
+
failure: FailureRecord | None
|
|
209
|
+
objectives: tuple[tuple[str, float], ...]
|
|
210
|
+
violations: tuple[tuple[str, float], ...]
|
|
211
|
+
checks: tuple[EvaluationCheck, ...]
|
|
212
|
+
receipt: ArtifactRef | None
|
|
213
|
+
evaluator: EvaluatorIdentity
|
|
214
|
+
active_wall_seconds: float | None = None
|
|
215
|
+
resource_queue_wall_seconds: float | None = None
|
|
216
|
+
observations: tuple[tuple[str, float], ...] = ()
|
|
217
|
+
"""Sub-problem measurements the evaluator already computed, carried but
|
|
218
|
+
**never scored**.
|
|
219
|
+
|
|
220
|
+
An evaluation unit that aggregates sub-problems -- a panel of layers, a set
|
|
221
|
+
of instances, a multi-medoid network -- publishes the parts and then throws
|
|
222
|
+
them away, because the only typed channel out of an adapter was the
|
|
223
|
+
aggregate objective vector. On Timeloop that discarded exactly the
|
|
224
|
+
per-medoid split, measured to be worth 43.1 % of that domain's attainable
|
|
225
|
+
range.
|
|
226
|
+
|
|
227
|
+
`observations` is that channel. It is deliberately parallel to
|
|
228
|
+
`violations`: a named finite vector, adapter-authored, sealed with the
|
|
229
|
+
evaluation. It differs from `objectives` in the one way that matters --
|
|
230
|
+
**nothing reads it to compute reward**. The reward path consumes
|
|
231
|
+
`objectives` alone, so widening the observation does not move the target,
|
|
232
|
+
and every existing `objectives` equality invariant holds unchanged.
|
|
233
|
+
|
|
234
|
+
Not required to be sorted, because sub-problem order is meaningful (medoid
|
|
235
|
+
0, 1, 2 is not an alphabetical fact), and not required nonnegative, because
|
|
236
|
+
a sub-problem measurement may legitimately be signed.
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
def __post_init__(self) -> None:
|
|
240
|
+
if self.failure is not None:
|
|
241
|
+
if type(self.failure) is not FailureRecord:
|
|
242
|
+
raise TypeError("failure must be an exact FailureRecord or None")
|
|
243
|
+
FailureRecord.__post_init__(self.failure)
|
|
244
|
+
_named_finite_values(
|
|
245
|
+
self.objectives,
|
|
246
|
+
name="objectives",
|
|
247
|
+
nonnegative=False,
|
|
248
|
+
require_sorted=False,
|
|
249
|
+
)
|
|
250
|
+
_named_finite_values(
|
|
251
|
+
self.violations,
|
|
252
|
+
name="violations",
|
|
253
|
+
nonnegative=True,
|
|
254
|
+
require_sorted=True,
|
|
255
|
+
)
|
|
256
|
+
_named_finite_values(
|
|
257
|
+
self.observations,
|
|
258
|
+
name="observations",
|
|
259
|
+
nonnegative=False,
|
|
260
|
+
require_sorted=False,
|
|
261
|
+
)
|
|
262
|
+
if self.failure is None and not self.objectives:
|
|
263
|
+
raise ValueError("successful detailed evaluations require objectives")
|
|
264
|
+
if self.failure is not None and (
|
|
265
|
+
self.objectives or self.violations or self.observations
|
|
266
|
+
):
|
|
267
|
+
raise ValueError("failed detailed evaluations cannot carry projections")
|
|
268
|
+
observation_names = tuple(name for name, _ in self.observations)
|
|
269
|
+
if len(set(observation_names)) != len(observation_names):
|
|
270
|
+
raise ValueError("observation names must be unique")
|
|
271
|
+
objective_names = {name for name, _ in self.objectives}
|
|
272
|
+
collisions = objective_names & set(observation_names)
|
|
273
|
+
if collisions:
|
|
274
|
+
raise ValueError(
|
|
275
|
+
"observations must not shadow objective names: "
|
|
276
|
+
f"{sorted(collisions)}"
|
|
277
|
+
)
|
|
278
|
+
if type(self.checks) is not tuple or any(
|
|
279
|
+
type(check) is not EvaluationCheck for check in self.checks
|
|
280
|
+
):
|
|
281
|
+
raise TypeError("checks must contain exact EvaluationCheck values")
|
|
282
|
+
for check in self.checks:
|
|
283
|
+
EvaluationCheck.__post_init__(check)
|
|
284
|
+
check_names = tuple(check.name for check in self.checks)
|
|
285
|
+
if check_names != tuple(sorted(set(check_names))):
|
|
286
|
+
raise ValueError("checks must be unique and canonically ordered")
|
|
287
|
+
if self.receipt is not None:
|
|
288
|
+
if type(self.receipt) is not ArtifactRef:
|
|
289
|
+
raise TypeError("receipt must be an exact ArtifactRef or None")
|
|
290
|
+
ArtifactRef.__post_init__(self.receipt)
|
|
291
|
+
if self.checks and self.receipt is None:
|
|
292
|
+
raise ValueError("receipt-addressable checks require a receipt ArtifactRef")
|
|
293
|
+
if type(self.evaluator) is not EvaluatorIdentity:
|
|
294
|
+
raise TypeError("evaluator must be an exact EvaluatorIdentity")
|
|
295
|
+
EvaluatorIdentity.__post_init__(self.evaluator)
|
|
296
|
+
for name in ("active_wall_seconds", "resource_queue_wall_seconds"):
|
|
297
|
+
value = getattr(self, name)
|
|
298
|
+
if value is not None:
|
|
299
|
+
_finite_nonnegative(value, name=name)
|
|
300
|
+
if type(value) is not float:
|
|
301
|
+
raise TypeError(f"{name} must be a canonical float or None")
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@runtime_checkable
|
|
305
|
+
class DetailedEvaluationAdapter(Protocol):
|
|
306
|
+
"""Domain port returning evidence without engine-owned phenotype identity."""
|
|
307
|
+
|
|
308
|
+
evaluator_identity: EvaluatorIdentity
|
|
309
|
+
|
|
310
|
+
def evaluate_evidence(
|
|
311
|
+
self,
|
|
312
|
+
configuration: dict[str, object],
|
|
313
|
+
) -> DetailedEvaluationPayload: ...
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def normalize_detailed_payload(
|
|
317
|
+
payload: DetailedEvaluationPayload,
|
|
318
|
+
objectives: tuple[ObjectiveSpec, ...],
|
|
319
|
+
) -> DetailedEvaluationPayload:
|
|
320
|
+
"""Validate the complete objective vector and freeze declaration order."""
|
|
321
|
+
|
|
322
|
+
if type(payload) is not DetailedEvaluationPayload:
|
|
323
|
+
raise TypeError("adapter must return an exact DetailedEvaluationPayload")
|
|
324
|
+
DetailedEvaluationPayload.__post_init__(payload)
|
|
325
|
+
if payload.failure is not None:
|
|
326
|
+
return payload
|
|
327
|
+
normalized = normalize_objective_values(dict(payload.objectives), objectives)
|
|
328
|
+
ordered = tuple((spec.name, normalized[spec.name]) for spec in objectives)
|
|
329
|
+
return replace(payload, objectives=ordered)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
@dataclass(frozen=True, slots=True)
|
|
333
|
+
class DetailedEvaluation:
|
|
334
|
+
"""One engine-sealed, phenotype-cached physical evaluation record."""
|
|
335
|
+
|
|
336
|
+
phenotype: PhenotypeIdentity
|
|
337
|
+
payload: DetailedEvaluationPayload
|
|
338
|
+
timings: EvaluationTimings
|
|
339
|
+
|
|
340
|
+
def __post_init__(self) -> None:
|
|
341
|
+
if type(self.phenotype) is not PhenotypeIdentity:
|
|
342
|
+
raise TypeError("phenotype must be an exact PhenotypeIdentity")
|
|
343
|
+
PhenotypeIdentity.__post_init__(self.phenotype)
|
|
344
|
+
if type(self.payload) is not DetailedEvaluationPayload:
|
|
345
|
+
raise TypeError("payload must be an exact DetailedEvaluationPayload")
|
|
346
|
+
DetailedEvaluationPayload.__post_init__(self.payload)
|
|
347
|
+
if type(self.timings) is not EvaluationTimings:
|
|
348
|
+
raise TypeError("timings must be an exact EvaluationTimings")
|
|
349
|
+
EvaluationTimings.__post_init__(self.timings)
|
|
350
|
+
if self.timings.active_wall_seconds != self.payload.active_wall_seconds:
|
|
351
|
+
raise ValueError("active timing must be copied unchanged from the adapter")
|
|
352
|
+
if (
|
|
353
|
+
self.timings.resource_queue_wall_seconds
|
|
354
|
+
!= self.payload.resource_queue_wall_seconds
|
|
355
|
+
):
|
|
356
|
+
raise ValueError("queue timing must be copied unchanged from the adapter")
|
|
357
|
+
|
|
358
|
+
@property
|
|
359
|
+
def failure(self) -> FailureRecord | None:
|
|
360
|
+
return self.payload.failure
|
|
361
|
+
|
|
362
|
+
@property
|
|
363
|
+
def objectives(self) -> tuple[tuple[str, float], ...]:
|
|
364
|
+
return self.payload.objectives
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def violations(self) -> tuple[tuple[str, float], ...]:
|
|
368
|
+
return self.payload.violations
|
|
369
|
+
|
|
370
|
+
@property
|
|
371
|
+
def checks(self) -> tuple[EvaluationCheck, ...]:
|
|
372
|
+
return self.payload.checks
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
def receipt(self) -> ArtifactRef | None:
|
|
376
|
+
return self.payload.receipt
|
|
377
|
+
|
|
378
|
+
@property
|
|
379
|
+
def success(self) -> bool:
|
|
380
|
+
return self.failure is None
|
|
381
|
+
|
|
382
|
+
@property
|
|
383
|
+
def observations(self) -> tuple[tuple[str, float], ...]:
|
|
384
|
+
return self.payload.observations
|
|
385
|
+
|
|
386
|
+
def _identity_record(self) -> dict[str, object]:
|
|
387
|
+
record: dict[str, object] = {
|
|
388
|
+
"phenotype": {
|
|
389
|
+
**self.phenotype.to_trace_record(),
|
|
390
|
+
"identity_sha256": self.phenotype.identity_sha256,
|
|
391
|
+
},
|
|
392
|
+
"failure": _failure_record(self.failure),
|
|
393
|
+
"objectives": [[name, value.hex()] for name, value in self.objectives],
|
|
394
|
+
"violations": [[name, value.hex()] for name, value in self.violations],
|
|
395
|
+
"checks": [check.to_record() for check in self.checks],
|
|
396
|
+
"receipt": _artifact_record(self.payload.receipt),
|
|
397
|
+
"evaluator": self.payload.evaluator.to_record(),
|
|
398
|
+
"timings": {
|
|
399
|
+
name: None if value is None else value.hex()
|
|
400
|
+
for name, value in self.timings.to_record().items()
|
|
401
|
+
},
|
|
402
|
+
}
|
|
403
|
+
# `observations` enters the seal only when an adapter actually supplies
|
|
404
|
+
# one. `evidence_sha256` is a published identity: it is carried in
|
|
405
|
+
# sealed campaign journals and in the prompt-shape commitment as
|
|
406
|
+
# `parent_evidence_sha256s` and `common_ancestor_evidence_sha256`.
|
|
407
|
+
# Adding an always-present key would re-hash every evaluation ever
|
|
408
|
+
# recorded and invalidate that material. Omitting the key when the
|
|
409
|
+
# tuple is empty makes the serialization byte-identical for every
|
|
410
|
+
# existing payload, so old records verify unchanged while new
|
|
411
|
+
# observations are still sealed rather than merely reported.
|
|
412
|
+
if self.observations:
|
|
413
|
+
record["observations"] = [
|
|
414
|
+
[name, value.hex()] for name, value in self.observations
|
|
415
|
+
]
|
|
416
|
+
return record
|
|
417
|
+
|
|
418
|
+
@property
|
|
419
|
+
def evidence_sha256(self) -> str:
|
|
420
|
+
canonical = json.dumps(
|
|
421
|
+
self._identity_record(),
|
|
422
|
+
ensure_ascii=True,
|
|
423
|
+
allow_nan=False,
|
|
424
|
+
separators=(",", ":"),
|
|
425
|
+
sort_keys=True,
|
|
426
|
+
).encode("ascii")
|
|
427
|
+
return hashlib.sha256(_HASH_DOMAIN + canonical).hexdigest()
|
|
428
|
+
|
|
429
|
+
def to_record(self) -> dict[str, object]:
|
|
430
|
+
return {
|
|
431
|
+
**self._identity_record(),
|
|
432
|
+
"objectives": {name: value for name, value in self.objectives},
|
|
433
|
+
"violations": {name: value for name, value in self.violations},
|
|
434
|
+
"observations": {name: value for name, value in self.observations},
|
|
435
|
+
"timings": self.timings.to_record(),
|
|
436
|
+
"evidence_sha256": self.evidence_sha256,
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
__all__ = [
|
|
441
|
+
"DetailedEvaluation",
|
|
442
|
+
"DetailedEvaluationAdapter",
|
|
443
|
+
"DetailedEvaluationPayload",
|
|
444
|
+
"EvaluationCheck",
|
|
445
|
+
"EvaluationCheckStatus",
|
|
446
|
+
"EvaluationTimings",
|
|
447
|
+
"EvaluatorIdentity",
|
|
448
|
+
"normalize_detailed_payload",
|
|
449
|
+
]
|