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,822 @@
1
+ """Pinned Adaptive-RAG silver-label reconstruction and native router training.
2
+
3
+ The author script owns tokenization, seq2seq loss, AdamW/Accelerate updates and
4
+ first-decoder-step A/B/C validation. Run each fit in a dedicated process. No
5
+ alternate classifier loss, generated labels, automatic fit retry or test tuning.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import importlib.metadata
11
+ import importlib.util
12
+ import json
13
+ import math
14
+ import os
15
+ import runpy
16
+ import sys
17
+ import time
18
+ from collections import Counter
19
+ from collections.abc import Mapping
20
+ from contextlib import contextmanager, redirect_stderr, redirect_stdout
21
+ from dataclasses import asdict, dataclass
22
+ from functools import wraps
23
+ from pathlib import Path
24
+
25
+ from agentinputlab.artifacts import load_pinned_json_mapping
26
+ from agentinputlab.contracts import ExternalDependencyError, ValidationError
27
+ from agentinputlab.contracts.serialization import content_hash
28
+
29
+ from .recomp_abstractive import validate_recomp_nltk_assets
30
+ from .recomp_extractive import _LOCK, _save, _scope
31
+
32
+ RELEASE = "acquire.adaptive_rag.rebuilt_offline"
33
+ PROTOCOL = "agentinputlab.adaptive-rag.native_router_fit.v1"
34
+ SCRIPT = "classifier/run_classifier.py"
35
+ _DEPENDENCIES = {
36
+ "transformers": "4.28.1",
37
+ "tokenizers": "0.13.3",
38
+ "accelerate": "0.15.0",
39
+ "numpy": "1.26.4",
40
+ "datasets": "2.14.7",
41
+ "pyarrow": "14.0.2",
42
+ "fsspec": "2023.10.0",
43
+ "huggingface-hub": "0.19.4",
44
+ "nltk": "3.9.2",
45
+ "safetensors": "0.5.3",
46
+ "sentencepiece": "0.2.1",
47
+ "jsonlines": "4.0.0",
48
+ }
49
+
50
+
51
+ def _sha(path):
52
+ from workers.adaptive_rag.driver import _file_sha256
53
+
54
+ return _file_sha256(path)
55
+
56
+
57
+ def _regular(path, label):
58
+ supplied = Path(path).expanduser()
59
+ if supplied.is_symlink() or not supplied.is_file():
60
+ raise ValidationError(f"Adaptive-RAG {label} requires a regular non-symlink file")
61
+ return supplied.resolve()
62
+
63
+
64
+ def _new_output_root(output_root, *protected):
65
+ root = Path(output_root).expanduser().absolute()
66
+ if root.exists() or root.is_symlink():
67
+ raise ValidationError("Adaptive-RAG output must be create-only; no automatic retry")
68
+ if any(root.resolve().is_relative_to(Path(p).resolve()) for p in protected):
69
+ raise ValidationError("Adaptive-RAG output must not mutate source or initial assets")
70
+ root.mkdir(parents=True)
71
+ return root
72
+
73
+
74
+ def validate_adaptive_training_checkout(checkout):
75
+ from workers.adaptive_rag.driver import (
76
+ DEFAULT_MANIFEST,
77
+ CompatibilityPolicy,
78
+ _git,
79
+ _safe_file,
80
+ )
81
+
82
+ root = Path(checkout).expanduser()
83
+ if root.is_symlink() or not root.is_dir():
84
+ raise ValidationError("Adaptive-RAG requires a regular native source checkout")
85
+ root = root.resolve()
86
+ policy = CompatibilityPolicy.from_mapping(json.loads(DEFAULT_MANIFEST.read_text()))
87
+ if (
88
+ _git(root, "rev-parse", "HEAD") != policy.commit
89
+ or _git(root, "rev-parse", "HEAD^{tree}") != policy.tree
90
+ or _git(root, "status", "--porcelain=v1", "--untracked-files=all")
91
+ ):
92
+ raise ExternalDependencyError("Adaptive-RAG training source must be exact and clean")
93
+ sources = {**policy.source_hashes, policy.license_path: policy.license_sha256}
94
+ # Preprocessing is also executed, not just copied as a provenance label.
95
+ relative = "classifier/preprocess/preprocess_utils.py"
96
+ import hashlib
97
+
98
+ raw = _safe_file(root, relative).read_bytes()
99
+ blob = hashlib.sha1(b"blob " + str(len(raw)).encode() + b"\0" + raw).hexdigest()
100
+ if blob != _git(root, "rev-parse", policy.commit + ":" + relative):
101
+ raise ExternalDependencyError("Adaptive-RAG native label source differs")
102
+ sources[relative] = hashlib.sha256(raw).hexdigest()
103
+ for relative, digest in sources.items():
104
+ if _sha(_safe_file(root, relative)) != digest:
105
+ raise ExternalDependencyError("Adaptive-RAG pinned source hash differs")
106
+ return root, dict(commit=policy.commit, tree=policy.tree, source_files=sources)
107
+
108
+
109
+ def rebuild_adaptive_silver(
110
+ *,
111
+ checkout,
112
+ original_file,
113
+ zero_file,
114
+ single_file,
115
+ multi_file,
116
+ dataset_name,
117
+ teacher_revision,
118
+ output_root,
119
+ max_data_bytes=32 * 1024 * 1024,
120
+ source_and_asset_acknowledged=False,
121
+ ):
122
+ """Call native label_complexity on caller-mounted original/prediction files.
123
+
124
+ The mappings must be native correct-prediction ID sets from the declared
125
+ teacher. This function does not run a teacher or assert teacher/reader parity.
126
+ Native C then B then A overwrites yield A > B > C; unanswerable IDs excluded.
127
+ """
128
+ if source_and_asset_acknowledged is not True:
129
+ raise ValidationError("Adaptive-RAG label rebuild requires acknowledgement")
130
+ for value in (dataset_name, teacher_revision):
131
+ if not isinstance(value, str) or not value.strip() or "\x00" in value:
132
+ raise ValidationError("Adaptive-RAG dataset and teacher revision must be explicit")
133
+ if type(max_data_bytes) is not int or max_data_bytes < 1:
134
+ raise ValidationError("Adaptive-RAG data byte cap must be positive")
135
+ source, binding = validate_adaptive_training_checkout(checkout)
136
+ paths = {
137
+ name: _regular(path, name)
138
+ for name, path in (
139
+ ("original", original_file),
140
+ ("zero", zero_file),
141
+ ("single", single_file),
142
+ ("multi", multi_file),
143
+ )
144
+ }
145
+ if any(p.stat().st_size > max_data_bytes for p in paths.values()):
146
+ raise ValidationError("Adaptive-RAG label inputs exceed the declared byte cap")
147
+ before = {name: _sha(path) for name, path in paths.items()}
148
+ root = _new_output_root(output_root, source)
149
+ spec = importlib.util.spec_from_file_location(
150
+ "_agentinputlab_pinned_adaptive_labels",
151
+ source / "classifier/preprocess/preprocess_utils.py",
152
+ )
153
+ module = importlib.util.module_from_spec(spec)
154
+ spec.loader.exec_module(module)
155
+ rows = module.label_complexity(
156
+ *(str(paths[n]) for n in ("original", "zero", "single", "multi")), dataset_name
157
+ )
158
+ if before != {name: _sha(path) for name, path in paths.items()}:
159
+ raise ValidationError("Adaptive-RAG label source inputs changed during reconstruction")
160
+ _save(root / "silver.json", rows)
161
+ _save(
162
+ root / "provenance.json",
163
+ dict(
164
+ source=binding,
165
+ native_function="label_complexity",
166
+ dataset=dataset_name,
167
+ teacher_revision=teacher_revision,
168
+ input_files={name: dict(path=str(p), sha256=before[name]) for name, p in paths.items()},
169
+ silver_sha256=_sha(root / "silver.json"),
170
+ rows=len(rows),
171
+ class_counts=dict(Counter(r["answer"] for r in rows)),
172
+ priority=["A", "B", "C"],
173
+ unanswerable_ids_excluded_by_native_source=True,
174
+ new_teacher_calls=0,
175
+ original_reader_matched_teacher_claimed=False,
176
+ ),
177
+ )
178
+ return root / "silver.json"
179
+
180
+
181
+ @dataclass(frozen=True, slots=True)
182
+ class AdaptiveRAGFitControls:
183
+ epochs: int = 2
184
+ batch_size: int = 8
185
+ eval_batch_size: int = 8
186
+ gradient_accumulation_steps: int = 1
187
+ learning_rate: float = 5e-5
188
+ weight_decay: float = 0.0
189
+ max_seq_length: int = 384
190
+ doc_stride: int = 128
191
+ max_answer_length: int = 30
192
+ max_steps: int | None = None
193
+ max_optimizer_steps: int = 10000
194
+ max_data_bytes: int = 64 * 1024 * 1024
195
+ seed: int = 17
196
+ device: str = "cpu"
197
+
198
+ def __post_init__(self):
199
+ for name in (
200
+ "epochs",
201
+ "batch_size",
202
+ "eval_batch_size",
203
+ "gradient_accumulation_steps",
204
+ "max_seq_length",
205
+ "doc_stride",
206
+ "max_answer_length",
207
+ "max_optimizer_steps",
208
+ "max_data_bytes",
209
+ "seed",
210
+ ):
211
+ value = getattr(self, name)
212
+ if type(value) is not int or value < (0 if name == "seed" else 1):
213
+ raise ValidationError(f"Adaptive-RAG {name} must be an integer in range")
214
+ for name in ("learning_rate", "weight_decay"):
215
+ value = getattr(self, name)
216
+ if (
217
+ type(value) not in (int, float)
218
+ or not math.isfinite(value)
219
+ or value < 0
220
+ or (name == "learning_rate" and value == 0)
221
+ ):
222
+ raise ValidationError(f"Adaptive-RAG {name} is invalid")
223
+ if self.max_steps is not None and (type(self.max_steps) is not int or self.max_steps < 1):
224
+ raise ValidationError("Adaptive-RAG max_steps must be a positive explicit bound")
225
+ if (
226
+ self.doc_stride >= self.max_seq_length
227
+ or self.max_answer_length > 512
228
+ or self.device not in {"cpu", "cuda"}
229
+ ):
230
+ raise ValidationError("Adaptive-RAG sequence, output cap or device is invalid")
231
+
232
+
233
+ def audit_adaptive_training_data(train_file, dev_file, controls):
234
+ paths = {n: _regular(p, n) for n, p in (("train", train_file), ("dev", dev_file))}
235
+ if paths["train"] == paths["dev"]:
236
+ raise ValidationError("Adaptive-RAG train/dev files must differ")
237
+ evidence, questions, ids = {}, {}, {}
238
+ for split, path in paths.items():
239
+ if path.suffix != ".json" or path.stat().st_size > controls.max_data_bytes:
240
+ raise ValidationError("Adaptive-RAG native JSON data exceeds its declared byte cap")
241
+ try:
242
+ rows = json.loads(path.read_text())
243
+ except (ValueError, UnicodeError) as exc:
244
+ raise ValidationError("Adaptive-RAG data must be native JSON record arrays") from exc
245
+ if not isinstance(rows, list) or not rows:
246
+ raise ValidationError("Adaptive-RAG requires nonempty native records")
247
+ for row in rows:
248
+ if (
249
+ not isinstance(row, dict)
250
+ or any(
251
+ not isinstance(row.get(k), str) or not row[k].strip() or "\x00" in row[k]
252
+ for k in ("id", "question", "dataset_name", "answer")
253
+ )
254
+ or row["answer"] not in {"A", "B", "C"}
255
+ ):
256
+ raise ValidationError(
257
+ "Adaptive-RAG native records require id/question/dataset/A-B-C"
258
+ )
259
+ questions[split] = {" ".join(r["question"].casefold().split()) for r in rows}
260
+ ids[split] = {r["id"] for r in rows}
261
+ if len(ids[split]) != len(rows):
262
+ raise ValidationError("Adaptive-RAG native IDs must be unique within each split")
263
+ evidence[split] = dict(
264
+ path=str(path),
265
+ sha256=_sha(path),
266
+ rows=len(rows),
267
+ class_counts=dict(Counter(r["answer"] for r in rows)),
268
+ )
269
+ if questions["train"] & questions["dev"] or ids["train"] & ids["dev"]:
270
+ raise ValidationError("Adaptive-RAG train/dev query or ID overlap is not permitted")
271
+ steps = controls.max_steps or controls.epochs * math.ceil(
272
+ math.ceil(evidence["train"]["rows"] / controls.batch_size)
273
+ / controls.gradient_accumulation_steps
274
+ )
275
+ if steps > controls.max_optimizer_steps:
276
+ raise ValidationError("Adaptive-RAG optimizer plan exceeds its declared step cap")
277
+ return dict(
278
+ files=evidence,
279
+ minimum_planned_optimizer_steps=steps,
280
+ query_and_id_overlap=False,
281
+ overflow_aware_step_cap_checked_before_native_training=True,
282
+ )
283
+
284
+
285
+ def validate_adaptive_router_checkpoint(root, manifest, expected_sha256):
286
+ metadata = load_pinned_json_mapping(manifest, expected_sha256=expected_sha256)
287
+ folder = Path(root).expanduser()
288
+ if folder.is_symlink() or not folder.is_dir():
289
+ raise ValidationError("Adaptive-RAG router checkpoint requires a regular directory")
290
+ folder = folder.resolve()
291
+ files = metadata.get("files")
292
+ if (
293
+ metadata.get("schema") != "agentinputlab.adaptive-rag.router_checkpoint.v1"
294
+ or not isinstance(files, dict)
295
+ or not {"config.json", "model.safetensors", "tokenizer.json"} <= files.keys()
296
+ ):
297
+ raise ValidationError(
298
+ "Adaptive-RAG requires an explicit safe T5/tokenizer checkpoint closure"
299
+ )
300
+ if {p.name for p in folder.iterdir()} != set(files):
301
+ raise ValidationError("Adaptive-RAG checkpoint closure contains missing or extra files")
302
+ for name, expected in files.items():
303
+ if (
304
+ not isinstance(name, str)
305
+ or Path(name).name != name
306
+ or name in {".", ".."}
307
+ or name.endswith((".bin", ".pkl", ".pickle", ".py"))
308
+ ):
309
+ raise ValidationError("Adaptive-RAG checkpoint paths must be flat and safe")
310
+ if _sha(_regular(folder / name, "checkpoint")) != expected:
311
+ raise ValidationError("Adaptive-RAG checkpoint file hash differs")
312
+ config = json.loads((folder / "config.json").read_text())
313
+ tokenizer_config = folder / "tokenizer_config.json"
314
+ custom_tokenizer = tokenizer_config.exists() and json.loads(tokenizer_config.read_text()).get(
315
+ "auto_map"
316
+ )
317
+ if config.get("model_type") != "t5" or config.get("auto_map") or custom_tokenizer:
318
+ raise ValidationError("Adaptive-RAG native initialization requires local standard T5")
319
+ return folder, metadata
320
+
321
+
322
+ def _t5_tied_aliases(tie_word_embeddings):
323
+ aliases = {
324
+ "encoder.embed_tokens.weight": "shared.weight",
325
+ "decoder.embed_tokens.weight": "shared.weight",
326
+ }
327
+ if tie_word_embeddings:
328
+ aliases["lm_head.weight"] = "shared.weight"
329
+ return aliases
330
+
331
+
332
+ def _align_t5_initial_keys(initial, expected_keys, *, tie_word_embeddings):
333
+ """Expand only standard T5 tied aliases omitted by safe serialization."""
334
+ expected = set(expected_keys)
335
+ missing = expected - set(initial)
336
+ allowed = _t5_tied_aliases(tie_word_embeddings)
337
+ if set(initial) - expected or missing - set(allowed) or "shared.weight" not in initial:
338
+ raise ValidationError("Adaptive-RAG trained namespace differs from initialization")
339
+ expanded = dict(initial)
340
+ for alias in missing:
341
+ expanded[alias] = initial[allowed[alias]]
342
+ return expanded, {alias: allowed[alias] for alias in sorted(missing)}
343
+
344
+
345
+ @contextmanager
346
+ def _observe_native(observed, controls):
347
+ import torch
348
+ import transformers
349
+ from accelerate import Accelerator
350
+ from torch.utils.data import DataLoader, RandomSampler
351
+
352
+ prepare, step = Accelerator.prepare, torch.optim.AdamW.step
353
+ generate = transformers.PreTrainedModel.generate
354
+ restores = []
355
+
356
+ def preparing(accelerator, *objects, **kwargs):
357
+ for obj in objects:
358
+ if isinstance(obj, torch.nn.Module):
359
+ if "model" in observed:
360
+ raise ValidationError("Adaptive-RAG native fit prepared more than one model")
361
+ observed["model"] = obj
362
+ forward = obj.forward
363
+
364
+ @wraps(forward)
365
+ def forwarding(*args, _original_forward=forward, **kw):
366
+ result = _original_forward(*args, **kw)
367
+ if result.loss is not None:
368
+ observed["loss_events"].append(
369
+ dict(
370
+ loss=float(result.loss.detach().cpu()),
371
+ gradient_enabled=torch.is_grad_enabled(),
372
+ label_tokens=int((kw["labels"] != -100).sum().item()),
373
+ )
374
+ )
375
+ return result
376
+
377
+ obj.forward = forwarding
378
+ restores.append((obj, forward))
379
+ if isinstance(obj, DataLoader) and isinstance(obj.sampler, RandomSampler):
380
+ updates = math.ceil(len(obj) / controls.gradient_accumulation_steps)
381
+ planned = controls.max_steps or controls.epochs * updates
382
+ if planned > controls.max_optimizer_steps:
383
+ raise ValidationError("Adaptive-RAG overflow-aware optimizer plan exceeds cap")
384
+ observed["planned_optimizer_steps"] = planned
385
+ observed["native_training_batches"] = len(obj)
386
+ return prepare(accelerator, *objects, **kwargs)
387
+
388
+ def stepping(optimizer, *args, **kwargs):
389
+ result = step(optimizer, *args, **kwargs)
390
+ observed["optimizer_steps"] += 1
391
+ return result
392
+
393
+ def generating(model, *args, **kwargs):
394
+ result = generate(model, *args, **kwargs)
395
+ tokens = result.sequences[:, 1:]
396
+ observed["validation_generation_events"].append(
397
+ dict(
398
+ examples=int(tokens.shape[0]),
399
+ generated_sequence_slots=int(tokens.numel()),
400
+ returned_nonpadding_tokens=int((tokens != model.config.pad_token_id).sum().item()),
401
+ max_length=kwargs.get("max_length"),
402
+ )
403
+ )
404
+ return result
405
+
406
+ Accelerator.prepare, torch.optim.AdamW.step = preparing, stepping
407
+ transformers.PreTrainedModel.generate = generating
408
+ try:
409
+ yield
410
+ finally:
411
+ for model, forward in restores:
412
+ model.forward = forward
413
+ Accelerator.prepare, torch.optim.AdamW.step = prepare, step
414
+ transformers.PreTrainedModel.generate = generate
415
+
416
+
417
+ @dataclass(frozen=True, slots=True)
418
+ class AdaptiveRAGTrainedRouterArtifact:
419
+ root: Path
420
+ artifact_id: str
421
+ checkpoint_manifest_sha256: str
422
+
423
+ @property
424
+ def checkpoint(self):
425
+ return self.root / "checkpoint"
426
+
427
+ @classmethod
428
+ def load(cls, root):
429
+ folder = Path(root).expanduser()
430
+ if folder.is_symlink() or not folder.is_dir():
431
+ raise ValidationError("Adaptive-RAG fit artifact directory is invalid")
432
+ folder = folder.resolve()
433
+ metadata = json.loads(_regular(folder / "artifact.json", "artifact").read_text())
434
+ identity = metadata.pop("artifact_id", None)
435
+ if (
436
+ identity != content_hash(metadata)
437
+ or metadata.get("protocol") != PROTOCOL
438
+ or metadata.get("release_id") != RELEASE
439
+ ):
440
+ raise ValidationError("Adaptive-RAG fit artifact identity differs")
441
+ for name in ("fit-plan.json", "fit-terminal.json"):
442
+ if _sha(_regular(folder / name, name)) != metadata.get(name + "_sha256"):
443
+ raise ValidationError("Adaptive-RAG fit plan/terminal hash differs")
444
+ terminal = json.loads((folder / "fit-terminal.json").read_text())
445
+ if (
446
+ terminal.get("status") != "trained_candidate"
447
+ or terminal.get("optimizer_steps", 0) < 1
448
+ or terminal.get("changed_parameter_tensors", 0) < 1
449
+ or not terminal.get("validation_generation_events")
450
+ ):
451
+ raise ValidationError("Adaptive-RAG native fit/validation is incomplete")
452
+ native_files = metadata.get("native_files")
453
+ if (
454
+ not isinstance(native_files, dict)
455
+ or not {
456
+ "pytorch_model.bin",
457
+ "dict_id_pred_results.json",
458
+ "final_eval_results.json",
459
+ "final_eval_results_perClass.json",
460
+ }
461
+ <= native_files.keys()
462
+ ):
463
+ raise ValidationError("Adaptive-RAG native output closure is incomplete")
464
+ if (folder / "native").is_symlink() or any(
465
+ p.is_symlink() for p in (folder / "native").rglob("*")
466
+ ):
467
+ raise ValidationError("Adaptive-RAG native output closure must not contain symlinks")
468
+ actual_files = {
469
+ p.relative_to(folder / "native").as_posix()
470
+ for p in (folder / "native").rglob("*")
471
+ if p.is_file()
472
+ }
473
+ if actual_files != set(native_files):
474
+ raise ValidationError(
475
+ "Adaptive-RAG native output closure contains extra or missing files"
476
+ )
477
+ for relative, expected in native_files.items():
478
+ p = Path(relative)
479
+ if p.is_absolute() or ".." in p.parts or str(p) != relative:
480
+ raise ValidationError("Adaptive-RAG native closure path is invalid")
481
+ if _sha(_regular(folder / "native" / p, "native output")) != expected:
482
+ raise ValidationError("Adaptive-RAG native output closure differs")
483
+ digest = metadata["checkpoint_manifest_sha256"]
484
+ validate_adaptive_router_checkpoint(
485
+ folder / "checkpoint", folder / "checkpoint-manifest.json", digest
486
+ )
487
+ return cls(folder, identity, digest)
488
+
489
+ def router_bindings(self):
490
+ """Bind the new snapshot to the existing controlled router deployment.
491
+
492
+ Generator/retriever/corpus/index identities remain independently required.
493
+ This does not promote controlled retrieval arms to upstream score parity.
494
+ """
495
+ from workers.adaptive_rag.driver import _path_closure_sha256
496
+
497
+ current = self.load(self.root)
498
+ return dict(
499
+ router_revision="native-fit-" + current.artifact_id,
500
+ router_snapshot_sha256=_path_closure_sha256(current.checkpoint),
501
+ router_weights_sha256=_sha(current.checkpoint / "model.safetensors"),
502
+ router_tokenizer_sha256=_sha(current.checkpoint / "tokenizer.json"),
503
+ )
504
+
505
+ def router_configuration(self):
506
+ """Keep native fit/validation input truncation explicit at deployment."""
507
+ current = self.load(self.root)
508
+ plan = json.loads((current.root / "fit-plan.json").read_text())
509
+ return dict(max_input_tokens=plan["controls"]["max_seq_length"])
510
+
511
+
512
+ class AdaptiveRAGOfflineTraining:
513
+ release_id = RELEASE
514
+
515
+ def __init__(self, controls=None):
516
+ self.controls = (
517
+ AdaptiveRAGFitControls(**controls)
518
+ if isinstance(controls, Mapping)
519
+ else controls or AdaptiveRAGFitControls()
520
+ )
521
+ if not isinstance(self.controls, AdaptiveRAGFitControls):
522
+ raise ValidationError("Adaptive-RAG fit requires typed controls")
523
+
524
+ def fit(
525
+ self,
526
+ *,
527
+ checkout,
528
+ initial_checkpoint,
529
+ initial_checkpoint_manifest,
530
+ initial_manifest_sha256,
531
+ train_file,
532
+ dev_file,
533
+ data_provenance,
534
+ data_provenance_sha256,
535
+ nltk_root,
536
+ nltk_manifest,
537
+ nltk_manifest_sha256,
538
+ output_root,
539
+ source_and_asset_acknowledged=False,
540
+ ):
541
+ if source_and_asset_acknowledged is not True:
542
+ raise ValidationError(
543
+ "Adaptive-RAG fit requires explicit source/model/data acknowledgement"
544
+ )
545
+ source, binding = validate_adaptive_training_checkout(checkout)
546
+ initial, _ = validate_adaptive_router_checkpoint(
547
+ initial_checkpoint, initial_checkpoint_manifest, initial_manifest_sha256
548
+ )
549
+ c = self.controls
550
+ audit = audit_adaptive_training_data(train_file, dev_file, c)
551
+ provenance = load_pinned_json_mapping(
552
+ data_provenance, expected_sha256=data_provenance_sha256
553
+ )
554
+ if (
555
+ provenance.get("schema") != "agentinputlab.adaptive-rag.training_data.v1"
556
+ or not isinstance(provenance.get("teacher_revision"), str)
557
+ or not provenance["teacher_revision"].strip()
558
+ or any(
559
+ provenance.get("files", {}).get(split, {}).get("sha256")
560
+ != audit["files"][split]["sha256"]
561
+ for split in ("train", "dev")
562
+ )
563
+ ):
564
+ raise ValidationError(
565
+ "Adaptive-RAG training provenance must bind both native data files and teacher"
566
+ )
567
+ resources = validate_recomp_nltk_assets(nltk_root, nltk_manifest, nltk_manifest_sha256)
568
+ versions = {name: importlib.metadata.version(name) for name in ("torch", *_DEPENDENCIES)}
569
+ if versions["torch"] not in {"1.13.0", "1.13.0+cpu", "1.13.0+cu117"} or any(
570
+ versions[k] != v for k, v in _DEPENDENCIES.items()
571
+ ):
572
+ raise ExternalDependencyError(
573
+ "Adaptive-RAG fit requires documented isolated dependency versions"
574
+ )
575
+ if os.environ.get("WORLD_SIZE", "1") != "1":
576
+ raise ValidationError("Adaptive-RAG bounded fit requires one process")
577
+ import torch
578
+
579
+ if (c.device == "cpu" and torch.cuda.is_available()) or (
580
+ c.device == "cuda" and (not torch.cuda.is_available() or torch.cuda.device_count() != 1)
581
+ ):
582
+ raise ValidationError("Select no visible CUDA devices for CPU or exactly one for CUDA")
583
+ from safetensors.torch import load_file
584
+
585
+ initial_tensors = load_file(str(initial / "model.safetensors"), device="cpu")
586
+ tied_words = json.loads((initial / "config.json").read_text()).get(
587
+ "tie_word_embeddings", True
588
+ )
589
+ for alias, canonical in _t5_tied_aliases(tied_words).items():
590
+ if alias in initial_tensors and (
591
+ canonical not in initial_tensors
592
+ or not torch.equal(initial_tensors[alias], initial_tensors[canonical])
593
+ ):
594
+ raise ValidationError("Adaptive-RAG initial tied T5 weights disagree")
595
+ root = _new_output_root(output_root, source, initial)
596
+ (root / "native").mkdir()
597
+ command = [
598
+ str(source / SCRIPT),
599
+ "--do_train",
600
+ "--do_eval",
601
+ "--model_name_or_path",
602
+ str(initial),
603
+ "--train_file",
604
+ audit["files"]["train"]["path"],
605
+ "--validation_file",
606
+ audit["files"]["dev"]["path"],
607
+ "--question_column",
608
+ "question",
609
+ "--answer_column",
610
+ "answer",
611
+ "--output_dir",
612
+ str(root / "native"),
613
+ "--num_train_epochs",
614
+ str(c.epochs),
615
+ "--per_device_train_batch_size",
616
+ str(c.batch_size),
617
+ "--per_device_eval_batch_size",
618
+ str(c.eval_batch_size),
619
+ "--gradient_accumulation_steps",
620
+ str(c.gradient_accumulation_steps),
621
+ "--learning_rate",
622
+ str(c.learning_rate),
623
+ "--weight_decay",
624
+ str(c.weight_decay),
625
+ "--max_seq_length",
626
+ str(c.max_seq_length),
627
+ "--doc_stride",
628
+ str(c.doc_stride),
629
+ "--max_answer_length",
630
+ str(c.max_answer_length),
631
+ "--val_max_answer_length",
632
+ str(c.max_answer_length),
633
+ "--seed",
634
+ str(c.seed),
635
+ ]
636
+ if c.max_steps is not None:
637
+ command.extend(("--max_train_steps", str(c.max_steps)))
638
+ plan = dict(
639
+ protocol=PROTOCOL,
640
+ release_id=RELEASE,
641
+ controls=asdict(c),
642
+ source=binding,
643
+ split_audit=audit,
644
+ data_provenance=provenance,
645
+ data_provenance_sha256=data_provenance_sha256,
646
+ initial_manifest_sha256=initial_manifest_sha256,
647
+ nltk_manifest_sha256=nltk_manifest_sha256,
648
+ dependency_versions=versions,
649
+ native_argv=command,
650
+ dependency_lock_adaptation_not_original_git_transformers=True,
651
+ original_paper_initialization_or_teacher_parity_claimed=False,
652
+ automatic_retry=False,
653
+ )
654
+ _save(root / "fit-plan.json", plan)
655
+ observed = dict(optimizer_steps=0, loss_events=[], validation_generation_events=[])
656
+ started, cpu = time.monotonic(), time.process_time()
657
+ try:
658
+ with _LOCK, _scope(root, c.seed):
659
+ import nltk
660
+ from safetensors.torch import load_file, save_file
661
+ from transformers import AutoTokenizer
662
+
663
+ paths, modules = sys.path[:], sys.modules.pop("utils", None)
664
+ nltk_paths = nltk.data.path[:]
665
+ environment = {
666
+ k: os.environ.get(k)
667
+ for k in (
668
+ "TRANSFORMERS_CACHE",
669
+ "HF_DATASETS_CACHE",
670
+ "NLTK_DATA",
671
+ "HF_DATASETS_OFFLINE",
672
+ )
673
+ }
674
+ sys.path.insert(0, str(source / "classifier"))
675
+ nltk.data.path.insert(0, str(resources))
676
+ os.environ.update(
677
+ NLTK_DATA=str(resources),
678
+ HF_DATASETS_OFFLINE="1",
679
+ HF_DATASETS_CACHE=str(root / "dataset-cache"),
680
+ )
681
+ sys.argv[:] = command
682
+ try:
683
+ with (
684
+ _observe_native(observed, c),
685
+ (root / "native-training.log").open("x") as log,
686
+ redirect_stdout(log),
687
+ redirect_stderr(log),
688
+ ):
689
+ runpy.run_path(str(source / SCRIPT), run_name="__main__")
690
+ finally:
691
+ sys.path[:] = paths
692
+ sys.modules.pop("utils", None)
693
+ if modules is not None:
694
+ sys.modules["utils"] = modules
695
+ nltk.data.path[:] = nltk_paths
696
+ for name, value in environment.items():
697
+ if value is None:
698
+ os.environ.pop(name, None)
699
+ else:
700
+ os.environ[name] = value
701
+ model = observed.pop("model")
702
+ if (
703
+ observed["optimizer_steps"] != observed.get("planned_optimizer_steps")
704
+ or not observed["loss_events"]
705
+ or not all(math.isfinite(e["loss"]) for e in observed["loss_events"])
706
+ ):
707
+ raise ValidationError("Adaptive-RAG native optimizer steps or losses differ")
708
+ validation = json.loads((root / "native/dict_id_pred_results.json").read_text())
709
+ dev = json.loads(Path(audit["files"]["dev"]["path"]).read_text())
710
+ if set(validation) != {r["id"] for r in dev} or any(
711
+ validation[r["id"]]["answer"] != r["answer"]
712
+ or validation[r["id"]]["prediction"] not in {"A", "B", "C"}
713
+ for r in dev
714
+ ):
715
+ raise ValidationError("Adaptive-RAG native validation records differ")
716
+ accuracy = (
717
+ 100
718
+ * sum(validation[r["id"]]["prediction"] == r["answer"] for r in dev)
719
+ / len(dev)
720
+ )
721
+ native_accuracy = json.loads((root / "native/final_eval_results.json").read_text())[
722
+ "final_acc_score"
723
+ ]
724
+ if not math.isclose(accuracy, native_accuracy, rel_tol=1e-12):
725
+ raise ValidationError("Adaptive-RAG native validation accuracy differs")
726
+ live = model.state_dict()
727
+ before, aliases = _align_t5_initial_keys(
728
+ initial_tensors, live, tie_word_embeddings=tied_words
729
+ )
730
+ for alias, canonical in aliases.items():
731
+ if live[alias].data_ptr() != live[canonical].data_ptr():
732
+ raise ValidationError(
733
+ "Adaptive-RAG safe omitted key is not a native tied weight"
734
+ )
735
+ trained = {n: t.detach().cpu().contiguous().clone() for n, t in live.items()}
736
+ changed = sum(not torch.equal(t, before[n]) for n, t in trained.items())
737
+ if not changed:
738
+ raise ValidationError("Adaptive-RAG native fit changed no model tensors")
739
+ destination = root / "checkpoint"
740
+ destination.mkdir()
741
+ model.config.save_pretrained(destination)
742
+ AutoTokenizer.from_pretrained(
743
+ str(initial), local_files_only=True, trust_remote_code=False
744
+ ).save_pretrained(destination)
745
+ save_file(
746
+ trained, str(destination / "model.safetensors"), metadata={"format": "pt"}
747
+ )
748
+ files = {p.name: _sha(p) for p in destination.iterdir()}
749
+ _save(
750
+ root / "checkpoint-manifest.json",
751
+ dict(schema="agentinputlab.adaptive-rag.router_checkpoint.v1", files=files),
752
+ )
753
+ digest = _sha(root / "checkpoint-manifest.json")
754
+ validate_adaptive_router_checkpoint(
755
+ destination, root / "checkpoint-manifest.json", digest
756
+ )
757
+ exported = load_file(str(destination / "model.safetensors"), device="cpu")
758
+ if not all(torch.equal(t, exported[n]) for n, t in trained.items()):
759
+ raise ValidationError(
760
+ "Adaptive-RAG safe export differs from live trained states"
761
+ )
762
+ _save(
763
+ root / "fit-terminal.json",
764
+ dict(
765
+ status="trained_candidate",
766
+ **observed,
767
+ changed_parameter_tensors=changed,
768
+ initial_safe_tensor_count=len(initial_tensors),
769
+ exported_tensor_count=len(trained),
770
+ initial_native_tied_aliases_expanded=aliases,
771
+ validation_rows=len(dev),
772
+ native_validation_accuracy=accuracy,
773
+ wall_seconds=time.monotonic() - started,
774
+ cpu_seconds=time.process_time() - cpu,
775
+ training_and_validation_compute_separate_not_free=True,
776
+ GPU_compute_not_fully_metered=True,
777
+ native_generation_costs_included=True,
778
+ original_published_score_parity=False,
779
+ automatic_retry=False,
780
+ ),
781
+ )
782
+ metadata = dict(
783
+ protocol=PROTOCOL,
784
+ release_id=RELEASE,
785
+ checkpoint_manifest_sha256=digest,
786
+ **{n + "_sha256": _sha(root / n) for n in ("fit-plan.json", "fit-terminal.json")},
787
+ native_files={
788
+ p.relative_to(root / "native").as_posix(): _sha(p)
789
+ for p in (root / "native").rglob("*")
790
+ if p.is_file()
791
+ },
792
+ full_quality_acceptance=False,
793
+ paper_results_changed=False,
794
+ )
795
+ _save(root / "artifact.json", dict(**metadata, artifact_id=content_hash(metadata)))
796
+ return AdaptiveRAGTrainedRouterArtifact.load(root)
797
+ except Exception as exc:
798
+ observed.pop("model", None)
799
+ if not (root / "fit-terminal.json").exists():
800
+ _save(
801
+ root / "fit-terminal.json",
802
+ dict(
803
+ status="failed_terminal",
804
+ **observed,
805
+ error_type=type(exc).__name__,
806
+ error=str(exc),
807
+ automatic_retry=False,
808
+ wall_seconds=time.monotonic() - started,
809
+ cpu_seconds=time.process_time() - cpu,
810
+ ),
811
+ )
812
+ raise
813
+
814
+
815
+ __all__ = [
816
+ "AdaptiveRAGFitControls",
817
+ "AdaptiveRAGOfflineTraining",
818
+ "AdaptiveRAGTrainedRouterArtifact",
819
+ "audit_adaptive_training_data",
820
+ "rebuild_adaptive_silver",
821
+ "validate_adaptive_router_checkpoint",
822
+ ]