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,891 @@
1
+ """Released Q-RAG value policy adapted to the shared agent arenas.
2
+
3
+ The upstream worker remains the paper-shaped selector/reader path. This module
4
+ provides a separate common-support intervention: the shared retriever builds an
5
+ ordered candidate pool, the released frozen PQN selects two documents with the
6
+ official QAEnv/PQN loop, and the unified downstream agent answers from those
7
+ real documents. No gold answer, supporting-fact label, reward, training step,
8
+ or upstream reader is available to the intervention.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import gc
14
+ import hashlib
15
+ import importlib.util
16
+ import json
17
+ import math
18
+ import os
19
+ import random
20
+ import re
21
+ import subprocess
22
+ import sys
23
+ import time
24
+ import types
25
+ from collections import defaultdict
26
+ from collections.abc import Mapping, Sequence
27
+ from contextlib import contextmanager, suppress
28
+ from dataclasses import dataclass, field
29
+ from pathlib import Path
30
+ from typing import Any, Protocol, runtime_checkable
31
+
32
+ from agentinputlab.backends.retrieval import RetrievalResult, Retriever
33
+ from agentinputlab.contracts import (
34
+ AlgorithmOutputError,
35
+ BudgetExceededError,
36
+ ContextBlock,
37
+ ExecutionTrace,
38
+ ExternalDependencyError,
39
+ FrozenAgentState,
40
+ InputPatch,
41
+ InterventionContext,
42
+ PatchOp,
43
+ PatchOperation,
44
+ SemanticFamily,
45
+ TraceEvent,
46
+ TracePhase,
47
+ ValidationError,
48
+ )
49
+ from agentinputlab.contracts.serialization import content_hash, freeze_mapping
50
+
51
+ from .bridge import (
52
+ QRAG_CHECKPOINT_CONFIG_SHA256,
53
+ QRAG_CHECKPOINT_FILE_SHA256,
54
+ QRAG_CHECKPOINT_REPOSITORY,
55
+ QRAG_CHECKPOINT_REVISION,
56
+ QRAG_EMBEDDER_MODEL_SHA256,
57
+ QRAG_EMBEDDER_REPOSITORY,
58
+ QRAG_EMBEDDER_REVISION,
59
+ QRAG_SOURCE_MANIFEST_SHA256,
60
+ QRAG_UPSTREAM_COMMIT,
61
+ )
62
+ from .native_axis import (
63
+ QRAG_SINGLE_CANDIDATE_AXIS_COMPAT,
64
+ install_single_candidate_axis_compat,
65
+ )
66
+
67
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
68
+ _SOURCE_RECEIPT = "agentinputlab-source-receipt.json"
69
+ _EMBEDDER_MANIFEST = "agentinputlab-manifest.json"
70
+
71
+
72
+ def _sha256_file(path: Path) -> str:
73
+ digest = hashlib.sha256()
74
+ with path.open("rb") as handle:
75
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
76
+ digest.update(chunk)
77
+ return digest.hexdigest()
78
+
79
+
80
+ def _json(path: Path) -> Mapping[str, Any]:
81
+ try:
82
+ value = json.loads(path.read_text(encoding="utf-8"))
83
+ except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:
84
+ raise ExternalDependencyError(f"Q-RAG artifact JSON is invalid: {path}") from exc
85
+ if not isinstance(value, Mapping):
86
+ raise ExternalDependencyError(f"Q-RAG artifact JSON must be an object: {path}")
87
+ return value
88
+
89
+
90
+ def _real_directory(value: Path, *, label: str) -> Path:
91
+ path = value.expanduser().resolve()
92
+ if not path.is_dir() or path.is_symlink():
93
+ raise ValidationError(f"Q-RAG {label} must be a real directory")
94
+ return path
95
+
96
+
97
+ def _real_file(value: Path, *, label: str) -> Path:
98
+ path = value.expanduser().resolve()
99
+ if not path.is_file() or path.is_symlink():
100
+ raise ValidationError(f"Q-RAG {label} must be a real file")
101
+ return path
102
+
103
+
104
+ def _safe_file(root: Path, relative: str) -> Path:
105
+ if not relative or Path(relative).is_absolute():
106
+ raise ExternalDependencyError("Q-RAG artifact path is invalid")
107
+ path = root / relative
108
+ if path.is_symlink():
109
+ raise ExternalDependencyError("Q-RAG artifact symlinks are forbidden")
110
+ try:
111
+ resolved = path.resolve(strict=True)
112
+ resolved.relative_to(root)
113
+ except (FileNotFoundError, ValueError) as exc:
114
+ raise ExternalDependencyError("Q-RAG artifact path escapes its root or is missing") from exc
115
+ if not resolved.is_file():
116
+ raise ExternalDependencyError("Q-RAG artifact path is not a file")
117
+ return resolved
118
+
119
+
120
+ @contextmanager
121
+ def _source_import(root: Path):
122
+ value = str(root)
123
+ sys.path.insert(0, value)
124
+ try:
125
+ yield
126
+ finally:
127
+ if sys.path and sys.path[0] == value:
128
+ sys.path.pop(0)
129
+ else: # pragma: no cover - defensive against third-party path mutation
130
+ with suppress(ValueError):
131
+ sys.path.remove(value)
132
+
133
+
134
+ @contextmanager
135
+ def _unused_vllm_import_compatibility():
136
+ """Allow the released dummy-feedback path without a worker-local vLLM.
137
+
138
+ Q-RAG's ``rl.feedback`` package imports its optional local reader at module
139
+ import time, even though the common-support runtime uses only the released
140
+ ``DummyFeedbackModel``. Keep target serving isolated in the external vLLM
141
+ process and fail closed if this unused reader is ever constructed.
142
+ """
143
+
144
+ try:
145
+ available = importlib.util.find_spec("vllm") is not None
146
+ except (ImportError, ValueError):
147
+ available = "vllm" in sys.modules
148
+ if available:
149
+ yield
150
+ return
151
+
152
+ class _UnavailableVLLM:
153
+ def __init__(self, *_args: Any, **_kwargs: Any) -> None:
154
+ raise RuntimeError(
155
+ "Q-RAG common-support execution must not instantiate its unused vLLM reader"
156
+ )
157
+
158
+ module = types.ModuleType("vllm")
159
+ module.LLM = _UnavailableVLLM
160
+ module.SamplingParams = _UnavailableVLLM
161
+ sys.modules["vllm"] = module
162
+ try:
163
+ yield
164
+ finally:
165
+ if sys.modules.get("vllm") is module:
166
+ del sys.modules["vllm"]
167
+
168
+
169
+ @dataclass(frozen=True, slots=True)
170
+ class QRAGPolicyRequest:
171
+ question: str
172
+ candidates: tuple[RetrievalResult, ...]
173
+ seed: int
174
+ max_steps: int = 2
175
+
176
+ def __post_init__(self) -> None:
177
+ if not self.question.strip() or not self.candidates:
178
+ raise ValidationError("Q-RAG policy request requires question and candidates")
179
+ if isinstance(self.seed, bool) or not isinstance(self.seed, int) or self.seed < 0:
180
+ raise ValidationError("Q-RAG policy seed must be non-negative")
181
+ if self.max_steps != 2:
182
+ raise ValidationError("released Q-RAG policy requires exactly two selection steps")
183
+ object.__setattr__(self, "candidates", tuple(self.candidates))
184
+
185
+
186
+ @runtime_checkable
187
+ class QRAGCommonSupportRuntime(Protocol):
188
+ def select(self, request: QRAGPolicyRequest) -> Mapping[str, Any]:
189
+ """Select two candidate indices with the released value policy."""
190
+
191
+ def fingerprint(self) -> Mapping[str, Any]:
192
+ """Return checksum-closed source, checkpoint, and embedder identity."""
193
+
194
+
195
+ @dataclass(slots=True)
196
+ class LocalQRAGFrozenPolicyRuntime: # pragma: no cover - L20 GPU acceptance
197
+ """Lazy inference-only runtime around the pinned upstream QAEnv and PQN."""
198
+
199
+ source_root: Path
200
+ checkpoint_root: Path
201
+ embedder_root: Path
202
+ compatibility_manifest_path: Path
203
+ compatibility_manifest_sha256: str
204
+ embedder_manifest_sha256: str
205
+ device: str = "cuda"
206
+ worker_id: str = "qrag-common-support-local"
207
+ single_candidate_axis_compat: bool = False
208
+ _runtime: tuple[Any, Any, Any] | None = field(init=False, default=None, repr=False)
209
+ _verified: bool = field(init=False, default=False, repr=False)
210
+
211
+ def __post_init__(self) -> None:
212
+ if not isinstance(self.single_candidate_axis_compat, bool):
213
+ raise ValidationError("Q-RAG single_candidate_axis_compat must be boolean")
214
+ self.source_root = _real_directory(self.source_root, label="source_root")
215
+ self.checkpoint_root = _real_directory(self.checkpoint_root, label="checkpoint_root")
216
+ self.embedder_root = _real_directory(self.embedder_root, label="embedder_root")
217
+ self.compatibility_manifest_path = _real_file(
218
+ self.compatibility_manifest_path,
219
+ label="compatibility_manifest_path",
220
+ )
221
+ for label, value in (
222
+ ("compatibility_manifest_sha256", self.compatibility_manifest_sha256),
223
+ ("embedder_manifest_sha256", self.embedder_manifest_sha256),
224
+ ):
225
+ if not isinstance(value, str) or _SHA256.fullmatch(value) is None:
226
+ raise ValidationError(f"Q-RAG {label} must be a lowercase SHA-256")
227
+ if not isinstance(self.device, str) or not self.device.strip():
228
+ raise ValidationError("Q-RAG device must not be empty")
229
+
230
+ def _verify_artifacts(self) -> Mapping[str, Any]:
231
+ manifest = _json(self.compatibility_manifest_path)
232
+ if content_hash(manifest) != self.compatibility_manifest_sha256:
233
+ raise ExternalDependencyError("Q-RAG compatibility manifest checksum mismatch")
234
+ source = manifest.get("source")
235
+ checkpoint = manifest.get("checkpoint")
236
+ embedder = manifest.get("embedder")
237
+ if not all(isinstance(row, Mapping) for row in (source, checkpoint, embedder)):
238
+ raise ExternalDependencyError("Q-RAG compatibility manifest sections are invalid")
239
+ assert isinstance(source, Mapping)
240
+ assert isinstance(checkpoint, Mapping)
241
+ assert isinstance(embedder, Mapping)
242
+ if (
243
+ source.get("commit") != QRAG_UPSTREAM_COMMIT
244
+ or source.get("content_manifest_sha256") != QRAG_SOURCE_MANIFEST_SHA256
245
+ or checkpoint.get("repository") != QRAG_CHECKPOINT_REPOSITORY
246
+ or checkpoint.get("revision") != QRAG_CHECKPOINT_REVISION
247
+ or embedder.get("repository") != QRAG_EMBEDDER_REPOSITORY
248
+ or embedder.get("revision") != QRAG_EMBEDDER_REVISION
249
+ or embedder.get("model_safetensors_sha256") != QRAG_EMBEDDER_MODEL_SHA256
250
+ ):
251
+ raise ExternalDependencyError("Q-RAG compatibility manifest identity drifted")
252
+ required = source.get("required_files")
253
+ if not isinstance(required, Mapping) or not required:
254
+ raise ExternalDependencyError("Q-RAG source required-file manifest is invalid")
255
+ for relative, expected in required.items():
256
+ if not isinstance(relative, str) or not isinstance(expected, str):
257
+ raise ExternalDependencyError("Q-RAG source required-file row is invalid")
258
+ if _sha256_file(_safe_file(self.source_root, relative)) != expected:
259
+ raise ExternalDependencyError(f"Q-RAG source hash mismatch: {relative}")
260
+ self._verify_source_transport(source)
261
+
262
+ model_path = _safe_file(self.checkpoint_root, "model_best.pt")
263
+ config_path = _safe_file(self.checkpoint_root, "config.yaml")
264
+ if model_path.stat().st_size != checkpoint.get("model_best_size"):
265
+ raise ExternalDependencyError("Q-RAG checkpoint size mismatch")
266
+ if _sha256_file(model_path) != QRAG_CHECKPOINT_FILE_SHA256:
267
+ raise ExternalDependencyError("Q-RAG checkpoint checksum mismatch")
268
+ if _sha256_file(config_path) != QRAG_CHECKPOINT_CONFIG_SHA256:
269
+ raise ExternalDependencyError("Q-RAG checkpoint configuration checksum mismatch")
270
+ self._verify_embedder_manifest()
271
+ self._verified = True
272
+ return manifest
273
+
274
+ def _verify_source_transport(self, source: Mapping[str, Any]) -> None:
275
+ git_dir = self.source_root / ".git"
276
+ if git_dir.exists():
277
+ completed = subprocess.run(
278
+ ["git", "-C", str(self.source_root), "rev-parse", "HEAD"],
279
+ check=False,
280
+ capture_output=True,
281
+ text=True,
282
+ timeout=10,
283
+ )
284
+ if completed.returncode or completed.stdout.strip() != QRAG_UPSTREAM_COMMIT:
285
+ raise ExternalDependencyError("Q-RAG source checkout commit mismatch")
286
+ return
287
+ receipt = _json(_safe_file(self.source_root, _SOURCE_RECEIPT))
288
+ expected = {
289
+ "repository": source.get("repository"),
290
+ "commit": source.get("commit"),
291
+ "tree": source.get("tree"),
292
+ "transport": "jsdelivr_commit_snapshot",
293
+ }
294
+ if any(receipt.get(key) != value for key, value in expected.items()):
295
+ raise ExternalDependencyError("Q-RAG source snapshot identity mismatch")
296
+ self._verify_file_closure(
297
+ self.source_root,
298
+ receipt.get("files"),
299
+ excluded={_SOURCE_RECEIPT},
300
+ label="source snapshot",
301
+ )
302
+
303
+ def _verify_embedder_manifest(self) -> None:
304
+ path = _safe_file(self.embedder_root, _EMBEDDER_MANIFEST)
305
+ manifest = _json(path)
306
+ if content_hash(manifest) != self.embedder_manifest_sha256:
307
+ raise ExternalDependencyError("Q-RAG embedder manifest checksum mismatch")
308
+ if (
309
+ manifest.get("repository") != QRAG_EMBEDDER_REPOSITORY
310
+ or manifest.get("revision") != QRAG_EMBEDDER_REVISION
311
+ ):
312
+ raise ExternalDependencyError("Q-RAG embedder repository/revision mismatch")
313
+ if _sha256_file(_safe_file(self.embedder_root, "model.safetensors")) != (
314
+ QRAG_EMBEDDER_MODEL_SHA256
315
+ ):
316
+ raise ExternalDependencyError("Q-RAG embedder weights checksum mismatch")
317
+ self._verify_file_closure(
318
+ self.embedder_root,
319
+ manifest.get("files"),
320
+ excluded={_EMBEDDER_MANIFEST},
321
+ label="embedder snapshot",
322
+ )
323
+
324
+ @staticmethod
325
+ def _verify_file_closure(
326
+ root: Path,
327
+ rows: Any,
328
+ *,
329
+ excluded: set[str],
330
+ label: str,
331
+ ) -> None:
332
+ if isinstance(rows, (str, bytes)) or not isinstance(rows, Sequence) or not rows:
333
+ raise ExternalDependencyError(f"Q-RAG {label} file receipt is invalid")
334
+ declared: set[str] = set()
335
+ for row in rows:
336
+ if not isinstance(row, Mapping) or set(row) != {"path", "sha256", "size"}:
337
+ raise ExternalDependencyError(f"Q-RAG {label} file row is invalid")
338
+ relative, digest, size = row.get("path"), row.get("sha256"), row.get("size")
339
+ if (
340
+ not isinstance(relative, str)
341
+ or relative in excluded
342
+ or relative in declared
343
+ or not isinstance(digest, str)
344
+ or _SHA256.fullmatch(digest) is None
345
+ or isinstance(size, bool)
346
+ or not isinstance(size, int)
347
+ or size < 0
348
+ ):
349
+ raise ExternalDependencyError(f"Q-RAG {label} file row is invalid")
350
+ path = _safe_file(root, relative)
351
+ if path.stat().st_size != size or _sha256_file(path) != digest:
352
+ raise ExternalDependencyError(f"Q-RAG {label} file checksum mismatch: {relative}")
353
+ declared.add(relative)
354
+ actual = {
355
+ str(path.relative_to(root))
356
+ for path in root.rglob("*")
357
+ if path.is_file()
358
+ and str(path.relative_to(root)) not in excluded
359
+ and ".cache" not in path.parts
360
+ and "__pycache__" not in path.parts
361
+ and path.suffix not in {".pyc", ".lock", ".incomplete"}
362
+ }
363
+ if actual != declared:
364
+ raise ExternalDependencyError(f"Q-RAG {label} file closure mismatch")
365
+
366
+ def _load(self) -> tuple[Any, Any, Any]:
367
+ if self._runtime is not None:
368
+ return self._runtime
369
+ if not self._verified:
370
+ self._verify_artifacts()
371
+ os.environ.setdefault("TRANSFORMERS_OFFLINE", "1")
372
+ os.environ.setdefault("HF_DATASETS_OFFLINE", "1")
373
+ try:
374
+ import torch
375
+ from omegaconf import OmegaConf
376
+ from omegaconf.base import ContainerMetadata, Metadata
377
+ from omegaconf.listconfig import ListConfig
378
+ from omegaconf.nodes import AnyNode
379
+ except ImportError as exc:
380
+ raise ExternalDependencyError(
381
+ "Q-RAG local runtime requires torch, numpy, omegaconf, hydra-core, "
382
+ "rotary-embedding-torch, sortedcontainers, nltk, and transformers"
383
+ ) from exc
384
+ with _unused_vllm_import_compatibility(), _source_import(self.source_root):
385
+ try:
386
+ from envs.qa_env import QAEnv
387
+ from envs.text_env import AbsolutePositionProcessor
388
+ from rl.agents.pqn import PQN
389
+ from rl.feedback.feedback import AFeedbackModel, DummyFeedbackModel
390
+ except ImportError as exc:
391
+ raise ExternalDependencyError("unable to import pinned Q-RAG source") from exc
392
+
393
+ class RunnableDummyFeedbackModel(DummyFeedbackModel):
394
+ """Repair the upstream missing abstract reset without changing feedback semantics."""
395
+
396
+ def reset(self, obs: Any, info: Any) -> None:
397
+ AFeedbackModel.reset(self, obs, info)
398
+
399
+ cfg = OmegaConf.load(self.checkpoint_root / "config.yaml")
400
+ cfg.algo.model.model_name = str(self.embedder_root)
401
+ cfg.algo.model.revision = None
402
+ OmegaConf.resolve(cfg)
403
+ torch.set_default_device(self.device)
404
+ torch.set_float32_matmul_precision("high")
405
+ with _source_import(self.source_root):
406
+ agent = PQN(cfg.algo)
407
+ # The released checkpoint contains an OmegaConf ListConfig under its
408
+ # scheduler state. Keep weights-only loading and scope the smallest
409
+ # inert constructor allowlist needed to deserialize that container;
410
+ # arbitrary upstream Python globals remain rejected.
411
+ safe_checkpoint_globals = [
412
+ ListConfig,
413
+ ContainerMetadata,
414
+ Metadata,
415
+ Any,
416
+ list,
417
+ defaultdict,
418
+ dict,
419
+ int,
420
+ AnyNode,
421
+ ]
422
+ with torch.serialization.safe_globals(safe_checkpoint_globals):
423
+ checkpoint = torch.load(
424
+ self.checkpoint_root / "model_best.pt",
425
+ map_location="cpu",
426
+ weights_only=True,
427
+ mmap=True,
428
+ )
429
+ required = {
430
+ "critic": agent.critic,
431
+ "policy": agent.policy,
432
+ "v_net_target": agent.v_net_target,
433
+ "action_embed_target": agent.action_embed_target,
434
+ }
435
+ if not isinstance(checkpoint, Mapping) or not set(required).issubset(checkpoint):
436
+ raise ExternalDependencyError("Q-RAG checkpoint lacks inference state dictionaries")
437
+ for name, module in required.items():
438
+ module.load_state_dict(checkpoint[name], strict=True)
439
+ module.eval()
440
+ agent.random_policy.eval()
441
+ if self.single_candidate_axis_compat:
442
+ install_single_candidate_axis_compat(agent.policy, self.source_root)
443
+ del checkpoint
444
+ gc.collect()
445
+ if str(self.device).startswith("cuda"):
446
+ torch.cuda.empty_cache()
447
+ env = QAEnv(
448
+ dataset=None,
449
+ max_steps=2,
450
+ positions_processor=AbsolutePositionProcessor(),
451
+ action_embed_length=int(cfg.max_action_length),
452
+ max_action_length_in_memory=int(cfg.algo.pqn.hyperparams.max_action_length_in_memory),
453
+ feedback_model=RunnableDummyFeedbackModel(),
454
+ separator=" [SEP] ",
455
+ sort_by_index=False,
456
+ )
457
+ self._runtime = (torch, agent, env)
458
+ return self._runtime
459
+
460
+ def select(self, request: QRAGPolicyRequest) -> Mapping[str, Any]:
461
+ if not isinstance(request, QRAGPolicyRequest):
462
+ raise TypeError("Q-RAG runtime requires QRAGPolicyRequest")
463
+ torch, agent, env = self._load()
464
+ try:
465
+ import numpy as np
466
+ except ImportError as exc: # pragma: no cover
467
+ raise ExternalDependencyError("Q-RAG runtime requires numpy") from exc
468
+ random.seed(request.seed)
469
+ np.random.seed(request.seed)
470
+ torch.manual_seed(request.seed)
471
+ if str(self.device).startswith("cuda"):
472
+ torch.cuda.manual_seed_all(request.seed)
473
+ torch.cuda.synchronize()
474
+ candidate_ids = tuple(row.document.doc_id for row in request.candidates)
475
+ chunks = tuple(_policy_candidate_text(row) for row in request.candidates)
476
+ sample = {
477
+ "id": content_hash({"question": request.question, "candidates": candidate_ids}),
478
+ "question": request.question,
479
+ "answer": "",
480
+ "chunks": chunks,
481
+ "sf_idx": [],
482
+ }
483
+ started = time.perf_counter()
484
+ state = env.reset(sample)
485
+ embeds, embeds_target = env.get_extra_embeds(
486
+ agent.action_tokenizer,
487
+ agent.critic.action_embed,
488
+ agent.action_embed_target,
489
+ )
490
+ steps: list[dict[str, Any]] = []
491
+ done = False
492
+ while not done and len(steps) < request.max_steps:
493
+ available = tuple(sorted(int(index) for index in state.available_ids))
494
+ embeds = env.update_embeds(embeds, agent.critic.action_embed)
495
+ embeds_target = env.update_embeds(embeds_target, agent.action_embed_target)
496
+ action, q_values, _ = agent.select_action(
497
+ state,
498
+ embeds["rope"],
499
+ embeds_target["rope"],
500
+ random=False,
501
+ evaluate=True,
502
+ )
503
+ q_row = q_values.detach().to(device="cpu", dtype=torch.float64).reshape(-1)
504
+ if q_row.numel() != len(candidate_ids) or action not in available:
505
+ raise AlgorithmOutputError("Q-RAG policy returned an invalid candidate action")
506
+ selected_q = float(q_row[action].item())
507
+ if not math.isfinite(selected_q):
508
+ raise AlgorithmOutputError("Q-RAG policy returned a non-finite selected value")
509
+ state, _, _, done = env.step(action)
510
+ selected = tuple(int(index) for index in state.item_ids)
511
+ steps.append(
512
+ {
513
+ "index": len(steps),
514
+ "available_indices": available,
515
+ "q_values": tuple(float(q_row[index].item()) for index in available),
516
+ "action_index": int(action),
517
+ "selected_q_value": selected_q,
518
+ "selected_indices": selected,
519
+ "selected_document_ids": tuple(candidate_ids[index] for index in selected),
520
+ }
521
+ )
522
+ if str(self.device).startswith("cuda"):
523
+ torch.cuda.synchronize()
524
+ elapsed = time.perf_counter() - started
525
+ selected = tuple(int(index) for index in state.item_ids)
526
+ expected_steps = min(2, len(candidate_ids))
527
+ if len(steps) != expected_steps or len(selected) != expected_steps:
528
+ raise AlgorithmOutputError("Q-RAG policy did not complete its fixed selection horizon")
529
+ return {
530
+ "status": "ok",
531
+ "trajectory": tuple(steps),
532
+ "trajectory_sha256": content_hash(steps),
533
+ "selected_indices": selected,
534
+ "selected_document_ids": tuple(candidate_ids[index] for index in selected),
535
+ "candidate_order_sha256": content_hash(candidate_ids),
536
+ "candidate_text_sha256": content_hash(chunks),
537
+ "usage": {
538
+ "model_calls": 0,
539
+ "retrieval_calls": 0,
540
+ "input_tokens": 0,
541
+ "output_tokens": 0,
542
+ "embedding_calls": 2 + 2 * len(steps),
543
+ "accelerator_seconds": elapsed,
544
+ },
545
+ "policy_steps": len(steps),
546
+ "attestation": {
547
+ "official_candidate_builder_called": True,
548
+ "official_pqn_select_action_called": True,
549
+ "official_qa_env_step_called": True,
550
+ "safe_weights_only_load": True,
551
+ "strict_state_dict_load": True,
552
+ "checkpoint_eval_mode": True,
553
+ "dummy_feedback_used": True,
554
+ "gold_answer_used": False,
555
+ "supporting_fact_labels_used": False,
556
+ "reward_used": False,
557
+ "training_called": False,
558
+ "stop_action_used": False,
559
+ "seed_applied": True,
560
+ },
561
+ }
562
+
563
+ def fingerprint(self) -> Mapping[str, Any]:
564
+ return freeze_mapping(
565
+ {
566
+ "runtime": "qrag_released_pqn_common_support.v1",
567
+ "source_repository": "griver/Q-RAG",
568
+ "source_commit": QRAG_UPSTREAM_COMMIT,
569
+ "source_manifest_sha256": QRAG_SOURCE_MANIFEST_SHA256,
570
+ "checkpoint_repository": QRAG_CHECKPOINT_REPOSITORY,
571
+ "checkpoint_revision": QRAG_CHECKPOINT_REVISION,
572
+ "checkpoint_file_sha256": QRAG_CHECKPOINT_FILE_SHA256,
573
+ "checkpoint_config_sha256": QRAG_CHECKPOINT_CONFIG_SHA256,
574
+ "embedder_repository": QRAG_EMBEDDER_REPOSITORY,
575
+ "embedder_revision": QRAG_EMBEDDER_REVISION,
576
+ "embedder_model_sha256": QRAG_EMBEDDER_MODEL_SHA256,
577
+ "embedder_manifest_sha256": self.embedder_manifest_sha256,
578
+ "compatibility_manifest_sha256": self.compatibility_manifest_sha256,
579
+ "safe_weights_only_load": True,
580
+ "strict_state_dict_load": True,
581
+ "optimizer_state_loaded": False,
582
+ "training_allowed": False,
583
+ "paper_result_parity_claimed": False,
584
+ **({"native_tensor_axis_adapter": QRAG_SINGLE_CANDIDATE_AXIS_COMPAT}
585
+ if self.single_candidate_axis_compat else {}),
586
+ }
587
+ )
588
+
589
+
590
+ @dataclass(frozen=True, slots=True)
591
+ class QRAGCommonSupportConfig:
592
+ candidate_top_k: int = 6
593
+ max_select_actions: int = 2
594
+
595
+ def __post_init__(self) -> None:
596
+ if self.candidate_top_k < 2:
597
+ raise ValidationError("Q-RAG common support requires at least two candidates")
598
+ if self.max_select_actions != 2:
599
+ raise ValidationError("released Q-RAG policy requires two selection actions")
600
+
601
+
602
+ @dataclass(slots=True)
603
+ class QRAGCommonSupport:
604
+ """Select real shared-corpus documents with the released Q-RAG PQN."""
605
+
606
+ config: QRAGCommonSupportConfig = QRAGCommonSupportConfig()
607
+ method_id: str = "qrag"
608
+ release_id: str = "acquire.qrag.common_support"
609
+ family: SemanticFamily = SemanticFamily.ACQUIRE
610
+
611
+ def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
612
+ if not state.query.strip():
613
+ raise ValidationError("Q-RAG requires a non-empty query")
614
+ if state.budget.max_retrieval_calls < 1:
615
+ raise BudgetExceededError("Q-RAG has no retrieval budget")
616
+ retriever = _retriever(context.retriever)
617
+ runtime = _runtime(context.external_runtime)
618
+ results = _validated_results(
619
+ retriever.retrieve(state.query, top_k=self.config.candidate_top_k),
620
+ top_k=self.config.candidate_top_k,
621
+ )
622
+ if len(results) < 2:
623
+ raise AlgorithmOutputError("Q-RAG requires at least two retrieved candidates")
624
+ candidate_ids = tuple(row.document.doc_id for row in results)
625
+ response = runtime.select(
626
+ QRAGPolicyRequest(
627
+ question=state.query,
628
+ candidates=results,
629
+ seed=context.seed,
630
+ max_steps=self.config.max_select_actions,
631
+ )
632
+ )
633
+ trajectory, selected, usage, attestation = _validate_response(response, candidate_ids)
634
+ blocks = tuple(
635
+ _real_context(results[index], rank) for rank, index in enumerate(selected, 1)
636
+ )
637
+ runtime_identity = dict(runtime.fingerprint())
638
+ events = [
639
+ TraceEvent(
640
+ TracePhase.PREPARE,
641
+ "qrag_common_support_candidate_pool",
642
+ {
643
+ "candidate_document_ids": candidate_ids,
644
+ "candidate_order_sha256": content_hash(candidate_ids),
645
+ "retriever": dict(retriever.fingerprint()),
646
+ "runtime": runtime_identity,
647
+ "selection_budget": 2,
648
+ "upstream_reader_used": False,
649
+ "paper_result_parity_claimed": False,
650
+ },
651
+ )
652
+ ]
653
+ events.extend(
654
+ TraceEvent(TracePhase.OBSERVE, "qrag_value_policy_step", dict(step))
655
+ for step in trajectory
656
+ )
657
+ events.append(
658
+ TraceEvent(
659
+ TracePhase.FINALIZE,
660
+ "qrag_selected_real_context",
661
+ {
662
+ "selected_indices": selected,
663
+ "selected_document_ids": tuple(candidate_ids[index] for index in selected),
664
+ "trajectory_sha256": content_hash(trajectory),
665
+ "gold_answer_used": False,
666
+ "supporting_fact_labels_used": False,
667
+ "reward_used": False,
668
+ },
669
+ )
670
+ )
671
+ return InputPatch(
672
+ method_id=self.method_id,
673
+ release_id=self.release_id,
674
+ source_state_hash=state.state_hash,
675
+ operations=(
676
+ PatchOperation(
677
+ PatchOp.ADD_CONTEXT,
678
+ blocks,
679
+ target="qrag_value_selected_real_documents",
680
+ rationale="select shared-corpus evidence with the released frozen Q-RAG PQN",
681
+ ),
682
+ ),
683
+ trace=ExecutionTrace(
684
+ method_id=self.method_id,
685
+ release_id=self.release_id,
686
+ events=tuple(events),
687
+ counters={
688
+ "retrieval_calls": 1,
689
+ "embedding_calls": usage["embedding_calls"],
690
+ "policy_steps": len(trajectory),
691
+ "selected_documents": len(blocks),
692
+ "accelerator_seconds": usage["accelerator_seconds"],
693
+ },
694
+ ),
695
+ implementation_identity=f"thin_external_wrapper:griver/Q-RAG@{QRAG_UPSTREAM_COMMIT}",
696
+ profile_kind="controlled_adapter",
697
+ metadata={
698
+ "common_support_adaptation": "released_value_policy_over_shared_candidate_pool",
699
+ "selected_indices": selected,
700
+ "selected_document_ids": tuple(candidate_ids[index] for index in selected),
701
+ "runtime_attestation": attestation,
702
+ "upstream_reader_used": False,
703
+ "real_documents_are_evidence": True,
704
+ "gold_answer_used": False,
705
+ "supporting_fact_labels_used": False,
706
+ "reward_used": False,
707
+ "training_called": False,
708
+ "upstream_checkpoint_parity_claimed": False,
709
+ "paper_result_parity_claimed": False,
710
+ },
711
+ )
712
+
713
+
714
+ def _policy_candidate_text(result: RetrievalResult) -> str:
715
+ title = result.document.title.strip()
716
+ text = result.document.text.strip()
717
+ return f"Title: {title}\n{text}" if title else text
718
+
719
+
720
+ def _retriever(value: object) -> Retriever:
721
+ if value is None or not hasattr(value, "retrieve") or not hasattr(value, "fingerprint"):
722
+ raise ExternalDependencyError("Q-RAG common support requires a Retriever")
723
+ return value # type: ignore[return-value]
724
+
725
+
726
+ def _runtime(value: object) -> QRAGCommonSupportRuntime:
727
+ if not isinstance(value, QRAGCommonSupportRuntime):
728
+ raise ExternalDependencyError(
729
+ "Q-RAG common support requires InterventionContext.external_runtime"
730
+ )
731
+ return value
732
+
733
+
734
+ def _validated_results(
735
+ values: Sequence[RetrievalResult], *, top_k: int
736
+ ) -> tuple[RetrievalResult, ...]:
737
+ try:
738
+ results = tuple(values)
739
+ except TypeError as exc:
740
+ raise AlgorithmOutputError("Q-RAG retriever returned a non-sequence") from exc
741
+ if not all(isinstance(row, RetrievalResult) for row in results) or len(results) > top_k:
742
+ raise AlgorithmOutputError("Q-RAG retriever returned invalid results")
743
+ ids = tuple(row.document.doc_id for row in results)
744
+ if any(not value for value in ids) or len(ids) != len(set(ids)):
745
+ raise AlgorithmOutputError("Q-RAG retrieval IDs must be non-empty and unique")
746
+ if tuple(row.rank for row in results) != tuple(range(1, len(results) + 1)):
747
+ raise AlgorithmOutputError("Q-RAG retrieval ranks must be contiguous and one-based")
748
+ return results
749
+
750
+
751
+ def _validate_response(
752
+ value: Mapping[str, Any],
753
+ candidate_ids: tuple[str, ...],
754
+ ) -> tuple[
755
+ tuple[Mapping[str, Any], ...],
756
+ tuple[int, ...],
757
+ Mapping[str, Any],
758
+ Mapping[str, Any],
759
+ ]:
760
+ if not isinstance(value, Mapping) or value.get("status") != "ok":
761
+ raise AlgorithmOutputError("Q-RAG policy runtime returned a failed response")
762
+ raw_steps = value.get("trajectory")
763
+ raw_selected = value.get("selected_indices")
764
+ usage = value.get("usage")
765
+ attestation = value.get("attestation")
766
+ if (
767
+ isinstance(raw_steps, (str, bytes))
768
+ or not isinstance(raw_steps, Sequence)
769
+ or isinstance(raw_selected, (str, bytes))
770
+ or not isinstance(raw_selected, Sequence)
771
+ or not isinstance(usage, Mapping)
772
+ or not isinstance(attestation, Mapping)
773
+ ):
774
+ raise AlgorithmOutputError("Q-RAG policy response schema is invalid")
775
+ selected = tuple(raw_selected)
776
+ if (
777
+ len(selected) != min(2, len(candidate_ids))
778
+ or any(isinstance(index, bool) or not isinstance(index, int) for index in selected)
779
+ or len(selected) != len(set(selected))
780
+ or any(index < 0 or index >= len(candidate_ids) for index in selected)
781
+ ):
782
+ raise AlgorithmOutputError("Q-RAG policy selected indices are invalid")
783
+ steps: list[Mapping[str, Any]] = []
784
+ history: tuple[int, ...] = ()
785
+ for step_index, row in enumerate(raw_steps):
786
+ if not isinstance(row, Mapping):
787
+ raise AlgorithmOutputError("Q-RAG policy trajectory row is invalid")
788
+ available = tuple(row.get("available_indices", ()))
789
+ q_values = tuple(row.get("q_values", ()))
790
+ action = row.get("action_index")
791
+ current = tuple(row.get("selected_indices", ()))
792
+ ids = tuple(row.get("selected_document_ids", ()))
793
+ expected_available = tuple(
794
+ index for index in range(len(candidate_ids)) if index not in history
795
+ )
796
+ if (
797
+ row.get("index") != step_index
798
+ or available != expected_available
799
+ or len(q_values) != len(available)
800
+ or not all(
801
+ isinstance(score, (int, float)) and math.isfinite(score) for score in q_values
802
+ )
803
+ or action not in available
804
+ or current != (*history, action)
805
+ or ids != tuple(candidate_ids[index] for index in current)
806
+ or row.get("selected_q_value") != q_values[available.index(action)]
807
+ ):
808
+ raise AlgorithmOutputError("Q-RAG policy trajectory is inconsistent")
809
+ history = current
810
+ steps.append(freeze_mapping(dict(row)))
811
+ if tuple(history) != selected or tuple(raw_steps) == ():
812
+ raise AlgorithmOutputError("Q-RAG policy trajectory disagrees with final selection")
813
+ if value.get("selected_document_ids") != tuple(candidate_ids[index] for index in selected):
814
+ raise AlgorithmOutputError("Q-RAG selected document IDs mismatch")
815
+ if value.get("candidate_order_sha256") != content_hash(candidate_ids):
816
+ raise AlgorithmOutputError("Q-RAG candidate order checksum mismatch")
817
+ if value.get("trajectory_sha256") != content_hash(raw_steps):
818
+ raise AlgorithmOutputError("Q-RAG trajectory checksum mismatch")
819
+ if (
820
+ value.get("policy_steps") != len(steps)
821
+ or usage.get("embedding_calls") != 2 + 2 * len(steps)
822
+ or any(
823
+ usage.get(field) != 0
824
+ for field in ("model_calls", "retrieval_calls", "input_tokens", "output_tokens")
825
+ )
826
+ or not isinstance(usage.get("accelerator_seconds"), (int, float))
827
+ or usage["accelerator_seconds"] < 0
828
+ ):
829
+ raise AlgorithmOutputError("Q-RAG usage receipt is invalid")
830
+ required_true = {
831
+ "official_candidate_builder_called",
832
+ "official_pqn_select_action_called",
833
+ "official_qa_env_step_called",
834
+ "safe_weights_only_load",
835
+ "strict_state_dict_load",
836
+ "checkpoint_eval_mode",
837
+ "dummy_feedback_used",
838
+ "seed_applied",
839
+ }
840
+ required_false = {
841
+ "gold_answer_used",
842
+ "supporting_fact_labels_used",
843
+ "reward_used",
844
+ "training_called",
845
+ "stop_action_used",
846
+ }
847
+ if any(attestation.get(key) is not True for key in required_true) or any(
848
+ attestation.get(key) is not False for key in required_false
849
+ ):
850
+ raise AlgorithmOutputError("Q-RAG runtime attestation failed")
851
+ return tuple(steps), selected, freeze_mapping(dict(usage)), freeze_mapping(dict(attestation))
852
+
853
+
854
+ def _real_context(result: RetrievalResult, selected_rank: int) -> ContextBlock:
855
+ document = result.document
856
+ if not document.corpus_revision:
857
+ raise AlgorithmOutputError("Q-RAG evidence requires a corpus revision")
858
+ reserved = {
859
+ "corpus_revision",
860
+ "document_id",
861
+ "evidence_kind",
862
+ "qrag_candidate_rank",
863
+ "qrag_selected_rank",
864
+ "title",
865
+ }
866
+ if reserved & set(document.metadata):
867
+ raise AlgorithmOutputError("Q-RAG document metadata uses reserved provenance keys")
868
+ return ContextBlock(
869
+ block_id=document.doc_id,
870
+ text=document.text,
871
+ source=document.corpus_revision,
872
+ score=result.score,
873
+ metadata={
874
+ **dict(document.metadata),
875
+ "document_id": document.doc_id,
876
+ "title": document.title,
877
+ "corpus_revision": document.corpus_revision,
878
+ "qrag_candidate_rank": result.rank,
879
+ "qrag_selected_rank": selected_rank,
880
+ "evidence_kind": "real_corpus_document",
881
+ },
882
+ )
883
+
884
+
885
+ __all__ = [
886
+ "LocalQRAGFrozenPolicyRuntime",
887
+ "QRAGCommonSupport",
888
+ "QRAGCommonSupportConfig",
889
+ "QRAGCommonSupportRuntime",
890
+ "QRAGPolicyRequest",
891
+ ]