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.
Files changed (469) hide show
  1. agentinputlab/__init__.py +28 -0
  2. agentinputlab/algorithms/__init__.py +6 -0
  3. agentinputlab/algorithms/acquire/__init__.py +145 -0
  4. agentinputlab/algorithms/acquire/adaptive_rag/__init__.py +43 -0
  5. agentinputlab/algorithms/acquire/adaptive_rag/replay.py +367 -0
  6. agentinputlab/algorithms/acquire/adaptive_rag/runtime.py +1202 -0
  7. agentinputlab/algorithms/acquire/adaptive_rag_common_support.py +542 -0
  8. agentinputlab/algorithms/acquire/hyde.py +296 -0
  9. agentinputlab/algorithms/acquire/hyde_controlled.py +200 -0
  10. agentinputlab/algorithms/acquire/hyde_external.py +148 -0
  11. agentinputlab/algorithms/acquire/ircot.py +28 -0
  12. agentinputlab/algorithms/acquire/ircot_common_support.py +478 -0
  13. agentinputlab/algorithms/acquire/ircot_native.py +355 -0
  14. agentinputlab/algorithms/acquire/ircot_replay.py +327 -0
  15. agentinputlab/algorithms/acquire/qrag/__init__.py +79 -0
  16. agentinputlab/algorithms/acquire/qrag/bridge.py +828 -0
  17. agentinputlab/algorithms/acquire/qrag/common_support.py +891 -0
  18. agentinputlab/algorithms/acquire/qrag/native_axis.py +71 -0
  19. agentinputlab/algorithms/acquire/qrag/reader_adapter.py +139 -0
  20. agentinputlab/algorithms/acquire/r2ag/__init__.py +57 -0
  21. agentinputlab/algorithms/acquire/r2ag/bridge.py +1312 -0
  22. agentinputlab/algorithms/acquire/r2ag/common_support.py +1029 -0
  23. agentinputlab/algorithms/acquire/r2ag/socket_runtime.py +255 -0
  24. agentinputlab/algorithms/clarify/__init__.py +61 -0
  25. agentinputlab/algorithms/clarify/_structured.py +64 -0
  26. agentinputlab/algorithms/clarify/active_task_disambiguation.py +371 -0
  27. agentinputlab/algorithms/clarify/ask_or_assume/__init__.py +17 -0
  28. agentinputlab/algorithms/clarify/ask_or_assume/monitor.py +410 -0
  29. agentinputlab/algorithms/clarify/future_turns.py +379 -0
  30. agentinputlab/algorithms/clarify/udcs.py +255 -0
  31. agentinputlab/algorithms/clarify/udcs_deterministic.py +196 -0
  32. agentinputlab/algorithms/curate/__init__.py +65 -0
  33. agentinputlab/algorithms/curate/acon/__init__.py +27 -0
  34. agentinputlab/algorithms/curate/acon/common.py +284 -0
  35. agentinputlab/algorithms/curate/acon/common_support.py +136 -0
  36. agentinputlab/algorithms/curate/acon/history_bridge.py +309 -0
  37. agentinputlab/algorithms/curate/acon/observation_bridge.py +290 -0
  38. agentinputlab/algorithms/curate/llmlingua/__init__.py +30 -0
  39. agentinputlab/algorithms/curate/llmlingua/adapters.py +537 -0
  40. agentinputlab/algorithms/curate/llmlingua/budget.py +48 -0
  41. agentinputlab/algorithms/curate/llmlingua/controlled.py +175 -0
  42. agentinputlab/algorithms/curate/llmlingua/multilingual.py +105 -0
  43. agentinputlab/algorithms/curate/llmlingua/span_map.py +167 -0
  44. agentinputlab/algorithms/curate/recomp/__init__.py +47 -0
  45. agentinputlab/algorithms/curate/recomp/external.py +1129 -0
  46. agentinputlab/algorithms/curate/recomp/selective.py +304 -0
  47. agentinputlab/algorithms/decompose/__init__.py +107 -0
  48. agentinputlab/algorithms/decompose/decomp/__init__.py +53 -0
  49. agentinputlab/algorithms/decompose/decomp/common_support.py +478 -0
  50. agentinputlab/algorithms/decompose/decomp/planner_component.py +199 -0
  51. agentinputlab/algorithms/decompose/decomp/worker_bridge.py +416 -0
  52. agentinputlab/algorithms/decompose/llm_compiler/__init__.py +35 -0
  53. agentinputlab/algorithms/decompose/llm_compiler/bridge.py +520 -0
  54. agentinputlab/algorithms/decompose/llm_compiler/common_support.py +504 -0
  55. agentinputlab/algorithms/decompose/plan_and_budget/__init__.py +43 -0
  56. agentinputlab/algorithms/decompose/plan_and_budget/cached_soft_budget.py +362 -0
  57. agentinputlab/algorithms/decompose/plan_and_budget/decomposer_component.py +107 -0
  58. agentinputlab/algorithms/decompose/plan_and_budget/full.py +205 -0
  59. agentinputlab/algorithms/decompose/plan_and_budget/hard_cap.py +246 -0
  60. agentinputlab/algorithms/decompose/plan_and_budget/regenerated_soft_budget.py +448 -0
  61. agentinputlab/algorithms/decompose/plan_and_solve/__init__.py +33 -0
  62. agentinputlab/algorithms/decompose/plan_and_solve/plan_component.py +192 -0
  63. agentinputlab/algorithms/decompose/plan_and_solve/ps_prompt.py +127 -0
  64. agentinputlab/algorithms/decompose/self_ask/__init__.py +27 -0
  65. agentinputlab/algorithms/decompose/self_ask/loop.py +362 -0
  66. agentinputlab/algorithms/decompose/self_ask/planner_component.py +117 -0
  67. agentinputlab/algorithms/reformulate/__init__.py +85 -0
  68. agentinputlab/algorithms/reformulate/infocqr/__init__.py +40 -0
  69. agentinputlab/algorithms/reformulate/infocqr/cache_replay.py +362 -0
  70. agentinputlab/algorithms/reformulate/infocqr/external.py +675 -0
  71. agentinputlab/algorithms/reformulate/infocqr/student.py +189 -0
  72. agentinputlab/algorithms/reformulate/query2doc/__init__.py +42 -0
  73. agentinputlab/algorithms/reformulate/query2doc/controlled_live.py +190 -0
  74. agentinputlab/algorithms/reformulate/query2doc/models.py +95 -0
  75. agentinputlab/algorithms/reformulate/query2doc/official_cached.py +335 -0
  76. agentinputlab/algorithms/reformulate/query2doc/querygym_bridge.py +223 -0
  77. agentinputlab/algorithms/reformulate/query2doc/querygym_runtime.py +326 -0
  78. agentinputlab/algorithms/reformulate/reformer/__init__.py +23 -0
  79. agentinputlab/algorithms/reformulate/reformer/external.py +417 -0
  80. agentinputlab/algorithms/reformulate/rrr.py +696 -0
  81. agentinputlab/annotation/__init__.py +5 -0
  82. agentinputlab/annotation/independent.py +428 -0
  83. agentinputlab/annotation/server.py +233 -0
  84. agentinputlab/annotation/static/app.js +121 -0
  85. agentinputlab/annotation/static/index.html +60 -0
  86. agentinputlab/annotation/static/review.css +2 -0
  87. agentinputlab/annotation/static/review.html +10 -0
  88. agentinputlab/annotation/static/review.js +11 -0
  89. agentinputlab/annotation/static/styles.css +55 -0
  90. agentinputlab/annotation/store.py +444 -0
  91. agentinputlab/api.py +368 -0
  92. agentinputlab/artifacts/__init__.py +15 -0
  93. agentinputlab/artifacts/json_file.py +104 -0
  94. agentinputlab/artifacts/manifest.py +98 -0
  95. agentinputlab/artifacts/store.py +157 -0
  96. agentinputlab/backends/__init__.py +98 -0
  97. agentinputlab/backends/embedding/__init__.py +25 -0
  98. agentinputlab/backends/embedding/base.py +145 -0
  99. agentinputlab/backends/embedding/callable.py +75 -0
  100. agentinputlab/backends/embedding/replay.py +129 -0
  101. agentinputlab/backends/llm/__init__.py +31 -0
  102. agentinputlab/backends/llm/base.py +149 -0
  103. agentinputlab/backends/llm/callable.py +108 -0
  104. agentinputlab/backends/llm/decomp_completion.py +88 -0
  105. agentinputlab/backends/llm/final_content_stop.py +72 -0
  106. agentinputlab/backends/llm/gpt_oss_final_channel.py +84 -0
  107. agentinputlab/backends/llm/openai_compatible.py +332 -0
  108. agentinputlab/backends/llm/transformers.py +171 -0
  109. agentinputlab/backends/retrieval/__init__.py +35 -0
  110. agentinputlab/backends/retrieval/base.py +50 -0
  111. agentinputlab/backends/retrieval/dense.py +777 -0
  112. agentinputlab/backends/retrieval/memory.py +119 -0
  113. agentinputlab/backends/retrieval/sqlite_fts.py +155 -0
  114. agentinputlab/backends/user/__init__.py +15 -0
  115. agentinputlab/backends/user/base.py +66 -0
  116. agentinputlab/backends/user/callable.py +54 -0
  117. agentinputlab/backends/user/replay.py +89 -0
  118. agentinputlab/backends/vector.py +38 -0
  119. agentinputlab/benchmarks/__init__.py +246 -0
  120. agentinputlab/benchmarks/acquisition.py +106 -0
  121. agentinputlab/benchmarks/ale.py +540 -0
  122. agentinputlab/benchmarks/appworld_ul.py +669 -0
  123. agentinputlab/benchmarks/assets.py +226 -0
  124. agentinputlab/benchmarks/base.py +68 -0
  125. agentinputlab/benchmarks/beir_archive.py +235 -0
  126. agentinputlab/benchmarks/beir_sample.py +269 -0
  127. agentinputlab/benchmarks/bfcl_native.py +245 -0
  128. agentinputlab/benchmarks/bfcl_v3.py +607 -0
  129. agentinputlab/benchmarks/cache.py +218 -0
  130. agentinputlab/benchmarks/clariq.py +203 -0
  131. agentinputlab/benchmarks/data/registry.json +321 -0
  132. agentinputlab/benchmarks/data/smoke_assets.json +511 -0
  133. agentinputlab/benchmarks/data/statebench_v0_8_1_task_ids.json +475 -0
  134. agentinputlab/benchmarks/data/toolsandbox_165848b_scenario_names.json +1 -0
  135. agentinputlab/benchmarks/execution.py +1111 -0
  136. agentinputlab/benchmarks/interactive.py +257 -0
  137. agentinputlab/benchmarks/ir_query.py +204 -0
  138. agentinputlab/benchmarks/longbench.py +203 -0
  139. agentinputlab/benchmarks/paired_replay.py +479 -0
  140. agentinputlab/benchmarks/preprocess.py +2313 -0
  141. agentinputlab/benchmarks/production.py +236 -0
  142. agentinputlab/benchmarks/qa.py +963 -0
  143. agentinputlab/benchmarks/registry.py +110 -0
  144. agentinputlab/benchmarks/retrieval.py +459 -0
  145. agentinputlab/benchmarks/runtime.py +509 -0
  146. agentinputlab/benchmarks/statebench.py +938 -0
  147. agentinputlab/benchmarks/tau3.py +725 -0
  148. agentinputlab/benchmarks/toolsandbox.py +626 -0
  149. agentinputlab/benchmarks/trec_dl_sample.py +263 -0
  150. agentinputlab/campaign.py +654 -0
  151. agentinputlab/campaign_runner.py +953 -0
  152. agentinputlab/cli/__init__.py +6 -0
  153. agentinputlab/cli/main.py +933 -0
  154. agentinputlab/connectors/__init__.py +46 -0
  155. agentinputlab/connectors/knowledge/__init__.py +4 -0
  156. agentinputlab/connectors/tools/__init__.py +30 -0
  157. agentinputlab/connectors/tools/base.py +57 -0
  158. agentinputlab/connectors/tools/mcp.py +222 -0
  159. agentinputlab/connectors/tools/memory.py +41 -0
  160. agentinputlab/connectors/tools/openapi.py +695 -0
  161. agentinputlab/connectors/tools/schema.py +102 -0
  162. agentinputlab/contracts/__init__.py +91 -0
  163. agentinputlab/contracts/availability.py +24 -0
  164. agentinputlab/contracts/dependency.py +58 -0
  165. agentinputlab/contracts/enums.py +82 -0
  166. agentinputlab/contracts/errors.py +63 -0
  167. agentinputlab/contracts/evidence.py +43 -0
  168. agentinputlab/contracts/intent.py +110 -0
  169. agentinputlab/contracts/lifecycle.py +164 -0
  170. agentinputlab/contracts/patch.py +167 -0
  171. agentinputlab/contracts/serialization.py +93 -0
  172. agentinputlab/contracts/state.py +127 -0
  173. agentinputlab/contracts/trace.py +59 -0
  174. agentinputlab/contracts/worker.py +42 -0
  175. agentinputlab/core/__init__.py +7 -0
  176. agentinputlab/data/__init__.py +32 -0
  177. agentinputlab/data/checksums.py +9 -0
  178. agentinputlab/data/downloader.py +235 -0
  179. agentinputlab/data/http.py +171 -0
  180. agentinputlab/data/index.py +21 -0
  181. agentinputlab/data/overlap.py +28 -0
  182. agentinputlab/data/preprocess.py +32 -0
  183. agentinputlab/data/storage.py +57 -0
  184. agentinputlab/data/trec_sample.py +427 -0
  185. agentinputlab/evaluation/__init__.py +5 -0
  186. agentinputlab/evaluation/outcomes.py +32 -0
  187. agentinputlab/experiments/__init__.py +278 -0
  188. agentinputlab/experiments/analysis.py +981 -0
  189. agentinputlab/experiments/artifacts.py +687 -0
  190. agentinputlab/experiments/automatic_measurement.py +678 -0
  191. agentinputlab/experiments/auxiliary_matrix.py +203 -0
  192. agentinputlab/experiments/bindings.py +430 -0
  193. agentinputlab/experiments/blueprints.py +147 -0
  194. agentinputlab/experiments/builders/__init__.py +45 -0
  195. agentinputlab/experiments/builders/executable_external_payload.py +423 -0
  196. agentinputlab/experiments/builders/external_process_arena.py +1018 -0
  197. agentinputlab/experiments/builders/registry_intervention.py +463 -0
  198. agentinputlab/experiments/cli.py +158 -0
  199. agentinputlab/experiments/controls.py +340 -0
  200. agentinputlab/experiments/driver_guard.py +205 -0
  201. agentinputlab/experiments/drivers/__init__.py +89 -0
  202. agentinputlab/experiments/drivers/external_arena.py +2908 -0
  203. agentinputlab/experiments/drivers/method_process.py +662 -0
  204. agentinputlab/experiments/drivers/parity_process.py +1484 -0
  205. agentinputlab/experiments/drivers/static_production.py +1574 -0
  206. agentinputlab/experiments/executor.py +448 -0
  207. agentinputlab/experiments/loader.py +605 -0
  208. agentinputlab/experiments/measurement.py +675 -0
  209. agentinputlab/experiments/paper_analysis.py +1818 -0
  210. agentinputlab/experiments/parity_identity.py +605 -0
  211. agentinputlab/experiments/plan.py +277 -0
  212. agentinputlab/experiments/production_builders.py +3739 -0
  213. agentinputlab/experiments/readiness.py +432 -0
  214. agentinputlab/experiments/schema.py +514 -0
  215. agentinputlab/experiments/secrets.py +177 -0
  216. agentinputlab/experiments/stateful_analysis.py +1738 -0
  217. agentinputlab/experiments/transfer_analysis.py +1316 -0
  218. agentinputlab/experiments/unseen_analysis.py +1025 -0
  219. agentinputlab/integrations/__init__.py +1 -0
  220. agentinputlab/integrations/action_space/__init__.py +1 -0
  221. agentinputlab/integrations/external_workers/__init__.py +76 -0
  222. agentinputlab/integrations/external_workers/ace.py +431 -0
  223. agentinputlab/integrations/external_workers/base.py +181 -0
  224. agentinputlab/integrations/external_workers/decomp_live.py +249 -0
  225. agentinputlab/integrations/external_workers/decomp_planner.py +30 -0
  226. agentinputlab/integrations/external_workers/infocqr_student.py +280 -0
  227. agentinputlab/integrations/external_workers/ircot.py +576 -0
  228. agentinputlab/integrations/external_workers/llmcompiler_live.py +360 -0
  229. agentinputlab/integrations/external_workers/longllmlingua.py +162 -0
  230. agentinputlab/integrations/external_workers/method.py +314 -0
  231. agentinputlab/integrations/external_workers/process.py +678 -0
  232. agentinputlab/integrations/external_workers/supervisor.py +1071 -0
  233. agentinputlab/integrations/full_architecture/__init__.py +1 -0
  234. agentinputlab/integrations/full_architecture/hyde.py +212 -0
  235. agentinputlab/integrations/full_architecture/plan_and_budget.py +188 -0
  236. agentinputlab/integrations/live_history.py +222 -0
  237. agentinputlab/integrations/prompt_optimization/__init__.py +1 -0
  238. agentinputlab/integrations/training/__init__.py +1 -0
  239. agentinputlab/metrics/__init__.py +50 -0
  240. agentinputlab/metrics/catalog.py +313 -0
  241. agentinputlab/metrics/harm.py +95 -0
  242. agentinputlab/metrics/paired.py +40 -0
  243. agentinputlab/metrics/qa.py +76 -0
  244. agentinputlab/metrics/text.py +33 -0
  245. agentinputlab/metrics/third_party.py +161 -0
  246. agentinputlab/models/__init__.py +4 -0
  247. agentinputlab/observability/__init__.py +56 -0
  248. agentinputlab/observability/budget.py +316 -0
  249. agentinputlab/observability/instrumentation.py +754 -0
  250. agentinputlab/observability/models.py +403 -0
  251. agentinputlab/observability/monitor.py +380 -0
  252. agentinputlab/optimizers/__init__.py +1 -0
  253. agentinputlab/optimizers/clarify/__init__.py +12 -0
  254. agentinputlab/optimizers/context/__init__.py +22 -0
  255. agentinputlab/optimizers/decompose/__init__.py +64 -0
  256. agentinputlab/optimizers/evidence/__init__.py +22 -0
  257. agentinputlab/optimizers/rewrite/__init__.py +30 -0
  258. agentinputlab/parity/__init__.py +5 -0
  259. agentinputlab/parity/base.py +206 -0
  260. agentinputlab/production_campaign.py +763 -0
  261. agentinputlab/py.typed +1 -0
  262. agentinputlab/recipes/__init__.py +333 -0
  263. agentinputlab/recipes/ace.py +418 -0
  264. agentinputlab/recipes/ace_bfcl.py +273 -0
  265. agentinputlab/recipes/ace_common_support.py +169 -0
  266. agentinputlab/recipes/ace_native_plan.py +322 -0
  267. agentinputlab/recipes/ace_online.py +711 -0
  268. agentinputlab/recipes/ace_retrieval.py +330 -0
  269. agentinputlab/recipes/ace_statebench.py +382 -0
  270. agentinputlab/recipes/ace_tau.py +463 -0
  271. agentinputlab/recipes/ace_toolsandbox.py +432 -0
  272. agentinputlab/recipes/acon_guideline.py +22 -0
  273. agentinputlab/recipes/adaptive_rag.py +822 -0
  274. agentinputlab/recipes/llmlingua2_inference.py +146 -0
  275. agentinputlab/recipes/llmlingua2_training.py +796 -0
  276. agentinputlab/recipes/mce.py +1486 -0
  277. agentinputlab/recipes/mce_final.py +335 -0
  278. agentinputlab/recipes/mce_text_fit.py +499 -0
  279. agentinputlab/recipes/mce_text_only.py +298 -0
  280. agentinputlab/recipes/qrag.py +729 -0
  281. agentinputlab/recipes/qrag_inference.py +364 -0
  282. agentinputlab/recipes/r2ag_features.py +236 -0
  283. agentinputlab/recipes/r2ag_inference.py +503 -0
  284. agentinputlab/recipes/r2ag_training.py +948 -0
  285. agentinputlab/recipes/recomp_abstractive.py +592 -0
  286. agentinputlab/recipes/recomp_extractive.py +525 -0
  287. agentinputlab/recipes/reformer.py +17 -0
  288. agentinputlab/recipes/rqrag.py +1516 -0
  289. agentinputlab/recipes/rqrag_common_support.py +193 -0
  290. agentinputlab/recipes/rqrag_completion.py +147 -0
  291. agentinputlab/recipes/skillopt.py +462 -0
  292. agentinputlab/recipes/skillopt_common_support.py +154 -0
  293. agentinputlab/recipes/skillopt_environment.py +165 -0
  294. agentinputlab/recipes/skillopt_environment_cli.py +5 -0
  295. agentinputlab/recipes/skillopt_retrieval.py +188 -0
  296. agentinputlab/recipes/smartsearch.py +897 -0
  297. agentinputlab/recipes/smartsearch_curriculum.py +283 -0
  298. agentinputlab/recipes/smartsearch_grpo_contracts.py +58 -0
  299. agentinputlab/recipes/smartsearch_grpo_data.py +314 -0
  300. agentinputlab/recipes/smartsearch_grpo_meter.py +324 -0
  301. agentinputlab/recipes/smartsearch_grpo_prefix.py +144 -0
  302. agentinputlab/recipes/smartsearch_grpo_rollout.py +119 -0
  303. agentinputlab/recipes/smartsearch_grpo_tools.py +364 -0
  304. agentinputlab/recipes/smartsearch_grpo_training.py +305 -0
  305. agentinputlab/recipes/smartsearch_grpo_transport.py +248 -0
  306. agentinputlab/recipes/smartsearch_grpo_worker.py +364 -0
  307. agentinputlab/recipes/smartsearch_inference.py +524 -0
  308. agentinputlab/recipes/smartsearch_native_data.py +172 -0
  309. agentinputlab/recipes/smartsearch_policy.py +616 -0
  310. agentinputlab/recipes/smartsearch_policy_worker.py +9 -0
  311. agentinputlab/recipes/smartsearch_sampling.py +232 -0
  312. agentinputlab/recipes/smartsearch_teacher.py +203 -0
  313. agentinputlab/recipes/smartsearch_training.py +265 -0
  314. agentinputlab/registry/__init__.py +46 -0
  315. agentinputlab/registry/beta.py +727 -0
  316. agentinputlab/registry/data/algorithms.json +1959 -0
  317. agentinputlab/registry/data/auxiliary_method_profiles.json +34 -0
  318. agentinputlab/registry/loader.py +100 -0
  319. agentinputlab/registry/result_manifest.py +184 -0
  320. agentinputlab/registry/runtime.py +195 -0
  321. agentinputlab/registry/schema.py +449 -0
  322. agentinputlab/runner/__init__.py +30 -0
  323. agentinputlab/runner/balance.py +248 -0
  324. agentinputlab/runner/cache.py +135 -0
  325. agentinputlab/runner/composite.py +130 -0
  326. agentinputlab/runner/engine.py +285 -0
  327. agentinputlab/runner/runtime_guard.py +268 -0
  328. agentinputlab/runner/worker.py +80 -0
  329. agentinputlab/runtime_bootstrap.py +288 -0
  330. agentinputlab/selectors/__init__.py +196 -0
  331. agentinputlab/selectors/advanced.py +1514 -0
  332. agentinputlab/selectors/artifacts.py +1087 -0
  333. agentinputlab/selectors/base.py +112 -0
  334. agentinputlab/selectors/campaigns.py +1893 -0
  335. agentinputlab/selectors/catalog.py +86 -0
  336. agentinputlab/selectors/discovery.py +1860 -0
  337. agentinputlab/selectors/evaluation.py +1348 -0
  338. agentinputlab/selectors/features.py +383 -0
  339. agentinputlab/selectors/learned.py +502 -0
  340. agentinputlab/selectors/no_op.py +28 -0
  341. agentinputlab/selectors/outcome_table.py +475 -0
  342. agentinputlab/selectors/producer.py +853 -0
  343. agentinputlab/selectors/rules.py +109 -0
  344. agentinputlab/selectors/runtime.py +420 -0
  345. agentinputlab/studies/__init__.py +16 -0
  346. agentinputlab/studies/design.py +165 -0
  347. agentinputlab/studies/paired.py +322 -0
  348. agentinputlab/studio/__init__.py +6 -0
  349. agentinputlab/studio/campaigns.py +819 -0
  350. agentinputlab/studio/engine.py +1408 -0
  351. agentinputlab/studio/model_backends.py +425 -0
  352. agentinputlab/studio/prepared.py +410 -0
  353. agentinputlab/studio/server.py +613 -0
  354. agentinputlab/studio/static/app.js +397 -0
  355. agentinputlab/studio/static/campaigns.html +175 -0
  356. agentinputlab/studio/static/campaigns.js +426 -0
  357. agentinputlab/studio/static/index.html +192 -0
  358. agentinputlab/studio/static/result.html +103 -0
  359. agentinputlab/studio/static/result.js +273 -0
  360. agentinputlab/studio/static/styles.css +467 -0
  361. agentinputlab-0.1.0a1.data/data/share/agentinputlab/CITATION.cff +22 -0
  362. agentinputlab-0.1.0a1.dist-info/METADATA +392 -0
  363. agentinputlab-0.1.0a1.dist-info/RECORD +469 -0
  364. agentinputlab-0.1.0a1.dist-info/WHEEL +5 -0
  365. agentinputlab-0.1.0a1.dist-info/entry_points.txt +6 -0
  366. agentinputlab-0.1.0a1.dist-info/licenses/LICENSE +21 -0
  367. agentinputlab-0.1.0a1.dist-info/licenses/NOTICE +31 -0
  368. agentinputlab-0.1.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +94 -0
  369. agentinputlab-0.1.0a1.dist-info/top_level.txt +2 -0
  370. workers/README.md +94 -0
  371. workers/ace/README.md +261 -0
  372. workers/ace/__init__.py +1 -0
  373. workers/ace/compatibility_manifest.json +39 -0
  374. workers/ace/driver.py +1682 -0
  375. workers/acon/README.md +215 -0
  376. workers/acon/__init__.py +5 -0
  377. workers/acon/compatibility_manifest.json +93 -0
  378. workers/acon/driver.py +1859 -0
  379. workers/acon/fitted.py +395 -0
  380. workers/acon/guideline.py +470 -0
  381. workers/acon/guideline_source_manifest.json +20 -0
  382. workers/adaptive_rag/README.md +96 -0
  383. workers/adaptive_rag/__init__.py +15 -0
  384. workers/adaptive_rag/compatibility_manifest.json +61 -0
  385. workers/adaptive_rag/driver.py +1470 -0
  386. workers/adaptive_rag/fixture_runtime.py +163 -0
  387. workers/adaptive_rag/runtime.py +252 -0
  388. workers/ask_or_assume/README.md +124 -0
  389. workers/ask_or_assume/__init__.py +1 -0
  390. workers/ask_or_assume/compatibility_manifest.json +36 -0
  391. workers/ask_or_assume/driver.py +1227 -0
  392. workers/decomp/README.md +133 -0
  393. workers/decomp/UPSTREAM_LICENSE.Apache-2.0.txt +201 -0
  394. workers/decomp/__init__.py +5 -0
  395. workers/decomp/compatibility_manifest.json +205 -0
  396. workers/decomp/driver.py +1015 -0
  397. workers/decomp/live.py +137 -0
  398. workers/decomp/runtime.py +231 -0
  399. workers/infocqr/README.md +106 -0
  400. workers/infocqr/__init__.py +1 -0
  401. workers/infocqr/compatibility_manifest.json +84 -0
  402. workers/infocqr/driver.py +1766 -0
  403. workers/ircot/README.md +167 -0
  404. workers/ircot/__init__.py +7 -0
  405. workers/ircot/compatibility_manifest.json +121 -0
  406. workers/ircot/controlled.py +457 -0
  407. workers/ircot/driver.py +1373 -0
  408. workers/ircot/fixture_bindings.json +39 -0
  409. workers/ircot/fixture_config.json +48 -0
  410. workers/ircot/fixture_prompt.txt +2 -0
  411. workers/ircot/native_qa.py +398 -0
  412. workers/ircot/qa_compatibility_manifest.json +57 -0
  413. workers/ircot/runtime.py +97 -0
  414. workers/llmcompiler/README.md +160 -0
  415. workers/llmcompiler/__init__.py +1 -0
  416. workers/llmcompiler/compatibility_manifest.json +45 -0
  417. workers/llmcompiler/driver.py +1514 -0
  418. workers/llmcompiler/export_prompts.py +74 -0
  419. workers/llmcompiler/live.py +174 -0
  420. workers/llmcompiler/patch_manifest.json +147 -0
  421. workers/mce/README.md +198 -0
  422. workers/mce/__init__.py +29 -0
  423. workers/mce/compatibility_manifest.json +115 -0
  424. workers/mce/driver.py +2585 -0
  425. workers/mce/final_eval.py +173 -0
  426. workers/official_arenas/README.md +25 -0
  427. workers/official_arenas/__init__.py +1 -0
  428. workers/official_arenas/capture_records.py +110 -0
  429. workers/official_arenas/driver.py +619 -0
  430. workers/official_arenas/protocol.py +334 -0
  431. workers/official_arenas/providers/__init__.py +1 -0
  432. workers/official_arenas/providers/_live_history.py +228 -0
  433. workers/official_arenas/providers/_message_compat.py +77 -0
  434. workers/official_arenas/providers/appworld_ul.py +196 -0
  435. workers/official_arenas/providers/fixture.py +112 -0
  436. workers/official_arenas/providers/statebench.py +960 -0
  437. workers/official_arenas/providers/tau3.py +1672 -0
  438. workers/official_arenas/providers/tau_retail.py +586 -0
  439. workers/official_arenas/providers/toolsandbox.py +1321 -0
  440. workers/official_arenas/providers/tooltalk.py +699 -0
  441. workers/official_arenas/retail_capture.py +188 -0
  442. workers/official_arenas/retail_driver.py +275 -0
  443. workers/qrag/README.md +172 -0
  444. workers/qrag/__init__.py +1 -0
  445. workers/qrag/compatibility_manifest.json +64 -0
  446. workers/qrag/driver.py +673 -0
  447. workers/r2ag/README.md +154 -0
  448. workers/r2ag/__init__.py +5 -0
  449. workers/r2ag/compatibility_manifest.json +55 -0
  450. workers/r2ag/driver.py +1287 -0
  451. workers/r2ag/feature_schema.json +8 -0
  452. workers/r2ag/runtime.py +589 -0
  453. workers/recomp/README.md +120 -0
  454. workers/recomp/__init__.py +1 -0
  455. workers/recomp/compatibility_manifest.json +43 -0
  456. workers/recomp/driver.py +1653 -0
  457. workers/reformer/README.md +125 -0
  458. workers/reformer/__init__.py +1 -0
  459. workers/reformer/compatibility_manifest.json +68 -0
  460. workers/reformer/driver.py +1459 -0
  461. workers/reformer/induction.py +457 -0
  462. workers/rrr/README.md +126 -0
  463. workers/rrr/__init__.py +1 -0
  464. workers/rrr/compatibility_manifest.json +57 -0
  465. workers/rrr/driver.py +1133 -0
  466. workers/smartsearch/README.md +331 -0
  467. workers/smartsearch/__init__.py +1 -0
  468. workers/smartsearch/compatibility_manifest.json +41 -0
  469. 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
+ ]