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,828 @@
1
+ """Fail-closed bridge for Q-RAG's released frozen E5/HotpotQA policy.
2
+
3
+ Q-RAG's source checkout has no repository-level license declaration. The
4
+ source and the separately licensed checkpoint therefore stay in a dedicated,
5
+ user-mounted worker. This module sends only the ordered candidate texts,
6
+ binds every treatment-defining artifact, and validates the official
7
+ candidate-index/Q-value trajectory. It never exposes training, rewards,
8
+ supporting-fact labels, or a synthetic ``stop`` action.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import math
14
+ import re
15
+ from collections.abc import Mapping, Sequence
16
+ from dataclasses import asdict, dataclass
17
+ from typing import Any
18
+
19
+ from agentinputlab.contracts import (
20
+ AlgorithmOutputError,
21
+ BudgetExceededError,
22
+ CompositeResult,
23
+ ExecutionTrace,
24
+ ExternalDependencyError,
25
+ FrozenAgentState,
26
+ InterventionContext,
27
+ SemanticFamily,
28
+ TraceEvent,
29
+ TracePhase,
30
+ ValidationError,
31
+ )
32
+ from agentinputlab.contracts.serialization import content_hash, freeze_mapping
33
+ from agentinputlab.integrations.external_workers import WorkerClient
34
+ from agentinputlab.integrations.external_workers.method import (
35
+ MethodWorkerRequest,
36
+ call_worker,
37
+ finite_number,
38
+ mapping_sequence,
39
+ nonnegative_integer,
40
+ required_text,
41
+ resolve_worker,
42
+ worker_fingerprint,
43
+ )
44
+ from agentinputlab.observability import external_usage_counters
45
+
46
+ from .reader_adapter import (
47
+ QRAG_INSTRUCTION_PROMPT_SHA256,
48
+ QRAG_INSTRUCTION_PROTOCOL,
49
+ QRAG_INSTRUCTION_READER_PROFILE,
50
+ )
51
+
52
+ QRAG_UPSTREAM_COMMIT = "e7598130b63eaab868469877e88bcacc59a44efb"
53
+ QRAG_PROTOCOL = "agentinputlab.qrag.frozen.v3"
54
+ QRAG_PROFILE_ID = "qrag.e5_hotpotqa.frozen.v1"
55
+
56
+ QRAG_CHECKPOINT_REPOSITORY = "Q-RAG/qrag-ft-e5-on-hotpotqa"
57
+ QRAG_CHECKPOINT_REVISION = "e0e48389f551075ace2ce61207522b6bad55593a"
58
+ QRAG_CHECKPOINT_FILE_SHA256 = "ccd4068d3917bed2e44afcd7ee7a9d66c8487b44dd2206252e6d2985352f92b7"
59
+ QRAG_CHECKPOINT_CONFIG_SHA256 = "edbba621832e545a63723eda2b6652eccfd51b29eda7d04145ba22a7ea48c241"
60
+ QRAG_EMBEDDER_REPOSITORY = "intfloat/multilingual-e5-large"
61
+ QRAG_EMBEDDER_REVISION = "3d7cfbdacd47fdda877c5cd8a79fbcc4f2a574f3"
62
+ QRAG_EMBEDDER_MODEL_SHA256 = "020afdebf2762b29fcaf286629a96c3b3b65af241f6a08226b1cfee60a21def6"
63
+ QRAG_SOURCE_MANIFEST_SHA256 = "86c49eee9c64329bd77f3b5a4286e937aadb7c5fcd67d1238f214421cc27ae1a"
64
+
65
+ QRAG_QA_ENV_SOURCE_SHA256 = "267c27c248f332478bf810a50f097a898a818cf6f8f4bd7b70a2893312c0eae1"
66
+ QRAG_TEXT_ENV_SOURCE_SHA256 = "2bfee69d8bea9e9fc2822dce8aa42c563344da1454a111f807fe2ac7a00fc39c"
67
+ QRAG_PQN_SOURCE_SHA256 = "5e69ee5e20f098c101ceebb0c3713a3e63ffcd0a1b614d7180c1b474465cce39"
68
+
69
+ QRAG_ENVIRONMENT_CONTRACT = freeze_mapping(
70
+ {
71
+ "dataset_profile": "hotpotqa",
72
+ "max_steps": 2,
73
+ "sort_by_index": False,
74
+ "separator": " [SEP] ",
75
+ "position_processor": "absolute_none",
76
+ "feedback_model": "DummyFeedbackModel",
77
+ "feedback_never_terminate": True,
78
+ "gold_answer_available": False,
79
+ "supporting_fact_labels_available": False,
80
+ }
81
+ )
82
+ QRAG_ENVIRONMENT_CONFIG_SHA256 = content_hash(QRAG_ENVIRONMENT_CONTRACT)
83
+ QRAG_ACTION_SCHEMA = freeze_mapping(
84
+ {
85
+ "action": "candidate_index",
86
+ "stop_action": False,
87
+ "policy": "argmax_available_q_value",
88
+ "termination": ("fixed_step_budget", "candidate_exhausted", "empty_candidates"),
89
+ }
90
+ )
91
+ QRAG_ACTION_SCHEMA_SHA256 = content_hash(QRAG_ACTION_SCHEMA)
92
+ QRAG_CANDIDATE_BUILDER_CONTRACT = freeze_mapping(
93
+ {
94
+ "input_fields": ("id", "question", "chunks"),
95
+ "candidate_fields": ("document_id", "text"),
96
+ "preserve_input_order": True,
97
+ "dummy_answer": "",
98
+ "dummy_supporting_fact_indices": (),
99
+ }
100
+ )
101
+ QRAG_CANDIDATE_BUILDER_SHA256 = content_hash(QRAG_CANDIDATE_BUILDER_CONTRACT)
102
+
103
+ QRAG_READER_SYSTEM_PROMPT = (
104
+ "Answer the question based on the given passages.\n"
105
+ "Only give me the short and precise answer, do not output any other words.\n"
106
+ "Keep your reasoning very brief and concise.\n"
107
+ 'Always end your response with "Final answer: [your final answer]".\n'
108
+ )
109
+ QRAG_READER_USER_TEMPLATE = (
110
+ "\nGIVEN PASSAGES:\n{context}\n\nQUESTION:\n{question}\n\nFinal answer: "
111
+ )
112
+ QRAG_READER_PROMPT_SHA256 = content_hash(
113
+ {"system": QRAG_READER_SYSTEM_PROMPT, "user": QRAG_READER_USER_TEMPLATE}
114
+ )
115
+
116
+ _HEX64 = re.compile(r"^[0-9a-f]{64}$")
117
+ _NATIVE_READER_PROFILE = "upstream_qwq32b_family_controlled"
118
+ _TRANSFER_READER_PROFILE = "factorial_reader_transfer"
119
+
120
+
121
+ @dataclass(frozen=True, slots=True)
122
+ class QRAGLicenseAcknowledgement:
123
+ """Explicitly acknowledge the two independently governed user mounts."""
124
+
125
+ source_noassertion_acknowledged: bool = False
126
+ checkpoint_cc_by_4_0_acknowledged: bool = False
127
+ user_mounted_source: bool = False
128
+ user_mounted_checkpoint: bool = False
129
+
130
+ def __post_init__(self) -> None:
131
+ if any(
132
+ not isinstance(value, bool)
133
+ for value in (
134
+ self.source_noassertion_acknowledged,
135
+ self.checkpoint_cc_by_4_0_acknowledged,
136
+ self.user_mounted_source,
137
+ self.user_mounted_checkpoint,
138
+ )
139
+ ):
140
+ raise ValidationError("Q-RAG license acknowledgements must be boolean")
141
+
142
+ def require_complete(self) -> None:
143
+ if not self.source_noassertion_acknowledged or not self.user_mounted_source:
144
+ raise ExternalDependencyError(
145
+ "Q-RAG source is NOASSERTION; explicitly acknowledge and user-mount "
146
+ "the pinned source checkout before execution"
147
+ )
148
+ if not self.checkpoint_cc_by_4_0_acknowledged or not self.user_mounted_checkpoint:
149
+ raise ExternalDependencyError(
150
+ "Q-RAG checkpoint is a separate CC-BY-4.0 asset; explicitly acknowledge "
151
+ "and user-mount the pinned checkpoint before execution"
152
+ )
153
+
154
+ def as_mapping(self) -> Mapping[str, bool]:
155
+ return freeze_mapping(asdict(self))
156
+
157
+
158
+ @dataclass(frozen=True, slots=True)
159
+ class QRAGArtifactIdentity:
160
+ """Treatment-defining identity for one frozen Q-RAG evaluation cell."""
161
+
162
+ checkpoint_manifest_sha256: str
163
+ checkpoint_file_sha256: str
164
+ embedder_manifest_sha256: str
165
+ source_manifest_sha256: str
166
+ compatibility_manifest_sha256: str
167
+ retriever_revision: str
168
+ retriever_deployment_fingerprint_sha256: str
169
+ corpus_sha256: str
170
+ index_sha256: str
171
+ reader_repository: str
172
+ reader_revision: str
173
+ reader_deployment_fingerprint_sha256: str
174
+ reader_profile: str = _NATIVE_READER_PROFILE
175
+ checkpoint_repository: str = QRAG_CHECKPOINT_REPOSITORY
176
+ checkpoint_revision: str = QRAG_CHECKPOINT_REVISION
177
+ embedder_repository: str = QRAG_EMBEDDER_REPOSITORY
178
+ embedder_revision: str = QRAG_EMBEDDER_REVISION
179
+ environment_config_sha256: str = QRAG_ENVIRONMENT_CONFIG_SHA256
180
+ action_schema_sha256: str = QRAG_ACTION_SCHEMA_SHA256
181
+ candidate_builder_sha256: str = QRAG_CANDIDATE_BUILDER_SHA256
182
+ reader_prompt_sha256: str = QRAG_READER_PROMPT_SHA256
183
+ checkpoint_config_sha256: str = QRAG_CHECKPOINT_CONFIG_SHA256
184
+ profile_id: str = QRAG_PROFILE_ID
185
+
186
+ def __post_init__(self) -> None:
187
+ fixed = {
188
+ "checkpoint_repository": QRAG_CHECKPOINT_REPOSITORY,
189
+ "checkpoint_revision": QRAG_CHECKPOINT_REVISION,
190
+ "checkpoint_file_sha256": QRAG_CHECKPOINT_FILE_SHA256,
191
+ "checkpoint_config_sha256": QRAG_CHECKPOINT_CONFIG_SHA256,
192
+ "embedder_repository": QRAG_EMBEDDER_REPOSITORY,
193
+ "embedder_revision": QRAG_EMBEDDER_REVISION,
194
+ "source_manifest_sha256": QRAG_SOURCE_MANIFEST_SHA256,
195
+ "environment_config_sha256": QRAG_ENVIRONMENT_CONFIG_SHA256,
196
+ "action_schema_sha256": QRAG_ACTION_SCHEMA_SHA256,
197
+ "candidate_builder_sha256": QRAG_CANDIDATE_BUILDER_SHA256,
198
+ "profile_id": QRAG_PROFILE_ID,
199
+ }
200
+ for name, expected in fixed.items():
201
+ if getattr(self, name) != expected:
202
+ raise ValidationError(f"Q-RAG {name} is fixed to {expected}")
203
+ for name in (
204
+ "checkpoint_manifest_sha256",
205
+ "embedder_manifest_sha256",
206
+ "compatibility_manifest_sha256",
207
+ "retriever_deployment_fingerprint_sha256",
208
+ "corpus_sha256",
209
+ "index_sha256",
210
+ "reader_deployment_fingerprint_sha256",
211
+ ):
212
+ value = getattr(self, name)
213
+ if not isinstance(value, str) or not _HEX64.fullmatch(value):
214
+ raise ValidationError(f"Q-RAG {name} must be a lowercase SHA-256 digest")
215
+ for name in (
216
+ "retriever_revision",
217
+ "reader_repository",
218
+ "reader_revision",
219
+ "reader_profile",
220
+ ):
221
+ value = getattr(self, name)
222
+ if not isinstance(value, str) or not value.strip():
223
+ raise ValidationError(f"Q-RAG {name} must not be empty")
224
+ if self.reader_profile not in {
225
+ _NATIVE_READER_PROFILE, _TRANSFER_READER_PROFILE, QRAG_INSTRUCTION_READER_PROFILE,
226
+ }:
227
+ raise ValidationError("Q-RAG reader_profile is unsupported")
228
+ expected_prompt = (
229
+ QRAG_INSTRUCTION_PROMPT_SHA256
230
+ if self.reader_profile == QRAG_INSTRUCTION_READER_PROFILE
231
+ else QRAG_READER_PROMPT_SHA256
232
+ )
233
+ if self.reader_prompt_sha256 != expected_prompt:
234
+ raise ValidationError("Q-RAG reader prompt does not match the explicit reader profile")
235
+
236
+ def as_mapping(self) -> Mapping[str, Any]:
237
+ return freeze_mapping(asdict(self))
238
+
239
+ @property
240
+ def identity_sha256(self) -> str:
241
+ return content_hash(self.as_mapping())
242
+
243
+
244
+ @dataclass(frozen=True, slots=True)
245
+ class QRAGControls:
246
+ """Fixed two-action selector; configurable reader output ceiling.
247
+
248
+ 4000 preserves the upstream reader default. The effective request ceiling
249
+ is also bounded by the run's remaining output tokens, not a requirement
250
+ to generate or reserve all 4000 tokens.
251
+ """
252
+
253
+ max_select_actions: int = 2
254
+ max_output_tokens: int = 4000
255
+ max_candidates: int = 128
256
+ max_candidate_chars: int = 2_000_000
257
+
258
+ def __post_init__(self) -> None:
259
+ if self.max_select_actions != 2:
260
+ raise ValidationError("Q-RAG HotpotQA frozen profile requires max_select_actions=2")
261
+ if any(
262
+ isinstance(value, bool) or not isinstance(value, int) or value < 1
263
+ for value in (self.max_output_tokens, self.max_candidates, self.max_candidate_chars)
264
+ ):
265
+ raise ValidationError("Q-RAG output and candidate limits must be positive integers")
266
+
267
+
268
+ @dataclass(frozen=True, slots=True)
269
+ class QRAGStep:
270
+ index: int
271
+ available_indices: tuple[int, ...]
272
+ q_values: tuple[float, ...]
273
+ action_index: int
274
+ selected_q_value: float
275
+ selected_indices: tuple[int, ...]
276
+ selected_document_ids: tuple[str, ...]
277
+
278
+ @classmethod
279
+ def from_mapping(cls, value: Mapping[str, object]) -> QRAGStep:
280
+ available = _integer_tuple(
281
+ value.get("available_indices"), label="Q-RAG available_indices", unique=True
282
+ )
283
+ q_raw = value.get("q_values")
284
+ if isinstance(q_raw, (str, bytes)) or not isinstance(q_raw, Sequence):
285
+ raise AlgorithmOutputError("Q-RAG q_values must be a sequence")
286
+ q_values = tuple(finite_number(item, label="Q-RAG q_value") for item in q_raw)
287
+ if len(q_values) != len(available):
288
+ raise AlgorithmOutputError("Q-RAG q_values must align with available_indices")
289
+ selected_ids_raw = value.get("selected_document_ids")
290
+ if isinstance(selected_ids_raw, (str, bytes)) or not isinstance(selected_ids_raw, Sequence):
291
+ raise AlgorithmOutputError("Q-RAG selected_document_ids must be a sequence")
292
+ selected_ids = tuple(selected_ids_raw)
293
+ if not all(isinstance(item, str) and item for item in selected_ids):
294
+ raise AlgorithmOutputError("Q-RAG selected_document_ids must contain non-empty strings")
295
+ return cls(
296
+ index=nonnegative_integer(value.get("index"), label="Q-RAG step index"),
297
+ available_indices=available,
298
+ q_values=q_values,
299
+ action_index=nonnegative_integer(value.get("action_index"), label="Q-RAG action_index"),
300
+ selected_q_value=finite_number(
301
+ value.get("selected_q_value"), label="Q-RAG selected_q_value"
302
+ ),
303
+ selected_indices=_integer_tuple(
304
+ value.get("selected_indices"),
305
+ label="Q-RAG selected_indices",
306
+ unique=True,
307
+ ),
308
+ selected_document_ids=selected_ids,
309
+ )
310
+
311
+
312
+ @dataclass(slots=True)
313
+ class _QRAGWorker:
314
+ artifacts: QRAGArtifactIdentity
315
+ acknowledgements: QRAGLicenseAcknowledgement = QRAGLicenseAcknowledgement()
316
+ client: WorkerClient | None = None
317
+ controls: QRAGControls = QRAGControls()
318
+ release_id: str = "acquire.qrag.released_checkpoint_native"
319
+ profile_kind: str = "controlled_adapter"
320
+ method_id: str = "qrag"
321
+ family: SemanticFamily = SemanticFamily.ACQUIRE
322
+
323
+ def __post_init__(self) -> None:
324
+ if not isinstance(self.artifacts, QRAGArtifactIdentity):
325
+ raise ValidationError("Q-RAG requires QRAGArtifactIdentity")
326
+ if not isinstance(self.acknowledgements, QRAGLicenseAcknowledgement):
327
+ raise ValidationError("Q-RAG requires QRAGLicenseAcknowledgement")
328
+ if not isinstance(self.controls, QRAGControls):
329
+ raise ValidationError("Q-RAG controls must be QRAGControls")
330
+
331
+ def run(self, state: FrozenAgentState, context: InterventionContext) -> CompositeResult:
332
+ self.acknowledgements.require_complete()
333
+ self._validate_reader_profile()
334
+ if not state.query.strip():
335
+ raise ValidationError("Q-RAG requires a non-empty question")
336
+ instruction_adapter = self.artifacts.reader_profile == QRAG_INSTRUCTION_READER_PROFILE
337
+ if state.messages or (state.instruction.strip() and not instruction_adapter):
338
+ raise ValidationError(
339
+ "the frozen Q-RAG profile accepts one question; instruction/messages "
340
+ "require a separate factorial profile"
341
+ )
342
+ if instruction_adapter and state.tool_names:
343
+ raise ValidationError("Q-RAG instruction reader does not execute tools")
344
+ if len(state.context) > self.controls.max_candidates:
345
+ raise ValidationError("Q-RAG candidate count exceeds max_candidates")
346
+ if sum(len(block.text) for block in state.context) > self.controls.max_candidate_chars:
347
+ raise ValidationError("Q-RAG candidate text exceeds max_candidate_chars")
348
+ candidate_ids = tuple(block.block_id for block in state.context)
349
+ if any(not value for value in candidate_ids) or len(candidate_ids) != len(
350
+ set(candidate_ids)
351
+ ):
352
+ raise ValidationError("Q-RAG candidates require unique non-empty IDs")
353
+
354
+ candidates = tuple(
355
+ {"document_id": block.block_id, "text": block.text} for block in state.context
356
+ )
357
+ candidate_pool_sha256 = content_hash(candidates)
358
+ candidate_order_sha256 = content_hash(candidate_ids)
359
+ remaining_budget = _remaining_budget(state, context)
360
+ if remaining_budget["model_calls"] < 1:
361
+ raise BudgetExceededError("Q-RAG reader requires one remaining model call")
362
+ if remaining_budget["output_tokens"] < 1:
363
+ raise BudgetExceededError("Q-RAG reader has no remaining output tokens")
364
+ reader_budget = {
365
+ "configured_max_output_tokens": self.controls.max_output_tokens,
366
+ "effective_max_output_tokens": min(
367
+ self.controls.max_output_tokens, remaining_budget["output_tokens"]
368
+ ),
369
+ "remaining_output_tokens": remaining_budget["output_tokens"],
370
+ "preset": (
371
+ "upstream_default" if self.controls.max_output_tokens == 4000 else "custom"
372
+ ),
373
+ }
374
+ if state.budget.max_cost_usd is not None:
375
+ raise BudgetExceededError(
376
+ "Q-RAG external reader is unpriced; a cost budget cannot be guaranteed"
377
+ )
378
+
379
+ worker = resolve_worker(self.client, context, label="Q-RAG")
380
+ worker_identity = worker_fingerprint(worker, label="Q-RAG")
381
+ artifact_mapping = self.artifacts.as_mapping()
382
+ reader_task = {
383
+ "instruction": state.instruction,
384
+ "candidate_annotations": tuple(
385
+ {"document_id": block.block_id, "source": block.source, "metadata": block.metadata}
386
+ for block in state.context
387
+ ),
388
+ } if instruction_adapter else None
389
+ reader_task_fields = (
390
+ {"reader_task": reader_task, "reader_task_sha256": content_hash(reader_task)}
391
+ if instruction_adapter else {}
392
+ )
393
+ request = MethodWorkerRequest(
394
+ method_id=self.method_id,
395
+ release_id=self.release_id,
396
+ upstream_commit=QRAG_UPSTREAM_COMMIT,
397
+ state_hash=state.state_hash,
398
+ payload={
399
+ **reader_task_fields,
400
+ "profile_id": self.artifacts.profile_id,
401
+ "task_id": state.task_id,
402
+ "question": state.query,
403
+ "candidates": candidates,
404
+ "candidate_pool_sha256": candidate_pool_sha256,
405
+ "candidate_order_sha256": candidate_order_sha256,
406
+ "artifacts": artifact_mapping,
407
+ "artifact_identity_sha256": self.artifacts.identity_sha256,
408
+ "acknowledgements": self.acknowledgements.as_mapping(),
409
+ "controls": asdict(self.controls),
410
+ "remaining_budget": remaining_budget,
411
+ "reader_budget": reader_budget,
412
+ "seed": context.seed,
413
+ "inference_contract": {
414
+ "mode": "frozen_checkpoint_inference",
415
+ "allow_training": False,
416
+ "allow_gold_answer": False,
417
+ "allow_supporting_fact_labels": False,
418
+ "allow_reward": False,
419
+ "allow_ground_truth_feedback": False,
420
+ "allow_stop_action": False,
421
+ },
422
+ },
423
+ dependency_fingerprints={
424
+ "worker": worker_identity,
425
+ "artifact_identity_sha256": self.artifacts.identity_sha256,
426
+ "candidate_pool_sha256": candidate_pool_sha256,
427
+ "candidate_order_sha256": candidate_order_sha256,
428
+ },
429
+ minimum_reservation={"model_calls": 1},
430
+ protocol_version=QRAG_INSTRUCTION_PROTOCOL if instruction_adapter else QRAG_PROTOCOL,
431
+ )
432
+ response = call_worker(worker, request)
433
+ payload = response.payload
434
+ if instruction_adapter and payload.get("reader_task_sha256") != content_hash(reader_task):
435
+ raise AlgorithmOutputError("Q-RAG worker task instruction binding mismatch")
436
+
437
+ echoed_artifacts = payload.get("artifacts")
438
+ if not isinstance(echoed_artifacts, Mapping) or content_hash(
439
+ echoed_artifacts
440
+ ) != content_hash(artifact_mapping):
441
+ raise AlgorithmOutputError("Q-RAG artifact identity mismatch")
442
+ for key, expected in (
443
+ ("profile_id", self.artifacts.profile_id),
444
+ ("artifact_identity_sha256", self.artifacts.identity_sha256),
445
+ ("candidate_pool_sha256", candidate_pool_sha256),
446
+ ("candidate_order_sha256", candidate_order_sha256),
447
+ ):
448
+ if required_text(payload, key, label="Q-RAG response") != expected:
449
+ raise AlgorithmOutputError(f"Q-RAG {key} mismatch")
450
+
451
+ attestation = _validate_runtime_attestation(payload, artifacts=self.artifacts)
452
+ if payload.get("reader_budget") != reader_budget:
453
+ raise AlgorithmOutputError("Q-RAG worker reader budget mismatch")
454
+ steps = tuple(
455
+ QRAGStep.from_mapping(row)
456
+ for row in mapping_sequence(payload.get("trajectory"), label="Q-RAG trajectory")
457
+ )
458
+ selected_indices = _validate_trajectory(
459
+ steps,
460
+ candidate_ids=candidate_ids,
461
+ max_select_actions=self.controls.max_select_actions,
462
+ )
463
+ final_selected = _integer_tuple(
464
+ payload.get("selected_indices"),
465
+ label="Q-RAG final selected_indices",
466
+ unique=True,
467
+ )
468
+ if final_selected != selected_indices:
469
+ raise AlgorithmOutputError("Q-RAG final selected indices disagree with trajectory")
470
+ final_document_ids = _string_tuple(
471
+ payload.get("selected_document_ids"),
472
+ label="Q-RAG final selected_document_ids",
473
+ )
474
+ expected_document_ids = tuple(candidate_ids[index] for index in selected_indices)
475
+ if final_document_ids != expected_document_ids:
476
+ raise AlgorithmOutputError("Q-RAG final selected document IDs disagree with trajectory")
477
+
478
+ termination = required_text(payload, "termination", label="Q-RAG response")
479
+ expected_termination = _expected_termination(
480
+ candidate_count=len(candidate_ids),
481
+ selected_count=len(selected_indices),
482
+ max_select_actions=self.controls.max_select_actions,
483
+ )
484
+ if termination != expected_termination:
485
+ raise AlgorithmOutputError("Q-RAG termination disagrees with fixed environment horizon")
486
+ answer = required_text(payload, "final_answer", label="Q-RAG response")
487
+ trajectory_sha256 = required_text(payload, "trajectory_sha256", label="Q-RAG response")
488
+ if not _HEX64.fullmatch(trajectory_sha256) or trajectory_sha256 != content_hash(
489
+ payload.get("trajectory")
490
+ ):
491
+ raise AlgorithmOutputError("Q-RAG trajectory_sha256 mismatch")
492
+ if response.usage.model_calls != 1:
493
+ raise AlgorithmOutputError("Q-RAG frozen reader must report exactly one model call")
494
+ if response.usage.retrieval_calls != 0 or response.usage.tool_calls != 0:
495
+ raise AlgorithmOutputError(
496
+ "Q-RAG receives a frozen candidate pool and cannot report retrieval/tool calls"
497
+ )
498
+ _validate_usage_against_sent_budget(response.usage, remaining_budget)
499
+ if response.usage.output_tokens > reader_budget["effective_max_output_tokens"]:
500
+ raise AlgorithmOutputError("Q-RAG worker exceeded effective reader output limit")
501
+
502
+ selected_blocks = tuple(state.context[index] for index in selected_indices)
503
+ trace_events: list[TraceEvent] = [
504
+ TraceEvent(
505
+ TracePhase.PREPARE,
506
+ "frozen_candidate_pool",
507
+ {
508
+ "profile_id": self.artifacts.profile_id,
509
+ "artifact_identity_sha256": self.artifacts.identity_sha256,
510
+ "candidate_pool_sha256": candidate_pool_sha256,
511
+ "candidate_order_sha256": candidate_order_sha256,
512
+ "checkpoint_revision": self.artifacts.checkpoint_revision,
513
+ "embedder_revision": self.artifacts.embedder_revision,
514
+ "retriever_revision": self.artifacts.retriever_revision,
515
+ "reader_revision": self.artifacts.reader_revision,
516
+ "selection_budget": self.controls.max_select_actions,
517
+ "reader_budget": reader_budget,
518
+ "paper_native_parity_claimed": False,
519
+ },
520
+ )
521
+ ]
522
+ trace_events.extend(
523
+ TraceEvent(
524
+ TracePhase.OBSERVE,
525
+ "candidate_index_policy_step",
526
+ {
527
+ "index": step.index,
528
+ "available_indices": step.available_indices,
529
+ "q_values": step.q_values,
530
+ "action_index": step.action_index,
531
+ "selected_q_value": step.selected_q_value,
532
+ "selected_indices": step.selected_indices,
533
+ "selected_document_ids": step.selected_document_ids,
534
+ },
535
+ )
536
+ for step in steps
537
+ )
538
+ trace_events.append(
539
+ TraceEvent(
540
+ TracePhase.FINALIZE,
541
+ "selected_context_and_reader_answer",
542
+ {
543
+ "selected_indices": selected_indices,
544
+ "selected_document_ids": expected_document_ids,
545
+ "termination": termination,
546
+ "trajectory_sha256": trajectory_sha256,
547
+ "answer_is_intervention_input": False,
548
+ },
549
+ )
550
+ )
551
+ trace = ExecutionTrace(
552
+ method_id=self.method_id,
553
+ release_id=self.release_id,
554
+ events=tuple(trace_events),
555
+ counters={
556
+ **external_usage_counters(response.usage),
557
+ "worker_calls": 1,
558
+ "policy_steps": len(steps),
559
+ "selected_documents": len(selected_blocks),
560
+ },
561
+ )
562
+ return CompositeResult(
563
+ method_id=self.method_id,
564
+ release_id=self.release_id,
565
+ source_state_hash=state.state_hash,
566
+ final_answer=answer,
567
+ evidence=selected_blocks,
568
+ trace=trace,
569
+ implementation_identity=(f"thin_external_wrapper:griver/Q-RAG@{QRAG_UPSTREAM_COMMIT}"),
570
+ profile_kind=self.profile_kind,
571
+ metadata={
572
+ "implementation_origin": "thin_external_wrapper",
573
+ "profile_id": self.artifacts.profile_id,
574
+ "artifact_identity_sha256": self.artifacts.identity_sha256,
575
+ "source_license_id": "NOASSERTION",
576
+ "checkpoint_license_id": "CC-BY-4.0",
577
+ "source_license_acknowledged": True,
578
+ "checkpoint_license_acknowledged": True,
579
+ "checkpoint_repository": self.artifacts.checkpoint_repository,
580
+ "checkpoint_revision": self.artifacts.checkpoint_revision,
581
+ "embedder_repository": self.artifacts.embedder_repository,
582
+ "embedder_revision": self.artifacts.embedder_revision,
583
+ "retriever_revision": self.artifacts.retriever_revision,
584
+ "reader_repository": self.artifacts.reader_repository,
585
+ "reader_revision": self.artifacts.reader_revision,
586
+ "reader_profile": self.artifacts.reader_profile,
587
+ "input_adapter": "instruction_preserving_v1" if instruction_adapter else "question_only",
588
+ "reader_prompt_sha256": self.artifacts.reader_prompt_sha256,
589
+ "reader_task_sha256": content_hash(reader_task) if instruction_adapter else None,
590
+ "task_instruction_preserved": instruction_adapter,
591
+ "reader_budget": reader_budget,
592
+ "candidate_pool_sha256": candidate_pool_sha256,
593
+ "candidate_order_sha256": candidate_order_sha256,
594
+ "selected_indices": selected_indices,
595
+ "selected_document_ids": expected_document_ids,
596
+ "termination": termination,
597
+ "trajectory_sha256": trajectory_sha256,
598
+ "runtime_attestation": attestation,
599
+ "worker_fingerprint": worker_identity,
600
+ "treatment_scope": "native_checkpoint_embedder_and_value_policy",
601
+ "reader_is_controlled_factor": True,
602
+ "paper_native_parity_claimed": False,
603
+ "gold_answer_used": False,
604
+ "supporting_fact_labels_used": False,
605
+ "reward_used": False,
606
+ "training_called": False,
607
+ },
608
+ )
609
+
610
+ def _validate_reader_profile(self) -> None:
611
+ expected = (
612
+ _TRANSFER_READER_PROFILE
613
+ if self.profile_kind == "factorial_adapter"
614
+ else _NATIVE_READER_PROFILE
615
+ )
616
+ allowed = {expected}
617
+ if self.profile_kind == "factorial_adapter":
618
+ allowed.add(QRAG_INSTRUCTION_READER_PROFILE)
619
+ if self.artifacts.reader_profile not in allowed:
620
+ raise ValidationError(f"Q-RAG {self.release_id} requires reader_profile={expected}")
621
+
622
+
623
+ class QRAGNativeWorker(_QRAGWorker):
624
+ """Native released checkpoint/retriever treatment with a controlled reader.
625
+
626
+ The historical class name is retained for registry compatibility. The
627
+ result is deliberately labelled ``controlled_adapter`` and never claims
628
+ end-to-end paper parity because upstream does not pin the reader artifact
629
+ and the benchmark-safe environment removes ground-truth feedback.
630
+ """
631
+
632
+
633
+ class QRAGReaderTransferWorker(_QRAGWorker):
634
+ def __init__(
635
+ self,
636
+ artifacts: QRAGArtifactIdentity,
637
+ acknowledgements: QRAGLicenseAcknowledgement | None = None,
638
+ client: WorkerClient | None = None,
639
+ *,
640
+ controls: QRAGControls | None = None,
641
+ ) -> None:
642
+ super().__init__(
643
+ artifacts=artifacts,
644
+ acknowledgements=(
645
+ acknowledgements if acknowledgements is not None else QRAGLicenseAcknowledgement()
646
+ ),
647
+ client=client,
648
+ controls=controls if controls is not None else QRAGControls(),
649
+ release_id="acquire.qrag.reader_transfer_factorial",
650
+ profile_kind="factorial_adapter",
651
+ )
652
+
653
+
654
+ def _validate_runtime_attestation(
655
+ payload: Mapping[str, Any], *, artifacts: QRAGArtifactIdentity
656
+ ) -> Mapping[str, Any]:
657
+ value = payload.get("runtime_attestation")
658
+ if not isinstance(value, Mapping):
659
+ raise AlgorithmOutputError("Q-RAG requires runtime_attestation")
660
+ expected: Mapping[str, Any] = {
661
+ "source_commit": QRAG_UPSTREAM_COMMIT,
662
+ "source_manifest_sha256": artifacts.source_manifest_sha256,
663
+ "compatibility_manifest_sha256": artifacts.compatibility_manifest_sha256,
664
+ "checkpoint_repository": artifacts.checkpoint_repository,
665
+ "checkpoint_revision": artifacts.checkpoint_revision,
666
+ "checkpoint_manifest_sha256": artifacts.checkpoint_manifest_sha256,
667
+ "checkpoint_file_sha256": artifacts.checkpoint_file_sha256,
668
+ "embedder_repository": artifacts.embedder_repository,
669
+ "embedder_revision": artifacts.embedder_revision,
670
+ "official_candidate_builder_called": True,
671
+ "official_pqn_select_action_called": True,
672
+ "official_qa_env_step_called": True,
673
+ "dummy_feedback_used": True,
674
+ "ground_truth_feedback_used": False,
675
+ "gold_answer_used": False,
676
+ "supporting_fact_labels_used": False,
677
+ "reward_used": False,
678
+ "training_called": False,
679
+ "stop_action_used": False,
680
+ "strict_state_dict_load": True,
681
+ "safe_weights_only_load": True,
682
+ "checkpoint_eval_mode": True,
683
+ "source_user_mounted": True,
684
+ "checkpoint_user_mounted": True,
685
+ "checkpoint_deserialization_isolated": True,
686
+ "host_secret_mounts": False,
687
+ "reader_profile": artifacts.reader_profile,
688
+ }
689
+ for key, expected_value in expected.items():
690
+ if value.get(key) != expected_value:
691
+ raise AlgorithmOutputError(f"Q-RAG runtime attestation {key} mismatch")
692
+ if value.get("source_attestation") not in {"git_checkout", "verified_archive_snapshot"}:
693
+ raise AlgorithmOutputError("Q-RAG source attestation is unsupported")
694
+ return freeze_mapping(value)
695
+
696
+
697
+ def _validate_trajectory(
698
+ steps: tuple[QRAGStep, ...],
699
+ *,
700
+ candidate_ids: tuple[str, ...],
701
+ max_select_actions: int,
702
+ ) -> tuple[int, ...]:
703
+ if tuple(step.index for step in steps) != tuple(range(len(steps))):
704
+ raise AlgorithmOutputError("Q-RAG step indices must be contiguous")
705
+ expected_steps = min(len(candidate_ids), max_select_actions)
706
+ if len(steps) != expected_steps:
707
+ raise AlgorithmOutputError("Q-RAG trajectory length disagrees with fixed horizon")
708
+ selected: list[int] = []
709
+ for step in steps:
710
+ expected_available = tuple(
711
+ index for index in range(len(candidate_ids)) if index not in selected
712
+ )
713
+ if step.available_indices != expected_available:
714
+ raise AlgorithmOutputError("Q-RAG available-index trajectory is inconsistent")
715
+ if step.action_index not in expected_available:
716
+ raise AlgorithmOutputError("Q-RAG action is unavailable or out of range")
717
+ q_position = expected_available.index(step.action_index)
718
+ if not math.isclose(
719
+ step.selected_q_value,
720
+ step.q_values[q_position],
721
+ rel_tol=1e-12,
722
+ abs_tol=1e-12,
723
+ ):
724
+ raise AlgorithmOutputError("Q-RAG selected_q_value disagrees with q_values")
725
+ if step.q_values and step.selected_q_value < max(step.q_values):
726
+ raise AlgorithmOutputError("Q-RAG action is not an argmax available Q-value")
727
+ selected.append(step.action_index)
728
+ if step.selected_indices != tuple(selected):
729
+ raise AlgorithmOutputError("Q-RAG selected-index history is inconsistent")
730
+ expected_ids = tuple(candidate_ids[index] for index in selected)
731
+ if step.selected_document_ids != expected_ids:
732
+ raise AlgorithmOutputError("Q-RAG selected-document history is inconsistent")
733
+ return tuple(selected)
734
+
735
+
736
+ def _expected_termination(
737
+ *, candidate_count: int, selected_count: int, max_select_actions: int
738
+ ) -> str:
739
+ if candidate_count == 0:
740
+ return "empty_candidates"
741
+ if selected_count == candidate_count:
742
+ return "candidate_exhausted"
743
+ if selected_count == max_select_actions:
744
+ return "fixed_step_budget"
745
+ raise AlgorithmOutputError("Q-RAG trajectory has no valid fixed-horizon termination")
746
+
747
+
748
+ def _integer_tuple(value: Any, *, label: str, unique: bool) -> tuple[int, ...]:
749
+ if isinstance(value, (str, bytes)) or not isinstance(value, Sequence):
750
+ raise AlgorithmOutputError(f"{label} must be a sequence")
751
+ result = tuple(nonnegative_integer(item, label=label) for item in value)
752
+ if unique and len(result) != len(set(result)):
753
+ raise AlgorithmOutputError(f"{label} contains duplicates")
754
+ return result
755
+
756
+
757
+ def _string_tuple(value: Any, *, label: str) -> tuple[str, ...]:
758
+ if isinstance(value, (str, bytes)) or not isinstance(value, Sequence):
759
+ raise AlgorithmOutputError(f"{label} must be a sequence")
760
+ result = tuple(value)
761
+ if not all(isinstance(item, str) and item for item in result):
762
+ raise AlgorithmOutputError(f"{label} must contain non-empty strings")
763
+ if len(result) != len(set(result)):
764
+ raise AlgorithmOutputError(f"{label} contains duplicates")
765
+ return result
766
+
767
+
768
+ def _remaining_budget(
769
+ state: FrozenAgentState, context: InterventionContext
770
+ ) -> Mapping[str, int | None]:
771
+ usage = None
772
+ ledger = context.budget_ledger
773
+ if ledger is not None:
774
+ ledger_budget = getattr(ledger, "budget", None)
775
+ usage = getattr(ledger, "usage", None)
776
+ if ledger_budget != state.budget or usage is None:
777
+ raise ValidationError("Q-RAG received an incompatible budget ledger")
778
+
779
+ def consumed(name: str) -> int:
780
+ value = 0 if usage is None else getattr(usage, name, None)
781
+ if isinstance(value, bool) or not isinstance(value, int) or value < 0:
782
+ raise ValidationError(f"Q-RAG budget usage {name} is invalid")
783
+ return value
784
+
785
+ remaining_context = None
786
+ if state.budget.max_context_tokens is not None:
787
+ remaining_context = max(0, state.budget.max_context_tokens - consumed("input_tokens"))
788
+ return freeze_mapping(
789
+ {
790
+ "model_calls": max(0, state.budget.max_model_calls - consumed("model_calls")),
791
+ "output_tokens": max(0, state.budget.max_output_tokens - consumed("output_tokens")),
792
+ "context_tokens": remaining_context,
793
+ }
794
+ )
795
+
796
+
797
+ def _validate_usage_against_sent_budget(usage: Any, budget: Mapping[str, int | None]) -> None:
798
+ if usage.model_calls > budget["model_calls"]:
799
+ raise AlgorithmOutputError("Q-RAG worker exceeded sent model_calls budget")
800
+ if usage.output_tokens > budget["output_tokens"]:
801
+ raise AlgorithmOutputError("Q-RAG worker exceeded sent output_tokens budget")
802
+ context_cap = budget["context_tokens"]
803
+ if context_cap is not None and usage.input_tokens > context_cap:
804
+ raise AlgorithmOutputError("Q-RAG worker exceeded sent context_tokens budget")
805
+
806
+
807
+ __all__ = [
808
+ "QRAG_ACTION_SCHEMA_SHA256",
809
+ "QRAG_CANDIDATE_BUILDER_SHA256",
810
+ "QRAG_CHECKPOINT_CONFIG_SHA256",
811
+ "QRAG_CHECKPOINT_FILE_SHA256",
812
+ "QRAG_CHECKPOINT_REPOSITORY",
813
+ "QRAG_CHECKPOINT_REVISION",
814
+ "QRAG_EMBEDDER_MODEL_SHA256",
815
+ "QRAG_EMBEDDER_REPOSITORY",
816
+ "QRAG_EMBEDDER_REVISION",
817
+ "QRAG_ENVIRONMENT_CONFIG_SHA256",
818
+ "QRAG_PROFILE_ID",
819
+ "QRAG_PROTOCOL",
820
+ "QRAG_SOURCE_MANIFEST_SHA256",
821
+ "QRAG_UPSTREAM_COMMIT",
822
+ "QRAGArtifactIdentity",
823
+ "QRAGControls",
824
+ "QRAGLicenseAcknowledgement",
825
+ "QRAGNativeWorker",
826
+ "QRAGReaderTransferWorker",
827
+ "QRAGStep",
828
+ ]