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,193 @@
|
|
|
1
|
+
"""Durable append-only JSONL EventStore.
|
|
2
|
+
|
|
3
|
+
Correctness is favored over indexing in this first milestone: streams are
|
|
4
|
+
revalidated before reads and appends. Event payloads remain small because large
|
|
5
|
+
blobs will live in the artifact store added by the second half of M1.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import threading
|
|
12
|
+
from contextlib import contextmanager
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Dict, Iterator, List, Tuple
|
|
15
|
+
|
|
16
|
+
from agent_evolve.domain.event import (
|
|
17
|
+
EventCodecError,
|
|
18
|
+
EventEnvelope,
|
|
19
|
+
event_from_json,
|
|
20
|
+
event_to_json,
|
|
21
|
+
)
|
|
22
|
+
from agent_evolve.domain.ids import EventId, RunId
|
|
23
|
+
from agent_evolve.infrastructure.events._validation import (
|
|
24
|
+
prepare_event_for_append,
|
|
25
|
+
validate_append,
|
|
26
|
+
validate_loaded_stream,
|
|
27
|
+
)
|
|
28
|
+
from agent_evolve.ports.event_store import (
|
|
29
|
+
CorruptEventLogError,
|
|
30
|
+
DuplicateEventIdError,
|
|
31
|
+
EventRunMismatchError,
|
|
32
|
+
EventSequenceError,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
try: # pragma: no cover - exercised on Unix CI; fallback is thread-only.
|
|
36
|
+
import fcntl
|
|
37
|
+
except ImportError: # pragma: no cover
|
|
38
|
+
fcntl = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class JsonlEventStore:
|
|
42
|
+
"""One canonical ``<run_id>.jsonl`` stream per run under *root*."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, root: str | os.PathLike[str]) -> None:
|
|
45
|
+
self.root = Path(root)
|
|
46
|
+
self.root.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
self._thread_lock = threading.RLock()
|
|
48
|
+
self._lock_path = self.root / ".event-store.lock"
|
|
49
|
+
# Fail early on malformed/tampered existing streams.
|
|
50
|
+
with self._locked():
|
|
51
|
+
self._load_all_unlocked()
|
|
52
|
+
|
|
53
|
+
def path_for_run(self, run_id: RunId) -> Path:
|
|
54
|
+
if type(run_id) is not RunId:
|
|
55
|
+
raise TypeError("run_id must be an exact RunId")
|
|
56
|
+
canonical_run_id = RunId(run_id.value)
|
|
57
|
+
return self.root / f"{canonical_run_id.value}.jsonl"
|
|
58
|
+
|
|
59
|
+
@contextmanager
|
|
60
|
+
def _locked(self) -> Iterator[None]:
|
|
61
|
+
with self._thread_lock:
|
|
62
|
+
lock_fd = os.open(self._lock_path, os.O_RDWR | os.O_CREAT, 0o600)
|
|
63
|
+
try:
|
|
64
|
+
if fcntl is not None:
|
|
65
|
+
fcntl.flock(lock_fd, fcntl.LOCK_EX)
|
|
66
|
+
yield
|
|
67
|
+
finally:
|
|
68
|
+
if fcntl is not None:
|
|
69
|
+
fcntl.flock(lock_fd, fcntl.LOCK_UN)
|
|
70
|
+
os.close(lock_fd)
|
|
71
|
+
|
|
72
|
+
def _read_file_unlocked(self, path: Path) -> Tuple[EventEnvelope, ...]:
|
|
73
|
+
data = path.read_bytes()
|
|
74
|
+
if not data:
|
|
75
|
+
return ()
|
|
76
|
+
if not data.endswith(b"\n"):
|
|
77
|
+
raise CorruptEventLogError(f"Event log has a truncated final line: {path}")
|
|
78
|
+
events: List[EventEnvelope] = []
|
|
79
|
+
for line_number, raw_line in enumerate(data.splitlines(), 1):
|
|
80
|
+
if not raw_line.strip():
|
|
81
|
+
raise CorruptEventLogError(f"Blank event line at {path}:{line_number}")
|
|
82
|
+
try:
|
|
83
|
+
line = raw_line.decode("utf-8")
|
|
84
|
+
except UnicodeDecodeError:
|
|
85
|
+
line = None
|
|
86
|
+
if line is None:
|
|
87
|
+
raise CorruptEventLogError(
|
|
88
|
+
f"Malformed event at {path}:{line_number}"
|
|
89
|
+
)
|
|
90
|
+
try:
|
|
91
|
+
event = event_from_json(line)
|
|
92
|
+
except EventCodecError:
|
|
93
|
+
event = None
|
|
94
|
+
if event is None:
|
|
95
|
+
raise CorruptEventLogError(
|
|
96
|
+
f"Malformed event at {path}:{line_number}"
|
|
97
|
+
)
|
|
98
|
+
events.append(event)
|
|
99
|
+
return tuple(events)
|
|
100
|
+
|
|
101
|
+
def _load_all_unlocked(
|
|
102
|
+
self,
|
|
103
|
+
) -> tuple[Dict[RunId, Tuple[EventEnvelope, ...]], set[EventId]]:
|
|
104
|
+
streams: Dict[RunId, Tuple[EventEnvelope, ...]] = {}
|
|
105
|
+
event_ids: set[EventId] = set()
|
|
106
|
+
for path in sorted(self.root.glob("*.jsonl")):
|
|
107
|
+
events = self._read_file_unlocked(path)
|
|
108
|
+
if not events:
|
|
109
|
+
# Empty files have no authoritative run identity yet.
|
|
110
|
+
continue
|
|
111
|
+
run_id = events[0].run_id
|
|
112
|
+
expected_name = f"{run_id.value}.jsonl"
|
|
113
|
+
if path.name != expected_name:
|
|
114
|
+
raise EventRunMismatchError(
|
|
115
|
+
f"Stream file {path.name!r} contains run {run_id}; "
|
|
116
|
+
f"expected file {expected_name!r}"
|
|
117
|
+
)
|
|
118
|
+
try:
|
|
119
|
+
validate_loaded_stream(run_id, events)
|
|
120
|
+
except (EventSequenceError, EventRunMismatchError, DuplicateEventIdError) as exc:
|
|
121
|
+
raise CorruptEventLogError(f"Invalid event stream {path}: {exc}") from exc
|
|
122
|
+
duplicate = event_ids.intersection(event.event_id for event in events)
|
|
123
|
+
if duplicate:
|
|
124
|
+
repeated = sorted(str(event_id) for event_id in duplicate)
|
|
125
|
+
raise CorruptEventLogError(f"Duplicate event ID across streams: {repeated}")
|
|
126
|
+
event_ids.update(event.event_id for event in events)
|
|
127
|
+
streams[run_id] = events
|
|
128
|
+
return streams, event_ids
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def _append_bytes(path: Path, data: bytes) -> None:
|
|
132
|
+
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600)
|
|
133
|
+
try:
|
|
134
|
+
view = memoryview(data)
|
|
135
|
+
while view:
|
|
136
|
+
written = os.write(fd, view)
|
|
137
|
+
if written <= 0: # pragma: no cover - defensive OS failure guard.
|
|
138
|
+
raise OSError("zero-byte write while appending event")
|
|
139
|
+
view = view[written:]
|
|
140
|
+
os.fsync(fd)
|
|
141
|
+
finally:
|
|
142
|
+
os.close(fd)
|
|
143
|
+
|
|
144
|
+
def _fsync_root_directory(self) -> None:
|
|
145
|
+
"""Make creation of a new stream name durable on POSIX filesystems."""
|
|
146
|
+
|
|
147
|
+
if os.name != "posix": # pragma: no cover - directory fsync is POSIX-specific.
|
|
148
|
+
return
|
|
149
|
+
flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0)
|
|
150
|
+
fd = os.open(self.root, flags)
|
|
151
|
+
try:
|
|
152
|
+
os.fsync(fd)
|
|
153
|
+
finally:
|
|
154
|
+
os.close(fd)
|
|
155
|
+
|
|
156
|
+
def append(
|
|
157
|
+
self,
|
|
158
|
+
event: EventEnvelope,
|
|
159
|
+
*,
|
|
160
|
+
expected_previous_sequence: int,
|
|
161
|
+
) -> None:
|
|
162
|
+
snapshot = prepare_event_for_append(event)
|
|
163
|
+
encoded = (event_to_json(snapshot) + "\n").encode("utf-8")
|
|
164
|
+
with self._locked():
|
|
165
|
+
streams, event_ids = self._load_all_unlocked()
|
|
166
|
+
existing = streams.get(snapshot.run_id, ())
|
|
167
|
+
validate_append(
|
|
168
|
+
existing,
|
|
169
|
+
snapshot,
|
|
170
|
+
expected_previous_sequence=expected_previous_sequence,
|
|
171
|
+
known_event_ids=event_ids,
|
|
172
|
+
)
|
|
173
|
+
self._append_bytes(self.path_for_run(snapshot.run_id), encoded)
|
|
174
|
+
self._fsync_root_directory()
|
|
175
|
+
|
|
176
|
+
def read(
|
|
177
|
+
self,
|
|
178
|
+
run_id: RunId,
|
|
179
|
+
*,
|
|
180
|
+
after_sequence: int = 0,
|
|
181
|
+
) -> Tuple[EventEnvelope, ...]:
|
|
182
|
+
if type(after_sequence) is not int or after_sequence < 0:
|
|
183
|
+
raise ValueError("after_sequence must be a non-negative integer")
|
|
184
|
+
if type(run_id) is not RunId:
|
|
185
|
+
raise TypeError("run_id must be an exact RunId")
|
|
186
|
+
canonical_run_id = RunId(run_id.value)
|
|
187
|
+
with self._locked():
|
|
188
|
+
streams, _ = self._load_all_unlocked()
|
|
189
|
+
return tuple(
|
|
190
|
+
event
|
|
191
|
+
for event in streams.get(canonical_run_id, ())
|
|
192
|
+
if event.sequence_number > after_sequence
|
|
193
|
+
)
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""Privacy-safe, bounded exception-origin projection.
|
|
2
|
+
|
|
3
|
+
This module is framework-neutral. It converts Python exception topology into
|
|
4
|
+
closed domain values without reading exception messages, reprs, arguments,
|
|
5
|
+
tracebacks, response objects, URLs, payloads, or arbitrary metadata.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
from collections import deque
|
|
13
|
+
|
|
14
|
+
from agent_evolve.domain.llm_task_queue import (
|
|
15
|
+
MAX_EXCEPTION_PROVENANCE_NODES,
|
|
16
|
+
ExceptionOriginFamily,
|
|
17
|
+
ExceptionProvenanceLink,
|
|
18
|
+
SanitizedExceptionProvenance,
|
|
19
|
+
SanitizedExceptionProvenanceNode,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
EXCEPTION_TYPE_IDENTITY_FINGERPRINT_ALGORITHM = (
|
|
24
|
+
"sha256_domain_and_bounded_module_qualname_projection_v1"
|
|
25
|
+
)
|
|
26
|
+
_EXCEPTION_TYPE_IDENTITY_DOMAIN = (
|
|
27
|
+
b"agent-evolve:sanitized-exception-type-identity:v1\x00"
|
|
28
|
+
)
|
|
29
|
+
EXCEPTION_TYPE_IDENTITY_DOMAIN_SHA256 = hashlib.sha256(
|
|
30
|
+
_EXCEPTION_TYPE_IDENTITY_DOMAIN
|
|
31
|
+
).hexdigest()
|
|
32
|
+
_MAX_TYPE_COMPONENT_CHARS = 512
|
|
33
|
+
_TYPE_COMPONENT_EDGE_CHARS = 128
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _runtime_type_text(exception_type: type[BaseException], name: str) -> str | None:
|
|
37
|
+
"""Read type metadata without invoking a custom metaclass override."""
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
value = type.__getattribute__(exception_type, name)
|
|
41
|
+
except BaseException:
|
|
42
|
+
return None
|
|
43
|
+
return value if type(value) is str else None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _bounded_type_component(value: str | None) -> dict[str, object]:
|
|
47
|
+
"""Project type metadata with fixed memory independent of input length."""
|
|
48
|
+
|
|
49
|
+
if value is None:
|
|
50
|
+
return {"state": "absent", "length": 0, "prefix": "", "suffix": ""}
|
|
51
|
+
length = len(value)
|
|
52
|
+
if length <= _MAX_TYPE_COMPONENT_CHARS:
|
|
53
|
+
return {
|
|
54
|
+
"state": "complete",
|
|
55
|
+
"length": length,
|
|
56
|
+
"prefix": value,
|
|
57
|
+
"suffix": "",
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
"state": "truncated",
|
|
61
|
+
"length": length,
|
|
62
|
+
"prefix": value[:_TYPE_COMPONENT_EDGE_CHARS],
|
|
63
|
+
"suffix": value[-_TYPE_COMPONENT_EDGE_CHARS:],
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def exception_type_identity_sha256(exception_type: type[BaseException]) -> str:
|
|
68
|
+
"""Return a stable, redacted fingerprint for one runtime exception type."""
|
|
69
|
+
|
|
70
|
+
if not isinstance(exception_type, type) or not issubclass(
|
|
71
|
+
exception_type, BaseException
|
|
72
|
+
):
|
|
73
|
+
raise TypeError("exception_type must be a BaseException type")
|
|
74
|
+
record = {
|
|
75
|
+
"schema_version": 1,
|
|
76
|
+
"module": _bounded_type_component(
|
|
77
|
+
_runtime_type_text(exception_type, "__module__")
|
|
78
|
+
),
|
|
79
|
+
"qualname": _bounded_type_component(
|
|
80
|
+
_runtime_type_text(exception_type, "__qualname__")
|
|
81
|
+
),
|
|
82
|
+
}
|
|
83
|
+
canonical = json.dumps(
|
|
84
|
+
record,
|
|
85
|
+
ensure_ascii=True,
|
|
86
|
+
allow_nan=False,
|
|
87
|
+
separators=(",", ":"),
|
|
88
|
+
sort_keys=True,
|
|
89
|
+
).encode("ascii")
|
|
90
|
+
return hashlib.sha256(_EXCEPTION_TYPE_IDENTITY_DOMAIN + canonical).hexdigest()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _origin_family(exception_type: type[BaseException]) -> ExceptionOriginFamily:
|
|
94
|
+
module = _runtime_type_text(exception_type, "__module__")
|
|
95
|
+
if module is None:
|
|
96
|
+
return ExceptionOriginFamily.OTHER
|
|
97
|
+
roots = (
|
|
98
|
+
("builtins", ExceptionOriginFamily.BUILTINS),
|
|
99
|
+
("asyncio", ExceptionOriginFamily.ASYNCIO),
|
|
100
|
+
("anyio", ExceptionOriginFamily.ANYIO),
|
|
101
|
+
("httpx", ExceptionOriginFamily.HTTPX),
|
|
102
|
+
("httpcore", ExceptionOriginFamily.HTTPCORE),
|
|
103
|
+
("openai", ExceptionOriginFamily.OPENAI),
|
|
104
|
+
("pydantic_ai", ExceptionOriginFamily.PYDANTIC_AI),
|
|
105
|
+
("pydantic", ExceptionOriginFamily.PYDANTIC),
|
|
106
|
+
("agent_evolve", ExceptionOriginFamily.AGENT_EVOLVE),
|
|
107
|
+
)
|
|
108
|
+
for root, family in roots:
|
|
109
|
+
if module == root or module.startswith(root + "."):
|
|
110
|
+
return family
|
|
111
|
+
return ExceptionOriginFamily.OTHER
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _base_exception_link(
|
|
115
|
+
value: BaseException,
|
|
116
|
+
attribute: str,
|
|
117
|
+
) -> BaseException | None:
|
|
118
|
+
try:
|
|
119
|
+
linked = BaseException.__getattribute__(value, attribute)
|
|
120
|
+
except BaseException:
|
|
121
|
+
return None
|
|
122
|
+
return linked if isinstance(linked, BaseException) else None
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _group_members(value: BaseException) -> tuple[BaseException, ...]:
|
|
126
|
+
if not isinstance(value, BaseExceptionGroup):
|
|
127
|
+
return ()
|
|
128
|
+
try:
|
|
129
|
+
members = BaseExceptionGroup.exceptions.__get__(value, type(value))
|
|
130
|
+
except BaseException:
|
|
131
|
+
return ()
|
|
132
|
+
if type(members) is not tuple:
|
|
133
|
+
return ()
|
|
134
|
+
# One extra member is enough to authenticate that the bounded graph was
|
|
135
|
+
# truncated; never enqueue an attacker-sized group in full.
|
|
136
|
+
return tuple(
|
|
137
|
+
member
|
|
138
|
+
for member in members[: MAX_EXCEPTION_PROVENANCE_NODES + 1]
|
|
139
|
+
if isinstance(member, BaseException)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def sanitized_exception_provenance(
|
|
144
|
+
exc: BaseException,
|
|
145
|
+
) -> SanitizedExceptionProvenance:
|
|
146
|
+
"""Project root/cause/context/group topology into at most sixteen nodes."""
|
|
147
|
+
|
|
148
|
+
if not isinstance(exc, BaseException):
|
|
149
|
+
raise TypeError("exc must be a BaseException")
|
|
150
|
+
pending: deque[tuple[BaseException, int | None, ExceptionProvenanceLink]] = deque(
|
|
151
|
+
[(exc, None, ExceptionProvenanceLink.ROOT)]
|
|
152
|
+
)
|
|
153
|
+
nodes: list[SanitizedExceptionProvenanceNode] = []
|
|
154
|
+
seen: set[int] = set()
|
|
155
|
+
overflowed = False
|
|
156
|
+
|
|
157
|
+
while pending and len(nodes) < MAX_EXCEPTION_PROVENANCE_NODES:
|
|
158
|
+
current, parent_index, link = pending.popleft()
|
|
159
|
+
identity = id(current)
|
|
160
|
+
if identity in seen:
|
|
161
|
+
continue
|
|
162
|
+
seen.add(identity)
|
|
163
|
+
node_index = len(nodes)
|
|
164
|
+
exception_type = type(current)
|
|
165
|
+
nodes.append(
|
|
166
|
+
SanitizedExceptionProvenanceNode(
|
|
167
|
+
parent_index=parent_index,
|
|
168
|
+
link=link,
|
|
169
|
+
family=_origin_family(exception_type),
|
|
170
|
+
type_identity_sha256=exception_type_identity_sha256(exception_type),
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
linked_values = (
|
|
175
|
+
(
|
|
176
|
+
_base_exception_link(current, "__cause__"),
|
|
177
|
+
ExceptionProvenanceLink.CAUSE,
|
|
178
|
+
),
|
|
179
|
+
(
|
|
180
|
+
_base_exception_link(current, "__context__"),
|
|
181
|
+
ExceptionProvenanceLink.CONTEXT,
|
|
182
|
+
),
|
|
183
|
+
)
|
|
184
|
+
children = [
|
|
185
|
+
(linked, node_index, child_link)
|
|
186
|
+
for linked, child_link in linked_values
|
|
187
|
+
if linked is not None and id(linked) not in seen
|
|
188
|
+
]
|
|
189
|
+
children.extend(
|
|
190
|
+
(member, node_index, ExceptionProvenanceLink.GROUP_MEMBER)
|
|
191
|
+
for member in _group_members(current)
|
|
192
|
+
if id(member) not in seen
|
|
193
|
+
)
|
|
194
|
+
for child in children:
|
|
195
|
+
# Bound pending storage as well as the emitted graph. The extra
|
|
196
|
+
# slot only records that more topology existed.
|
|
197
|
+
if len(nodes) + len(pending) < MAX_EXCEPTION_PROVENANCE_NODES:
|
|
198
|
+
pending.append(child)
|
|
199
|
+
else:
|
|
200
|
+
overflowed = True
|
|
201
|
+
|
|
202
|
+
if pending:
|
|
203
|
+
overflowed = True
|
|
204
|
+
return SanitizedExceptionProvenance(
|
|
205
|
+
nodes=tuple(nodes),
|
|
206
|
+
truncated=overflowed,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
__all__ = [
|
|
211
|
+
"EXCEPTION_TYPE_IDENTITY_DOMAIN_SHA256",
|
|
212
|
+
"EXCEPTION_TYPE_IDENTITY_FINGERPRINT_ALGORITHM",
|
|
213
|
+
"exception_type_identity_sha256",
|
|
214
|
+
"sanitized_exception_provenance",
|
|
215
|
+
]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Production and deterministic ID factories."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import threading
|
|
6
|
+
import uuid
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
from typing import DefaultDict, Type, TypeVar
|
|
9
|
+
|
|
10
|
+
from agent_evolve.domain.ids import (
|
|
11
|
+
CandidateId,
|
|
12
|
+
CorrelationId,
|
|
13
|
+
EvaluationAttemptId,
|
|
14
|
+
EvaluationId,
|
|
15
|
+
EventId,
|
|
16
|
+
GenerationId,
|
|
17
|
+
InsightId,
|
|
18
|
+
LLMCallId,
|
|
19
|
+
OperatorInvocationId,
|
|
20
|
+
ProviderAttemptId,
|
|
21
|
+
RunId,
|
|
22
|
+
StableId,
|
|
23
|
+
validate_id_namespace,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
IdT = TypeVar("IdT", bound=StableId)
|
|
27
|
+
class UuidIdFactory:
|
|
28
|
+
"""Allocate opaque UUID4-backed IDs.
|
|
29
|
+
|
|
30
|
+
Ordering comes from the event sequence, so IDs do not encode wall time and do
|
|
31
|
+
not risk clock-regression ambiguity.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def _new(id_type: Type[IdT]) -> IdT:
|
|
36
|
+
return id_type(f"{id_type.PREFIX}_{uuid.uuid4().hex}")
|
|
37
|
+
|
|
38
|
+
def new_run_id(self) -> RunId:
|
|
39
|
+
return self._new(RunId)
|
|
40
|
+
|
|
41
|
+
def new_event_id(self) -> EventId:
|
|
42
|
+
return self._new(EventId)
|
|
43
|
+
|
|
44
|
+
def new_generation_id(self) -> GenerationId:
|
|
45
|
+
return self._new(GenerationId)
|
|
46
|
+
|
|
47
|
+
def new_candidate_id(self) -> CandidateId:
|
|
48
|
+
return self._new(CandidateId)
|
|
49
|
+
|
|
50
|
+
def new_insight_id(self) -> InsightId:
|
|
51
|
+
return self._new(InsightId)
|
|
52
|
+
|
|
53
|
+
def new_operator_invocation_id(self) -> OperatorInvocationId:
|
|
54
|
+
return self._new(OperatorInvocationId)
|
|
55
|
+
|
|
56
|
+
def new_llm_call_id(self) -> LLMCallId:
|
|
57
|
+
return self._new(LLMCallId)
|
|
58
|
+
|
|
59
|
+
def new_provider_attempt_id(self) -> ProviderAttemptId:
|
|
60
|
+
return self._new(ProviderAttemptId)
|
|
61
|
+
|
|
62
|
+
def new_evaluation_id(self) -> EvaluationId:
|
|
63
|
+
return self._new(EvaluationId)
|
|
64
|
+
|
|
65
|
+
def new_evaluation_attempt_id(self) -> EvaluationAttemptId:
|
|
66
|
+
return self._new(EvaluationAttemptId)
|
|
67
|
+
|
|
68
|
+
def new_correlation_id(self) -> CorrelationId:
|
|
69
|
+
return self._new(CorrelationId)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class DeterministicIdFactory:
|
|
73
|
+
"""Per-ID-type deterministic allocator for tests and recorded replay."""
|
|
74
|
+
|
|
75
|
+
def __init__(self, namespace: str = "test") -> None:
|
|
76
|
+
validate_id_namespace(namespace)
|
|
77
|
+
self._namespace = namespace
|
|
78
|
+
self._counters: DefaultDict[Type[StableId], int] = defaultdict(int)
|
|
79
|
+
self._lock = threading.Lock()
|
|
80
|
+
|
|
81
|
+
def _new(self, id_type: Type[IdT]) -> IdT:
|
|
82
|
+
with self._lock:
|
|
83
|
+
self._counters[id_type] += 1
|
|
84
|
+
ordinal = self._counters[id_type]
|
|
85
|
+
return id_type(f"{id_type.PREFIX}_{self._namespace}_{ordinal:06d}")
|
|
86
|
+
|
|
87
|
+
def new_run_id(self) -> RunId:
|
|
88
|
+
return self._new(RunId)
|
|
89
|
+
|
|
90
|
+
def new_event_id(self) -> EventId:
|
|
91
|
+
return self._new(EventId)
|
|
92
|
+
|
|
93
|
+
def new_generation_id(self) -> GenerationId:
|
|
94
|
+
return self._new(GenerationId)
|
|
95
|
+
|
|
96
|
+
def new_candidate_id(self) -> CandidateId:
|
|
97
|
+
return self._new(CandidateId)
|
|
98
|
+
|
|
99
|
+
def new_insight_id(self) -> InsightId:
|
|
100
|
+
return self._new(InsightId)
|
|
101
|
+
|
|
102
|
+
def new_operator_invocation_id(self) -> OperatorInvocationId:
|
|
103
|
+
return self._new(OperatorInvocationId)
|
|
104
|
+
|
|
105
|
+
def new_llm_call_id(self) -> LLMCallId:
|
|
106
|
+
return self._new(LLMCallId)
|
|
107
|
+
|
|
108
|
+
def new_provider_attempt_id(self) -> ProviderAttemptId:
|
|
109
|
+
return self._new(ProviderAttemptId)
|
|
110
|
+
|
|
111
|
+
def new_evaluation_id(self) -> EvaluationId:
|
|
112
|
+
return self._new(EvaluationId)
|
|
113
|
+
|
|
114
|
+
def new_evaluation_attempt_id(self) -> EvaluationAttemptId:
|
|
115
|
+
return self._new(EvaluationAttemptId)
|
|
116
|
+
|
|
117
|
+
def new_correlation_id(self) -> CorrelationId:
|
|
118
|
+
return self._new(CorrelationId)
|