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,165 @@
|
|
|
1
|
+
"""Deterministic native, controlled, and factorial experiment planning."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import itertools
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from agentinputlab.contracts.dependency import DependencyBinding, DependencyRole
|
|
11
|
+
from agentinputlab.contracts.enums import ProfileKind
|
|
12
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
13
|
+
from agentinputlab.runner.balance import BalanceAuditor, ComparisonArm, ComparisonProfile
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class StudyArmSpec:
|
|
18
|
+
arm_id: str
|
|
19
|
+
release_id: str
|
|
20
|
+
bindings: tuple[DependencyBinding, ...]
|
|
21
|
+
parameters: Mapping[str, Any] = field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
def __post_init__(self) -> None:
|
|
24
|
+
object.__setattr__(self, "bindings", tuple(self.bindings))
|
|
25
|
+
object.__setattr__(self, "parameters", freeze_mapping(self.parameters))
|
|
26
|
+
ComparisonArm(self.arm_id, self.release_id, self.bindings).binding_map()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True, slots=True)
|
|
30
|
+
class StudyCell:
|
|
31
|
+
benchmark_id: str
|
|
32
|
+
example_id: str
|
|
33
|
+
seed: int
|
|
34
|
+
profile_id: str
|
|
35
|
+
arms: tuple[StudyArmSpec, ...]
|
|
36
|
+
|
|
37
|
+
def __post_init__(self) -> None:
|
|
38
|
+
object.__setattr__(self, "arms", tuple(self.arms))
|
|
39
|
+
if not self.benchmark_id or not self.example_id:
|
|
40
|
+
raise ValueError("study cell requires benchmark and example IDs")
|
|
41
|
+
if isinstance(self.seed, bool) or not isinstance(self.seed, int):
|
|
42
|
+
raise ValueError("study cell seed must be an integer")
|
|
43
|
+
if len(self.arms) < 2:
|
|
44
|
+
raise ValueError("study cell requires at least two comparison arms")
|
|
45
|
+
if len({arm.arm_id for arm in self.arms}) != len(self.arms):
|
|
46
|
+
raise ValueError("study cell arm IDs must be unique")
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def cell_id(self) -> str:
|
|
50
|
+
return content_hash(self)[:20]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True, slots=True)
|
|
54
|
+
class StudyPlan:
|
|
55
|
+
study_id: str
|
|
56
|
+
profile: ComparisonProfile
|
|
57
|
+
cells: tuple[StudyCell, ...]
|
|
58
|
+
metadata: Mapping[str, Any] = field(default_factory=dict)
|
|
59
|
+
|
|
60
|
+
def __post_init__(self) -> None:
|
|
61
|
+
object.__setattr__(self, "cells", tuple(self.cells))
|
|
62
|
+
object.__setattr__(self, "metadata", freeze_mapping(self.metadata))
|
|
63
|
+
if not self.study_id or not self.cells:
|
|
64
|
+
raise ValueError("study plan requires an ID and at least one cell")
|
|
65
|
+
if any(cell.profile_id != self.profile.profile_id for cell in self.cells):
|
|
66
|
+
raise ValueError("study cells must reference the plan comparison profile")
|
|
67
|
+
if len({cell.cell_id for cell in self.cells}) != len(self.cells):
|
|
68
|
+
raise ValueError("study plan contains duplicate cells")
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def plan_hash(self) -> str:
|
|
72
|
+
return content_hash(self)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def build_study_plan(
|
|
76
|
+
*,
|
|
77
|
+
study_id: str,
|
|
78
|
+
profile: ComparisonProfile,
|
|
79
|
+
benchmark_id: str,
|
|
80
|
+
example_ids: Sequence[str],
|
|
81
|
+
seeds: Sequence[int],
|
|
82
|
+
arms: Sequence[StudyArmSpec],
|
|
83
|
+
factorial_levels: Mapping[str, Sequence[DependencyBinding]] | None = None,
|
|
84
|
+
metadata: Mapping[str, Any] | None = None,
|
|
85
|
+
) -> StudyPlan:
|
|
86
|
+
"""Expand a frozen manifest without executing or silently dropping cells."""
|
|
87
|
+
|
|
88
|
+
examples = tuple(example_ids)
|
|
89
|
+
seed_values = tuple(seeds)
|
|
90
|
+
base_arms = tuple(arms)
|
|
91
|
+
if not examples or not seed_values or not base_arms:
|
|
92
|
+
raise ValueError("study expansion requires examples, seeds, and arms")
|
|
93
|
+
if len(set(examples)) != len(examples):
|
|
94
|
+
raise ValueError("example IDs must be unique")
|
|
95
|
+
if len(set(seed_values)) != len(seed_values):
|
|
96
|
+
raise ValueError("seeds must be unique")
|
|
97
|
+
levels = factorial_levels or {}
|
|
98
|
+
if levels and profile.kind is not ProfileKind.FACTORIAL_ADAPTER:
|
|
99
|
+
raise ValueError("factorial levels require a factorial comparison profile")
|
|
100
|
+
if profile.kind is ProfileKind.FACTORIAL_ADAPTER and set(levels) != set(profile.varied_slots):
|
|
101
|
+
raise ValueError("factorial level slots must exactly match profile.varied_slots")
|
|
102
|
+
expanded_arms = _expand_arms(base_arms, levels)
|
|
103
|
+
if profile.kind is not ProfileKind.OFFICIAL_NATIVE:
|
|
104
|
+
BalanceAuditor().audit(
|
|
105
|
+
profile,
|
|
106
|
+
tuple(ComparisonArm(arm.arm_id, arm.release_id, arm.bindings) for arm in expanded_arms),
|
|
107
|
+
).require_eligible()
|
|
108
|
+
cells = tuple(
|
|
109
|
+
StudyCell(
|
|
110
|
+
benchmark_id=benchmark_id,
|
|
111
|
+
example_id=example_id,
|
|
112
|
+
seed=seed,
|
|
113
|
+
profile_id=profile.profile_id,
|
|
114
|
+
arms=expanded_arms,
|
|
115
|
+
)
|
|
116
|
+
for example_id in examples
|
|
117
|
+
for seed in seed_values
|
|
118
|
+
)
|
|
119
|
+
return StudyPlan(
|
|
120
|
+
study_id=study_id,
|
|
121
|
+
profile=profile,
|
|
122
|
+
cells=cells,
|
|
123
|
+
metadata=metadata or {},
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _expand_arms(
|
|
128
|
+
arms: tuple[StudyArmSpec, ...],
|
|
129
|
+
levels: Mapping[str, Sequence[DependencyBinding]],
|
|
130
|
+
) -> tuple[StudyArmSpec, ...]:
|
|
131
|
+
if not levels:
|
|
132
|
+
return arms
|
|
133
|
+
slot_names = tuple(sorted(levels))
|
|
134
|
+
choices = tuple(tuple(levels[slot]) for slot in slot_names)
|
|
135
|
+
if any(not values for values in choices):
|
|
136
|
+
raise ValueError("each factorial slot requires at least one dependency level")
|
|
137
|
+
for slot, values in zip(slot_names, choices, strict=True):
|
|
138
|
+
if any(binding.slot != slot for binding in values):
|
|
139
|
+
raise ValueError(f"factorial bindings for {slot} must use that slot name")
|
|
140
|
+
if any(binding.role is not DependencyRole.CROSSED for binding in values):
|
|
141
|
+
raise ValueError(f"factorial bindings for {slot} must have role='crossed'")
|
|
142
|
+
expanded: list[StudyArmSpec] = []
|
|
143
|
+
for arm in arms:
|
|
144
|
+
base = {binding.slot: binding for binding in arm.bindings}
|
|
145
|
+
overlap = set(base) & set(slot_names)
|
|
146
|
+
if overlap:
|
|
147
|
+
joined = ", ".join(sorted(overlap))
|
|
148
|
+
raise ValueError(
|
|
149
|
+
f"factorial slots cannot silently replace base-arm dependencies: {joined}"
|
|
150
|
+
)
|
|
151
|
+
for combination in itertools.product(*choices):
|
|
152
|
+
bindings = dict(base)
|
|
153
|
+
bindings.update({binding.slot: binding for binding in combination})
|
|
154
|
+
suffix = ".".join(
|
|
155
|
+
f"{binding.slot}={binding.resolved_hash[:8]}" for binding in combination
|
|
156
|
+
)
|
|
157
|
+
expanded.append(
|
|
158
|
+
StudyArmSpec(
|
|
159
|
+
arm_id=f"{arm.arm_id}::{suffix}",
|
|
160
|
+
release_id=arm.release_id,
|
|
161
|
+
bindings=tuple(bindings[key] for key in sorted(bindings)),
|
|
162
|
+
parameters=arm.parameters,
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
return tuple(expanded)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""Paired study runner with mandatory pre-run balance audit."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from types import TracebackType
|
|
9
|
+
|
|
10
|
+
from agentinputlab.contracts.errors import (
|
|
11
|
+
AlgorithmUnavailableError,
|
|
12
|
+
ArmExecutionError,
|
|
13
|
+
ArtifactError,
|
|
14
|
+
BalanceError,
|
|
15
|
+
CapabilityError,
|
|
16
|
+
RegistryError,
|
|
17
|
+
ValidationError,
|
|
18
|
+
)
|
|
19
|
+
from agentinputlab.contracts.lifecycle import Intervention, InterventionContext
|
|
20
|
+
from agentinputlab.contracts.serialization import freeze_mapping
|
|
21
|
+
from agentinputlab.contracts.state import FrozenAgentState
|
|
22
|
+
from agentinputlab.observability import (
|
|
23
|
+
BudgetLedger,
|
|
24
|
+
RunMonitor,
|
|
25
|
+
)
|
|
26
|
+
from agentinputlab.runner.balance import (
|
|
27
|
+
BalanceAuditor,
|
|
28
|
+
BalanceReport,
|
|
29
|
+
ComparisonArm,
|
|
30
|
+
ComparisonProfile,
|
|
31
|
+
context_dependency_fingerprints,
|
|
32
|
+
)
|
|
33
|
+
from agentinputlab.runner.engine import InterventionRunner, RunRecord
|
|
34
|
+
from agentinputlab.runner.runtime_guard import (
|
|
35
|
+
inspect_object_graph,
|
|
36
|
+
is_runtime_dependency,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
_PAIRED_RUNTIME_SLOTS = (
|
|
40
|
+
"backend",
|
|
41
|
+
"dense_embedder",
|
|
42
|
+
"retriever",
|
|
43
|
+
"vector_searcher",
|
|
44
|
+
"tools",
|
|
45
|
+
"external_runtime",
|
|
46
|
+
"artifact_manager",
|
|
47
|
+
)
|
|
48
|
+
_CELL_INVALID_ERRORS = (
|
|
49
|
+
AlgorithmUnavailableError,
|
|
50
|
+
ArtifactError,
|
|
51
|
+
BalanceError,
|
|
52
|
+
CapabilityError,
|
|
53
|
+
RegistryError,
|
|
54
|
+
ValidationError,
|
|
55
|
+
)
|
|
56
|
+
_SECRET_TEXT_PATTERNS = (
|
|
57
|
+
re.compile(r"(?i)\bbearer\s+[A-Za-z0-9._~+/=-]{8,}"),
|
|
58
|
+
re.compile(r"\bsk-[A-Za-z0-9_-]{8,}"),
|
|
59
|
+
re.compile(r"\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\b"),
|
|
60
|
+
re.compile(
|
|
61
|
+
r"(?i)(\b(?:[a-z0-9]+[_-])*(?:api[_-]?key|x[_-]?api[_-]?key|authorization)"
|
|
62
|
+
r"\b\s*[:=]\s*)['\"]?(?:bearer\s+)?[^\s,;'\"]{4,}"
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass(frozen=True, slots=True)
|
|
68
|
+
class PairedArm:
|
|
69
|
+
comparison_arm: ComparisonArm
|
|
70
|
+
intervention: Intervention
|
|
71
|
+
context: InterventionContext
|
|
72
|
+
|
|
73
|
+
def __post_init__(self) -> None:
|
|
74
|
+
if self.comparison_arm.release_id != self.intervention.release_id:
|
|
75
|
+
raise ValueError("comparison arm and intervention release IDs differ")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True, slots=True)
|
|
79
|
+
class PairedRun:
|
|
80
|
+
state_hash: str
|
|
81
|
+
balance: BalanceReport
|
|
82
|
+
outcomes: tuple[ArmOutcome, ...]
|
|
83
|
+
observed_dependency_hashes: Mapping[str, Mapping[str, str]]
|
|
84
|
+
|
|
85
|
+
def __post_init__(self) -> None:
|
|
86
|
+
object.__setattr__(self, "outcomes", tuple(self.outcomes))
|
|
87
|
+
object.__setattr__(
|
|
88
|
+
self,
|
|
89
|
+
"observed_dependency_hashes",
|
|
90
|
+
freeze_mapping(self.observed_dependency_hashes),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def records(self) -> tuple[RunRecord, ...]:
|
|
95
|
+
"""Successful records retained for backward-compatible aggregation."""
|
|
96
|
+
|
|
97
|
+
return tuple(outcome.record for outcome in self.outcomes if outcome.record is not None)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass(frozen=True, slots=True)
|
|
101
|
+
class ArmFailure:
|
|
102
|
+
category: str
|
|
103
|
+
message: str
|
|
104
|
+
monitor_run_id: str = ""
|
|
105
|
+
|
|
106
|
+
def __post_init__(self) -> None:
|
|
107
|
+
if not self.category:
|
|
108
|
+
raise ValueError("arm failure category must be non-empty")
|
|
109
|
+
object.__setattr__(self, "message", _safe_failure_message(self.message))
|
|
110
|
+
if not isinstance(self.monitor_run_id, str):
|
|
111
|
+
raise TypeError("monitor_run_id must be a string")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@dataclass(frozen=True, slots=True)
|
|
115
|
+
class ArmOutcome:
|
|
116
|
+
arm_id: str
|
|
117
|
+
status: str
|
|
118
|
+
record: RunRecord | None = None
|
|
119
|
+
failure: ArmFailure | None = None
|
|
120
|
+
|
|
121
|
+
def __post_init__(self) -> None:
|
|
122
|
+
if self.status not in {"succeeded", "failed"}:
|
|
123
|
+
raise ValueError("arm outcome status must be succeeded or failed")
|
|
124
|
+
if (self.record is None) == (self.failure is None):
|
|
125
|
+
raise ValueError("arm outcome requires exactly one record or failure")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class PairedStudyRunner:
|
|
129
|
+
def __init__(self) -> None:
|
|
130
|
+
self._balance = BalanceAuditor()
|
|
131
|
+
self._runner = InterventionRunner()
|
|
132
|
+
|
|
133
|
+
def run(
|
|
134
|
+
self,
|
|
135
|
+
state: FrozenAgentState,
|
|
136
|
+
profile: ComparisonProfile,
|
|
137
|
+
arms: tuple[PairedArm, ...],
|
|
138
|
+
) -> PairedRun:
|
|
139
|
+
_reject_shared_runtime_instances(arms)
|
|
140
|
+
before = {
|
|
141
|
+
arm.comparison_arm.arm_id: context_dependency_fingerprints(arm.context) for arm in arms
|
|
142
|
+
}
|
|
143
|
+
report = self._balance.audit(
|
|
144
|
+
profile,
|
|
145
|
+
tuple(arm.comparison_arm for arm in arms),
|
|
146
|
+
runtime_fingerprints=before,
|
|
147
|
+
)
|
|
148
|
+
report.require_eligible()
|
|
149
|
+
outcomes: list[ArmOutcome] = []
|
|
150
|
+
for arm in arms:
|
|
151
|
+
monitor = arm.context.monitor or self._runner.monitor
|
|
152
|
+
if monitor is not None and not isinstance(monitor, RunMonitor):
|
|
153
|
+
raise TypeError("context.monitor must be a RunMonitor")
|
|
154
|
+
prior_run_ids = (
|
|
155
|
+
frozenset(snapshot.run_id for snapshot in monitor.list_snapshots())
|
|
156
|
+
if monitor is not None
|
|
157
|
+
else frozenset()
|
|
158
|
+
)
|
|
159
|
+
try:
|
|
160
|
+
record = self._runner.run(arm.intervention, state, arm.context)
|
|
161
|
+
except Exception as exc:
|
|
162
|
+
monitor_run_id = _find_new_monitor_run_id(
|
|
163
|
+
monitor,
|
|
164
|
+
prior_run_ids,
|
|
165
|
+
release_id=arm.intervention.release_id,
|
|
166
|
+
state_hash=state.state_hash,
|
|
167
|
+
)
|
|
168
|
+
if _invalidates_cell(exc):
|
|
169
|
+
raise
|
|
170
|
+
outcomes.append(
|
|
171
|
+
ArmOutcome(
|
|
172
|
+
arm_id=arm.comparison_arm.arm_id,
|
|
173
|
+
status="failed",
|
|
174
|
+
failure=ArmFailure(
|
|
175
|
+
type(exc).__name__,
|
|
176
|
+
str(exc),
|
|
177
|
+
monitor_run_id=monitor_run_id,
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
else:
|
|
182
|
+
outcomes.append(
|
|
183
|
+
ArmOutcome(
|
|
184
|
+
arm_id=arm.comparison_arm.arm_id,
|
|
185
|
+
status="succeeded",
|
|
186
|
+
record=record,
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
records = tuple(outcome.record for outcome in outcomes if outcome.record is not None)
|
|
190
|
+
if any(record.input_state_hash != state.state_hash for record in records):
|
|
191
|
+
raise RuntimeError("paired runner produced a non-paired input identity")
|
|
192
|
+
after = {
|
|
193
|
+
arm.comparison_arm.arm_id: context_dependency_fingerprints(arm.context) for arm in arms
|
|
194
|
+
}
|
|
195
|
+
if before != after:
|
|
196
|
+
raise BalanceError("runtime dependency identity changed while executing paired arms")
|
|
197
|
+
post_report = self._balance.audit(
|
|
198
|
+
profile,
|
|
199
|
+
tuple(arm.comparison_arm for arm in arms),
|
|
200
|
+
runtime_fingerprints=after,
|
|
201
|
+
)
|
|
202
|
+
post_report.require_eligible()
|
|
203
|
+
return PairedRun(
|
|
204
|
+
state_hash=state.state_hash,
|
|
205
|
+
balance=post_report,
|
|
206
|
+
outcomes=tuple(outcomes),
|
|
207
|
+
observed_dependency_hashes=after,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _reject_shared_runtime_instances(arms: tuple[PairedArm, ...]) -> None:
|
|
212
|
+
"""Require equal-but-independent runtime dependencies across comparison arms."""
|
|
213
|
+
|
|
214
|
+
runtime_owners: dict[int, set[str]] = {}
|
|
215
|
+
ledger_owners: dict[int, set[str]] = {}
|
|
216
|
+
for arm in arms:
|
|
217
|
+
arm_id = arm.comparison_arm.arm_id
|
|
218
|
+
if isinstance(arm.context.budget_ledger, BudgetLedger):
|
|
219
|
+
ledger_owners.setdefault(id(arm.context.budget_ledger), set()).add(arm_id)
|
|
220
|
+
for slot in _PAIRED_RUNTIME_SLOTS:
|
|
221
|
+
dependency = getattr(arm.context, slot)
|
|
222
|
+
if dependency is None:
|
|
223
|
+
continue
|
|
224
|
+
graph = inspect_object_graph(
|
|
225
|
+
dependency,
|
|
226
|
+
root_path=f"context.{slot}",
|
|
227
|
+
terminal_types=(RunMonitor, BudgetLedger),
|
|
228
|
+
traverse_runtime_delegates=True,
|
|
229
|
+
)
|
|
230
|
+
for node in graph:
|
|
231
|
+
if is_runtime_dependency(node.value):
|
|
232
|
+
runtime_owners.setdefault(id(node.value), set()).add(arm_id)
|
|
233
|
+
if isinstance(node.value, BudgetLedger):
|
|
234
|
+
ledger_owners.setdefault(id(node.value), set()).add(arm_id)
|
|
235
|
+
|
|
236
|
+
shared_runtimes = [sorted(arm_ids) for arm_ids in runtime_owners.values() if len(arm_ids) > 1]
|
|
237
|
+
if shared_runtimes:
|
|
238
|
+
details = ", ".join("/".join(arm_ids) for arm_ids in shared_runtimes)
|
|
239
|
+
raise BalanceError(
|
|
240
|
+
"runtime dependency objects, including proxy inners, must be independently "
|
|
241
|
+
f"constructed across arms: {details}"
|
|
242
|
+
)
|
|
243
|
+
shared_ledgers = [sorted(arm_ids) for arm_ids in ledger_owners.values() if len(arm_ids) > 1]
|
|
244
|
+
if shared_ledgers:
|
|
245
|
+
details = ", ".join("/".join(arm_ids) for arm_ids in shared_ledgers)
|
|
246
|
+
raise BalanceError(
|
|
247
|
+
"runtime BudgetLedger instances must be independently constructed across arms: "
|
|
248
|
+
f"{details}"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _find_new_monitor_run_id(
|
|
253
|
+
monitor: RunMonitor | None,
|
|
254
|
+
prior_run_ids: frozenset[str],
|
|
255
|
+
*,
|
|
256
|
+
release_id: str,
|
|
257
|
+
state_hash: str,
|
|
258
|
+
) -> str:
|
|
259
|
+
if monitor is None:
|
|
260
|
+
return ""
|
|
261
|
+
matches = [
|
|
262
|
+
snapshot.run_id
|
|
263
|
+
for snapshot in monitor.list_snapshots()
|
|
264
|
+
if snapshot.run_id not in prior_run_ids
|
|
265
|
+
and snapshot.release_id == release_id
|
|
266
|
+
and snapshot.state_hash == state_hash
|
|
267
|
+
]
|
|
268
|
+
return matches[-1] if matches else ""
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _invalidates_cell(error: Exception) -> bool:
|
|
272
|
+
"""Return whether an exception invalidates the experiment rather than one arm."""
|
|
273
|
+
|
|
274
|
+
# Arm-local subclasses take precedence because they intentionally remain
|
|
275
|
+
# ValidationError subclasses for public API compatibility.
|
|
276
|
+
if isinstance(error, ArmExecutionError):
|
|
277
|
+
return False
|
|
278
|
+
if isinstance(error, (*_CELL_INVALID_ERRORS, MemoryError)):
|
|
279
|
+
return True
|
|
280
|
+
frames = _traceback_frames(error.__traceback__)
|
|
281
|
+
if any(
|
|
282
|
+
module == "agentinputlab.observability.monitor" and function != "run_scope"
|
|
283
|
+
for module, function in frames
|
|
284
|
+
):
|
|
285
|
+
return True
|
|
286
|
+
origin = frames[-1][0] if frames else ""
|
|
287
|
+
if origin.startswith(("agentinputlab.artifacts", "agentinputlab.data")):
|
|
288
|
+
return True
|
|
289
|
+
if origin == "agentinputlab.observability.instrumentation" and isinstance(
|
|
290
|
+
error, (TypeError, ValueError)
|
|
291
|
+
):
|
|
292
|
+
return True
|
|
293
|
+
if origin == "agentinputlab.runner.runtime_guard" and isinstance(
|
|
294
|
+
error, (AttributeError, TypeError)
|
|
295
|
+
):
|
|
296
|
+
return True
|
|
297
|
+
return origin == "agentinputlab.runner.engine" and isinstance(
|
|
298
|
+
error, (AttributeError, TypeError)
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def _traceback_frames(traceback: TracebackType | None) -> tuple[tuple[str, str], ...]:
|
|
303
|
+
frames: list[tuple[str, str]] = []
|
|
304
|
+
while traceback is not None:
|
|
305
|
+
frames.append(
|
|
306
|
+
(
|
|
307
|
+
str(traceback.tb_frame.f_globals.get("__name__", "")),
|
|
308
|
+
traceback.tb_frame.f_code.co_name,
|
|
309
|
+
)
|
|
310
|
+
)
|
|
311
|
+
traceback = traceback.tb_next
|
|
312
|
+
return tuple(frames)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _safe_failure_message(message: object) -> str:
|
|
316
|
+
safe = str(message)[:2048]
|
|
317
|
+
for pattern in _SECRET_TEXT_PATTERNS:
|
|
318
|
+
if pattern.groups:
|
|
319
|
+
safe = pattern.sub(lambda match: f"{match.group(1)}<redacted>", safe)
|
|
320
|
+
else:
|
|
321
|
+
safe = pattern.sub("<redacted>", safe)
|
|
322
|
+
return safe
|