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,463 @@
|
|
|
1
|
+
"""Strict registry-backed construction for static prompt interventions.
|
|
2
|
+
|
|
3
|
+
The builder is an assembly boundary, not a reimplementation of any method.
|
|
4
|
+
It resolves the exact entrypoint already declared by the algorithm registry,
|
|
5
|
+
constructs that object with checksum-locked JSON parameters. Executable
|
|
6
|
+
dependencies are deliberately *not* stored on the intervention: the static
|
|
7
|
+
driver supplies the shared runtime graph through :class:`InterventionContext`
|
|
8
|
+
when the intervention is executed.
|
|
9
|
+
|
|
10
|
+
Full-system/composite and offline-recipe releases are intentionally rejected:
|
|
11
|
+
they must run through their process or atomic-arena execution profile instead
|
|
12
|
+
of being mislabeled as a one-shot prompt intervention.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import dataclasses
|
|
18
|
+
import importlib
|
|
19
|
+
import inspect
|
|
20
|
+
import os
|
|
21
|
+
import re
|
|
22
|
+
from collections.abc import Mapping, Sequence
|
|
23
|
+
from enum import Enum
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
from agentinputlab.contracts.enums import SemanticFamily
|
|
28
|
+
from agentinputlab.contracts.errors import ArtifactError, ValidationError
|
|
29
|
+
from agentinputlab.contracts.lifecycle import Intervention
|
|
30
|
+
from agentinputlab.contracts.serialization import freeze_mapping
|
|
31
|
+
from agentinputlab.experiments.drivers.static_production import StaticArmBuildRequest
|
|
32
|
+
from agentinputlab.experiments.secrets import require_secret_free
|
|
33
|
+
from agentinputlab.registry import AlgorithmRegistry
|
|
34
|
+
from agentinputlab.selectors import NoOpIntervention
|
|
35
|
+
|
|
36
|
+
REGISTRY_INTERVENTION_BUILDER_PROTOCOL = "agentinputlab.registry-intervention-builder.v1"
|
|
37
|
+
|
|
38
|
+
_SCHEMA_VERSION = 1
|
|
39
|
+
_ENVIRONMENT_NAME = re.compile(r"^[A-Z_][A-Z0-9_]*$")
|
|
40
|
+
_IDENTITY_ARGUMENTS = frozenset({"method_id", "release_id", "family"})
|
|
41
|
+
_SAFE_OBJECT_PREFIXES = (
|
|
42
|
+
"agentinputlab.algorithms.",
|
|
43
|
+
"agentinputlab.recipes.",
|
|
44
|
+
"agentinputlab.integrations.external_workers.",
|
|
45
|
+
)
|
|
46
|
+
_PARAMETER_FIELDS = frozenset(
|
|
47
|
+
{
|
|
48
|
+
"schema_version",
|
|
49
|
+
"release_id",
|
|
50
|
+
"constructor_kwargs",
|
|
51
|
+
"runtime_bindings",
|
|
52
|
+
"arm_parameter_bindings",
|
|
53
|
+
"required_environment",
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
_TYPED_SPEC_KINDS = frozenset({"dataclass", "enum", "path", "tuple"})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class RegistryInterventionBuilder:
|
|
60
|
+
"""Build an unchanged registered intervention under explicit fair settings."""
|
|
61
|
+
|
|
62
|
+
builder_kind = "intervention"
|
|
63
|
+
|
|
64
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
65
|
+
return freeze_mapping(
|
|
66
|
+
{
|
|
67
|
+
"builder_id": REGISTRY_INTERVENTION_BUILDER_PROTOCOL,
|
|
68
|
+
"schema_version": _SCHEMA_VERSION,
|
|
69
|
+
"registry_source": "packaged",
|
|
70
|
+
"identity_injection": sorted(_IDENTITY_ARGUMENTS),
|
|
71
|
+
"no_op_profile_policy": "inherit_requested_profile.v1",
|
|
72
|
+
"runtime_dependency_policy": "intervention_context_only.v1",
|
|
73
|
+
"typed_spec_kinds": sorted(_TYPED_SPEC_KINDS),
|
|
74
|
+
"composite_policy": "reject_and_route_to_process_or_atomic_arena",
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def preflight(self, parameters: Mapping[str, Any]) -> Sequence[str]:
|
|
79
|
+
"""Validate a frozen construction recipe without loading model assets."""
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
specification = _parse_parameters(parameters)
|
|
83
|
+
if specification["release_id"] == "baseline.no_op":
|
|
84
|
+
return ()
|
|
85
|
+
_, _, constructor = _resolve_release(specification["release_id"])
|
|
86
|
+
blockers = list(_constructor_blockers(constructor, specification))
|
|
87
|
+
blockers.extend(
|
|
88
|
+
f"missing required environment {name}"
|
|
89
|
+
for name in specification["required_environment"]
|
|
90
|
+
if not os.environ.get(name)
|
|
91
|
+
)
|
|
92
|
+
return tuple(blockers)
|
|
93
|
+
except (ArtifactError, ValidationError) as exc:
|
|
94
|
+
return (str(exc),)
|
|
95
|
+
|
|
96
|
+
def build(self, request: StaticArmBuildRequest) -> Intervention:
|
|
97
|
+
"""Construct one exact release using the request's shared runtime graph."""
|
|
98
|
+
|
|
99
|
+
if not isinstance(request, StaticArmBuildRequest):
|
|
100
|
+
raise TypeError("registry intervention builder requires StaticArmBuildRequest")
|
|
101
|
+
specification = _parse_parameters(request.builder_parameters)
|
|
102
|
+
configured_release = specification["release_id"]
|
|
103
|
+
if configured_release != request.release_id:
|
|
104
|
+
raise ValidationError(
|
|
105
|
+
"registry intervention builder release differs from the requested arm"
|
|
106
|
+
)
|
|
107
|
+
if request.release_id == "baseline.no_op":
|
|
108
|
+
if request.family is not SemanticFamily.NO_OP:
|
|
109
|
+
raise ValidationError("baseline.no_op requires the no_op family")
|
|
110
|
+
return NoOpIntervention(profile_kind=request.profile_kind.value)
|
|
111
|
+
|
|
112
|
+
method, release, constructor = _resolve_release(request.release_id)
|
|
113
|
+
if method.semantic_family is not request.family:
|
|
114
|
+
raise ValidationError("registry intervention builder family differs from the registry")
|
|
115
|
+
if request.profile_kind not in release.profile_modes:
|
|
116
|
+
raise ValidationError("requested profile kind is not declared by the selected release")
|
|
117
|
+
blockers = _constructor_blockers(constructor, specification)
|
|
118
|
+
if blockers:
|
|
119
|
+
raise ArtifactError("; ".join(blockers))
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
kwargs = {
|
|
123
|
+
name: _materialize_value(value)
|
|
124
|
+
for name, value in specification["constructor_kwargs"].items()
|
|
125
|
+
}
|
|
126
|
+
for argument, arm_parameter in specification["arm_parameter_bindings"].items():
|
|
127
|
+
if arm_parameter not in request.arm_parameters:
|
|
128
|
+
raise ArtifactError(
|
|
129
|
+
f"arm parameter {arm_parameter!r} required for constructor "
|
|
130
|
+
f"argument {argument!r} is missing"
|
|
131
|
+
)
|
|
132
|
+
kwargs[argument] = _materialize_value(request.arm_parameters[arm_parameter])
|
|
133
|
+
except ArtifactError:
|
|
134
|
+
raise
|
|
135
|
+
except (TypeError, ValueError) as exc:
|
|
136
|
+
raise ValidationError(
|
|
137
|
+
f"cannot materialize constructor values for {request.release_id!r}: {exc}"
|
|
138
|
+
) from exc
|
|
139
|
+
|
|
140
|
+
signature = inspect.signature(constructor)
|
|
141
|
+
implementation_method_id = method.method_id.rsplit(".", 1)[-1]
|
|
142
|
+
identity_values = {
|
|
143
|
+
"method_id": implementation_method_id,
|
|
144
|
+
"release_id": release.id,
|
|
145
|
+
"family": method.semantic_family,
|
|
146
|
+
}
|
|
147
|
+
for name, value in identity_values.items():
|
|
148
|
+
if name in signature.parameters:
|
|
149
|
+
configured = kwargs.get(name, value)
|
|
150
|
+
if configured != value:
|
|
151
|
+
raise ValidationError(
|
|
152
|
+
f"constructor identity argument {name!r} differs from the registry"
|
|
153
|
+
)
|
|
154
|
+
kwargs[name] = value
|
|
155
|
+
try:
|
|
156
|
+
intervention = constructor(**kwargs)
|
|
157
|
+
except TypeError as exc:
|
|
158
|
+
raise ValidationError(
|
|
159
|
+
f"cannot construct registered release {request.release_id!r}: {exc}"
|
|
160
|
+
) from exc
|
|
161
|
+
if not isinstance(intervention, Intervention):
|
|
162
|
+
raise ValidationError(
|
|
163
|
+
f"release {request.release_id!r} is not a one-shot Intervention; "
|
|
164
|
+
"use its process or atomic-arena execution profile"
|
|
165
|
+
)
|
|
166
|
+
if intervention.method_id != implementation_method_id:
|
|
167
|
+
raise ValidationError("constructed intervention method_id differs from the registry")
|
|
168
|
+
if intervention.release_id != release.id:
|
|
169
|
+
raise ValidationError("constructed intervention release_id differs from the registry")
|
|
170
|
+
if intervention.family is not method.semantic_family:
|
|
171
|
+
raise ValidationError("constructed intervention family differs from the registry")
|
|
172
|
+
return intervention
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def registry_intervention_builder_factory() -> RegistryInterventionBuilder:
|
|
176
|
+
"""Return the zero-argument builder used by locked production configs."""
|
|
177
|
+
|
|
178
|
+
return RegistryInterventionBuilder()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _parse_parameters(parameters: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
182
|
+
if not isinstance(parameters, Mapping):
|
|
183
|
+
raise ValidationError("registry intervention parameters must be an object")
|
|
184
|
+
if not set(parameters).issubset(_PARAMETER_FIELDS):
|
|
185
|
+
unknown = sorted(set(parameters) - _PARAMETER_FIELDS)
|
|
186
|
+
raise ValidationError(f"registry intervention parameters contain unknown fields: {unknown}")
|
|
187
|
+
if parameters.get("schema_version") != _SCHEMA_VERSION:
|
|
188
|
+
raise ValidationError("unsupported registry intervention schema_version")
|
|
189
|
+
release_id = parameters.get("release_id")
|
|
190
|
+
if not isinstance(release_id, str) or not release_id.strip():
|
|
191
|
+
raise ValidationError("registry intervention release_id must be non-empty")
|
|
192
|
+
|
|
193
|
+
constructor_kwargs = _string_mapping(
|
|
194
|
+
parameters.get("constructor_kwargs", {}),
|
|
195
|
+
label="constructor_kwargs",
|
|
196
|
+
)
|
|
197
|
+
runtime_bindings = _string_mapping(
|
|
198
|
+
parameters.get("runtime_bindings", {}),
|
|
199
|
+
label="runtime_bindings",
|
|
200
|
+
values_must_be_strings=True,
|
|
201
|
+
)
|
|
202
|
+
if runtime_bindings:
|
|
203
|
+
raise ValidationError(
|
|
204
|
+
"runtime_bindings are forbidden: executable dependencies must be supplied "
|
|
205
|
+
"through InterventionContext by the experiment driver"
|
|
206
|
+
)
|
|
207
|
+
arm_bindings = _string_mapping(
|
|
208
|
+
parameters.get("arm_parameter_bindings", {}),
|
|
209
|
+
label="arm_parameter_bindings",
|
|
210
|
+
values_must_be_strings=True,
|
|
211
|
+
)
|
|
212
|
+
targets = (
|
|
213
|
+
set(constructor_kwargs),
|
|
214
|
+
set(runtime_bindings),
|
|
215
|
+
set(arm_bindings),
|
|
216
|
+
)
|
|
217
|
+
if targets[0] & targets[1] or targets[0] & targets[2] or targets[1] & targets[2]:
|
|
218
|
+
raise ValidationError(
|
|
219
|
+
"constructor, runtime, and arm-parameter bindings must target distinct arguments"
|
|
220
|
+
)
|
|
221
|
+
for argument in set().union(*targets):
|
|
222
|
+
_constructor_argument(argument)
|
|
223
|
+
for name in arm_bindings.values():
|
|
224
|
+
if not name.strip() or name != name.strip():
|
|
225
|
+
raise ValidationError("arm parameter binding names must be trimmed and non-empty")
|
|
226
|
+
|
|
227
|
+
raw_environment = parameters.get("required_environment", ())
|
|
228
|
+
if isinstance(raw_environment, (str, bytes)) or not isinstance(
|
|
229
|
+
raw_environment,
|
|
230
|
+
Sequence,
|
|
231
|
+
):
|
|
232
|
+
raise ValidationError("required_environment must be an array")
|
|
233
|
+
required_environment = tuple(raw_environment)
|
|
234
|
+
if len(required_environment) != len(set(required_environment)) or any(
|
|
235
|
+
not isinstance(name, str) or _ENVIRONMENT_NAME.fullmatch(name) is None
|
|
236
|
+
for name in required_environment
|
|
237
|
+
):
|
|
238
|
+
raise ValidationError("required_environment must contain unique environment-variable names")
|
|
239
|
+
require_secret_free(parameters, label="registry intervention parameters")
|
|
240
|
+
for value in constructor_kwargs.values():
|
|
241
|
+
_validate_typed_value(value)
|
|
242
|
+
result = {
|
|
243
|
+
"schema_version": _SCHEMA_VERSION,
|
|
244
|
+
"release_id": release_id,
|
|
245
|
+
"constructor_kwargs": constructor_kwargs,
|
|
246
|
+
"runtime_bindings": runtime_bindings,
|
|
247
|
+
"arm_parameter_bindings": arm_bindings,
|
|
248
|
+
"required_environment": required_environment,
|
|
249
|
+
}
|
|
250
|
+
try:
|
|
251
|
+
return freeze_mapping(result)
|
|
252
|
+
except (TypeError, ValueError) as exc:
|
|
253
|
+
raise ValidationError("registry intervention parameters must be canonical JSON") from exc
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _resolve_release(release_id: str) -> tuple[Any, Any, Any]:
|
|
257
|
+
registry = AlgorithmRegistry.default()
|
|
258
|
+
try:
|
|
259
|
+
method, release = registry.get_release(release_id)
|
|
260
|
+
constructor = registry.resolve_entrypoint(release_id)
|
|
261
|
+
except Exception as exc:
|
|
262
|
+
raise ArtifactError(f"cannot resolve registered release {release_id!r}: {exc}") from exc
|
|
263
|
+
if not callable(constructor):
|
|
264
|
+
raise ArtifactError(f"registered release {release_id!r} is not callable")
|
|
265
|
+
return method, release, constructor
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _constructor_blockers(
|
|
269
|
+
constructor: Any,
|
|
270
|
+
specification: Mapping[str, Any],
|
|
271
|
+
) -> tuple[str, ...]:
|
|
272
|
+
if not hasattr(constructor, "propose"):
|
|
273
|
+
return (
|
|
274
|
+
f"release {specification['release_id']!r} is composite/offline rather "
|
|
275
|
+
"than a one-shot intervention; use method_process or external_arena",
|
|
276
|
+
)
|
|
277
|
+
try:
|
|
278
|
+
signature = inspect.signature(constructor)
|
|
279
|
+
except (TypeError, ValueError) as exc:
|
|
280
|
+
raise ArtifactError("registered intervention has no inspectable signature") from exc
|
|
281
|
+
supplied = (
|
|
282
|
+
set(specification["constructor_kwargs"])
|
|
283
|
+
| set(specification["runtime_bindings"])
|
|
284
|
+
| set(specification["arm_parameter_bindings"])
|
|
285
|
+
| (set(signature.parameters) & _IDENTITY_ARGUMENTS)
|
|
286
|
+
)
|
|
287
|
+
accepts_kwargs = any(
|
|
288
|
+
parameter.kind is inspect.Parameter.VAR_KEYWORD
|
|
289
|
+
for parameter in signature.parameters.values()
|
|
290
|
+
)
|
|
291
|
+
blockers: list[str] = []
|
|
292
|
+
for name in supplied:
|
|
293
|
+
parameter = signature.parameters.get(name)
|
|
294
|
+
if parameter is None and not accepts_kwargs:
|
|
295
|
+
blockers.append(f"constructor does not accept configured argument {name!r}")
|
|
296
|
+
elif parameter is not None and parameter.kind is inspect.Parameter.POSITIONAL_ONLY:
|
|
297
|
+
blockers.append(f"constructor argument {name!r} is positional-only")
|
|
298
|
+
for name, parameter in signature.parameters.items():
|
|
299
|
+
if parameter.kind in {
|
|
300
|
+
inspect.Parameter.VAR_POSITIONAL,
|
|
301
|
+
inspect.Parameter.VAR_KEYWORD,
|
|
302
|
+
}:
|
|
303
|
+
continue
|
|
304
|
+
if parameter.default is inspect.Parameter.empty and name not in supplied:
|
|
305
|
+
blockers.append(f"required constructor argument {name!r} has no frozen binding")
|
|
306
|
+
return tuple(blockers)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _string_mapping(
|
|
310
|
+
value: Any,
|
|
311
|
+
*,
|
|
312
|
+
label: str,
|
|
313
|
+
values_must_be_strings: bool = False,
|
|
314
|
+
) -> Mapping[str, Any]:
|
|
315
|
+
if not isinstance(value, Mapping):
|
|
316
|
+
raise ValidationError(f"{label} must be an object")
|
|
317
|
+
result: dict[str, Any] = {}
|
|
318
|
+
for key, item in value.items():
|
|
319
|
+
_constructor_argument(key)
|
|
320
|
+
if values_must_be_strings and (
|
|
321
|
+
not isinstance(item, str) or not item.strip() or item != item.strip()
|
|
322
|
+
):
|
|
323
|
+
raise ValidationError(f"{label} values must be trimmed non-empty strings")
|
|
324
|
+
result[key] = item
|
|
325
|
+
return freeze_mapping(result)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _constructor_argument(name: Any) -> None:
|
|
329
|
+
if not isinstance(name, str) or not name.isidentifier() or name.startswith("_"):
|
|
330
|
+
raise ValidationError("constructor argument names must be public Python identifiers")
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def _validate_typed_value(value: Any) -> None:
|
|
334
|
+
if isinstance(value, Mapping):
|
|
335
|
+
if "$type" in value:
|
|
336
|
+
kind = value.get("$type")
|
|
337
|
+
if kind not in _TYPED_SPEC_KINDS:
|
|
338
|
+
raise ValidationError(f"unsupported typed constructor value {kind!r}")
|
|
339
|
+
_validate_typed_spec(value, kind=kind)
|
|
340
|
+
return
|
|
341
|
+
for item in value.values():
|
|
342
|
+
_validate_typed_value(item)
|
|
343
|
+
return
|
|
344
|
+
if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
|
|
345
|
+
for item in value:
|
|
346
|
+
_validate_typed_value(item)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def _validate_typed_spec(value: Mapping[str, Any], *, kind: str) -> None:
|
|
350
|
+
if kind == "dataclass":
|
|
351
|
+
if set(value) != {"$type", "entrypoint", "kwargs"}:
|
|
352
|
+
raise ValidationError("dataclass typed values require $type, entrypoint, and kwargs")
|
|
353
|
+
candidate = _resolve_safe_type(value["entrypoint"])
|
|
354
|
+
if not dataclasses.is_dataclass(candidate):
|
|
355
|
+
raise ValidationError("dataclass typed value entrypoint is not a dataclass type")
|
|
356
|
+
kwargs = _string_mapping(value["kwargs"], label="dataclass kwargs")
|
|
357
|
+
for item in kwargs.values():
|
|
358
|
+
_validate_typed_value(item)
|
|
359
|
+
_signature_accepts(candidate, set(kwargs), label="dataclass typed value")
|
|
360
|
+
return
|
|
361
|
+
if kind == "enum":
|
|
362
|
+
if set(value) != {"$type", "entrypoint", "value"}:
|
|
363
|
+
raise ValidationError("enum typed values require $type, entrypoint, and value")
|
|
364
|
+
candidate = _resolve_safe_type(value["entrypoint"])
|
|
365
|
+
if not inspect.isclass(candidate) or not issubclass(candidate, Enum):
|
|
366
|
+
raise ValidationError("enum typed value entrypoint is not an Enum type")
|
|
367
|
+
try:
|
|
368
|
+
candidate(value["value"])
|
|
369
|
+
except (TypeError, ValueError) as exc:
|
|
370
|
+
raise ValidationError("enum typed value is not a declared member value") from exc
|
|
371
|
+
return
|
|
372
|
+
if kind == "path":
|
|
373
|
+
if set(value) != {"$type", "value"}:
|
|
374
|
+
raise ValidationError("path typed values require $type and value")
|
|
375
|
+
raw = value["value"]
|
|
376
|
+
if not isinstance(raw, str) or not raw.strip():
|
|
377
|
+
raise ValidationError("path typed value must be non-empty")
|
|
378
|
+
if not Path(raw).expanduser().is_absolute():
|
|
379
|
+
raise ValidationError("path typed value must be absolute")
|
|
380
|
+
return
|
|
381
|
+
if kind == "tuple":
|
|
382
|
+
if set(value) != {"$type", "items"}:
|
|
383
|
+
raise ValidationError("tuple typed values require $type and items")
|
|
384
|
+
items = value["items"]
|
|
385
|
+
if isinstance(items, (str, bytes)) or not isinstance(items, Sequence):
|
|
386
|
+
raise ValidationError("tuple typed value items must be an array")
|
|
387
|
+
for item in items:
|
|
388
|
+
_validate_typed_value(item)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def _resolve_safe_type(entrypoint: Any) -> Any:
|
|
392
|
+
if not isinstance(entrypoint, str) or ":" not in entrypoint:
|
|
393
|
+
raise ValidationError("typed value entrypoint must use module:attribute syntax")
|
|
394
|
+
module_name, attribute_path = entrypoint.split(":", 1)
|
|
395
|
+
if not module_name.startswith(_SAFE_OBJECT_PREFIXES):
|
|
396
|
+
raise ValidationError("typed value entrypoint is outside the algorithm allowlist")
|
|
397
|
+
if any(
|
|
398
|
+
not segment.isidentifier() or segment.startswith("_")
|
|
399
|
+
for segment in (module_name.split(".") + attribute_path.split("."))
|
|
400
|
+
):
|
|
401
|
+
raise ValidationError("typed value entrypoint contains a private or invalid segment")
|
|
402
|
+
try:
|
|
403
|
+
candidate: Any = importlib.import_module(module_name)
|
|
404
|
+
for segment in attribute_path.split("."):
|
|
405
|
+
candidate = getattr(candidate, segment)
|
|
406
|
+
except (ImportError, AttributeError) as exc:
|
|
407
|
+
raise ArtifactError(f"cannot resolve typed value entrypoint {entrypoint!r}") from exc
|
|
408
|
+
if not inspect.isclass(candidate):
|
|
409
|
+
raise ValidationError("typed value entrypoint must resolve to a class")
|
|
410
|
+
return candidate
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _signature_accepts(candidate: Any, names: set[str], *, label: str) -> None:
|
|
414
|
+
signature = inspect.signature(candidate)
|
|
415
|
+
accepts_kwargs = any(
|
|
416
|
+
parameter.kind is inspect.Parameter.VAR_KEYWORD
|
|
417
|
+
for parameter in signature.parameters.values()
|
|
418
|
+
)
|
|
419
|
+
unknown = sorted(set(names) - set(signature.parameters))
|
|
420
|
+
if unknown and not accepts_kwargs:
|
|
421
|
+
raise ValidationError(f"{label} has unsupported arguments: {unknown}")
|
|
422
|
+
missing = sorted(
|
|
423
|
+
name
|
|
424
|
+
for name, parameter in signature.parameters.items()
|
|
425
|
+
if parameter.kind
|
|
426
|
+
not in {
|
|
427
|
+
inspect.Parameter.VAR_POSITIONAL,
|
|
428
|
+
inspect.Parameter.VAR_KEYWORD,
|
|
429
|
+
}
|
|
430
|
+
and parameter.default is inspect.Parameter.empty
|
|
431
|
+
and name not in names
|
|
432
|
+
)
|
|
433
|
+
if missing:
|
|
434
|
+
raise ValidationError(f"{label} is missing required arguments: {missing}")
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def _materialize_value(value: Any) -> Any:
|
|
438
|
+
if isinstance(value, Mapping):
|
|
439
|
+
kind = value.get("$type")
|
|
440
|
+
if kind is None:
|
|
441
|
+
return {key: _materialize_value(item) for key, item in value.items()}
|
|
442
|
+
_validate_typed_spec(value, kind=kind)
|
|
443
|
+
if kind == "dataclass":
|
|
444
|
+
candidate = _resolve_safe_type(value["entrypoint"])
|
|
445
|
+
kwargs = {key: _materialize_value(item) for key, item in value["kwargs"].items()}
|
|
446
|
+
return candidate(**kwargs)
|
|
447
|
+
if kind == "enum":
|
|
448
|
+
return _resolve_safe_type(value["entrypoint"])(value["value"])
|
|
449
|
+
if kind == "path":
|
|
450
|
+
return Path(value["value"]).expanduser()
|
|
451
|
+
if kind == "tuple":
|
|
452
|
+
return tuple(_materialize_value(item) for item in value["items"])
|
|
453
|
+
raise ValidationError(f"unsupported typed constructor value {kind!r}")
|
|
454
|
+
if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
|
|
455
|
+
return [_materialize_value(item) for item in value]
|
|
456
|
+
return value
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
__all__ = [
|
|
460
|
+
"REGISTRY_INTERVENTION_BUILDER_PROTOCOL",
|
|
461
|
+
"RegistryInterventionBuilder",
|
|
462
|
+
"registry_intervention_builder_factory",
|
|
463
|
+
]
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Command-line entry point for validating, planning, and explicitly running studies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from agentinputlab.contracts.errors import ArtifactError, ValidationError
|
|
12
|
+
|
|
13
|
+
from .driver_guard import activate_guarded_driver
|
|
14
|
+
from .executor import execute_experiment_plan
|
|
15
|
+
from .loader import load_experiment_manifest, preflight_experiment
|
|
16
|
+
from .plan import build_experiment_plan
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _dump(value: Any) -> None:
|
|
20
|
+
print(json.dumps(value, ensure_ascii=False, sort_keys=True, indent=2))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _preflight(args: argparse.Namespace) -> tuple[Any, Any, Any]:
|
|
24
|
+
manifest = load_experiment_manifest(args.manifest)
|
|
25
|
+
report, units = preflight_experiment(
|
|
26
|
+
manifest,
|
|
27
|
+
driver_entrypoint=args.driver,
|
|
28
|
+
resolve_units=not args.no_resolve_units,
|
|
29
|
+
)
|
|
30
|
+
plan = None
|
|
31
|
+
if report.ready and units:
|
|
32
|
+
plan = build_experiment_plan(manifest, units)
|
|
33
|
+
if args.shard_count is not None:
|
|
34
|
+
plan = plan.shard(index=args.shard_index, count=args.shard_count)
|
|
35
|
+
return manifest, report, plan
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _cmd_validate(args: argparse.Namespace) -> int:
|
|
39
|
+
manifest, report, plan = _preflight(args)
|
|
40
|
+
_dump(
|
|
41
|
+
{
|
|
42
|
+
"manifest": {
|
|
43
|
+
"study_id": manifest.study_id,
|
|
44
|
+
"stage": manifest.stage.value,
|
|
45
|
+
"manifest_hash": manifest.manifest_hash,
|
|
46
|
+
},
|
|
47
|
+
"preflight": report.to_dict(),
|
|
48
|
+
"plan": (
|
|
49
|
+
{
|
|
50
|
+
"plan_hash": plan.plan_hash,
|
|
51
|
+
"cell_count": len(plan.cells),
|
|
52
|
+
}
|
|
53
|
+
if plan is not None
|
|
54
|
+
else None
|
|
55
|
+
),
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
return 0 if report.ready else 2
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _cmd_plan(args: argparse.Namespace) -> int:
|
|
62
|
+
_manifest, report, plan = _preflight(args)
|
|
63
|
+
if not report.ready or plan is None:
|
|
64
|
+
_dump({"preflight": report.to_dict(), "plan": None})
|
|
65
|
+
return 2
|
|
66
|
+
_dump(plan.to_dict())
|
|
67
|
+
return 0
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _cmd_run(args: argparse.Namespace) -> int:
|
|
71
|
+
manifest, report, plan = _preflight(args)
|
|
72
|
+
if not report.ready or plan is None:
|
|
73
|
+
_dump({"preflight": report.to_dict(), "executed": False})
|
|
74
|
+
return 2
|
|
75
|
+
if not args.execute:
|
|
76
|
+
_dump(
|
|
77
|
+
{
|
|
78
|
+
"preflight": report.to_dict(),
|
|
79
|
+
"plan_hash": plan.plan_hash,
|
|
80
|
+
"cell_count": len(plan.cells),
|
|
81
|
+
"executed": False,
|
|
82
|
+
"next_step": "repeat with --execute after reviewing this frozen plan",
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
return 0
|
|
86
|
+
effective_driver = args.driver or manifest.driver_entrypoint
|
|
87
|
+
if effective_driver is None: # pragma: no cover - preflight invariant
|
|
88
|
+
raise ArtifactError("experiment driver is not configured")
|
|
89
|
+
if report.binding_receipt is None: # pragma: no cover - preflight invariant
|
|
90
|
+
raise ArtifactError("ready preflight did not produce a frozen binding receipt")
|
|
91
|
+
with activate_guarded_driver(
|
|
92
|
+
manifest=manifest,
|
|
93
|
+
operator_entrypoint=effective_driver,
|
|
94
|
+
operator_fingerprint=report.operator_driver_fingerprint,
|
|
95
|
+
binding_receipt=report.binding_receipt,
|
|
96
|
+
parity_contract=report.parity_contract,
|
|
97
|
+
) as guarded_entrypoint:
|
|
98
|
+
summary = execute_experiment_plan(
|
|
99
|
+
manifest,
|
|
100
|
+
plan,
|
|
101
|
+
driver_entrypoint=guarded_entrypoint,
|
|
102
|
+
output_root=str(Path(args.output_root).expanduser()),
|
|
103
|
+
resume=args.resume,
|
|
104
|
+
fail_fast=args.fail_fast,
|
|
105
|
+
)
|
|
106
|
+
_dump({"preflight": report.to_dict(), "executed": True, "summary": summary.to_dict()})
|
|
107
|
+
return 0 if summary.failed_cells == 0 else 3
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
111
|
+
parser = argparse.ArgumentParser(
|
|
112
|
+
prog="python -m agentinputlab.experiments.cli",
|
|
113
|
+
description=(
|
|
114
|
+
"Validate and materialize experiments by default; real execution requires --execute."
|
|
115
|
+
),
|
|
116
|
+
)
|
|
117
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
118
|
+
for command, help_text, handler in (
|
|
119
|
+
("validate", "Validate manifest, prerequisites, and exact units.", _cmd_validate),
|
|
120
|
+
("plan", "Print a stable, optionally sharded experiment plan.", _cmd_plan),
|
|
121
|
+
("run", "Preflight by default; execute only with --execute.", _cmd_run),
|
|
122
|
+
):
|
|
123
|
+
child = subparsers.add_parser(command, help=help_text)
|
|
124
|
+
child.add_argument("manifest", help="Path to a strict experiment JSON manifest.")
|
|
125
|
+
child.add_argument(
|
|
126
|
+
"--driver",
|
|
127
|
+
help="Operator driver override using module:zero_argument_factory.",
|
|
128
|
+
)
|
|
129
|
+
child.add_argument(
|
|
130
|
+
"--no-resolve-units",
|
|
131
|
+
action="store_true",
|
|
132
|
+
help="Validate schema and static prerequisites without reading unit inventories.",
|
|
133
|
+
)
|
|
134
|
+
child.add_argument("--shard-count", type=int)
|
|
135
|
+
child.add_argument("--shard-index", type=int, default=0)
|
|
136
|
+
child.set_defaults(handler=handler)
|
|
137
|
+
if command == "run":
|
|
138
|
+
child.add_argument("--execute", action="store_true")
|
|
139
|
+
child.add_argument("--output-root", default="results")
|
|
140
|
+
child.add_argument("--resume", action="store_true")
|
|
141
|
+
child.add_argument("--fail-fast", action="store_true")
|
|
142
|
+
return parser
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def main(argv: list[str] | None = None) -> int:
|
|
146
|
+
parser = build_parser()
|
|
147
|
+
args = parser.parse_args(argv)
|
|
148
|
+
if args.shard_count is None and args.shard_index != 0:
|
|
149
|
+
parser.error("--shard-index requires --shard-count")
|
|
150
|
+
try:
|
|
151
|
+
return int(args.handler(args))
|
|
152
|
+
except (ArtifactError, ValidationError, OSError) as exc:
|
|
153
|
+
print(f"BLOCKED: {exc}", file=sys.stderr)
|
|
154
|
+
return 2
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
if __name__ == "__main__":
|
|
158
|
+
raise SystemExit(main())
|