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,1202 @@
|
|
|
1
|
+
"""Controlled Adaptive-RAG router-parity reimplementation.
|
|
2
|
+
|
|
3
|
+
The pinned upstream implementation trains a T5-large complexity classifier and,
|
|
4
|
+
at inference time, takes an argmax over the first decoder-step logits for the
|
|
5
|
+
tokens ``A``, ``B``, and ``C``. Those labels select no retrieval, one retrieval,
|
|
6
|
+
and IRCoT respectively. The legacy stack depends on a large, pinned
|
|
7
|
+
Elasticsearch/LLM environment, so this release preserves the published router
|
|
8
|
+
decision rule while executing explicitly controlled, replaceable arm
|
|
9
|
+
implementations in an isolated worker. It is not the upstream script or an
|
|
10
|
+
upstream arm-parity claim. This module validates the selected controlled arm,
|
|
11
|
+
evaluation-label separation, component closure, budgets, and retrieval
|
|
12
|
+
trajectory.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import math
|
|
18
|
+
import re
|
|
19
|
+
from collections.abc import Mapping
|
|
20
|
+
from dataclasses import asdict, dataclass, field
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from agentinputlab.contracts import (
|
|
24
|
+
AlgorithmOutputError,
|
|
25
|
+
BudgetExceededError,
|
|
26
|
+
CompositeResult,
|
|
27
|
+
ContextBlock,
|
|
28
|
+
ExecutionTrace,
|
|
29
|
+
FrozenAgentState,
|
|
30
|
+
InterventionContext,
|
|
31
|
+
SemanticFamily,
|
|
32
|
+
TraceEvent,
|
|
33
|
+
TracePhase,
|
|
34
|
+
ValidationError,
|
|
35
|
+
)
|
|
36
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
37
|
+
from agentinputlab.integrations.external_workers import WorkerClient
|
|
38
|
+
from agentinputlab.integrations.external_workers.method import (
|
|
39
|
+
MethodWorkerRequest,
|
|
40
|
+
call_worker,
|
|
41
|
+
finite_number,
|
|
42
|
+
mapping_sequence,
|
|
43
|
+
optional_text,
|
|
44
|
+
required_text,
|
|
45
|
+
resolve_worker,
|
|
46
|
+
string_tuple,
|
|
47
|
+
worker_fingerprint,
|
|
48
|
+
)
|
|
49
|
+
from agentinputlab.observability import external_usage_counters
|
|
50
|
+
|
|
51
|
+
from .replay import ADAPTIVE_RAG_UPSTREAM_COMMIT, AdaptiveRAGStrategy
|
|
52
|
+
|
|
53
|
+
_HEX64 = re.compile(r"[0-9a-f]{64}")
|
|
54
|
+
_ROUTE_ORDER = ("A", "B", "C")
|
|
55
|
+
_ROUTE_TO_STRATEGY = {
|
|
56
|
+
"A": AdaptiveRAGStrategy.NO_RETRIEVAL,
|
|
57
|
+
"B": AdaptiveRAGStrategy.SINGLE_RETRIEVAL,
|
|
58
|
+
"C": AdaptiveRAGStrategy.IRCOT,
|
|
59
|
+
}
|
|
60
|
+
ADAPTIVE_RAG_UPSTREAM_TREE = "8dadc754562d61d5d6e6e3ee2fc3aa4481763320"
|
|
61
|
+
ADAPTIVE_RAG_COMPATIBILITY_MANIFEST_SHA256 = (
|
|
62
|
+
"85299456b7f858734c34de84fe4625e0a014651242001d7242ca33b260be7382"
|
|
63
|
+
)
|
|
64
|
+
ADAPTIVE_RAG_SOURCE_CLOSURE_SHA256 = (
|
|
65
|
+
"43677c9862dd16a69aafadab36a7ac9ca9cdfb037c8854321e64a2a3df14597c"
|
|
66
|
+
)
|
|
67
|
+
_SUPERVISOR_EVENT_SCHEMA = "agentinputlab.adaptive-rag.supervisor-event.v1"
|
|
68
|
+
_EXECUTION_EVIDENCE_SCHEMA = "agentinputlab.adaptive-rag.execution-evidence.v1"
|
|
69
|
+
_ALLOWED_DOCUMENT_METADATA = frozenset({"source_uri", "chunk_index", "language", "content_sha256"})
|
|
70
|
+
_EVENT_USAGE_FIELDS = (
|
|
71
|
+
"model_calls",
|
|
72
|
+
"retrieval_calls",
|
|
73
|
+
"tool_calls",
|
|
74
|
+
"embedding_calls",
|
|
75
|
+
"unpriced_model_calls",
|
|
76
|
+
"input_tokens",
|
|
77
|
+
"output_tokens",
|
|
78
|
+
"cpu_seconds",
|
|
79
|
+
"accelerator_seconds",
|
|
80
|
+
"cost_usd",
|
|
81
|
+
"compute_cost_usd",
|
|
82
|
+
)
|
|
83
|
+
_EVENT_RESERVATION_FIELDS = frozenset(
|
|
84
|
+
{
|
|
85
|
+
"model_calls",
|
|
86
|
+
"retrieval_calls",
|
|
87
|
+
"estimated_input_tokens",
|
|
88
|
+
"max_output_tokens",
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _pinned_revision(value: object, *, label: str) -> str:
|
|
94
|
+
if not isinstance(value, str) or not value.strip():
|
|
95
|
+
raise ValidationError(f"Adaptive-RAG {label} must be a non-empty revision")
|
|
96
|
+
revision = value.strip()
|
|
97
|
+
if revision.lower() in {"default", "head", "latest", "main", "master"}:
|
|
98
|
+
raise ValidationError(f"Adaptive-RAG {label} must be immutable")
|
|
99
|
+
return revision
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _sha256(value: object, *, label: str) -> str:
|
|
103
|
+
if not isinstance(value, str) or not _HEX64.fullmatch(value):
|
|
104
|
+
raise ValidationError(f"Adaptive-RAG {label} must be a lowercase SHA-256 digest")
|
|
105
|
+
return value
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _validated_document_metadata(value: Mapping[str, Any]) -> dict[str, Any]:
|
|
109
|
+
"""Accept only non-oracle corpus provenance exposed to the generator."""
|
|
110
|
+
|
|
111
|
+
unknown = set(value) - _ALLOWED_DOCUMENT_METADATA
|
|
112
|
+
if unknown:
|
|
113
|
+
raise AlgorithmOutputError(
|
|
114
|
+
"Adaptive-RAG document metadata contains non-allowlisted fields: "
|
|
115
|
+
+ ", ".join(sorted(str(item) for item in unknown))
|
|
116
|
+
)
|
|
117
|
+
normalized: dict[str, Any] = {}
|
|
118
|
+
for key, item in value.items():
|
|
119
|
+
if key in {"source_uri", "language"}:
|
|
120
|
+
if not isinstance(item, str) or not item.strip():
|
|
121
|
+
raise AlgorithmOutputError(
|
|
122
|
+
f"Adaptive-RAG document metadata {key} must be non-empty text"
|
|
123
|
+
)
|
|
124
|
+
normalized[key] = item.strip()
|
|
125
|
+
elif key == "chunk_index":
|
|
126
|
+
if isinstance(item, bool) or not isinstance(item, int) or item < 0:
|
|
127
|
+
raise AlgorithmOutputError(
|
|
128
|
+
"Adaptive-RAG document metadata chunk_index must be non-negative"
|
|
129
|
+
)
|
|
130
|
+
normalized[key] = item
|
|
131
|
+
else:
|
|
132
|
+
if not isinstance(item, str) or _HEX64.fullmatch(item) is None:
|
|
133
|
+
raise AlgorithmOutputError(
|
|
134
|
+
"Adaptive-RAG document metadata content_sha256 must be a SHA-256 digest"
|
|
135
|
+
)
|
|
136
|
+
normalized[key] = item
|
|
137
|
+
return normalized
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@dataclass(frozen=True, slots=True)
|
|
141
|
+
class AdaptiveRAGArtifactIdentity:
|
|
142
|
+
"""Pinned classifier, generator, retrieval, and prompt identities.
|
|
143
|
+
|
|
144
|
+
The base model and retriever are deliberately configurable, but every
|
|
145
|
+
replacement produces a different identity hash. This prevents a router
|
|
146
|
+
trained for one three-arm bundle from being silently reused with another.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
router_checkpoint: str
|
|
150
|
+
worker_fingerprint_sha256: str
|
|
151
|
+
router_revision: str
|
|
152
|
+
router_snapshot_sha256: str
|
|
153
|
+
router_weights_sha256: str
|
|
154
|
+
router_tokenizer_sha256: str
|
|
155
|
+
base_model_revision: str
|
|
156
|
+
generator_artifact_sha256: str
|
|
157
|
+
generator_config_sha256: str
|
|
158
|
+
retriever_revision: str
|
|
159
|
+
retriever_implementation_sha256: str
|
|
160
|
+
retriever_config_sha256: str
|
|
161
|
+
corpus_revision: str
|
|
162
|
+
corpus_manifest_sha256: str
|
|
163
|
+
index_revision: str
|
|
164
|
+
index_manifest_sha256: str
|
|
165
|
+
no_retrieval_prompt_sha256: str
|
|
166
|
+
single_retrieval_prompt_sha256: str
|
|
167
|
+
ircot_prompt_sha256: str
|
|
168
|
+
upstream_commit: str = ADAPTIVE_RAG_UPSTREAM_COMMIT
|
|
169
|
+
|
|
170
|
+
def __post_init__(self) -> None:
|
|
171
|
+
if self.upstream_commit != ADAPTIVE_RAG_UPSTREAM_COMMIT:
|
|
172
|
+
raise ValidationError("Adaptive-RAG artifacts target an unsupported upstream commit")
|
|
173
|
+
for name in (
|
|
174
|
+
"router_checkpoint",
|
|
175
|
+
"router_revision",
|
|
176
|
+
"base_model_revision",
|
|
177
|
+
"retriever_revision",
|
|
178
|
+
"corpus_revision",
|
|
179
|
+
"index_revision",
|
|
180
|
+
):
|
|
181
|
+
object.__setattr__(
|
|
182
|
+
self,
|
|
183
|
+
name,
|
|
184
|
+
_pinned_revision(getattr(self, name), label=name),
|
|
185
|
+
)
|
|
186
|
+
for name in (
|
|
187
|
+
"worker_fingerprint_sha256",
|
|
188
|
+
"router_snapshot_sha256",
|
|
189
|
+
"router_weights_sha256",
|
|
190
|
+
"router_tokenizer_sha256",
|
|
191
|
+
"generator_artifact_sha256",
|
|
192
|
+
"generator_config_sha256",
|
|
193
|
+
"retriever_implementation_sha256",
|
|
194
|
+
"retriever_config_sha256",
|
|
195
|
+
"corpus_manifest_sha256",
|
|
196
|
+
"index_manifest_sha256",
|
|
197
|
+
"no_retrieval_prompt_sha256",
|
|
198
|
+
"single_retrieval_prompt_sha256",
|
|
199
|
+
"ircot_prompt_sha256",
|
|
200
|
+
):
|
|
201
|
+
object.__setattr__(self, name, _sha256(getattr(self, name), label=name))
|
|
202
|
+
|
|
203
|
+
def as_mapping(self) -> Mapping[str, Any]:
|
|
204
|
+
return freeze_mapping(asdict(self))
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def identity_sha256(self) -> str:
|
|
208
|
+
return content_hash(self.as_mapping())
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@dataclass(frozen=True, slots=True)
|
|
212
|
+
class AdaptiveRAGControls:
|
|
213
|
+
"""Explicit resource and retrieval settings for the three strategy arms."""
|
|
214
|
+
|
|
215
|
+
single_retrieval_top_k: int = 15
|
|
216
|
+
ircot_per_step_top_k: int = 6
|
|
217
|
+
ircot_max_steps: int = 8
|
|
218
|
+
max_total_documents: int = 64
|
|
219
|
+
max_output_tokens: int = 4096
|
|
220
|
+
ircot_reset_policy: str = "upstream_native"
|
|
221
|
+
deduplicate_documents: bool = True
|
|
222
|
+
|
|
223
|
+
def __post_init__(self) -> None:
|
|
224
|
+
for name in (
|
|
225
|
+
"single_retrieval_top_k",
|
|
226
|
+
"ircot_per_step_top_k",
|
|
227
|
+
"ircot_max_steps",
|
|
228
|
+
"max_total_documents",
|
|
229
|
+
"max_output_tokens",
|
|
230
|
+
):
|
|
231
|
+
value = getattr(self, name)
|
|
232
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
233
|
+
raise ValidationError(f"Adaptive-RAG {name} must be a positive integer")
|
|
234
|
+
if self.ircot_reset_policy not in {
|
|
235
|
+
"upstream_native",
|
|
236
|
+
"never",
|
|
237
|
+
"replace_each_step",
|
|
238
|
+
}:
|
|
239
|
+
raise ValidationError("Adaptive-RAG ircot_reset_policy is unsupported")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass(frozen=True, slots=True)
|
|
243
|
+
class AdaptiveRAGDocument:
|
|
244
|
+
document_id: str
|
|
245
|
+
text: str
|
|
246
|
+
title: str
|
|
247
|
+
corpus_revision: str
|
|
248
|
+
score: float | None = None
|
|
249
|
+
metadata: Mapping[str, Any] = field(default_factory=dict)
|
|
250
|
+
|
|
251
|
+
def __post_init__(self) -> None:
|
|
252
|
+
if not self.document_id.strip() or not self.text:
|
|
253
|
+
raise AlgorithmOutputError("Adaptive-RAG documents require ID and text")
|
|
254
|
+
if not self.corpus_revision.strip():
|
|
255
|
+
raise AlgorithmOutputError("Adaptive-RAG documents require corpus_revision")
|
|
256
|
+
if self.score is not None and (
|
|
257
|
+
isinstance(self.score, bool)
|
|
258
|
+
or not isinstance(self.score, (int, float))
|
|
259
|
+
or not math.isfinite(float(self.score))
|
|
260
|
+
):
|
|
261
|
+
raise AlgorithmOutputError("Adaptive-RAG document score must be finite or None")
|
|
262
|
+
if not isinstance(self.metadata, Mapping):
|
|
263
|
+
raise AlgorithmOutputError("Adaptive-RAG document metadata must be a mapping")
|
|
264
|
+
object.__setattr__(
|
|
265
|
+
self,
|
|
266
|
+
"metadata",
|
|
267
|
+
freeze_mapping(_validated_document_metadata(self.metadata)),
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
@classmethod
|
|
271
|
+
def from_mapping(cls, value: Mapping[str, Any]) -> AdaptiveRAGDocument:
|
|
272
|
+
score_value = value.get("score")
|
|
273
|
+
score = (
|
|
274
|
+
None
|
|
275
|
+
if score_value is None
|
|
276
|
+
else finite_number(score_value, label="Adaptive-RAG document score")
|
|
277
|
+
)
|
|
278
|
+
metadata = value.get("metadata", {})
|
|
279
|
+
if not isinstance(metadata, Mapping):
|
|
280
|
+
raise AlgorithmOutputError("Adaptive-RAG document metadata must be a mapping")
|
|
281
|
+
return cls(
|
|
282
|
+
document_id=required_text(value, "document_id", label="Adaptive-RAG document"),
|
|
283
|
+
text=required_text(value, "text", label="Adaptive-RAG document"),
|
|
284
|
+
title=optional_text(value, "title", label="Adaptive-RAG document"),
|
|
285
|
+
corpus_revision=required_text(
|
|
286
|
+
value,
|
|
287
|
+
"corpus_revision",
|
|
288
|
+
label="Adaptive-RAG document",
|
|
289
|
+
),
|
|
290
|
+
score=score,
|
|
291
|
+
metadata=dict(metadata),
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@dataclass(frozen=True, slots=True)
|
|
296
|
+
class AdaptiveRAGInitialRetrieval:
|
|
297
|
+
query: str
|
|
298
|
+
document_ids: tuple[str, ...]
|
|
299
|
+
|
|
300
|
+
@classmethod
|
|
301
|
+
def from_mapping(cls, value: Mapping[str, Any]) -> AdaptiveRAGInitialRetrieval:
|
|
302
|
+
return cls(
|
|
303
|
+
query=required_text(value, "query", label="Adaptive-RAG initial retrieval"),
|
|
304
|
+
document_ids=string_tuple(
|
|
305
|
+
value.get("document_ids"),
|
|
306
|
+
label="Adaptive-RAG initial retrieval document_ids",
|
|
307
|
+
allow_empty=False,
|
|
308
|
+
unique=True,
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@dataclass(frozen=True, slots=True)
|
|
314
|
+
class AdaptiveRAGIRCoTStep:
|
|
315
|
+
index: int
|
|
316
|
+
cot_step: str
|
|
317
|
+
latest_cot_sentence: str
|
|
318
|
+
retrieval_query: str
|
|
319
|
+
retrieved_document_ids: tuple[str, ...]
|
|
320
|
+
new_document_ids: tuple[str, ...]
|
|
321
|
+
active_document_ids: tuple[str, ...]
|
|
322
|
+
reset_applied: bool
|
|
323
|
+
|
|
324
|
+
@classmethod
|
|
325
|
+
def from_mapping(cls, value: Mapping[str, Any]) -> AdaptiveRAGIRCoTStep:
|
|
326
|
+
index = value.get("index")
|
|
327
|
+
if isinstance(index, bool) or not isinstance(index, int) or index < 0:
|
|
328
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT step index must be non-negative")
|
|
329
|
+
reset = value.get("reset_applied", False)
|
|
330
|
+
if not isinstance(reset, bool):
|
|
331
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT reset_applied must be boolean")
|
|
332
|
+
cot_step = required_text(value, "cot_step", label="Adaptive-RAG IRCoT step")
|
|
333
|
+
latest = required_text(
|
|
334
|
+
value,
|
|
335
|
+
"latest_cot_sentence",
|
|
336
|
+
label="Adaptive-RAG IRCoT step",
|
|
337
|
+
)
|
|
338
|
+
query = required_text(
|
|
339
|
+
value,
|
|
340
|
+
"retrieval_query",
|
|
341
|
+
label="Adaptive-RAG IRCoT step",
|
|
342
|
+
)
|
|
343
|
+
if not cot_step.rstrip().endswith(latest):
|
|
344
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT latest sentence must terminate cot_step")
|
|
345
|
+
if query.strip() != latest.strip():
|
|
346
|
+
raise AlgorithmOutputError(
|
|
347
|
+
"Adaptive-RAG IRCoT retrieval query must equal the latest CoT sentence"
|
|
348
|
+
)
|
|
349
|
+
return cls(
|
|
350
|
+
index=index,
|
|
351
|
+
cot_step=cot_step,
|
|
352
|
+
latest_cot_sentence=latest,
|
|
353
|
+
retrieval_query=query,
|
|
354
|
+
retrieved_document_ids=string_tuple(
|
|
355
|
+
value.get("retrieved_document_ids"),
|
|
356
|
+
label="Adaptive-RAG IRCoT retrieved_document_ids",
|
|
357
|
+
unique=True,
|
|
358
|
+
),
|
|
359
|
+
new_document_ids=string_tuple(
|
|
360
|
+
value.get("new_document_ids"),
|
|
361
|
+
label="Adaptive-RAG IRCoT new_document_ids",
|
|
362
|
+
unique=True,
|
|
363
|
+
),
|
|
364
|
+
active_document_ids=string_tuple(
|
|
365
|
+
value.get("active_document_ids"),
|
|
366
|
+
label="Adaptive-RAG IRCoT active_document_ids",
|
|
367
|
+
unique=True,
|
|
368
|
+
),
|
|
369
|
+
reset_applied=reset,
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
@dataclass(slots=True)
|
|
374
|
+
class AdaptiveRAGControlledWorker:
|
|
375
|
+
"""Run classifier inference and its selected QA arm in one pinned worker."""
|
|
376
|
+
|
|
377
|
+
artifacts: AdaptiveRAGArtifactIdentity
|
|
378
|
+
client: WorkerClient | None = None
|
|
379
|
+
controls: AdaptiveRAGControls = AdaptiveRAGControls()
|
|
380
|
+
method_id: str = "adaptive_rag"
|
|
381
|
+
release_id: str = "acquire.adaptive_rag.controlled_reimplementation"
|
|
382
|
+
family: SemanticFamily = SemanticFamily.ACQUIRE
|
|
383
|
+
expected_source_tree: str = ADAPTIVE_RAG_UPSTREAM_TREE
|
|
384
|
+
expected_compatibility_manifest_sha256: str = ADAPTIVE_RAG_COMPATIBILITY_MANIFEST_SHA256
|
|
385
|
+
expected_source_closure_sha256: str = ADAPTIVE_RAG_SOURCE_CLOSURE_SHA256
|
|
386
|
+
allow_fixture_runtime: bool = False
|
|
387
|
+
|
|
388
|
+
def __post_init__(self) -> None:
|
|
389
|
+
if not isinstance(self.artifacts, AdaptiveRAGArtifactIdentity):
|
|
390
|
+
raise ValidationError("Adaptive-RAG requires AdaptiveRAGArtifactIdentity")
|
|
391
|
+
if not isinstance(self.controls, AdaptiveRAGControls):
|
|
392
|
+
raise ValidationError("Adaptive-RAG controls must be AdaptiveRAGControls")
|
|
393
|
+
for name in (
|
|
394
|
+
"expected_source_tree",
|
|
395
|
+
"expected_compatibility_manifest_sha256",
|
|
396
|
+
"expected_source_closure_sha256",
|
|
397
|
+
):
|
|
398
|
+
value = getattr(self, name)
|
|
399
|
+
pattern = re.fullmatch(
|
|
400
|
+
r"[0-9a-f]{40}" if name == "expected_source_tree" else r"[0-9a-f]{64}",
|
|
401
|
+
value,
|
|
402
|
+
)
|
|
403
|
+
if pattern is None:
|
|
404
|
+
raise ValidationError(f"Adaptive-RAG {name} has an invalid digest")
|
|
405
|
+
if not isinstance(self.allow_fixture_runtime, bool):
|
|
406
|
+
raise ValidationError("Adaptive-RAG allow_fixture_runtime must be boolean")
|
|
407
|
+
|
|
408
|
+
def run(self, state: FrozenAgentState, context: InterventionContext) -> CompositeResult:
|
|
409
|
+
if not state.query.strip():
|
|
410
|
+
raise ValidationError("Adaptive-RAG requires a non-empty question")
|
|
411
|
+
if state.instruction.strip() or state.messages or state.context:
|
|
412
|
+
raise ValidationError(
|
|
413
|
+
"Adaptive-RAG controlled reimplementation accepts a question-only state; "
|
|
414
|
+
"instruction, messages, or preloaded context require a separate profile"
|
|
415
|
+
)
|
|
416
|
+
if state.budget.max_cost_usd is not None:
|
|
417
|
+
raise BudgetExceededError(
|
|
418
|
+
"Adaptive-RAG external execution has no pre-call cost upper bound"
|
|
419
|
+
)
|
|
420
|
+
remaining_budget = _remaining_budget(state, context)
|
|
421
|
+
if remaining_budget["model_calls"] < 2:
|
|
422
|
+
raise BudgetExceededError(
|
|
423
|
+
"Adaptive-RAG requires at least classifier and answer model calls"
|
|
424
|
+
)
|
|
425
|
+
if remaining_budget["output_tokens"] < 1:
|
|
426
|
+
raise BudgetExceededError("Adaptive-RAG has no remaining output-token budget")
|
|
427
|
+
|
|
428
|
+
worker = resolve_worker(self.client, context, label="Adaptive-RAG")
|
|
429
|
+
worker_identity = worker_fingerprint(worker, label="Adaptive-RAG")
|
|
430
|
+
if content_hash(worker_identity) != self.artifacts.worker_fingerprint_sha256:
|
|
431
|
+
raise ValidationError(
|
|
432
|
+
"Adaptive-RAG worker fingerprint does not match the locked artifact bundle"
|
|
433
|
+
)
|
|
434
|
+
artifact_mapping = self.artifacts.as_mapping()
|
|
435
|
+
request = MethodWorkerRequest(
|
|
436
|
+
method_id=self.method_id,
|
|
437
|
+
release_id=self.release_id,
|
|
438
|
+
upstream_commit=ADAPTIVE_RAG_UPSTREAM_COMMIT,
|
|
439
|
+
state_hash=state.state_hash,
|
|
440
|
+
payload={
|
|
441
|
+
"task_id": state.task_id,
|
|
442
|
+
"question": state.query,
|
|
443
|
+
"artifacts": artifact_mapping,
|
|
444
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
445
|
+
"controls": asdict(self.controls),
|
|
446
|
+
"remaining_budget": remaining_budget,
|
|
447
|
+
"seed": context.seed,
|
|
448
|
+
"execution_contract": {
|
|
449
|
+
"input_view": "question_only",
|
|
450
|
+
"route_labels": list(_ROUTE_ORDER),
|
|
451
|
+
"route_rule": "first_decoder_step_logit_argmax_A_first",
|
|
452
|
+
"strategy_map": {
|
|
453
|
+
"A": AdaptiveRAGStrategy.NO_RETRIEVAL.value,
|
|
454
|
+
"B": AdaptiveRAGStrategy.SINGLE_RETRIEVAL.value,
|
|
455
|
+
"C": AdaptiveRAGStrategy.IRCOT.value,
|
|
456
|
+
},
|
|
457
|
+
"evaluation_label_access": "none",
|
|
458
|
+
"selected_arm_only": True,
|
|
459
|
+
"fallback_allowed": False,
|
|
460
|
+
"arm_execution_semantics": "controlled_reimplementation",
|
|
461
|
+
"upstream_router_parity": True,
|
|
462
|
+
"supervisor_event_schema": _SUPERVISOR_EVENT_SCHEMA,
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
dependency_fingerprints={
|
|
466
|
+
"worker": worker_identity,
|
|
467
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
468
|
+
},
|
|
469
|
+
minimum_reservation={"model_calls": 2},
|
|
470
|
+
protocol_version="agentinputlab.adaptive-rag.v1",
|
|
471
|
+
)
|
|
472
|
+
response = call_worker(worker, request)
|
|
473
|
+
payload = response.payload
|
|
474
|
+
_validate_identity(payload, artifacts=self.artifacts)
|
|
475
|
+
if required_text(payload, "question", label="Adaptive-RAG response") != state.query:
|
|
476
|
+
raise AlgorithmOutputError("Adaptive-RAG worker changed the classifier question")
|
|
477
|
+
|
|
478
|
+
route_logits = _parse_route_logits(payload.get("route_logits"))
|
|
479
|
+
expected_label = max(_ROUTE_ORDER, key=lambda label: route_logits[label])
|
|
480
|
+
route_label = required_text(payload, "route_label", label="Adaptive-RAG response")
|
|
481
|
+
if route_label not in _ROUTE_TO_STRATEGY:
|
|
482
|
+
raise AlgorithmOutputError("Adaptive-RAG route_label must be A, B, or C")
|
|
483
|
+
if route_label != expected_label:
|
|
484
|
+
raise AlgorithmOutputError("Adaptive-RAG route does not match first-step logit argmax")
|
|
485
|
+
strategy = _ROUTE_TO_STRATEGY[route_label]
|
|
486
|
+
selected_strategy = required_text(
|
|
487
|
+
payload,
|
|
488
|
+
"selected_strategy",
|
|
489
|
+
label="Adaptive-RAG response",
|
|
490
|
+
)
|
|
491
|
+
if selected_strategy != strategy.value:
|
|
492
|
+
raise AlgorithmOutputError(
|
|
493
|
+
"Adaptive-RAG selected strategy does not match classifier route"
|
|
494
|
+
)
|
|
495
|
+
answer = required_text(payload, "answer", label="Adaptive-RAG response")
|
|
496
|
+
documents = tuple(
|
|
497
|
+
AdaptiveRAGDocument.from_mapping(item)
|
|
498
|
+
for item in mapping_sequence(
|
|
499
|
+
payload.get("documents", ()),
|
|
500
|
+
label="Adaptive-RAG documents",
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
document_ids = tuple(document.document_id for document in documents)
|
|
504
|
+
if len(document_ids) != len(set(document_ids)):
|
|
505
|
+
raise AlgorithmOutputError("Adaptive-RAG returned duplicate document records")
|
|
506
|
+
if any(
|
|
507
|
+
document.corpus_revision != self.artifacts.corpus_revision for document in documents
|
|
508
|
+
):
|
|
509
|
+
raise AlgorithmOutputError("Adaptive-RAG returned a corpus revision mismatch")
|
|
510
|
+
|
|
511
|
+
initial_retrieval = _parse_initial_retrieval(payload.get("initial_retrieval"))
|
|
512
|
+
ircot_steps = tuple(
|
|
513
|
+
AdaptiveRAGIRCoTStep.from_mapping(item)
|
|
514
|
+
for item in mapping_sequence(
|
|
515
|
+
payload.get("ircot_steps", ()),
|
|
516
|
+
label="Adaptive-RAG IRCoT steps",
|
|
517
|
+
)
|
|
518
|
+
)
|
|
519
|
+
active_document_ids = string_tuple(
|
|
520
|
+
payload.get("active_document_ids", ()),
|
|
521
|
+
label="Adaptive-RAG active_document_ids",
|
|
522
|
+
unique=True,
|
|
523
|
+
)
|
|
524
|
+
_validate_strategy_trajectory(
|
|
525
|
+
strategy=strategy,
|
|
526
|
+
question=state.query,
|
|
527
|
+
documents=documents,
|
|
528
|
+
initial_retrieval=initial_retrieval,
|
|
529
|
+
ircot_steps=ircot_steps,
|
|
530
|
+
active_document_ids=active_document_ids,
|
|
531
|
+
controls=self.controls,
|
|
532
|
+
)
|
|
533
|
+
execution_evidence = _validate_execution_evidence(
|
|
534
|
+
payload.get("execution_evidence"),
|
|
535
|
+
artifacts=self.artifacts,
|
|
536
|
+
controls=self.controls,
|
|
537
|
+
strategy=strategy,
|
|
538
|
+
question=state.query,
|
|
539
|
+
route_logits=route_logits,
|
|
540
|
+
answer=answer,
|
|
541
|
+
initial_retrieval=initial_retrieval,
|
|
542
|
+
ircot_steps=ircot_steps,
|
|
543
|
+
response_usage=response.usage,
|
|
544
|
+
remaining_budget=remaining_budget,
|
|
545
|
+
expected_source_tree=self.expected_source_tree,
|
|
546
|
+
expected_manifest_sha256=self.expected_compatibility_manifest_sha256,
|
|
547
|
+
expected_source_closure_sha256=self.expected_source_closure_sha256,
|
|
548
|
+
allow_fixture_runtime=self.allow_fixture_runtime,
|
|
549
|
+
)
|
|
550
|
+
_validate_usage(
|
|
551
|
+
response.usage,
|
|
552
|
+
remaining_budget=remaining_budget,
|
|
553
|
+
strategy=strategy,
|
|
554
|
+
ircot_steps=ircot_steps,
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
by_id = {document.document_id: document for document in documents}
|
|
558
|
+
evidence = tuple(
|
|
559
|
+
_context_from_document(by_id[document_id], strategy=strategy)
|
|
560
|
+
for document_id in active_document_ids
|
|
561
|
+
)
|
|
562
|
+
events: list[TraceEvent] = [
|
|
563
|
+
TraceEvent(
|
|
564
|
+
TracePhase.PREPARE,
|
|
565
|
+
"controlled_three_arm_bundle",
|
|
566
|
+
{
|
|
567
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
568
|
+
"worker_fingerprint": worker_identity,
|
|
569
|
+
"controls": asdict(self.controls),
|
|
570
|
+
"remaining_budget": remaining_budget,
|
|
571
|
+
"evaluation_label_access": "none",
|
|
572
|
+
},
|
|
573
|
+
),
|
|
574
|
+
TraceEvent(
|
|
575
|
+
TracePhase.PROPOSE,
|
|
576
|
+
"complexity_route",
|
|
577
|
+
{
|
|
578
|
+
"route_label": route_label,
|
|
579
|
+
"strategy": strategy.value,
|
|
580
|
+
"route_logits": route_logits,
|
|
581
|
+
"route_logits_sha256": content_hash(route_logits),
|
|
582
|
+
"prediction_type": "first_decoder_step_logit_argmax",
|
|
583
|
+
"router_checkpoint": self.artifacts.router_checkpoint,
|
|
584
|
+
"router_revision": self.artifacts.router_revision,
|
|
585
|
+
},
|
|
586
|
+
),
|
|
587
|
+
]
|
|
588
|
+
if initial_retrieval is not None:
|
|
589
|
+
events.append(
|
|
590
|
+
TraceEvent(
|
|
591
|
+
TracePhase.OBSERVE,
|
|
592
|
+
"initial_retrieval",
|
|
593
|
+
{
|
|
594
|
+
"query": initial_retrieval.query,
|
|
595
|
+
"document_ids": initial_retrieval.document_ids,
|
|
596
|
+
},
|
|
597
|
+
)
|
|
598
|
+
)
|
|
599
|
+
events.extend(
|
|
600
|
+
TraceEvent(
|
|
601
|
+
TracePhase.OBSERVE,
|
|
602
|
+
"ircot_step",
|
|
603
|
+
{
|
|
604
|
+
"index": step.index,
|
|
605
|
+
"cot_step": step.cot_step,
|
|
606
|
+
"latest_cot_sentence": step.latest_cot_sentence,
|
|
607
|
+
"retrieval_query": step.retrieval_query,
|
|
608
|
+
"retrieved_document_ids": step.retrieved_document_ids,
|
|
609
|
+
"new_document_ids": step.new_document_ids,
|
|
610
|
+
"active_document_ids": step.active_document_ids,
|
|
611
|
+
"reset_applied": step.reset_applied,
|
|
612
|
+
},
|
|
613
|
+
)
|
|
614
|
+
for step in ircot_steps
|
|
615
|
+
)
|
|
616
|
+
events.append(
|
|
617
|
+
TraceEvent(
|
|
618
|
+
TracePhase.FINALIZE,
|
|
619
|
+
"selected_strategy_output",
|
|
620
|
+
{
|
|
621
|
+
"strategy": strategy.value,
|
|
622
|
+
"answer": answer,
|
|
623
|
+
"active_document_ids": active_document_ids,
|
|
624
|
+
},
|
|
625
|
+
)
|
|
626
|
+
)
|
|
627
|
+
trace = ExecutionTrace(
|
|
628
|
+
method_id=self.method_id,
|
|
629
|
+
release_id=self.release_id,
|
|
630
|
+
events=tuple(events),
|
|
631
|
+
counters={
|
|
632
|
+
**external_usage_counters(response.usage),
|
|
633
|
+
"worker_calls": 1,
|
|
634
|
+
"strategy_arms_executed": 1,
|
|
635
|
+
"ircot_steps": len(ircot_steps),
|
|
636
|
+
"active_documents": len(active_document_ids),
|
|
637
|
+
},
|
|
638
|
+
)
|
|
639
|
+
return CompositeResult(
|
|
640
|
+
method_id=self.method_id,
|
|
641
|
+
release_id=self.release_id,
|
|
642
|
+
source_state_hash=state.state_hash,
|
|
643
|
+
final_answer=answer,
|
|
644
|
+
evidence=evidence,
|
|
645
|
+
trace=trace,
|
|
646
|
+
implementation_identity=(
|
|
647
|
+
"controlled_reimplementation_with_upstream_router:"
|
|
648
|
+
f"starsuzi/Adaptive-RAG@{ADAPTIVE_RAG_UPSTREAM_COMMIT}"
|
|
649
|
+
),
|
|
650
|
+
profile_kind="controlled_adapter",
|
|
651
|
+
metadata={
|
|
652
|
+
"implementation_origin": "controlled_reimplementation",
|
|
653
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
654
|
+
"artifacts": artifact_mapping,
|
|
655
|
+
"worker_fingerprint": worker_identity,
|
|
656
|
+
"route_label": route_label,
|
|
657
|
+
"strategy": strategy.value,
|
|
658
|
+
"route_logits": route_logits,
|
|
659
|
+
"route_logits_sha256": content_hash(route_logits),
|
|
660
|
+
"evaluation_label_access": "none",
|
|
661
|
+
"classifier_prediction_type": "first_decoder_step_logit_argmax",
|
|
662
|
+
"active_document_ids": active_document_ids,
|
|
663
|
+
"execution_evidence_kind": execution_evidence["evidence_kind"],
|
|
664
|
+
"source_tree": execution_evidence["source_tree"],
|
|
665
|
+
"source_closure_sha256": execution_evidence["source_closure_sha256"],
|
|
666
|
+
"compatibility_manifest_sha256": execution_evidence[
|
|
667
|
+
"compatibility_manifest_sha256"
|
|
668
|
+
],
|
|
669
|
+
"supervisor_event_log_sha256": execution_evidence["event_log_sha256"],
|
|
670
|
+
"controlled_method_execution": True,
|
|
671
|
+
"controlled_upstream_router_parity": True,
|
|
672
|
+
"controlled_online_selected_arm": True,
|
|
673
|
+
"upstream_arm_execution_parity": False,
|
|
674
|
+
"official_execution_parity": False,
|
|
675
|
+
"official_parity_claimed": False,
|
|
676
|
+
},
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def _validate_identity(
|
|
681
|
+
payload: Mapping[str, Any],
|
|
682
|
+
*,
|
|
683
|
+
artifacts: AdaptiveRAGArtifactIdentity,
|
|
684
|
+
) -> None:
|
|
685
|
+
returned = payload.get("artifacts")
|
|
686
|
+
if not isinstance(returned, Mapping) or dict(returned) != dict(artifacts.as_mapping()):
|
|
687
|
+
raise AlgorithmOutputError("Adaptive-RAG worker artifact identity mismatch")
|
|
688
|
+
identity = required_text(
|
|
689
|
+
payload,
|
|
690
|
+
"artifact_identity_sha256",
|
|
691
|
+
label="Adaptive-RAG response",
|
|
692
|
+
)
|
|
693
|
+
if identity != artifacts.identity_sha256:
|
|
694
|
+
raise AlgorithmOutputError("Adaptive-RAG worker artifact hash mismatch")
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
def _parse_route_logits(value: object) -> Mapping[str, float]:
|
|
698
|
+
if not isinstance(value, Mapping) or set(value) != set(_ROUTE_ORDER):
|
|
699
|
+
raise AlgorithmOutputError("Adaptive-RAG route_logits must contain exactly A, B, and C")
|
|
700
|
+
return freeze_mapping(
|
|
701
|
+
{
|
|
702
|
+
label: finite_number(
|
|
703
|
+
value[label],
|
|
704
|
+
label=f"Adaptive-RAG route logit {label}",
|
|
705
|
+
)
|
|
706
|
+
for label in _ROUTE_ORDER
|
|
707
|
+
}
|
|
708
|
+
)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
def _parse_initial_retrieval(value: object) -> AdaptiveRAGInitialRetrieval | None:
|
|
712
|
+
if value is None:
|
|
713
|
+
return None
|
|
714
|
+
if not isinstance(value, Mapping):
|
|
715
|
+
raise AlgorithmOutputError("Adaptive-RAG initial_retrieval must be a mapping or null")
|
|
716
|
+
return AdaptiveRAGInitialRetrieval.from_mapping(value)
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
def _validate_strategy_trajectory(
|
|
720
|
+
*,
|
|
721
|
+
strategy: AdaptiveRAGStrategy,
|
|
722
|
+
question: str,
|
|
723
|
+
documents: tuple[AdaptiveRAGDocument, ...],
|
|
724
|
+
initial_retrieval: AdaptiveRAGInitialRetrieval | None,
|
|
725
|
+
ircot_steps: tuple[AdaptiveRAGIRCoTStep, ...],
|
|
726
|
+
active_document_ids: tuple[str, ...],
|
|
727
|
+
controls: AdaptiveRAGControls,
|
|
728
|
+
) -> None:
|
|
729
|
+
known = {document.document_id for document in documents}
|
|
730
|
+
if strategy is AdaptiveRAGStrategy.NO_RETRIEVAL:
|
|
731
|
+
if initial_retrieval is not None or ircot_steps or documents or active_document_ids:
|
|
732
|
+
raise AlgorithmOutputError("Adaptive-RAG no-retrieval arm returned retrieval artifacts")
|
|
733
|
+
return
|
|
734
|
+
if initial_retrieval is None:
|
|
735
|
+
raise AlgorithmOutputError("Adaptive-RAG retrieval arms require initial_retrieval")
|
|
736
|
+
if initial_retrieval.query.strip() != question.strip():
|
|
737
|
+
raise AlgorithmOutputError("Adaptive-RAG initial retrieval query must equal the question")
|
|
738
|
+
initial_ids = initial_retrieval.document_ids
|
|
739
|
+
top_k = (
|
|
740
|
+
controls.single_retrieval_top_k
|
|
741
|
+
if strategy is AdaptiveRAGStrategy.SINGLE_RETRIEVAL
|
|
742
|
+
else controls.ircot_per_step_top_k
|
|
743
|
+
)
|
|
744
|
+
if len(initial_ids) > top_k:
|
|
745
|
+
raise AlgorithmOutputError("Adaptive-RAG initial retrieval exceeds its top-k control")
|
|
746
|
+
if len(initial_ids) > controls.max_total_documents:
|
|
747
|
+
raise AlgorithmOutputError("Adaptive-RAG initial retrieval exceeds max_total_documents")
|
|
748
|
+
if not set(initial_ids) <= known:
|
|
749
|
+
raise AlgorithmOutputError("Adaptive-RAG initial retrieval lacks document records")
|
|
750
|
+
|
|
751
|
+
if strategy is AdaptiveRAGStrategy.SINGLE_RETRIEVAL:
|
|
752
|
+
if ircot_steps:
|
|
753
|
+
raise AlgorithmOutputError("Adaptive-RAG single-retrieval arm returned IRCoT steps")
|
|
754
|
+
if active_document_ids != initial_ids:
|
|
755
|
+
raise AlgorithmOutputError(
|
|
756
|
+
"Adaptive-RAG single-retrieval evidence must equal its one retrieval"
|
|
757
|
+
)
|
|
758
|
+
if known != set(initial_ids):
|
|
759
|
+
raise AlgorithmOutputError(
|
|
760
|
+
"Adaptive-RAG single-retrieval documents must match its retrieval"
|
|
761
|
+
)
|
|
762
|
+
return
|
|
763
|
+
|
|
764
|
+
if len(ircot_steps) > controls.ircot_max_steps:
|
|
765
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT trajectory exceeds max steps")
|
|
766
|
+
if not active_document_ids:
|
|
767
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT arm returned no active evidence")
|
|
768
|
+
seen = set(initial_ids)
|
|
769
|
+
active = set(initial_ids)
|
|
770
|
+
for expected_index, step in enumerate(ircot_steps):
|
|
771
|
+
if step.index != expected_index:
|
|
772
|
+
raise AlgorithmOutputError(
|
|
773
|
+
"Adaptive-RAG IRCoT step indices must be contiguous and zero-based"
|
|
774
|
+
)
|
|
775
|
+
retrieved = set(step.retrieved_document_ids)
|
|
776
|
+
new = set(step.new_document_ids)
|
|
777
|
+
next_active = set(step.active_document_ids)
|
|
778
|
+
if len(step.retrieved_document_ids) > controls.ircot_per_step_top_k:
|
|
779
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT retrieval exceeds per-step top-k")
|
|
780
|
+
if not retrieved <= known:
|
|
781
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT retrieved unknown documents")
|
|
782
|
+
if not new <= retrieved:
|
|
783
|
+
raise AlgorithmOutputError(
|
|
784
|
+
"Adaptive-RAG IRCoT new documents must come from that retrieval"
|
|
785
|
+
)
|
|
786
|
+
if controls.deduplicate_documents and new != retrieved - seen:
|
|
787
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT new_document_ids violate deduplication")
|
|
788
|
+
seen.update(new)
|
|
789
|
+
if len(seen) > controls.max_total_documents:
|
|
790
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT exceeds max_total_documents")
|
|
791
|
+
if not next_active <= seen:
|
|
792
|
+
raise AlgorithmOutputError(
|
|
793
|
+
"Adaptive-RAG IRCoT activated a document that was never retrieved"
|
|
794
|
+
)
|
|
795
|
+
if controls.ircot_reset_policy == "never" and step.reset_applied:
|
|
796
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT reset violates reset_policy")
|
|
797
|
+
if controls.ircot_reset_policy == "replace_each_step" and not step.reset_applied:
|
|
798
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT replace_each_step requires a reset")
|
|
799
|
+
if step.reset_applied:
|
|
800
|
+
if next_active != retrieved:
|
|
801
|
+
raise AlgorithmOutputError(
|
|
802
|
+
"Adaptive-RAG IRCoT reset evidence must equal that retrieval"
|
|
803
|
+
)
|
|
804
|
+
elif next_active != active | new:
|
|
805
|
+
raise AlgorithmOutputError(
|
|
806
|
+
"Adaptive-RAG IRCoT non-reset step lost or invented active evidence"
|
|
807
|
+
)
|
|
808
|
+
active = next_active
|
|
809
|
+
if seen != known:
|
|
810
|
+
raise AlgorithmOutputError(
|
|
811
|
+
"Adaptive-RAG document records must exactly match observed retrievals"
|
|
812
|
+
)
|
|
813
|
+
if active_document_ids != (ircot_steps[-1].active_document_ids if ircot_steps else initial_ids):
|
|
814
|
+
raise AlgorithmOutputError(
|
|
815
|
+
"Adaptive-RAG final evidence disagrees with the IRCoT trajectory"
|
|
816
|
+
)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def _validate_execution_evidence(
|
|
820
|
+
value: object,
|
|
821
|
+
*,
|
|
822
|
+
artifacts: AdaptiveRAGArtifactIdentity,
|
|
823
|
+
controls: AdaptiveRAGControls,
|
|
824
|
+
strategy: AdaptiveRAGStrategy,
|
|
825
|
+
question: str,
|
|
826
|
+
route_logits: Mapping[str, float],
|
|
827
|
+
answer: str,
|
|
828
|
+
initial_retrieval: AdaptiveRAGInitialRetrieval | None,
|
|
829
|
+
ircot_steps: tuple[AdaptiveRAGIRCoTStep, ...],
|
|
830
|
+
response_usage: Any,
|
|
831
|
+
remaining_budget: Mapping[str, int | None],
|
|
832
|
+
expected_source_tree: str,
|
|
833
|
+
expected_manifest_sha256: str,
|
|
834
|
+
expected_source_closure_sha256: str,
|
|
835
|
+
allow_fixture_runtime: bool,
|
|
836
|
+
) -> Mapping[str, Any]:
|
|
837
|
+
if not isinstance(value, Mapping):
|
|
838
|
+
raise AlgorithmOutputError("Adaptive-RAG response requires execution_evidence")
|
|
839
|
+
expected: Mapping[str, object] = {
|
|
840
|
+
"schema": _EXECUTION_EVIDENCE_SCHEMA,
|
|
841
|
+
"source_commit": ADAPTIVE_RAG_UPSTREAM_COMMIT,
|
|
842
|
+
"source_tree": expected_source_tree,
|
|
843
|
+
"source_closure_sha256": expected_source_closure_sha256,
|
|
844
|
+
"compatibility_manifest_sha256": expected_manifest_sha256,
|
|
845
|
+
"router_revision": artifacts.router_revision,
|
|
846
|
+
"router_snapshot_sha256": artifacts.router_snapshot_sha256,
|
|
847
|
+
"router_weights_sha256": artifacts.router_weights_sha256,
|
|
848
|
+
"router_tokenizer_sha256": artifacts.router_tokenizer_sha256,
|
|
849
|
+
"base_model_revision": artifacts.base_model_revision,
|
|
850
|
+
"generator_artifact_sha256": artifacts.generator_artifact_sha256,
|
|
851
|
+
"generator_config_sha256": artifacts.generator_config_sha256,
|
|
852
|
+
"retriever_revision": artifacts.retriever_revision,
|
|
853
|
+
"retriever_implementation_sha256": artifacts.retriever_implementation_sha256,
|
|
854
|
+
"retriever_config_sha256": artifacts.retriever_config_sha256,
|
|
855
|
+
"corpus_revision": artifacts.corpus_revision,
|
|
856
|
+
"corpus_manifest_sha256": artifacts.corpus_manifest_sha256,
|
|
857
|
+
"index_revision": artifacts.index_revision,
|
|
858
|
+
"index_manifest_sha256": artifacts.index_manifest_sha256,
|
|
859
|
+
"selected_strategy": strategy.value,
|
|
860
|
+
"controlled_method_execution": True,
|
|
861
|
+
"controlled_upstream_router_parity": True,
|
|
862
|
+
"upstream_arm_parity_claimed": False,
|
|
863
|
+
"official_parity_claimed": False,
|
|
864
|
+
}
|
|
865
|
+
for key, expected_value in expected.items():
|
|
866
|
+
if value.get(key) != expected_value:
|
|
867
|
+
raise AlgorithmOutputError(f"Adaptive-RAG execution evidence mismatch for {key}")
|
|
868
|
+
|
|
869
|
+
fixture_runtime = value.get("fixture_runtime")
|
|
870
|
+
if not isinstance(fixture_runtime, bool):
|
|
871
|
+
raise AlgorithmOutputError("Adaptive-RAG fixture_runtime evidence must be boolean")
|
|
872
|
+
evidence_kind = value.get("evidence_kind")
|
|
873
|
+
expected_kind = "hermetic_fixture" if fixture_runtime else "controlled_component_closure"
|
|
874
|
+
if evidence_kind != expected_kind:
|
|
875
|
+
raise AlgorithmOutputError("Adaptive-RAG execution evidence kind is inconsistent")
|
|
876
|
+
if fixture_runtime and not allow_fixture_runtime:
|
|
877
|
+
raise AlgorithmOutputError("Adaptive-RAG production profile rejects fixture runtime")
|
|
878
|
+
expected_source_state = "verified_fixture_snapshot" if fixture_runtime else "clean_git_checkout"
|
|
879
|
+
if value.get("source_state") != expected_source_state:
|
|
880
|
+
raise AlgorithmOutputError("Adaptive-RAG source-state evidence mismatch")
|
|
881
|
+
prompt_hashes = value.get("prompt_sha256")
|
|
882
|
+
expected_prompts = {
|
|
883
|
+
"no_retrieval": artifacts.no_retrieval_prompt_sha256,
|
|
884
|
+
"single_retrieval": artifacts.single_retrieval_prompt_sha256,
|
|
885
|
+
"ircot": artifacts.ircot_prompt_sha256,
|
|
886
|
+
}
|
|
887
|
+
if not isinstance(prompt_hashes, Mapping) or dict(prompt_hashes) != expected_prompts:
|
|
888
|
+
raise AlgorithmOutputError("Adaptive-RAG prompt evidence mismatch")
|
|
889
|
+
|
|
890
|
+
events = mapping_sequence(
|
|
891
|
+
value.get("events"),
|
|
892
|
+
label="Adaptive-RAG supervisor events",
|
|
893
|
+
)
|
|
894
|
+
if len(events) < 2:
|
|
895
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor event log is incomplete")
|
|
896
|
+
if value.get("event_log_sha256") != content_hash(events):
|
|
897
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor event-log hash mismatch")
|
|
898
|
+
if value.get("final_event_sha256") != events[-1].get("event_sha256"):
|
|
899
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor final-event hash mismatch")
|
|
900
|
+
|
|
901
|
+
expected_operations = ["router.first_decoder_step"]
|
|
902
|
+
if strategy is AdaptiveRAGStrategy.NO_RETRIEVAL:
|
|
903
|
+
expected_operations.append("answer.no_retrieval")
|
|
904
|
+
elif strategy is AdaptiveRAGStrategy.SINGLE_RETRIEVAL:
|
|
905
|
+
expected_operations.extend(("retrieve.single.initial", "answer.single_retrieval"))
|
|
906
|
+
else:
|
|
907
|
+
expected_operations.append("retrieve.ircot.initial")
|
|
908
|
+
for step in ircot_steps:
|
|
909
|
+
expected_operations.extend(
|
|
910
|
+
(f"ircot.reason.{step.index}", f"retrieve.ircot.step.{step.index}")
|
|
911
|
+
)
|
|
912
|
+
expected_operations.append("answer.ircot")
|
|
913
|
+
if [event.get("operation") for event in events] != expected_operations:
|
|
914
|
+
raise AlgorithmOutputError(
|
|
915
|
+
"Adaptive-RAG supervisor events do not execute exactly the selected arm"
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
previous_hash = "0" * 64
|
|
919
|
+
remaining: dict[str, int | None] = {
|
|
920
|
+
"model_calls": int(remaining_budget["model_calls"]),
|
|
921
|
+
"retrieval_calls": int(remaining_budget["retrieval_calls"]),
|
|
922
|
+
"input_tokens": remaining_budget["context_tokens"],
|
|
923
|
+
"output_tokens": int(remaining_budget["output_tokens"]),
|
|
924
|
+
}
|
|
925
|
+
totals: dict[str, int | float] = {
|
|
926
|
+
key: 0
|
|
927
|
+
if key
|
|
928
|
+
not in {
|
|
929
|
+
"cpu_seconds",
|
|
930
|
+
"accelerator_seconds",
|
|
931
|
+
"cost_usd",
|
|
932
|
+
"compute_cost_usd",
|
|
933
|
+
}
|
|
934
|
+
else 0.0
|
|
935
|
+
for key in _EVENT_USAGE_FIELDS
|
|
936
|
+
}
|
|
937
|
+
for index, event in enumerate(events):
|
|
938
|
+
expected_event_keys = {
|
|
939
|
+
"schema",
|
|
940
|
+
"sequence",
|
|
941
|
+
"previous_event_sha256",
|
|
942
|
+
"call_kind",
|
|
943
|
+
"operation",
|
|
944
|
+
"pre_call_remaining",
|
|
945
|
+
"reservation",
|
|
946
|
+
"usage",
|
|
947
|
+
"result",
|
|
948
|
+
"event_sha256",
|
|
949
|
+
}
|
|
950
|
+
if set(event) != expected_event_keys:
|
|
951
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor event fields drifted")
|
|
952
|
+
if (
|
|
953
|
+
event.get("schema") != _SUPERVISOR_EVENT_SCHEMA
|
|
954
|
+
or event.get("sequence") != index
|
|
955
|
+
or event.get("previous_event_sha256") != previous_hash
|
|
956
|
+
):
|
|
957
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor event chain is invalid")
|
|
958
|
+
unsigned = {key: item for key, item in event.items() if key != "event_sha256"}
|
|
959
|
+
if event.get("event_sha256") != content_hash(unsigned):
|
|
960
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor event hash mismatch")
|
|
961
|
+
previous_hash = str(event["event_sha256"])
|
|
962
|
+
before = event.get("pre_call_remaining")
|
|
963
|
+
if not isinstance(before, Mapping) or dict(before) != remaining:
|
|
964
|
+
raise AlgorithmOutputError("Adaptive-RAG pre-call budget snapshot is invalid")
|
|
965
|
+
reservation = event.get("reservation")
|
|
966
|
+
usage = event.get("usage")
|
|
967
|
+
if not isinstance(reservation, Mapping) or not isinstance(usage, Mapping):
|
|
968
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor budget record is invalid")
|
|
969
|
+
if set(reservation) != _EVENT_RESERVATION_FIELDS:
|
|
970
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor reservation fields drifted")
|
|
971
|
+
if set(usage) != set(_EVENT_USAGE_FIELDS):
|
|
972
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor usage fields drifted")
|
|
973
|
+
call_kind = event.get("call_kind")
|
|
974
|
+
expected_model = 1 if call_kind == "model" else 0
|
|
975
|
+
expected_retrieval = 1 if call_kind == "retrieval" else 0
|
|
976
|
+
if call_kind not in {"model", "retrieval"}:
|
|
977
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor call kind is invalid")
|
|
978
|
+
if (
|
|
979
|
+
reservation.get("model_calls") != expected_model
|
|
980
|
+
or reservation.get("retrieval_calls") != expected_retrieval
|
|
981
|
+
or usage.get("model_calls") != expected_model
|
|
982
|
+
or usage.get("retrieval_calls") != expected_retrieval
|
|
983
|
+
):
|
|
984
|
+
raise AlgorithmOutputError("Adaptive-RAG call evidence disagrees with its kind")
|
|
985
|
+
input_tokens = usage.get("input_tokens")
|
|
986
|
+
output_tokens = usage.get("output_tokens")
|
|
987
|
+
if (
|
|
988
|
+
isinstance(input_tokens, bool)
|
|
989
|
+
or not isinstance(input_tokens, int)
|
|
990
|
+
or input_tokens < 0
|
|
991
|
+
or isinstance(output_tokens, bool)
|
|
992
|
+
or not isinstance(output_tokens, int)
|
|
993
|
+
or output_tokens < 0
|
|
994
|
+
):
|
|
995
|
+
raise AlgorithmOutputError("Adaptive-RAG event token usage is invalid")
|
|
996
|
+
estimated_input = reservation.get("estimated_input_tokens")
|
|
997
|
+
output_cap = reservation.get("max_output_tokens")
|
|
998
|
+
if (
|
|
999
|
+
isinstance(estimated_input, bool)
|
|
1000
|
+
or not isinstance(estimated_input, int)
|
|
1001
|
+
or estimated_input < input_tokens
|
|
1002
|
+
or isinstance(output_cap, bool)
|
|
1003
|
+
or not isinstance(output_cap, int)
|
|
1004
|
+
):
|
|
1005
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor reservation is invalid")
|
|
1006
|
+
requested_output_cap = (
|
|
1007
|
+
1
|
|
1008
|
+
if event.get("operation") == "router.first_decoder_step"
|
|
1009
|
+
else controls.max_output_tokens
|
|
1010
|
+
)
|
|
1011
|
+
expected_output_cap = (
|
|
1012
|
+
min(requested_output_cap, int(remaining["output_tokens"] or 0)) if expected_model else 0
|
|
1013
|
+
)
|
|
1014
|
+
if expected_model and expected_output_cap < 1:
|
|
1015
|
+
raise AlgorithmOutputError(
|
|
1016
|
+
"Adaptive-RAG supervisor dispatched a model after output budget exhaustion"
|
|
1017
|
+
)
|
|
1018
|
+
if output_cap != expected_output_cap:
|
|
1019
|
+
raise AlgorithmOutputError(
|
|
1020
|
+
"Adaptive-RAG supervisor reservation output cap disagrees with sent controls"
|
|
1021
|
+
)
|
|
1022
|
+
if output_cap < output_tokens:
|
|
1023
|
+
raise AlgorithmOutputError("Adaptive-RAG post-call usage exceeds its reservation")
|
|
1024
|
+
remaining["model_calls"] = int(remaining["model_calls"] or 0) - expected_model
|
|
1025
|
+
remaining["retrieval_calls"] = int(remaining["retrieval_calls"] or 0) - expected_retrieval
|
|
1026
|
+
if min(int(remaining["model_calls"]), int(remaining["retrieval_calls"])) < 0:
|
|
1027
|
+
raise AlgorithmOutputError("Adaptive-RAG event log exceeded a call budget")
|
|
1028
|
+
if remaining["input_tokens"] is not None:
|
|
1029
|
+
remaining["input_tokens"] = int(remaining["input_tokens"]) - input_tokens
|
|
1030
|
+
if remaining["input_tokens"] < 0:
|
|
1031
|
+
raise AlgorithmOutputError("Adaptive-RAG event log exceeded context budget")
|
|
1032
|
+
remaining["output_tokens"] = int(remaining["output_tokens"] or 0) - output_tokens
|
|
1033
|
+
if remaining["output_tokens"] < 0:
|
|
1034
|
+
raise AlgorithmOutputError("Adaptive-RAG event log exceeded output budget")
|
|
1035
|
+
for key in _EVENT_USAGE_FIELDS:
|
|
1036
|
+
event_value = usage.get(key)
|
|
1037
|
+
if (
|
|
1038
|
+
isinstance(event_value, bool)
|
|
1039
|
+
or not isinstance(event_value, (int, float))
|
|
1040
|
+
or not math.isfinite(float(event_value))
|
|
1041
|
+
or event_value < 0
|
|
1042
|
+
):
|
|
1043
|
+
raise AlgorithmOutputError("Adaptive-RAG supervisor usage contains invalid values")
|
|
1044
|
+
totals[key] += event_value
|
|
1045
|
+
|
|
1046
|
+
first_result = events[0].get("result")
|
|
1047
|
+
if (
|
|
1048
|
+
not isinstance(first_result, Mapping)
|
|
1049
|
+
or first_result.get("question_sha256") != content_hash(question)
|
|
1050
|
+
or first_result.get("route_logits") != route_logits
|
|
1051
|
+
):
|
|
1052
|
+
raise AlgorithmOutputError("Adaptive-RAG router event disagrees with the response")
|
|
1053
|
+
if strategy is not AdaptiveRAGStrategy.NO_RETRIEVAL:
|
|
1054
|
+
retrieval_result = events[1].get("result")
|
|
1055
|
+
if (
|
|
1056
|
+
initial_retrieval is None
|
|
1057
|
+
or not isinstance(retrieval_result, Mapping)
|
|
1058
|
+
or retrieval_result.get("query") != initial_retrieval.query
|
|
1059
|
+
or tuple(retrieval_result.get("document_ids", ())) != initial_retrieval.document_ids
|
|
1060
|
+
):
|
|
1061
|
+
raise AlgorithmOutputError("Adaptive-RAG initial retrieval event mismatch")
|
|
1062
|
+
if strategy is AdaptiveRAGStrategy.IRCOT:
|
|
1063
|
+
for step in ircot_steps:
|
|
1064
|
+
reason_result = events[2 + step.index * 2].get("result")
|
|
1065
|
+
retrieval_result = events[3 + step.index * 2].get("result")
|
|
1066
|
+
if (
|
|
1067
|
+
not isinstance(reason_result, Mapping)
|
|
1068
|
+
or reason_result.get("text_sha256") != content_hash(step.cot_step)
|
|
1069
|
+
or not isinstance(retrieval_result, Mapping)
|
|
1070
|
+
or retrieval_result.get("query") != step.retrieval_query
|
|
1071
|
+
or tuple(retrieval_result.get("document_ids", ())) != step.retrieved_document_ids
|
|
1072
|
+
):
|
|
1073
|
+
raise AlgorithmOutputError("Adaptive-RAG IRCoT event trajectory mismatch")
|
|
1074
|
+
final_result = events[-1].get("result")
|
|
1075
|
+
if not isinstance(final_result, Mapping) or final_result.get("text_sha256") != content_hash(
|
|
1076
|
+
answer
|
|
1077
|
+
):
|
|
1078
|
+
raise AlgorithmOutputError("Adaptive-RAG answer event disagrees with the response")
|
|
1079
|
+
for key in _EVENT_USAGE_FIELDS:
|
|
1080
|
+
if getattr(response_usage, key) != totals[key]:
|
|
1081
|
+
raise AlgorithmOutputError(
|
|
1082
|
+
f"Adaptive-RAG response usage disagrees with supervisor events for {key}"
|
|
1083
|
+
)
|
|
1084
|
+
return freeze_mapping(value)
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
def _validate_usage(
|
|
1088
|
+
usage: Any,
|
|
1089
|
+
*,
|
|
1090
|
+
remaining_budget: Mapping[str, int | None],
|
|
1091
|
+
strategy: AdaptiveRAGStrategy,
|
|
1092
|
+
ircot_steps: tuple[AdaptiveRAGIRCoTStep, ...],
|
|
1093
|
+
) -> None:
|
|
1094
|
+
if usage.model_calls < 2:
|
|
1095
|
+
raise AlgorithmOutputError(
|
|
1096
|
+
"Adaptive-RAG must account for classifier and answer model calls"
|
|
1097
|
+
)
|
|
1098
|
+
expected_retrieval_calls = {
|
|
1099
|
+
AdaptiveRAGStrategy.NO_RETRIEVAL: 0,
|
|
1100
|
+
AdaptiveRAGStrategy.SINGLE_RETRIEVAL: 1,
|
|
1101
|
+
AdaptiveRAGStrategy.IRCOT: 1 + len(ircot_steps),
|
|
1102
|
+
}[strategy]
|
|
1103
|
+
if usage.retrieval_calls != expected_retrieval_calls:
|
|
1104
|
+
raise AlgorithmOutputError(
|
|
1105
|
+
"Adaptive-RAG retrieval-call accounting disagrees with the selected arm"
|
|
1106
|
+
)
|
|
1107
|
+
if usage.model_calls > remaining_budget["model_calls"]:
|
|
1108
|
+
raise AlgorithmOutputError("Adaptive-RAG worker exceeded sent model-call budget")
|
|
1109
|
+
if usage.retrieval_calls > remaining_budget["retrieval_calls"]:
|
|
1110
|
+
raise AlgorithmOutputError("Adaptive-RAG worker exceeded sent retrieval-call budget")
|
|
1111
|
+
if usage.output_tokens > remaining_budget["output_tokens"]:
|
|
1112
|
+
raise AlgorithmOutputError("Adaptive-RAG worker exceeded sent output-token budget")
|
|
1113
|
+
context_limit = remaining_budget["context_tokens"]
|
|
1114
|
+
if context_limit is not None and usage.input_tokens > context_limit:
|
|
1115
|
+
raise AlgorithmOutputError("Adaptive-RAG worker exceeded sent context-token budget")
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
def _remaining_budget(
|
|
1119
|
+
state: FrozenAgentState,
|
|
1120
|
+
context: InterventionContext,
|
|
1121
|
+
) -> Mapping[str, int | None]:
|
|
1122
|
+
usage = None
|
|
1123
|
+
ledger = context.budget_ledger
|
|
1124
|
+
if ledger is not None:
|
|
1125
|
+
ledger_budget = getattr(ledger, "budget", None)
|
|
1126
|
+
usage = getattr(ledger, "usage", None)
|
|
1127
|
+
if ledger_budget != state.budget or usage is None:
|
|
1128
|
+
raise ValidationError("Adaptive-RAG received an incompatible budget ledger")
|
|
1129
|
+
|
|
1130
|
+
def consumed(name: str) -> int:
|
|
1131
|
+
value = 0 if usage is None else getattr(usage, name, None)
|
|
1132
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
|
1133
|
+
raise ValidationError(f"Adaptive-RAG budget usage {name} is invalid")
|
|
1134
|
+
return value
|
|
1135
|
+
|
|
1136
|
+
remaining_context = None
|
|
1137
|
+
if state.budget.max_context_tokens is not None:
|
|
1138
|
+
remaining_context = max(
|
|
1139
|
+
0,
|
|
1140
|
+
state.budget.max_context_tokens - consumed("input_tokens"),
|
|
1141
|
+
)
|
|
1142
|
+
return freeze_mapping(
|
|
1143
|
+
{
|
|
1144
|
+
"model_calls": max(
|
|
1145
|
+
0,
|
|
1146
|
+
state.budget.max_model_calls - consumed("model_calls"),
|
|
1147
|
+
),
|
|
1148
|
+
"retrieval_calls": max(
|
|
1149
|
+
0,
|
|
1150
|
+
state.budget.max_retrieval_calls - consumed("retrieval_calls"),
|
|
1151
|
+
),
|
|
1152
|
+
"output_tokens": max(
|
|
1153
|
+
0,
|
|
1154
|
+
state.budget.max_output_tokens - consumed("output_tokens"),
|
|
1155
|
+
),
|
|
1156
|
+
"context_tokens": remaining_context,
|
|
1157
|
+
}
|
|
1158
|
+
)
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
def _context_from_document(
|
|
1162
|
+
document: AdaptiveRAGDocument,
|
|
1163
|
+
*,
|
|
1164
|
+
strategy: AdaptiveRAGStrategy,
|
|
1165
|
+
) -> ContextBlock:
|
|
1166
|
+
reserved = {
|
|
1167
|
+
"adaptive_rag_strategy",
|
|
1168
|
+
"corpus_revision",
|
|
1169
|
+
"document_id",
|
|
1170
|
+
"evidence_kind",
|
|
1171
|
+
"title",
|
|
1172
|
+
}
|
|
1173
|
+
overlap = reserved & set(document.metadata)
|
|
1174
|
+
if overlap:
|
|
1175
|
+
raise AlgorithmOutputError(
|
|
1176
|
+
"Adaptive-RAG document metadata uses reserved provenance keys: "
|
|
1177
|
+
+ ", ".join(sorted(overlap))
|
|
1178
|
+
)
|
|
1179
|
+
return ContextBlock(
|
|
1180
|
+
block_id=document.document_id,
|
|
1181
|
+
text=document.text,
|
|
1182
|
+
source=document.corpus_revision,
|
|
1183
|
+
score=document.score,
|
|
1184
|
+
metadata={
|
|
1185
|
+
**dict(document.metadata),
|
|
1186
|
+
"document_id": document.document_id,
|
|
1187
|
+
"title": document.title,
|
|
1188
|
+
"corpus_revision": document.corpus_revision,
|
|
1189
|
+
"evidence_kind": "real_corpus_document",
|
|
1190
|
+
"adaptive_rag_strategy": strategy.value,
|
|
1191
|
+
},
|
|
1192
|
+
)
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
__all__ = [
|
|
1196
|
+
"AdaptiveRAGArtifactIdentity",
|
|
1197
|
+
"AdaptiveRAGControlledWorker",
|
|
1198
|
+
"AdaptiveRAGControls",
|
|
1199
|
+
"AdaptiveRAGDocument",
|
|
1200
|
+
"AdaptiveRAGIRCoTStep",
|
|
1201
|
+
"AdaptiveRAGInitialRetrieval",
|
|
1202
|
+
]
|