agentinputlab 0.1.0a1__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.
- agentinputlab/__init__.py +28 -0
- agentinputlab/algorithms/__init__.py +6 -0
- agentinputlab/algorithms/acquire/__init__.py +145 -0
- agentinputlab/algorithms/acquire/adaptive_rag/__init__.py +43 -0
- agentinputlab/algorithms/acquire/adaptive_rag/replay.py +367 -0
- agentinputlab/algorithms/acquire/adaptive_rag/runtime.py +1202 -0
- agentinputlab/algorithms/acquire/adaptive_rag_common_support.py +542 -0
- agentinputlab/algorithms/acquire/hyde.py +296 -0
- agentinputlab/algorithms/acquire/hyde_controlled.py +200 -0
- agentinputlab/algorithms/acquire/hyde_external.py +148 -0
- agentinputlab/algorithms/acquire/ircot.py +28 -0
- agentinputlab/algorithms/acquire/ircot_common_support.py +478 -0
- agentinputlab/algorithms/acquire/ircot_native.py +355 -0
- agentinputlab/algorithms/acquire/ircot_replay.py +327 -0
- agentinputlab/algorithms/acquire/qrag/__init__.py +79 -0
- agentinputlab/algorithms/acquire/qrag/bridge.py +828 -0
- agentinputlab/algorithms/acquire/qrag/common_support.py +891 -0
- agentinputlab/algorithms/acquire/qrag/native_axis.py +71 -0
- agentinputlab/algorithms/acquire/qrag/reader_adapter.py +139 -0
- agentinputlab/algorithms/acquire/r2ag/__init__.py +57 -0
- agentinputlab/algorithms/acquire/r2ag/bridge.py +1312 -0
- agentinputlab/algorithms/acquire/r2ag/common_support.py +1029 -0
- agentinputlab/algorithms/acquire/r2ag/socket_runtime.py +255 -0
- agentinputlab/algorithms/clarify/__init__.py +61 -0
- agentinputlab/algorithms/clarify/_structured.py +64 -0
- agentinputlab/algorithms/clarify/active_task_disambiguation.py +371 -0
- agentinputlab/algorithms/clarify/ask_or_assume/__init__.py +17 -0
- agentinputlab/algorithms/clarify/ask_or_assume/monitor.py +410 -0
- agentinputlab/algorithms/clarify/future_turns.py +379 -0
- agentinputlab/algorithms/clarify/udcs.py +255 -0
- agentinputlab/algorithms/clarify/udcs_deterministic.py +196 -0
- agentinputlab/algorithms/curate/__init__.py +65 -0
- agentinputlab/algorithms/curate/acon/__init__.py +27 -0
- agentinputlab/algorithms/curate/acon/common.py +284 -0
- agentinputlab/algorithms/curate/acon/common_support.py +136 -0
- agentinputlab/algorithms/curate/acon/history_bridge.py +309 -0
- agentinputlab/algorithms/curate/acon/observation_bridge.py +290 -0
- agentinputlab/algorithms/curate/llmlingua/__init__.py +30 -0
- agentinputlab/algorithms/curate/llmlingua/adapters.py +537 -0
- agentinputlab/algorithms/curate/llmlingua/budget.py +48 -0
- agentinputlab/algorithms/curate/llmlingua/controlled.py +175 -0
- agentinputlab/algorithms/curate/llmlingua/multilingual.py +105 -0
- agentinputlab/algorithms/curate/llmlingua/span_map.py +167 -0
- agentinputlab/algorithms/curate/recomp/__init__.py +47 -0
- agentinputlab/algorithms/curate/recomp/external.py +1129 -0
- agentinputlab/algorithms/curate/recomp/selective.py +304 -0
- agentinputlab/algorithms/decompose/__init__.py +107 -0
- agentinputlab/algorithms/decompose/decomp/__init__.py +53 -0
- agentinputlab/algorithms/decompose/decomp/common_support.py +478 -0
- agentinputlab/algorithms/decompose/decomp/planner_component.py +199 -0
- agentinputlab/algorithms/decompose/decomp/worker_bridge.py +416 -0
- agentinputlab/algorithms/decompose/llm_compiler/__init__.py +35 -0
- agentinputlab/algorithms/decompose/llm_compiler/bridge.py +520 -0
- agentinputlab/algorithms/decompose/llm_compiler/common_support.py +504 -0
- agentinputlab/algorithms/decompose/plan_and_budget/__init__.py +43 -0
- agentinputlab/algorithms/decompose/plan_and_budget/cached_soft_budget.py +362 -0
- agentinputlab/algorithms/decompose/plan_and_budget/decomposer_component.py +107 -0
- agentinputlab/algorithms/decompose/plan_and_budget/full.py +205 -0
- agentinputlab/algorithms/decompose/plan_and_budget/hard_cap.py +246 -0
- agentinputlab/algorithms/decompose/plan_and_budget/regenerated_soft_budget.py +448 -0
- agentinputlab/algorithms/decompose/plan_and_solve/__init__.py +33 -0
- agentinputlab/algorithms/decompose/plan_and_solve/plan_component.py +192 -0
- agentinputlab/algorithms/decompose/plan_and_solve/ps_prompt.py +127 -0
- agentinputlab/algorithms/decompose/self_ask/__init__.py +27 -0
- agentinputlab/algorithms/decompose/self_ask/loop.py +362 -0
- agentinputlab/algorithms/decompose/self_ask/planner_component.py +117 -0
- agentinputlab/algorithms/reformulate/__init__.py +85 -0
- agentinputlab/algorithms/reformulate/infocqr/__init__.py +40 -0
- agentinputlab/algorithms/reformulate/infocqr/cache_replay.py +362 -0
- agentinputlab/algorithms/reformulate/infocqr/external.py +675 -0
- agentinputlab/algorithms/reformulate/infocqr/student.py +189 -0
- agentinputlab/algorithms/reformulate/query2doc/__init__.py +42 -0
- agentinputlab/algorithms/reformulate/query2doc/controlled_live.py +190 -0
- agentinputlab/algorithms/reformulate/query2doc/models.py +95 -0
- agentinputlab/algorithms/reformulate/query2doc/official_cached.py +335 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_bridge.py +223 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_runtime.py +326 -0
- agentinputlab/algorithms/reformulate/reformer/__init__.py +23 -0
- agentinputlab/algorithms/reformulate/reformer/external.py +417 -0
- agentinputlab/algorithms/reformulate/rrr.py +696 -0
- agentinputlab/annotation/__init__.py +5 -0
- agentinputlab/annotation/independent.py +428 -0
- agentinputlab/annotation/server.py +233 -0
- agentinputlab/annotation/static/app.js +121 -0
- agentinputlab/annotation/static/index.html +60 -0
- agentinputlab/annotation/static/review.css +2 -0
- agentinputlab/annotation/static/review.html +10 -0
- agentinputlab/annotation/static/review.js +11 -0
- agentinputlab/annotation/static/styles.css +55 -0
- agentinputlab/annotation/store.py +444 -0
- agentinputlab/api.py +368 -0
- agentinputlab/artifacts/__init__.py +15 -0
- agentinputlab/artifacts/json_file.py +104 -0
- agentinputlab/artifacts/manifest.py +98 -0
- agentinputlab/artifacts/store.py +157 -0
- agentinputlab/backends/__init__.py +98 -0
- agentinputlab/backends/embedding/__init__.py +25 -0
- agentinputlab/backends/embedding/base.py +145 -0
- agentinputlab/backends/embedding/callable.py +75 -0
- agentinputlab/backends/embedding/replay.py +129 -0
- agentinputlab/backends/llm/__init__.py +31 -0
- agentinputlab/backends/llm/base.py +149 -0
- agentinputlab/backends/llm/callable.py +108 -0
- agentinputlab/backends/llm/decomp_completion.py +88 -0
- agentinputlab/backends/llm/final_content_stop.py +72 -0
- agentinputlab/backends/llm/gpt_oss_final_channel.py +84 -0
- agentinputlab/backends/llm/openai_compatible.py +332 -0
- agentinputlab/backends/llm/transformers.py +171 -0
- agentinputlab/backends/retrieval/__init__.py +35 -0
- agentinputlab/backends/retrieval/base.py +50 -0
- agentinputlab/backends/retrieval/dense.py +777 -0
- agentinputlab/backends/retrieval/memory.py +119 -0
- agentinputlab/backends/retrieval/sqlite_fts.py +155 -0
- agentinputlab/backends/user/__init__.py +15 -0
- agentinputlab/backends/user/base.py +66 -0
- agentinputlab/backends/user/callable.py +54 -0
- agentinputlab/backends/user/replay.py +89 -0
- agentinputlab/backends/vector.py +38 -0
- agentinputlab/benchmarks/__init__.py +246 -0
- agentinputlab/benchmarks/acquisition.py +106 -0
- agentinputlab/benchmarks/ale.py +540 -0
- agentinputlab/benchmarks/appworld_ul.py +669 -0
- agentinputlab/benchmarks/assets.py +226 -0
- agentinputlab/benchmarks/base.py +68 -0
- agentinputlab/benchmarks/beir_archive.py +235 -0
- agentinputlab/benchmarks/beir_sample.py +269 -0
- agentinputlab/benchmarks/bfcl_native.py +245 -0
- agentinputlab/benchmarks/bfcl_v3.py +607 -0
- agentinputlab/benchmarks/cache.py +218 -0
- agentinputlab/benchmarks/clariq.py +203 -0
- agentinputlab/benchmarks/data/registry.json +321 -0
- agentinputlab/benchmarks/data/smoke_assets.json +511 -0
- agentinputlab/benchmarks/data/statebench_v0_8_1_task_ids.json +475 -0
- agentinputlab/benchmarks/data/toolsandbox_165848b_scenario_names.json +1 -0
- agentinputlab/benchmarks/execution.py +1111 -0
- agentinputlab/benchmarks/interactive.py +257 -0
- agentinputlab/benchmarks/ir_query.py +204 -0
- agentinputlab/benchmarks/longbench.py +203 -0
- agentinputlab/benchmarks/paired_replay.py +479 -0
- agentinputlab/benchmarks/preprocess.py +2313 -0
- agentinputlab/benchmarks/production.py +236 -0
- agentinputlab/benchmarks/qa.py +963 -0
- agentinputlab/benchmarks/registry.py +110 -0
- agentinputlab/benchmarks/retrieval.py +459 -0
- agentinputlab/benchmarks/runtime.py +509 -0
- agentinputlab/benchmarks/statebench.py +938 -0
- agentinputlab/benchmarks/tau3.py +725 -0
- agentinputlab/benchmarks/toolsandbox.py +626 -0
- agentinputlab/benchmarks/trec_dl_sample.py +263 -0
- agentinputlab/campaign.py +654 -0
- agentinputlab/campaign_runner.py +953 -0
- agentinputlab/cli/__init__.py +6 -0
- agentinputlab/cli/main.py +933 -0
- agentinputlab/connectors/__init__.py +46 -0
- agentinputlab/connectors/knowledge/__init__.py +4 -0
- agentinputlab/connectors/tools/__init__.py +30 -0
- agentinputlab/connectors/tools/base.py +57 -0
- agentinputlab/connectors/tools/mcp.py +222 -0
- agentinputlab/connectors/tools/memory.py +41 -0
- agentinputlab/connectors/tools/openapi.py +695 -0
- agentinputlab/connectors/tools/schema.py +102 -0
- agentinputlab/contracts/__init__.py +91 -0
- agentinputlab/contracts/availability.py +24 -0
- agentinputlab/contracts/dependency.py +58 -0
- agentinputlab/contracts/enums.py +82 -0
- agentinputlab/contracts/errors.py +63 -0
- agentinputlab/contracts/evidence.py +43 -0
- agentinputlab/contracts/intent.py +110 -0
- agentinputlab/contracts/lifecycle.py +164 -0
- agentinputlab/contracts/patch.py +167 -0
- agentinputlab/contracts/serialization.py +93 -0
- agentinputlab/contracts/state.py +127 -0
- agentinputlab/contracts/trace.py +59 -0
- agentinputlab/contracts/worker.py +42 -0
- agentinputlab/core/__init__.py +7 -0
- agentinputlab/data/__init__.py +32 -0
- agentinputlab/data/checksums.py +9 -0
- agentinputlab/data/downloader.py +235 -0
- agentinputlab/data/http.py +171 -0
- agentinputlab/data/index.py +21 -0
- agentinputlab/data/overlap.py +28 -0
- agentinputlab/data/preprocess.py +32 -0
- agentinputlab/data/storage.py +57 -0
- agentinputlab/data/trec_sample.py +427 -0
- agentinputlab/evaluation/__init__.py +5 -0
- agentinputlab/evaluation/outcomes.py +32 -0
- agentinputlab/experiments/__init__.py +278 -0
- agentinputlab/experiments/analysis.py +981 -0
- agentinputlab/experiments/artifacts.py +687 -0
- agentinputlab/experiments/automatic_measurement.py +678 -0
- agentinputlab/experiments/auxiliary_matrix.py +203 -0
- agentinputlab/experiments/bindings.py +430 -0
- agentinputlab/experiments/blueprints.py +147 -0
- agentinputlab/experiments/builders/__init__.py +45 -0
- agentinputlab/experiments/builders/executable_external_payload.py +423 -0
- agentinputlab/experiments/builders/external_process_arena.py +1018 -0
- agentinputlab/experiments/builders/registry_intervention.py +463 -0
- agentinputlab/experiments/cli.py +158 -0
- agentinputlab/experiments/controls.py +340 -0
- agentinputlab/experiments/driver_guard.py +205 -0
- agentinputlab/experiments/drivers/__init__.py +89 -0
- agentinputlab/experiments/drivers/external_arena.py +2908 -0
- agentinputlab/experiments/drivers/method_process.py +662 -0
- agentinputlab/experiments/drivers/parity_process.py +1484 -0
- agentinputlab/experiments/drivers/static_production.py +1574 -0
- agentinputlab/experiments/executor.py +448 -0
- agentinputlab/experiments/loader.py +605 -0
- agentinputlab/experiments/measurement.py +675 -0
- agentinputlab/experiments/paper_analysis.py +1818 -0
- agentinputlab/experiments/parity_identity.py +605 -0
- agentinputlab/experiments/plan.py +277 -0
- agentinputlab/experiments/production_builders.py +3739 -0
- agentinputlab/experiments/readiness.py +432 -0
- agentinputlab/experiments/schema.py +514 -0
- agentinputlab/experiments/secrets.py +177 -0
- agentinputlab/experiments/stateful_analysis.py +1738 -0
- agentinputlab/experiments/transfer_analysis.py +1316 -0
- agentinputlab/experiments/unseen_analysis.py +1025 -0
- agentinputlab/integrations/__init__.py +1 -0
- agentinputlab/integrations/action_space/__init__.py +1 -0
- agentinputlab/integrations/external_workers/__init__.py +76 -0
- agentinputlab/integrations/external_workers/ace.py +431 -0
- agentinputlab/integrations/external_workers/base.py +181 -0
- agentinputlab/integrations/external_workers/decomp_live.py +249 -0
- agentinputlab/integrations/external_workers/decomp_planner.py +30 -0
- agentinputlab/integrations/external_workers/infocqr_student.py +280 -0
- agentinputlab/integrations/external_workers/ircot.py +576 -0
- agentinputlab/integrations/external_workers/llmcompiler_live.py +360 -0
- agentinputlab/integrations/external_workers/longllmlingua.py +162 -0
- agentinputlab/integrations/external_workers/method.py +314 -0
- agentinputlab/integrations/external_workers/process.py +678 -0
- agentinputlab/integrations/external_workers/supervisor.py +1071 -0
- agentinputlab/integrations/full_architecture/__init__.py +1 -0
- agentinputlab/integrations/full_architecture/hyde.py +212 -0
- agentinputlab/integrations/full_architecture/plan_and_budget.py +188 -0
- agentinputlab/integrations/live_history.py +222 -0
- agentinputlab/integrations/prompt_optimization/__init__.py +1 -0
- agentinputlab/integrations/training/__init__.py +1 -0
- agentinputlab/metrics/__init__.py +50 -0
- agentinputlab/metrics/catalog.py +313 -0
- agentinputlab/metrics/harm.py +95 -0
- agentinputlab/metrics/paired.py +40 -0
- agentinputlab/metrics/qa.py +76 -0
- agentinputlab/metrics/text.py +33 -0
- agentinputlab/metrics/third_party.py +161 -0
- agentinputlab/models/__init__.py +4 -0
- agentinputlab/observability/__init__.py +56 -0
- agentinputlab/observability/budget.py +316 -0
- agentinputlab/observability/instrumentation.py +754 -0
- agentinputlab/observability/models.py +403 -0
- agentinputlab/observability/monitor.py +380 -0
- agentinputlab/optimizers/__init__.py +1 -0
- agentinputlab/optimizers/clarify/__init__.py +12 -0
- agentinputlab/optimizers/context/__init__.py +22 -0
- agentinputlab/optimizers/decompose/__init__.py +64 -0
- agentinputlab/optimizers/evidence/__init__.py +22 -0
- agentinputlab/optimizers/rewrite/__init__.py +30 -0
- agentinputlab/parity/__init__.py +5 -0
- agentinputlab/parity/base.py +206 -0
- agentinputlab/production_campaign.py +763 -0
- agentinputlab/py.typed +1 -0
- agentinputlab/recipes/__init__.py +333 -0
- agentinputlab/recipes/ace.py +418 -0
- agentinputlab/recipes/ace_bfcl.py +273 -0
- agentinputlab/recipes/ace_common_support.py +169 -0
- agentinputlab/recipes/ace_native_plan.py +322 -0
- agentinputlab/recipes/ace_online.py +711 -0
- agentinputlab/recipes/ace_retrieval.py +330 -0
- agentinputlab/recipes/ace_statebench.py +382 -0
- agentinputlab/recipes/ace_tau.py +463 -0
- agentinputlab/recipes/ace_toolsandbox.py +432 -0
- agentinputlab/recipes/acon_guideline.py +22 -0
- agentinputlab/recipes/adaptive_rag.py +822 -0
- agentinputlab/recipes/llmlingua2_inference.py +146 -0
- agentinputlab/recipes/llmlingua2_training.py +796 -0
- agentinputlab/recipes/mce.py +1486 -0
- agentinputlab/recipes/mce_final.py +335 -0
- agentinputlab/recipes/mce_text_fit.py +499 -0
- agentinputlab/recipes/mce_text_only.py +298 -0
- agentinputlab/recipes/qrag.py +729 -0
- agentinputlab/recipes/qrag_inference.py +364 -0
- agentinputlab/recipes/r2ag_features.py +236 -0
- agentinputlab/recipes/r2ag_inference.py +503 -0
- agentinputlab/recipes/r2ag_training.py +948 -0
- agentinputlab/recipes/recomp_abstractive.py +592 -0
- agentinputlab/recipes/recomp_extractive.py +525 -0
- agentinputlab/recipes/reformer.py +17 -0
- agentinputlab/recipes/rqrag.py +1516 -0
- agentinputlab/recipes/rqrag_common_support.py +193 -0
- agentinputlab/recipes/rqrag_completion.py +147 -0
- agentinputlab/recipes/skillopt.py +462 -0
- agentinputlab/recipes/skillopt_common_support.py +154 -0
- agentinputlab/recipes/skillopt_environment.py +165 -0
- agentinputlab/recipes/skillopt_environment_cli.py +5 -0
- agentinputlab/recipes/skillopt_retrieval.py +188 -0
- agentinputlab/recipes/smartsearch.py +897 -0
- agentinputlab/recipes/smartsearch_curriculum.py +283 -0
- agentinputlab/recipes/smartsearch_grpo_contracts.py +58 -0
- agentinputlab/recipes/smartsearch_grpo_data.py +314 -0
- agentinputlab/recipes/smartsearch_grpo_meter.py +324 -0
- agentinputlab/recipes/smartsearch_grpo_prefix.py +144 -0
- agentinputlab/recipes/smartsearch_grpo_rollout.py +119 -0
- agentinputlab/recipes/smartsearch_grpo_tools.py +364 -0
- agentinputlab/recipes/smartsearch_grpo_training.py +305 -0
- agentinputlab/recipes/smartsearch_grpo_transport.py +248 -0
- agentinputlab/recipes/smartsearch_grpo_worker.py +364 -0
- agentinputlab/recipes/smartsearch_inference.py +524 -0
- agentinputlab/recipes/smartsearch_native_data.py +172 -0
- agentinputlab/recipes/smartsearch_policy.py +616 -0
- agentinputlab/recipes/smartsearch_policy_worker.py +9 -0
- agentinputlab/recipes/smartsearch_sampling.py +232 -0
- agentinputlab/recipes/smartsearch_teacher.py +203 -0
- agentinputlab/recipes/smartsearch_training.py +265 -0
- agentinputlab/registry/__init__.py +46 -0
- agentinputlab/registry/beta.py +727 -0
- agentinputlab/registry/data/algorithms.json +1959 -0
- agentinputlab/registry/data/auxiliary_method_profiles.json +34 -0
- agentinputlab/registry/loader.py +100 -0
- agentinputlab/registry/result_manifest.py +184 -0
- agentinputlab/registry/runtime.py +195 -0
- agentinputlab/registry/schema.py +449 -0
- agentinputlab/runner/__init__.py +30 -0
- agentinputlab/runner/balance.py +248 -0
- agentinputlab/runner/cache.py +135 -0
- agentinputlab/runner/composite.py +130 -0
- agentinputlab/runner/engine.py +285 -0
- agentinputlab/runner/runtime_guard.py +268 -0
- agentinputlab/runner/worker.py +80 -0
- agentinputlab/runtime_bootstrap.py +288 -0
- agentinputlab/selectors/__init__.py +196 -0
- agentinputlab/selectors/advanced.py +1514 -0
- agentinputlab/selectors/artifacts.py +1087 -0
- agentinputlab/selectors/base.py +112 -0
- agentinputlab/selectors/campaigns.py +1893 -0
- agentinputlab/selectors/catalog.py +86 -0
- agentinputlab/selectors/discovery.py +1860 -0
- agentinputlab/selectors/evaluation.py +1348 -0
- agentinputlab/selectors/features.py +383 -0
- agentinputlab/selectors/learned.py +502 -0
- agentinputlab/selectors/no_op.py +28 -0
- agentinputlab/selectors/outcome_table.py +475 -0
- agentinputlab/selectors/producer.py +853 -0
- agentinputlab/selectors/rules.py +109 -0
- agentinputlab/selectors/runtime.py +420 -0
- agentinputlab/studies/__init__.py +16 -0
- agentinputlab/studies/design.py +165 -0
- agentinputlab/studies/paired.py +322 -0
- agentinputlab/studio/__init__.py +6 -0
- agentinputlab/studio/campaigns.py +819 -0
- agentinputlab/studio/engine.py +1408 -0
- agentinputlab/studio/model_backends.py +425 -0
- agentinputlab/studio/prepared.py +410 -0
- agentinputlab/studio/server.py +613 -0
- agentinputlab/studio/static/app.js +397 -0
- agentinputlab/studio/static/campaigns.html +175 -0
- agentinputlab/studio/static/campaigns.js +426 -0
- agentinputlab/studio/static/index.html +192 -0
- agentinputlab/studio/static/result.html +103 -0
- agentinputlab/studio/static/result.js +273 -0
- agentinputlab/studio/static/styles.css +467 -0
- agentinputlab-0.1.0a1.data/data/share/agentinputlab/CITATION.cff +22 -0
- agentinputlab-0.1.0a1.dist-info/METADATA +392 -0
- agentinputlab-0.1.0a1.dist-info/RECORD +469 -0
- agentinputlab-0.1.0a1.dist-info/WHEEL +5 -0
- agentinputlab-0.1.0a1.dist-info/entry_points.txt +6 -0
- agentinputlab-0.1.0a1.dist-info/licenses/LICENSE +21 -0
- agentinputlab-0.1.0a1.dist-info/licenses/NOTICE +31 -0
- agentinputlab-0.1.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +94 -0
- agentinputlab-0.1.0a1.dist-info/top_level.txt +2 -0
- workers/README.md +94 -0
- workers/ace/README.md +261 -0
- workers/ace/__init__.py +1 -0
- workers/ace/compatibility_manifest.json +39 -0
- workers/ace/driver.py +1682 -0
- workers/acon/README.md +215 -0
- workers/acon/__init__.py +5 -0
- workers/acon/compatibility_manifest.json +93 -0
- workers/acon/driver.py +1859 -0
- workers/acon/fitted.py +395 -0
- workers/acon/guideline.py +470 -0
- workers/acon/guideline_source_manifest.json +20 -0
- workers/adaptive_rag/README.md +96 -0
- workers/adaptive_rag/__init__.py +15 -0
- workers/adaptive_rag/compatibility_manifest.json +61 -0
- workers/adaptive_rag/driver.py +1470 -0
- workers/adaptive_rag/fixture_runtime.py +163 -0
- workers/adaptive_rag/runtime.py +252 -0
- workers/ask_or_assume/README.md +124 -0
- workers/ask_or_assume/__init__.py +1 -0
- workers/ask_or_assume/compatibility_manifest.json +36 -0
- workers/ask_or_assume/driver.py +1227 -0
- workers/decomp/README.md +133 -0
- workers/decomp/UPSTREAM_LICENSE.Apache-2.0.txt +201 -0
- workers/decomp/__init__.py +5 -0
- workers/decomp/compatibility_manifest.json +205 -0
- workers/decomp/driver.py +1015 -0
- workers/decomp/live.py +137 -0
- workers/decomp/runtime.py +231 -0
- workers/infocqr/README.md +106 -0
- workers/infocqr/__init__.py +1 -0
- workers/infocqr/compatibility_manifest.json +84 -0
- workers/infocqr/driver.py +1766 -0
- workers/ircot/README.md +167 -0
- workers/ircot/__init__.py +7 -0
- workers/ircot/compatibility_manifest.json +121 -0
- workers/ircot/controlled.py +457 -0
- workers/ircot/driver.py +1373 -0
- workers/ircot/fixture_bindings.json +39 -0
- workers/ircot/fixture_config.json +48 -0
- workers/ircot/fixture_prompt.txt +2 -0
- workers/ircot/native_qa.py +398 -0
- workers/ircot/qa_compatibility_manifest.json +57 -0
- workers/ircot/runtime.py +97 -0
- workers/llmcompiler/README.md +160 -0
- workers/llmcompiler/__init__.py +1 -0
- workers/llmcompiler/compatibility_manifest.json +45 -0
- workers/llmcompiler/driver.py +1514 -0
- workers/llmcompiler/export_prompts.py +74 -0
- workers/llmcompiler/live.py +174 -0
- workers/llmcompiler/patch_manifest.json +147 -0
- workers/mce/README.md +198 -0
- workers/mce/__init__.py +29 -0
- workers/mce/compatibility_manifest.json +115 -0
- workers/mce/driver.py +2585 -0
- workers/mce/final_eval.py +173 -0
- workers/official_arenas/README.md +25 -0
- workers/official_arenas/__init__.py +1 -0
- workers/official_arenas/capture_records.py +110 -0
- workers/official_arenas/driver.py +619 -0
- workers/official_arenas/protocol.py +334 -0
- workers/official_arenas/providers/__init__.py +1 -0
- workers/official_arenas/providers/_live_history.py +228 -0
- workers/official_arenas/providers/_message_compat.py +77 -0
- workers/official_arenas/providers/appworld_ul.py +196 -0
- workers/official_arenas/providers/fixture.py +112 -0
- workers/official_arenas/providers/statebench.py +960 -0
- workers/official_arenas/providers/tau3.py +1672 -0
- workers/official_arenas/providers/tau_retail.py +586 -0
- workers/official_arenas/providers/toolsandbox.py +1321 -0
- workers/official_arenas/providers/tooltalk.py +699 -0
- workers/official_arenas/retail_capture.py +188 -0
- workers/official_arenas/retail_driver.py +275 -0
- workers/qrag/README.md +172 -0
- workers/qrag/__init__.py +1 -0
- workers/qrag/compatibility_manifest.json +64 -0
- workers/qrag/driver.py +673 -0
- workers/r2ag/README.md +154 -0
- workers/r2ag/__init__.py +5 -0
- workers/r2ag/compatibility_manifest.json +55 -0
- workers/r2ag/driver.py +1287 -0
- workers/r2ag/feature_schema.json +8 -0
- workers/r2ag/runtime.py +589 -0
- workers/recomp/README.md +120 -0
- workers/recomp/__init__.py +1 -0
- workers/recomp/compatibility_manifest.json +43 -0
- workers/recomp/driver.py +1653 -0
- workers/reformer/README.md +125 -0
- workers/reformer/__init__.py +1 -0
- workers/reformer/compatibility_manifest.json +68 -0
- workers/reformer/driver.py +1459 -0
- workers/reformer/induction.py +457 -0
- workers/rrr/README.md +126 -0
- workers/rrr/__init__.py +1 -0
- workers/rrr/compatibility_manifest.json +57 -0
- workers/rrr/driver.py +1133 -0
- workers/smartsearch/README.md +331 -0
- workers/smartsearch/__init__.py +1 -0
- workers/smartsearch/compatibility_manifest.json +41 -0
- workers/smartsearch/driver.py +1643 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Pre- and post-run dependency balance auditing."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from agentinputlab.contracts.dependency import DependencyBinding
|
|
11
|
+
from agentinputlab.contracts.enums import ProfileKind
|
|
12
|
+
from agentinputlab.contracts.errors import BalanceError, ValidationError
|
|
13
|
+
from agentinputlab.contracts.lifecycle import InterventionContext
|
|
14
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
15
|
+
|
|
16
|
+
_RUNTIME_COMPONENT_SLOTS = (
|
|
17
|
+
"backend",
|
|
18
|
+
"dense_embedder",
|
|
19
|
+
"retriever",
|
|
20
|
+
"vector_searcher",
|
|
21
|
+
"tools",
|
|
22
|
+
"external_runtime",
|
|
23
|
+
"artifact_manager",
|
|
24
|
+
)
|
|
25
|
+
_HASH_PATTERN = re.compile(r"[0-9a-f]{64}")
|
|
26
|
+
_RESERVED_FINGERPRINT_SLOTS = frozenset(
|
|
27
|
+
(
|
|
28
|
+
*_RUNTIME_COMPONENT_SLOTS,
|
|
29
|
+
"seed",
|
|
30
|
+
"pricing_catalog",
|
|
31
|
+
"intent_contract",
|
|
32
|
+
"strict_intent",
|
|
33
|
+
"run_config",
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True, slots=True)
|
|
39
|
+
class ComparisonProfile:
|
|
40
|
+
profile_id: str
|
|
41
|
+
kind: ProfileKind
|
|
42
|
+
required_slots: tuple[str, ...]
|
|
43
|
+
varied_slots: tuple[str, ...] = ()
|
|
44
|
+
seed_policy: str = "fixed"
|
|
45
|
+
cache_policy: str = "frozen"
|
|
46
|
+
|
|
47
|
+
def __post_init__(self) -> None:
|
|
48
|
+
if set(self.required_slots) & set(self.varied_slots):
|
|
49
|
+
raise ValidationError("a slot cannot be both required-common and varied")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True, slots=True)
|
|
53
|
+
class ComparisonArm:
|
|
54
|
+
arm_id: str
|
|
55
|
+
release_id: str
|
|
56
|
+
bindings: tuple[DependencyBinding, ...]
|
|
57
|
+
|
|
58
|
+
def binding_map(self) -> dict[str, DependencyBinding]:
|
|
59
|
+
mapping = {binding.slot: binding for binding in self.bindings}
|
|
60
|
+
if len(mapping) != len(self.bindings):
|
|
61
|
+
raise ValidationError(f"arm {self.arm_id} contains duplicate dependency slots")
|
|
62
|
+
return mapping
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(frozen=True, slots=True)
|
|
66
|
+
class BalanceReport:
|
|
67
|
+
eligible: bool
|
|
68
|
+
differences: tuple[str, ...]
|
|
69
|
+
missing: tuple[str, ...]
|
|
70
|
+
|
|
71
|
+
def require_eligible(self) -> None:
|
|
72
|
+
if not self.eligible:
|
|
73
|
+
details = "; ".join((*self.missing, *self.differences))
|
|
74
|
+
raise BalanceError(f"comparison is not balanced: {details}")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class BalanceAuditor:
|
|
78
|
+
"""Compare resolved dependency hashes, never human-readable aliases."""
|
|
79
|
+
|
|
80
|
+
def audit(
|
|
81
|
+
self,
|
|
82
|
+
profile: ComparisonProfile,
|
|
83
|
+
arms: tuple[ComparisonArm, ...],
|
|
84
|
+
*,
|
|
85
|
+
runtime_fingerprints: Mapping[str, Mapping[str, str]] | None = None,
|
|
86
|
+
) -> BalanceReport:
|
|
87
|
+
if len(arms) < 2:
|
|
88
|
+
raise ValidationError("balance audit requires at least two arms")
|
|
89
|
+
if len({arm.arm_id for arm in arms}) != len(arms):
|
|
90
|
+
raise ValidationError("balance audit requires unique arm IDs")
|
|
91
|
+
maps = {arm.arm_id: arm.binding_map() for arm in arms}
|
|
92
|
+
missing: list[str] = []
|
|
93
|
+
differences: list[str] = []
|
|
94
|
+
|
|
95
|
+
for slot in profile.required_slots:
|
|
96
|
+
absent = [arm.arm_id for arm in arms if slot not in maps[arm.arm_id]]
|
|
97
|
+
if absent:
|
|
98
|
+
missing.append(f"{slot} missing in {','.join(absent)}")
|
|
99
|
+
continue
|
|
100
|
+
hashes = {maps[arm.arm_id][slot].resolved_hash for arm in arms}
|
|
101
|
+
if len(hashes) != 1:
|
|
102
|
+
differences.append(f"{slot} differs across arms")
|
|
103
|
+
|
|
104
|
+
for slot in profile.varied_slots:
|
|
105
|
+
absent = [arm.arm_id for arm in arms if slot not in maps[arm.arm_id]]
|
|
106
|
+
if absent:
|
|
107
|
+
missing.append(f"{slot} missing in {','.join(absent)}")
|
|
108
|
+
|
|
109
|
+
all_slots = set().union(*(set(mapping) for mapping in maps.values()))
|
|
110
|
+
undeclared = all_slots - set(profile.required_slots) - set(profile.varied_slots)
|
|
111
|
+
for slot in sorted(undeclared):
|
|
112
|
+
present = [maps[arm.arm_id].get(slot) for arm in arms]
|
|
113
|
+
if None in present:
|
|
114
|
+
differences.append(f"{slot} is an undeclared asymmetric dependency")
|
|
115
|
+
continue
|
|
116
|
+
hashes = {binding.resolved_hash for binding in present if binding is not None}
|
|
117
|
+
if len(hashes) > 1:
|
|
118
|
+
differences.append(f"{slot} varies but is not declared crossed")
|
|
119
|
+
|
|
120
|
+
if runtime_fingerprints is not None:
|
|
121
|
+
arm_ids = {arm.arm_id for arm in arms}
|
|
122
|
+
if set(runtime_fingerprints) != arm_ids:
|
|
123
|
+
raise ValidationError("runtime fingerprints must be present for every arm")
|
|
124
|
+
for arm_id, fingerprints in runtime_fingerprints.items():
|
|
125
|
+
if not isinstance(fingerprints, Mapping):
|
|
126
|
+
raise ValidationError(f"runtime fingerprints for {arm_id} must be a mapping")
|
|
127
|
+
for slot, fingerprint in fingerprints.items():
|
|
128
|
+
if not isinstance(slot, str) or not slot:
|
|
129
|
+
raise ValidationError("runtime fingerprint slots must be non-empty strings")
|
|
130
|
+
if not isinstance(fingerprint, str) or not _HASH_PATTERN.fullmatch(fingerprint):
|
|
131
|
+
raise ValidationError(
|
|
132
|
+
f"runtime fingerprint {arm_id}.{slot} must be a SHA-256 hex string"
|
|
133
|
+
)
|
|
134
|
+
observed_slots = set().union(*(set(runtime_fingerprints[arm_id]) for arm_id in arm_ids))
|
|
135
|
+
for slot in profile.required_slots:
|
|
136
|
+
if slot not in _RUNTIME_COMPONENT_SLOTS and slot not in observed_slots:
|
|
137
|
+
continue
|
|
138
|
+
absent = [
|
|
139
|
+
arm.arm_id for arm in arms if slot not in runtime_fingerprints[arm.arm_id]
|
|
140
|
+
]
|
|
141
|
+
if absent:
|
|
142
|
+
_append_unique(missing, f"{slot} runtime missing in {','.join(absent)}")
|
|
143
|
+
continue
|
|
144
|
+
hashes = {runtime_fingerprints[arm.arm_id][slot] for arm in arms}
|
|
145
|
+
if len(hashes) != 1:
|
|
146
|
+
_append_unique(differences, f"{slot} runtime differs across arms")
|
|
147
|
+
|
|
148
|
+
for slot in profile.varied_slots:
|
|
149
|
+
if slot not in _RUNTIME_COMPONENT_SLOTS and slot not in observed_slots:
|
|
150
|
+
continue
|
|
151
|
+
absent = [
|
|
152
|
+
arm.arm_id for arm in arms if slot not in runtime_fingerprints[arm.arm_id]
|
|
153
|
+
]
|
|
154
|
+
if absent:
|
|
155
|
+
_append_unique(missing, f"{slot} runtime missing in {','.join(absent)}")
|
|
156
|
+
|
|
157
|
+
for slot in sorted(observed_slots):
|
|
158
|
+
present = [runtime_fingerprints[arm.arm_id].get(slot) for arm in arms]
|
|
159
|
+
if slot == "seed":
|
|
160
|
+
if profile.seed_policy == "fixed" and len(set(present)) != 1:
|
|
161
|
+
_append_unique(differences, "seed runtime differs across arms")
|
|
162
|
+
continue
|
|
163
|
+
if slot in profile.required_slots or slot in profile.varied_slots:
|
|
164
|
+
continue
|
|
165
|
+
if None in present:
|
|
166
|
+
_append_unique(
|
|
167
|
+
differences,
|
|
168
|
+
f"{slot} is an undeclared asymmetric runtime dependency",
|
|
169
|
+
)
|
|
170
|
+
elif len(set(present)) > 1:
|
|
171
|
+
_append_unique(
|
|
172
|
+
differences,
|
|
173
|
+
f"{slot} runtime varies but is not declared crossed",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
return BalanceReport(
|
|
177
|
+
eligible=not missing and not differences,
|
|
178
|
+
differences=tuple(differences),
|
|
179
|
+
missing=tuple(missing),
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def context_dependency_fingerprints(context: InterventionContext) -> dict[str, str]:
|
|
184
|
+
"""Derive hashes from the objects that will actually execute an arm."""
|
|
185
|
+
|
|
186
|
+
observed: dict[str, str] = {"seed": content_hash(context.seed)}
|
|
187
|
+
for slot in _RUNTIME_COMPONENT_SLOTS:
|
|
188
|
+
dependency = getattr(context, slot)
|
|
189
|
+
if dependency is None:
|
|
190
|
+
continue
|
|
191
|
+
fingerprint = getattr(dependency, "fingerprint", None)
|
|
192
|
+
if not callable(fingerprint):
|
|
193
|
+
raise ValidationError(f"runtime {slot} does not expose fingerprint()")
|
|
194
|
+
identity = fingerprint()
|
|
195
|
+
if not isinstance(identity, Mapping) or not identity:
|
|
196
|
+
raise ValidationError(f"runtime {slot} fingerprint must be a non-empty mapping")
|
|
197
|
+
observed[slot] = _canonical_fingerprint_hash(identity, label=f"runtime {slot} fingerprint")
|
|
198
|
+
|
|
199
|
+
if context.pricing_catalog is not None:
|
|
200
|
+
observed["pricing_catalog"] = content_hash(context.pricing_catalog)
|
|
201
|
+
if context.intent_contract is not None:
|
|
202
|
+
observed["intent_contract"] = content_hash(context.intent_contract)
|
|
203
|
+
observed["strict_intent"] = content_hash(context.strict_intent)
|
|
204
|
+
|
|
205
|
+
declared = context.run_config.get("dependency_fingerprints", {})
|
|
206
|
+
if not isinstance(declared, Mapping):
|
|
207
|
+
raise ValidationError("dependency_fingerprints must be a mapping")
|
|
208
|
+
for slot, identity in declared.items():
|
|
209
|
+
if slot in _RESERVED_FINGERPRINT_SLOTS:
|
|
210
|
+
raise ValidationError(
|
|
211
|
+
f"reserved dependency slot must come from its actual context field: {slot}"
|
|
212
|
+
)
|
|
213
|
+
if slot in observed:
|
|
214
|
+
raise ValidationError(f"runtime dependency slot is reserved or duplicated: {slot}")
|
|
215
|
+
if not isinstance(slot, str) or not slot:
|
|
216
|
+
raise ValidationError("declared dependency slots must be non-empty strings")
|
|
217
|
+
if not isinstance(identity, Mapping) or not identity:
|
|
218
|
+
raise ValidationError(
|
|
219
|
+
f"declared dependency identity for {slot} must be a non-empty mapping"
|
|
220
|
+
)
|
|
221
|
+
observed[slot] = _canonical_fingerprint_hash(
|
|
222
|
+
identity,
|
|
223
|
+
label=f"declared dependency identity for {slot}",
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
remaining_config: dict[str, Any] = {
|
|
227
|
+
key: value for key, value in context.run_config.items() if key != "dependency_fingerprints"
|
|
228
|
+
}
|
|
229
|
+
if remaining_config:
|
|
230
|
+
observed["run_config"] = content_hash(remaining_config)
|
|
231
|
+
return observed
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _append_unique(values: list[str], message: str) -> None:
|
|
235
|
+
if message not in values:
|
|
236
|
+
values.append(message)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def _canonical_fingerprint_hash(identity: Mapping[str, Any], *, label: str) -> str:
|
|
240
|
+
try:
|
|
241
|
+
normalized = freeze_mapping(identity)
|
|
242
|
+
if not normalized:
|
|
243
|
+
raise ValidationError(f"{label} must be a non-empty mapping")
|
|
244
|
+
return content_hash(normalized)
|
|
245
|
+
except ValidationError:
|
|
246
|
+
raise
|
|
247
|
+
except (TypeError, ValueError) as exc:
|
|
248
|
+
raise ValidationError(f"{label} must be canonically serializable: {exc}") from exc
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""Run cache identities include every declared scientific dependency."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from agentinputlab.contracts.errors import ValidationError
|
|
10
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
11
|
+
from agentinputlab.contracts.state import FrozenAgentState
|
|
12
|
+
|
|
13
|
+
_HASH_PATTERN = re.compile(r"[0-9a-f]{64}")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def run_cache_key(
|
|
17
|
+
*,
|
|
18
|
+
state: FrozenAgentState,
|
|
19
|
+
release_id: str,
|
|
20
|
+
profile_id: str,
|
|
21
|
+
seed: int,
|
|
22
|
+
dependency_hashes: Mapping[str, str] | None = None,
|
|
23
|
+
backend_fingerprint: Mapping[str, Any] | None = None,
|
|
24
|
+
retriever_fingerprint: Mapping[str, Any] | None = None,
|
|
25
|
+
prompt_hash: str = "",
|
|
26
|
+
extra: Mapping[str, Any] | None = None,
|
|
27
|
+
) -> str:
|
|
28
|
+
"""Return a v2 cache identity over all declared execution dependencies.
|
|
29
|
+
|
|
30
|
+
``dependency_hashes`` accepts the output of
|
|
31
|
+
:func:`context_dependency_fingerprints` directly. The legacy backend and
|
|
32
|
+
retriever fingerprint mappings remain supported during the alpha API, but
|
|
33
|
+
a slot may not be supplied through both interfaces.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
if isinstance(seed, bool) or not isinstance(seed, int) or seed < 0:
|
|
37
|
+
raise ValidationError("cache seed must be a non-negative integer")
|
|
38
|
+
|
|
39
|
+
normalized = _normalize_dependency_hashes(dependency_hashes, seed=seed)
|
|
40
|
+
for slot, fingerprint in (
|
|
41
|
+
("backend", backend_fingerprint),
|
|
42
|
+
("retriever", retriever_fingerprint),
|
|
43
|
+
):
|
|
44
|
+
if fingerprint is None:
|
|
45
|
+
continue
|
|
46
|
+
if slot in normalized:
|
|
47
|
+
raise ValidationError(
|
|
48
|
+
f"dependency slot supplied through both dependency_hashes and legacy API: {slot}"
|
|
49
|
+
)
|
|
50
|
+
if not isinstance(fingerprint, Mapping):
|
|
51
|
+
raise ValidationError(f"legacy {slot} fingerprint must be a mapping")
|
|
52
|
+
normalized[slot] = _canonical_mapping_hash(
|
|
53
|
+
fingerprint,
|
|
54
|
+
label=f"legacy {slot} fingerprint",
|
|
55
|
+
require_non_empty=True,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
normalized_extra = _normalize_extra(extra)
|
|
59
|
+
|
|
60
|
+
return content_hash(
|
|
61
|
+
{
|
|
62
|
+
"schema": "agentinputlab-run-cache-v2",
|
|
63
|
+
"state_hash": state.state_hash,
|
|
64
|
+
"release_id": release_id,
|
|
65
|
+
"profile_id": profile_id,
|
|
66
|
+
"dependency_hashes": dict(sorted(normalized.items())),
|
|
67
|
+
"seed": seed,
|
|
68
|
+
"prompt_hash": prompt_hash,
|
|
69
|
+
"extra": dict(normalized_extra),
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _normalize_dependency_hashes(
|
|
75
|
+
dependency_hashes: Mapping[str, str] | None,
|
|
76
|
+
*,
|
|
77
|
+
seed: int,
|
|
78
|
+
) -> dict[str, str]:
|
|
79
|
+
if dependency_hashes is None:
|
|
80
|
+
return {}
|
|
81
|
+
if not isinstance(dependency_hashes, Mapping):
|
|
82
|
+
raise ValidationError("dependency_hashes must be a mapping")
|
|
83
|
+
|
|
84
|
+
normalized: dict[str, str] = {}
|
|
85
|
+
for slot, fingerprint in dependency_hashes.items():
|
|
86
|
+
if not isinstance(slot, str) or not slot or slot != slot.strip():
|
|
87
|
+
raise ValidationError(
|
|
88
|
+
"dependency hash slots must be non-empty strings without surrounding whitespace"
|
|
89
|
+
)
|
|
90
|
+
if slot in normalized:
|
|
91
|
+
raise ValidationError(f"duplicate dependency hash slot: {slot}")
|
|
92
|
+
if not isinstance(fingerprint, str) or not _HASH_PATTERN.fullmatch(fingerprint):
|
|
93
|
+
raise ValidationError(f"dependency hash {slot} must be a SHA-256 hex string")
|
|
94
|
+
normalized[slot] = fingerprint
|
|
95
|
+
|
|
96
|
+
# The context helper treats seed like any other runtime dependency, while
|
|
97
|
+
# the cache schema stores its value explicitly. Accept the derived hash as
|
|
98
|
+
# a consistency assertion, then remove it so omission cannot create a
|
|
99
|
+
# second key for the same seed.
|
|
100
|
+
supplied_seed_hash = normalized.pop("seed", None)
|
|
101
|
+
if supplied_seed_hash is not None and supplied_seed_hash != content_hash(seed):
|
|
102
|
+
raise ValidationError("dependency seed hash does not match the explicit cache seed")
|
|
103
|
+
return normalized
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _normalize_extra(extra: Mapping[str, Any] | None) -> Mapping[str, Any]:
|
|
107
|
+
if extra is None:
|
|
108
|
+
return freeze_mapping(None)
|
|
109
|
+
if not isinstance(extra, Mapping):
|
|
110
|
+
raise ValidationError("cache extra must be a mapping or None")
|
|
111
|
+
try:
|
|
112
|
+
normalized = freeze_mapping(extra)
|
|
113
|
+
# ``deep_freeze_jsonable`` rejects unsupported values, while canonical
|
|
114
|
+
# serialization additionally rejects non-finite floats.
|
|
115
|
+
content_hash(normalized)
|
|
116
|
+
except (TypeError, ValueError) as exc:
|
|
117
|
+
raise ValidationError(f"cache extra must be canonically serializable: {exc}") from exc
|
|
118
|
+
return normalized
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _canonical_mapping_hash(
|
|
122
|
+
value: Mapping[str, Any],
|
|
123
|
+
*,
|
|
124
|
+
label: str,
|
|
125
|
+
require_non_empty: bool,
|
|
126
|
+
) -> str:
|
|
127
|
+
try:
|
|
128
|
+
normalized = freeze_mapping(value)
|
|
129
|
+
if require_non_empty and not normalized:
|
|
130
|
+
raise ValidationError(f"{label} must be a non-empty mapping")
|
|
131
|
+
return content_hash(normalized)
|
|
132
|
+
except ValidationError:
|
|
133
|
+
raise
|
|
134
|
+
except (TypeError, ValueError) as exc:
|
|
135
|
+
raise ValidationError(f"{label} must be canonically serializable: {exc}") from exc
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Observed runner for full agent/search architectures."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
from agentinputlab.contracts import (
|
|
8
|
+
AlgorithmOutputError,
|
|
9
|
+
BudgetExceededError,
|
|
10
|
+
CompositeIntervention,
|
|
11
|
+
CompositeResult,
|
|
12
|
+
FrozenAgentState,
|
|
13
|
+
InterventionContext,
|
|
14
|
+
)
|
|
15
|
+
from agentinputlab.observability import (
|
|
16
|
+
BudgetLedger,
|
|
17
|
+
EventKind,
|
|
18
|
+
ObservedRunStatus,
|
|
19
|
+
PricingCatalog,
|
|
20
|
+
ResourceUsage,
|
|
21
|
+
RunMonitor,
|
|
22
|
+
instrument_context,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
from .engine import InterventionRunner, _reject_hidden_runtime_dependencies
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True, slots=True)
|
|
29
|
+
class CompositeRunRecord:
|
|
30
|
+
"""Observed terminal record for a composite architecture."""
|
|
31
|
+
|
|
32
|
+
release_id: str
|
|
33
|
+
input_state_hash: str
|
|
34
|
+
result: CompositeResult
|
|
35
|
+
monitor_run_id: str = ""
|
|
36
|
+
duration_ms: float | None = None
|
|
37
|
+
usage: ResourceUsage = field(default_factory=ResourceUsage)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CompositeInterventionRunner:
|
|
41
|
+
"""Run a composite profile with the same accounting guarantees as patches."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, *, monitor: RunMonitor | None = None) -> None:
|
|
44
|
+
self.monitor = monitor or RunMonitor()
|
|
45
|
+
|
|
46
|
+
def run(
|
|
47
|
+
self,
|
|
48
|
+
intervention: CompositeIntervention,
|
|
49
|
+
state: FrozenAgentState,
|
|
50
|
+
context: InterventionContext,
|
|
51
|
+
) -> CompositeRunRecord:
|
|
52
|
+
_reject_hidden_runtime_dependencies(intervention)
|
|
53
|
+
monitor = context.monitor or self.monitor
|
|
54
|
+
if not isinstance(monitor, RunMonitor):
|
|
55
|
+
raise TypeError("context.monitor must be a RunMonitor")
|
|
56
|
+
with monitor.run_scope(
|
|
57
|
+
release_id=intervention.release_id,
|
|
58
|
+
state_hash=state.state_hash,
|
|
59
|
+
tags={
|
|
60
|
+
"method_id": intervention.method_id,
|
|
61
|
+
"family": intervention.family.value,
|
|
62
|
+
"execution_kind": "composite",
|
|
63
|
+
},
|
|
64
|
+
) as run_id:
|
|
65
|
+
pricing = context.pricing_catalog
|
|
66
|
+
if pricing is not None and not isinstance(pricing, PricingCatalog):
|
|
67
|
+
raise TypeError("context.pricing_catalog must be a PricingCatalog")
|
|
68
|
+
runtime_context = instrument_context(
|
|
69
|
+
context,
|
|
70
|
+
state,
|
|
71
|
+
monitor,
|
|
72
|
+
run_id=run_id,
|
|
73
|
+
pricing=pricing,
|
|
74
|
+
)
|
|
75
|
+
ledger = runtime_context.budget_ledger
|
|
76
|
+
if not isinstance(ledger, BudgetLedger): # pragma: no cover - helper invariant
|
|
77
|
+
raise TypeError("instrumented context did not produce a BudgetLedger")
|
|
78
|
+
monitor.emit(EventKind.STAGE_STARTED, component="composite_intervention")
|
|
79
|
+
try:
|
|
80
|
+
result = intervention.run(state, runtime_context)
|
|
81
|
+
self._validate_result(intervention, state, result)
|
|
82
|
+
InterventionRunner._reconcile_trace_usage(result, ledger, monitor)
|
|
83
|
+
ledger.require_within_budget()
|
|
84
|
+
except BudgetExceededError as exc:
|
|
85
|
+
monitor.record_failure(
|
|
86
|
+
exc,
|
|
87
|
+
category="budget_exhausted",
|
|
88
|
+
stage="composite_intervention",
|
|
89
|
+
)
|
|
90
|
+
monitor.finish_run(ObservedRunStatus.BUDGET_EXHAUSTED, run_id=run_id)
|
|
91
|
+
raise
|
|
92
|
+
|
|
93
|
+
monitor.emit(
|
|
94
|
+
EventKind.STAGE_FINISHED,
|
|
95
|
+
component="composite_intervention",
|
|
96
|
+
payload={"status": "success", "result_hash": result.result_hash},
|
|
97
|
+
)
|
|
98
|
+
snapshot = monitor.finish_run(
|
|
99
|
+
ObservedRunStatus.SUCCEEDED,
|
|
100
|
+
run_id=run_id,
|
|
101
|
+
payload={"outcome": "success"},
|
|
102
|
+
)
|
|
103
|
+
return CompositeRunRecord(
|
|
104
|
+
release_id=intervention.release_id,
|
|
105
|
+
input_state_hash=state.state_hash,
|
|
106
|
+
result=result,
|
|
107
|
+
monitor_run_id=run_id,
|
|
108
|
+
duration_ms=snapshot.duration_ms,
|
|
109
|
+
usage=snapshot.usage,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def _validate_result(
|
|
114
|
+
intervention: CompositeIntervention,
|
|
115
|
+
state: FrozenAgentState,
|
|
116
|
+
result: object,
|
|
117
|
+
) -> None:
|
|
118
|
+
if not isinstance(result, CompositeResult):
|
|
119
|
+
raise AlgorithmOutputError(
|
|
120
|
+
f"composite intervention must return a CompositeResult; got {type(result).__name__}"
|
|
121
|
+
)
|
|
122
|
+
if result.method_id != intervention.method_id:
|
|
123
|
+
raise AlgorithmOutputError("composite returned a result for another method")
|
|
124
|
+
if result.release_id != intervention.release_id:
|
|
125
|
+
raise AlgorithmOutputError("composite returned a result for another release")
|
|
126
|
+
if result.source_state_hash != state.state_hash:
|
|
127
|
+
raise AlgorithmOutputError("composite result source_state_hash mismatch")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
__all__ = ["CompositeInterventionRunner", "CompositeRunRecord"]
|