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,109 @@
|
|
|
1
|
+
"""Transparent selector baseline used before learned selector confirmation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
from collections.abc import Collection
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from agentinputlab.contracts.enums import SemanticFamily
|
|
10
|
+
from agentinputlab.contracts.serialization import content_hash
|
|
11
|
+
from agentinputlab.contracts.state import FrozenAgentState
|
|
12
|
+
|
|
13
|
+
from .base import SelectionDecision, SelectionFeatures
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class RuleSelector:
|
|
18
|
+
threshold: float = 0.6
|
|
19
|
+
margin: float = 0.1
|
|
20
|
+
|
|
21
|
+
def __post_init__(self) -> None:
|
|
22
|
+
if (
|
|
23
|
+
isinstance(self.threshold, bool)
|
|
24
|
+
or not isinstance(self.threshold, (int, float))
|
|
25
|
+
or not math.isfinite(self.threshold)
|
|
26
|
+
or not 0 <= self.threshold <= 1
|
|
27
|
+
):
|
|
28
|
+
raise ValueError("rule selector threshold must be finite and in [0, 1]")
|
|
29
|
+
if (
|
|
30
|
+
isinstance(self.margin, bool)
|
|
31
|
+
or not isinstance(self.margin, (int, float))
|
|
32
|
+
or not math.isfinite(self.margin)
|
|
33
|
+
or self.margin < 0
|
|
34
|
+
):
|
|
35
|
+
raise ValueError("rule selector margin must be finite and non-negative")
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def model_hash(self) -> str:
|
|
39
|
+
return content_hash(
|
|
40
|
+
{
|
|
41
|
+
"selector": "rule",
|
|
42
|
+
"threshold": self.threshold,
|
|
43
|
+
"margin": self.margin,
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def select(
|
|
48
|
+
self,
|
|
49
|
+
state: FrozenAgentState,
|
|
50
|
+
features: SelectionFeatures,
|
|
51
|
+
*,
|
|
52
|
+
eligible_families: Collection[SemanticFamily] | None = None,
|
|
53
|
+
) -> SelectionDecision:
|
|
54
|
+
del state
|
|
55
|
+
scores = {
|
|
56
|
+
SemanticFamily.CLARIFY.value: features.ambiguity_score,
|
|
57
|
+
SemanticFamily.DECOMPOSE.value: features.multi_step_score,
|
|
58
|
+
SemanticFamily.ACQUIRE.value: features.retrieval_need_score,
|
|
59
|
+
SemanticFamily.CURATE.value: features.context_pressure,
|
|
60
|
+
SemanticFamily.REFORMULATE.value: features.reformulation_need_score,
|
|
61
|
+
}
|
|
62
|
+
eligible = _eligible_actions(eligible_families)
|
|
63
|
+
ordered = sorted(
|
|
64
|
+
((family.value, scores[family.value]) for family in eligible),
|
|
65
|
+
key=lambda item: (-item[1], item[0]),
|
|
66
|
+
)
|
|
67
|
+
if not ordered:
|
|
68
|
+
return SelectionDecision(
|
|
69
|
+
family=SemanticFamily.NO_OP,
|
|
70
|
+
release_id="baseline.no_op",
|
|
71
|
+
selection_score=0.0,
|
|
72
|
+
rationale="abstained: no intervention family is eligible",
|
|
73
|
+
scores=scores,
|
|
74
|
+
)
|
|
75
|
+
best_name, best_score = ordered[0]
|
|
76
|
+
runner_up = max(0.0, ordered[1][1] if len(ordered) > 1 else 0.0)
|
|
77
|
+
if best_score < self.threshold or best_score - runner_up <= self.margin:
|
|
78
|
+
return SelectionDecision(
|
|
79
|
+
family=SemanticFamily.NO_OP,
|
|
80
|
+
release_id="baseline.no_op",
|
|
81
|
+
selection_score=0.0,
|
|
82
|
+
rationale="abstained: no family passed threshold and margin",
|
|
83
|
+
scores=scores,
|
|
84
|
+
)
|
|
85
|
+
return SelectionDecision(
|
|
86
|
+
family=SemanticFamily(best_name),
|
|
87
|
+
release_id=None,
|
|
88
|
+
selection_score=best_score,
|
|
89
|
+
rationale=f"selected highest eligible family score: {best_name}",
|
|
90
|
+
scores=scores,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _eligible_actions(
|
|
95
|
+
eligible_families: Collection[SemanticFamily] | None,
|
|
96
|
+
) -> tuple[SemanticFamily, ...]:
|
|
97
|
+
actions = (
|
|
98
|
+
SemanticFamily.REFORMULATE,
|
|
99
|
+
SemanticFamily.DECOMPOSE,
|
|
100
|
+
SemanticFamily.ACQUIRE,
|
|
101
|
+
SemanticFamily.CLARIFY,
|
|
102
|
+
SemanticFamily.CURATE,
|
|
103
|
+
)
|
|
104
|
+
if eligible_families is None:
|
|
105
|
+
return actions
|
|
106
|
+
eligible = tuple(eligible_families)
|
|
107
|
+
if any(not isinstance(family, SemanticFamily) for family in eligible):
|
|
108
|
+
raise ValueError("eligible_families must contain SemanticFamily values")
|
|
109
|
+
return tuple(family for family in actions if family in eligible)
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
"""Leakage-aware selector-to-intervention orchestration.
|
|
2
|
+
|
|
3
|
+
This module deliberately keeps feature extraction, release selection, and
|
|
4
|
+
intervention construction as separate auditable boundaries. A selector score
|
|
5
|
+
is not executable until the chosen release is validated against the canonical
|
|
6
|
+
registry and constructed by an explicitly locked factory.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
from collections.abc import Callable, Collection, Mapping
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from types import MappingProxyType
|
|
15
|
+
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
16
|
+
|
|
17
|
+
from agentinputlab.contracts.enums import SemanticFamily, StrEnum, SupportStatus
|
|
18
|
+
from agentinputlab.contracts.errors import RegistryError, ValidationError
|
|
19
|
+
from agentinputlab.contracts.lifecycle import Intervention, InterventionContext
|
|
20
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
21
|
+
from agentinputlab.contracts.state import FrozenAgentState
|
|
22
|
+
from agentinputlab.registry import AlgorithmRegistry
|
|
23
|
+
from agentinputlab.runner import InterventionRunner, RunRecord
|
|
24
|
+
|
|
25
|
+
from .base import SelectionDecision, SelectionFeatures, Selector
|
|
26
|
+
from .no_op import NoOpIntervention
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from .artifacts import SelectorArtifactBundle
|
|
30
|
+
|
|
31
|
+
_SHA256 = re.compile(r"^[0-9a-f]{64}$")
|
|
32
|
+
_DEFAULT_RUNNABLE_STATUSES = frozenset(
|
|
33
|
+
{
|
|
34
|
+
SupportStatus.EXPERIMENTAL,
|
|
35
|
+
SupportStatus.SUPPORTED,
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
_SELECTOR_ACTIONS = frozenset(
|
|
39
|
+
{
|
|
40
|
+
SemanticFamily.REFORMULATE,
|
|
41
|
+
SemanticFamily.DECOMPOSE,
|
|
42
|
+
SemanticFamily.ACQUIRE,
|
|
43
|
+
SemanticFamily.CLARIFY,
|
|
44
|
+
SemanticFamily.CURATE,
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class FeatureAccessDomain(StrEnum):
|
|
50
|
+
"""Domains a feature extractor may attest that it consulted."""
|
|
51
|
+
|
|
52
|
+
VISIBLE_PRE_ACTION = "visible_pre_action"
|
|
53
|
+
EVALUATOR_GOLD = "evaluator_gold"
|
|
54
|
+
POST_ACTION = "post_action"
|
|
55
|
+
OTHER_ARM_OUTCOME = "other_arm_outcome"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True, slots=True)
|
|
59
|
+
class FeatureObservation:
|
|
60
|
+
"""One feature vector bound to a visible pre-action state and extractor."""
|
|
61
|
+
|
|
62
|
+
features: SelectionFeatures
|
|
63
|
+
state_hash: str
|
|
64
|
+
extractor_id: str
|
|
65
|
+
extractor_revision: str
|
|
66
|
+
access_domains: tuple[FeatureAccessDomain, ...] = (FeatureAccessDomain.VISIBLE_PRE_ACTION,)
|
|
67
|
+
provenance: Mapping[str, object] = field(default_factory=dict)
|
|
68
|
+
|
|
69
|
+
def __post_init__(self) -> None:
|
|
70
|
+
if not isinstance(self.features, SelectionFeatures):
|
|
71
|
+
raise ValidationError("feature observation requires SelectionFeatures")
|
|
72
|
+
for label, value in (
|
|
73
|
+
("state_hash", self.state_hash),
|
|
74
|
+
("extractor_id", self.extractor_id),
|
|
75
|
+
("extractor_revision", self.extractor_revision),
|
|
76
|
+
):
|
|
77
|
+
if not isinstance(value, str) or not value.strip():
|
|
78
|
+
raise ValidationError(f"feature observation {label} must be non-empty")
|
|
79
|
+
domains = tuple(self.access_domains)
|
|
80
|
+
if not domains or any(not isinstance(item, FeatureAccessDomain) for item in domains):
|
|
81
|
+
raise ValidationError("feature access domains must be typed and non-empty")
|
|
82
|
+
if set(domains) != {FeatureAccessDomain.VISIBLE_PRE_ACTION}:
|
|
83
|
+
raise ValidationError(
|
|
84
|
+
"selector features may access visible_pre_action state only; "
|
|
85
|
+
"gold, post-action data, and other-arm outcomes are forbidden"
|
|
86
|
+
)
|
|
87
|
+
object.__setattr__(self, "access_domains", domains)
|
|
88
|
+
object.__setattr__(self, "provenance", freeze_mapping(self.provenance))
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def feature_hash(self) -> str:
|
|
92
|
+
return content_hash(self)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@runtime_checkable
|
|
96
|
+
class FeatureExtractor(Protocol):
|
|
97
|
+
"""Extract features from the physically gold-free state supplied by the runner."""
|
|
98
|
+
|
|
99
|
+
def extract(self, state: FrozenAgentState) -> FeatureObservation: ...
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True, slots=True)
|
|
103
|
+
class SelectorArtifactIdentity:
|
|
104
|
+
selector_id: str
|
|
105
|
+
revision: str
|
|
106
|
+
sha256: str
|
|
107
|
+
|
|
108
|
+
def __post_init__(self) -> None:
|
|
109
|
+
if not isinstance(self.selector_id, str) or not self.selector_id.strip():
|
|
110
|
+
raise ValidationError("selector_id must be non-empty")
|
|
111
|
+
if not isinstance(self.revision, str) or not self.revision.strip():
|
|
112
|
+
raise ValidationError("selector revision must be non-empty")
|
|
113
|
+
if not isinstance(self.sha256, str) or not _SHA256.fullmatch(self.sha256):
|
|
114
|
+
raise ValidationError("selector identity requires a lowercase SHA-256")
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_selector(
|
|
118
|
+
cls,
|
|
119
|
+
selector: Selector,
|
|
120
|
+
*,
|
|
121
|
+
selector_id: str,
|
|
122
|
+
revision: str,
|
|
123
|
+
) -> SelectorArtifactIdentity:
|
|
124
|
+
declared = getattr(selector, "model_hash", None)
|
|
125
|
+
if isinstance(declared, str) and _SHA256.fullmatch(declared):
|
|
126
|
+
digest = declared
|
|
127
|
+
else:
|
|
128
|
+
try:
|
|
129
|
+
digest = content_hash(selector)
|
|
130
|
+
except TypeError as exc:
|
|
131
|
+
raise ValidationError(
|
|
132
|
+
"selector is not canonically hashable; provide a frozen selector artifact"
|
|
133
|
+
) from exc
|
|
134
|
+
return cls(selector_id=selector_id, revision=revision, sha256=digest)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@runtime_checkable
|
|
138
|
+
class InterventionFactory(Protocol):
|
|
139
|
+
def create(self, release_id: str) -> Intervention: ...
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass(frozen=True, slots=True)
|
|
143
|
+
class RegistryInterventionFactory:
|
|
144
|
+
"""Construct only explicitly registered and locally approved releases."""
|
|
145
|
+
|
|
146
|
+
builders: Mapping[str, Callable[[], Intervention]]
|
|
147
|
+
registry: AlgorithmRegistry = field(default_factory=AlgorithmRegistry.default)
|
|
148
|
+
allowed_statuses: frozenset[SupportStatus] = _DEFAULT_RUNNABLE_STATUSES
|
|
149
|
+
|
|
150
|
+
def __post_init__(self) -> None:
|
|
151
|
+
builders = dict(self.builders)
|
|
152
|
+
if not builders:
|
|
153
|
+
raise ValidationError("intervention factory requires at least one builder")
|
|
154
|
+
statuses = frozenset(self.allowed_statuses)
|
|
155
|
+
if not statuses or any(not isinstance(item, SupportStatus) for item in statuses):
|
|
156
|
+
raise ValidationError("allowed_statuses must contain SupportStatus values")
|
|
157
|
+
for release_id, builder in builders.items():
|
|
158
|
+
if not isinstance(release_id, str) or not release_id.strip() or not callable(builder):
|
|
159
|
+
raise ValidationError("factory builders require release IDs and callables")
|
|
160
|
+
self.registry.get_release(release_id)
|
|
161
|
+
object.__setattr__(self, "builders", MappingProxyType(builders))
|
|
162
|
+
object.__setattr__(self, "allowed_statuses", statuses)
|
|
163
|
+
|
|
164
|
+
def create(self, release_id: str) -> Intervention:
|
|
165
|
+
method, release = self.registry.get_release(release_id)
|
|
166
|
+
if release.status not in self.allowed_statuses:
|
|
167
|
+
raise RegistryError(
|
|
168
|
+
f"selector release {release_id} has status {release.status.value}, "
|
|
169
|
+
"which is not enabled by this factory"
|
|
170
|
+
)
|
|
171
|
+
try:
|
|
172
|
+
intervention = self.builders[release_id]()
|
|
173
|
+
except KeyError as exc:
|
|
174
|
+
raise RegistryError(f"selector release {release_id} has no locked builder") from exc
|
|
175
|
+
if not isinstance(intervention, Intervention):
|
|
176
|
+
raise ValidationError("release builder did not return an Intervention")
|
|
177
|
+
if intervention.release_id != release_id:
|
|
178
|
+
raise ValidationError("release builder returned a different release identity")
|
|
179
|
+
if intervention.method_id != method.method_id:
|
|
180
|
+
raise ValidationError("release builder returned a different method identity")
|
|
181
|
+
if intervention.family is not method.semantic_family:
|
|
182
|
+
raise ValidationError("release builder returned a different semantic family")
|
|
183
|
+
return intervention
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@dataclass(frozen=True, slots=True)
|
|
187
|
+
class SelectorRunRecord:
|
|
188
|
+
input_state_hash: str
|
|
189
|
+
feature_hash: str
|
|
190
|
+
selector_identity: SelectorArtifactIdentity
|
|
191
|
+
decision: SelectionDecision
|
|
192
|
+
executed_release_id: str
|
|
193
|
+
run: RunRecord
|
|
194
|
+
feature_observation: FeatureObservation | None = None
|
|
195
|
+
|
|
196
|
+
def __post_init__(self) -> None:
|
|
197
|
+
if self.input_state_hash != self.run.input_state_hash:
|
|
198
|
+
raise ValidationError("selector and intervention input state hashes differ")
|
|
199
|
+
if self.executed_release_id != self.run.release_id:
|
|
200
|
+
raise ValidationError("selector and intervention release IDs differ")
|
|
201
|
+
if self.feature_observation is not None:
|
|
202
|
+
if not isinstance(self.feature_observation, FeatureObservation):
|
|
203
|
+
raise ValidationError("selector run feature_observation has an invalid type")
|
|
204
|
+
if self.feature_observation.feature_hash != self.feature_hash:
|
|
205
|
+
raise ValidationError("selector run feature hash differs from its observation")
|
|
206
|
+
if self.feature_observation.state_hash != self.input_state_hash:
|
|
207
|
+
raise ValidationError("selector run observation is bound to another input state")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class SelectorRuntime:
|
|
211
|
+
"""Extract, select, resolve, and execute one intervention or explicit NO_OP."""
|
|
212
|
+
|
|
213
|
+
def __init__(
|
|
214
|
+
self,
|
|
215
|
+
*,
|
|
216
|
+
selector: Selector,
|
|
217
|
+
selector_identity: SelectorArtifactIdentity,
|
|
218
|
+
feature_extractor: FeatureExtractor,
|
|
219
|
+
factory: InterventionFactory,
|
|
220
|
+
representative_by_family: Mapping[SemanticFamily, str] | None = None,
|
|
221
|
+
registry: AlgorithmRegistry | None = None,
|
|
222
|
+
runner: InterventionRunner | None = None,
|
|
223
|
+
selector_bundle: SelectorArtifactBundle | None = None,
|
|
224
|
+
) -> None:
|
|
225
|
+
if not isinstance(selector, Selector):
|
|
226
|
+
raise ValidationError("selector does not satisfy the Selector protocol")
|
|
227
|
+
if not isinstance(feature_extractor, FeatureExtractor):
|
|
228
|
+
raise ValidationError("feature extractor does not satisfy its protocol")
|
|
229
|
+
if not isinstance(factory, InterventionFactory):
|
|
230
|
+
raise ValidationError("intervention factory does not satisfy its protocol")
|
|
231
|
+
if not isinstance(selector_identity, SelectorArtifactIdentity):
|
|
232
|
+
raise ValidationError("selector_identity must be SelectorArtifactIdentity")
|
|
233
|
+
from .artifacts import (
|
|
234
|
+
SelectorArtifactBundle,
|
|
235
|
+
SelectorArtifactStage,
|
|
236
|
+
selector_model_hash,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
expected_identity = SelectorArtifactIdentity.from_selector(
|
|
240
|
+
selector,
|
|
241
|
+
selector_id=selector_identity.selector_id,
|
|
242
|
+
revision=selector_identity.revision,
|
|
243
|
+
)
|
|
244
|
+
extractor_id = getattr(feature_extractor, "extractor_id", None)
|
|
245
|
+
extractor_revision = getattr(feature_extractor, "extractor_revision", None)
|
|
246
|
+
extractor_hash = getattr(feature_extractor, "extractor_hash", None)
|
|
247
|
+
feature_schema_id = getattr(feature_extractor, "feature_schema_id", None)
|
|
248
|
+
feature_schema_hash = getattr(feature_extractor, "feature_schema_hash", None)
|
|
249
|
+
if selector_bundle is None:
|
|
250
|
+
if selector_identity.sha256 != expected_identity.sha256:
|
|
251
|
+
raise ValidationError("selector identity does not match the supplied model")
|
|
252
|
+
else:
|
|
253
|
+
if not isinstance(selector_bundle, SelectorArtifactBundle):
|
|
254
|
+
raise ValidationError("selector_bundle must be SelectorArtifactBundle")
|
|
255
|
+
if selector_bundle.stage is not SelectorArtifactStage.FROZEN:
|
|
256
|
+
raise ValidationError("SelectorRuntime requires a frozen selector bundle")
|
|
257
|
+
if (
|
|
258
|
+
selector_identity.selector_id != selector_bundle.selector_card_id
|
|
259
|
+
or selector_identity.revision != selector_bundle.revision
|
|
260
|
+
or selector_identity.sha256 != selector_bundle.bundle_hash
|
|
261
|
+
):
|
|
262
|
+
raise ValidationError("selector identity does not match its frozen bundle")
|
|
263
|
+
if selector_model_hash(selector) != selector_bundle.model_hash:
|
|
264
|
+
raise ValidationError("selector model does not match its frozen bundle")
|
|
265
|
+
if (
|
|
266
|
+
extractor_id != selector_bundle.extractor_id
|
|
267
|
+
or extractor_revision != selector_bundle.extractor_revision
|
|
268
|
+
or extractor_hash != selector_bundle.extractor_hash
|
|
269
|
+
):
|
|
270
|
+
raise ValidationError(
|
|
271
|
+
"feature extractor identity does not match the frozen selector bundle"
|
|
272
|
+
)
|
|
273
|
+
if (
|
|
274
|
+
feature_schema_id != selector_bundle.feature_schema_id
|
|
275
|
+
or feature_schema_hash != selector_bundle.feature_schema_hash
|
|
276
|
+
):
|
|
277
|
+
raise ValidationError(
|
|
278
|
+
"feature schema identity does not match the frozen selector bundle"
|
|
279
|
+
)
|
|
280
|
+
representatives = dict(representative_by_family or {})
|
|
281
|
+
if any(
|
|
282
|
+
not isinstance(family, SemanticFamily)
|
|
283
|
+
or family in {SemanticFamily.NO_OP, SemanticFamily.COMPOSITE}
|
|
284
|
+
or not isinstance(release_id, str)
|
|
285
|
+
or not release_id.strip()
|
|
286
|
+
for family, release_id in representatives.items()
|
|
287
|
+
):
|
|
288
|
+
raise ValidationError("representative mapping requires intervention families and IDs")
|
|
289
|
+
model_representatives = getattr(selector, "release_by_family", None)
|
|
290
|
+
if isinstance(model_representatives, Mapping):
|
|
291
|
+
declared = dict(model_representatives)
|
|
292
|
+
overlap = set(representatives) & set(declared)
|
|
293
|
+
if any(representatives[family] != declared[family] for family in overlap):
|
|
294
|
+
raise ValidationError(
|
|
295
|
+
"runtime representatives differ from selector release mapping"
|
|
296
|
+
)
|
|
297
|
+
representatives = {**declared, **representatives}
|
|
298
|
+
if selector_bundle is not None:
|
|
299
|
+
bundle_representatives = dict(selector_bundle.representative_by_family)
|
|
300
|
+
if representatives and representatives != bundle_representatives:
|
|
301
|
+
raise ValidationError(
|
|
302
|
+
"runtime representatives differ from the frozen selector bundle"
|
|
303
|
+
)
|
|
304
|
+
representatives = bundle_representatives
|
|
305
|
+
self.selector = selector
|
|
306
|
+
self.selector_identity = selector_identity
|
|
307
|
+
self.selector_bundle = selector_bundle
|
|
308
|
+
self.feature_extractor = feature_extractor
|
|
309
|
+
self.extractor_id = extractor_id
|
|
310
|
+
self.extractor_revision = extractor_revision
|
|
311
|
+
self.extractor_hash = extractor_hash
|
|
312
|
+
self.feature_schema_id = feature_schema_id
|
|
313
|
+
self.feature_schema_hash = feature_schema_hash
|
|
314
|
+
self.factory = factory
|
|
315
|
+
self.representative_by_family = MappingProxyType(representatives)
|
|
316
|
+
self.registry = registry or AlgorithmRegistry.default()
|
|
317
|
+
self.runner = runner or InterventionRunner()
|
|
318
|
+
for family, release_id in representatives.items():
|
|
319
|
+
method, _ = self.registry.get_release(release_id)
|
|
320
|
+
if method.semantic_family is not family:
|
|
321
|
+
raise ValidationError(
|
|
322
|
+
f"representative {release_id} does not belong to {family.value}"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
def run(
|
|
326
|
+
self,
|
|
327
|
+
state: FrozenAgentState,
|
|
328
|
+
context: InterventionContext,
|
|
329
|
+
*,
|
|
330
|
+
eligible_families: Collection[SemanticFamily] | None = None,
|
|
331
|
+
) -> SelectorRunRecord:
|
|
332
|
+
observation = self.feature_extractor.extract(state)
|
|
333
|
+
if not isinstance(observation, FeatureObservation):
|
|
334
|
+
raise ValidationError("feature extractor did not return FeatureObservation")
|
|
335
|
+
if observation.state_hash != state.state_hash:
|
|
336
|
+
raise ValidationError("feature observation is bound to another input state")
|
|
337
|
+
if (self.extractor_id is not None and observation.extractor_id != self.extractor_id) or (
|
|
338
|
+
self.extractor_revision is not None
|
|
339
|
+
and observation.extractor_revision != self.extractor_revision
|
|
340
|
+
):
|
|
341
|
+
raise ValidationError(
|
|
342
|
+
"feature observation identity differs from the configured extractor"
|
|
343
|
+
)
|
|
344
|
+
if self.selector_bundle is not None:
|
|
345
|
+
expected_provenance = {
|
|
346
|
+
"extractor_hash": self.selector_bundle.extractor_hash,
|
|
347
|
+
"schema_id": self.selector_bundle.feature_schema_id,
|
|
348
|
+
"schema_hash": self.selector_bundle.feature_schema_hash,
|
|
349
|
+
}
|
|
350
|
+
if any(
|
|
351
|
+
observation.provenance.get(key) != value
|
|
352
|
+
for key, value in expected_provenance.items()
|
|
353
|
+
):
|
|
354
|
+
raise ValidationError(
|
|
355
|
+
"feature observation provenance differs from the frozen selector bundle"
|
|
356
|
+
)
|
|
357
|
+
decision = self.selector.select(
|
|
358
|
+
state,
|
|
359
|
+
observation.features,
|
|
360
|
+
eligible_families=eligible_families,
|
|
361
|
+
)
|
|
362
|
+
if not isinstance(decision, SelectionDecision):
|
|
363
|
+
raise ValidationError("selector did not return SelectionDecision")
|
|
364
|
+
if decision.family not in {*_SELECTOR_ACTIONS, SemanticFamily.NO_OP}:
|
|
365
|
+
raise ValidationError(f"selector chose unsupported family {decision.family.value}")
|
|
366
|
+
if eligible_families is not None:
|
|
367
|
+
eligible = tuple(eligible_families)
|
|
368
|
+
if any(not isinstance(family, SemanticFamily) for family in eligible):
|
|
369
|
+
raise ValidationError("eligible_families must contain SemanticFamily values")
|
|
370
|
+
if decision.family is not SemanticFamily.NO_OP and decision.family not in eligible:
|
|
371
|
+
raise ValidationError(f"selector chose ineligible family {decision.family.value}")
|
|
372
|
+
if decision.family is SemanticFamily.NO_OP:
|
|
373
|
+
if decision.release_id not in {None, "baseline.no_op"}:
|
|
374
|
+
raise ValidationError("NO_OP selector decisions may reference baseline.no_op only")
|
|
375
|
+
intervention: Intervention = NoOpIntervention()
|
|
376
|
+
else:
|
|
377
|
+
locked_release = self.representative_by_family.get(decision.family)
|
|
378
|
+
if (
|
|
379
|
+
decision.release_id is not None
|
|
380
|
+
and locked_release is not None
|
|
381
|
+
and decision.release_id != locked_release
|
|
382
|
+
):
|
|
383
|
+
raise RegistryError(
|
|
384
|
+
f"selector chose release {decision.release_id} instead of frozen "
|
|
385
|
+
f"representative {locked_release}"
|
|
386
|
+
)
|
|
387
|
+
release_id = decision.release_id or locked_release
|
|
388
|
+
if release_id is None:
|
|
389
|
+
raise RegistryError(
|
|
390
|
+
f"selector chose {decision.family.value} without a release or locked representative"
|
|
391
|
+
)
|
|
392
|
+
method, _ = self.registry.get_release(release_id)
|
|
393
|
+
if method.semantic_family is not decision.family:
|
|
394
|
+
raise RegistryError(
|
|
395
|
+
f"selector release {release_id} belongs to {method.semantic_family.value}, "
|
|
396
|
+
f"not {decision.family.value}"
|
|
397
|
+
)
|
|
398
|
+
intervention = self.factory.create(release_id)
|
|
399
|
+
run = self.runner.run(intervention, state, context)
|
|
400
|
+
return SelectorRunRecord(
|
|
401
|
+
input_state_hash=state.state_hash,
|
|
402
|
+
feature_hash=observation.feature_hash,
|
|
403
|
+
selector_identity=self.selector_identity,
|
|
404
|
+
decision=decision,
|
|
405
|
+
executed_release_id=intervention.release_id,
|
|
406
|
+
run=run,
|
|
407
|
+
feature_observation=observation,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
__all__ = [
|
|
412
|
+
"FeatureAccessDomain",
|
|
413
|
+
"FeatureExtractor",
|
|
414
|
+
"FeatureObservation",
|
|
415
|
+
"InterventionFactory",
|
|
416
|
+
"RegistryInterventionFactory",
|
|
417
|
+
"SelectorArtifactIdentity",
|
|
418
|
+
"SelectorRunRecord",
|
|
419
|
+
"SelectorRuntime",
|
|
420
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Smoke, discovery, confirmation, selector, and transfer study orchestration."""
|
|
2
|
+
|
|
3
|
+
from .design import StudyArmSpec, StudyCell, StudyPlan, build_study_plan
|
|
4
|
+
from .paired import ArmFailure, ArmOutcome, PairedArm, PairedRun, PairedStudyRunner
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"ArmFailure",
|
|
8
|
+
"ArmOutcome",
|
|
9
|
+
"PairedArm",
|
|
10
|
+
"PairedRun",
|
|
11
|
+
"PairedStudyRunner",
|
|
12
|
+
"StudyArmSpec",
|
|
13
|
+
"StudyCell",
|
|
14
|
+
"StudyPlan",
|
|
15
|
+
"build_study_plan",
|
|
16
|
+
]
|