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,364 @@
1
+ """Fresh native Ray worker bindings; native losses and rollout math stay upstream."""
2
+ from __future__ import annotations
3
+
4
+ import ast
5
+ import inspect
6
+ import math
7
+ import numbers
8
+ import random
9
+ import re
10
+ from pathlib import Path
11
+ from types import FunctionType
12
+
13
+ from agentinputlab.contracts import ExternalDependencyError, ValidationError
14
+ from agentinputlab.contracts.serialization import content_hash
15
+
16
+ from .qrag import _sha
17
+ from .smartsearch_grpo_contracts import NativeGRPORewardManagerContract
18
+ from .smartsearch_grpo_data import verify_smartsearch_grpo_source
19
+ from .smartsearch_grpo_meter import MeteredNativeGRPOEngine, observe_native_grpo_optimizer
20
+ from .smartsearch_grpo_prefix import SmartSearchNativeGRPOPrefixBuilder
21
+ from .smartsearch_grpo_rollout import install_native_rollout_batch_contracts
22
+ from .smartsearch_grpo_tools import SmartSearchNativeGRPOReward, _new_output, _save
23
+ from .smartsearch_grpo_transport import SmartSearchGRPOCoordinatorClient
24
+ from .smartsearch_teacher import SmartSearchTeacherControls
25
+
26
+ _NATIVE_COLOCATION_SHA256 = "b3a4237fc9b37d1011a259210196d259efbb1c68a50d25fe2616f24ee98075d1"
27
+
28
+
29
+ def _verify_runtime(descriptor):
30
+ from .smartsearch_grpo_training import _RUNTIME_FILES
31
+ if set(descriptor.get("toolkit_modules", {})) != set(_RUNTIME_FILES) or any(
32
+ _sha(Path(__file__).with_name(name)) != descriptor["toolkit_modules"][name] for name in _RUNTIME_FILES
33
+ ):
34
+ raise ExternalDependencyError("SmartSearch GRPO child toolkit bytes differ from its launcher")
35
+
36
+
37
+ def _teacher_controls(descriptor):
38
+ return SmartSearchTeacherControls(max_model_calls=descriptor["cost_limits"]["helper_requests"],
39
+ max_total_output_tokens=descriptor["cost_limits"]["helper_output_tokens"],
40
+ max_rollout_rows=descriptor["max_helper_rows"], seed=descriptor["seed"])
41
+
42
+
43
+ def _nonfinite(value):
44
+ if isinstance(value, dict):
45
+ return sum(_nonfinite(v) for v in value.values())
46
+ if isinstance(value, (tuple, list)):
47
+ return sum(_nonfinite(v) for v in value)
48
+ return int(isinstance(value, numbers.Real) and not math.isfinite(value))
49
+
50
+
51
+ def native_grpo_actor_class(native_class, descriptor):
52
+ """Subclass the pinned worker, adding transport/accounting/export only."""
53
+ _verify_runtime(descriptor)
54
+ source, _ = verify_smartsearch_grpo_source(descriptor["checkout"])
55
+ if Path(inspect.getfile(native_class)).resolve() != source / "src/verl/workers/fsdp_workers.py":
56
+ raise ExternalDependencyError("SmartSearch GRPO actor class is not the bound native worker")
57
+ import torch
58
+ from verl.single_controller.base.decorator import Dispatch, register
59
+
60
+ class ObservedSmartSearchActor(native_class):
61
+ _ail_native_worker_class = native_class
62
+
63
+ def __init__(self, *args, **kwargs):
64
+ super().__init__(*args, **kwargs)
65
+ import numpy as np
66
+ random.seed(descriptor["seed"])
67
+ np.random.seed(descriptor["seed"])
68
+ torch.manual_seed(descriptor["seed"])
69
+ torch.cuda.manual_seed_all(descriptor["seed"])
70
+ self._ail_descriptor = descriptor
71
+ self._ail_root = _new_output(Path(descriptor["output_root"]) / "workers" / f"{self.role}-rank-{self.rank}")
72
+ self._ail_client = SmartSearchGRPOCoordinatorClient(descriptor["coordinator_endpoint"])
73
+ self._ail_prefix = None
74
+ self._ail_usage = dict(forward_attempts=0, forward_responses=0,
75
+ input_token_positions=0, nonfinite_native_metrics=0)
76
+ _save(self._ail_root, "claim.json", dict(rank=self.rank, role=self.role,
77
+ descriptor_sha256=content_hash(descriptor), source_worker_sha256=_sha(source / "src/verl/workers/fsdp_workers.py"),
78
+ forward_scope="FSDP outer forward boundary after native init_model",
79
+ initialization_and_internal_checkpoint_recomputation_forwards_unmeasured=True,
80
+ no_automatic_retry=True))
81
+
82
+ def _build_rollout(self, *args, **kwargs):
83
+ rollout, sharding = super()._build_rollout(*args, **kwargs)
84
+ self._ail_prefix = SmartSearchNativeGRPOPrefixBuilder(self._ail_client.generate,
85
+ checkout=source, references=descriptor["train_references"],
86
+ model_fingerprint_sha256=descriptor["helper_fingerprint_sha256"],
87
+ controls=_teacher_controls(descriptor), output_root=self._ail_root / "prefix")
88
+ binding = install_native_rollout_batch_contracts(checkout=source, rollout_class=type(rollout),
89
+ prefix_builder=self._ail_prefix,
90
+ prefix_builder_binding=dict(descriptor_sha256=content_hash(descriptor), shared_coordinator=True))
91
+ _save(self._ail_root, "rollout-adapter.json", binding)
92
+ rollout.inference_engine = MeteredNativeGRPOEngine(rollout.inference_engine,
93
+ ledger=self._ail_client, worker=f"{self.role}-rank-{self.rank}")
94
+ return rollout, sharding
95
+
96
+ @register(dispatch_mode=Dispatch.ONE_TO_ALL)
97
+ def init_model(self):
98
+ super().init_model()
99
+ modules = []
100
+ if self._is_actor:
101
+ modules.append(self.actor_module_fsdp)
102
+ observe_native_grpo_optimizer(self.actor_optimizer, ledger=self._ail_client, rank=self.rank)
103
+ original_update = self.actor.update_policy
104
+
105
+ def update_policy(*args, **kwargs):
106
+ result = original_update(*args, **kwargs)
107
+ bad = _nonfinite(result)
108
+ self._ail_usage["nonfinite_native_metrics"] += bad
109
+ if bad:
110
+ self._ail_client.fail(f"nonfinite-actor-rank-{self.rank}", error_type="NonfiniteNativeMetrics")
111
+ raise ExternalDependencyError("SmartSearch native actor returned nonfinite metrics")
112
+ return result
113
+
114
+ self.actor.update_policy = update_policy
115
+ if self._is_ref:
116
+ modules.append(self.ref_module_fsdp)
117
+ for module in modules:
118
+ def before(_module, args, kwargs):
119
+ self._ail_usage["forward_attempts"] += 1
120
+ ids = kwargs.get("input_ids")
121
+ if ids is None and args:
122
+ ids = args[0]
123
+ if hasattr(ids, "numel"):
124
+ self._ail_usage["input_token_positions"] += int(ids.numel())
125
+ def after(*_args):
126
+ self._ail_usage["forward_responses"] += 1
127
+ module.register_forward_pre_hook(before, with_kwargs=True)
128
+ module.register_forward_hook(after)
129
+
130
+ @register(dispatch_mode=Dispatch.ONE_TO_ALL)
131
+ def finalize_smartsearch_costs(self):
132
+ if self._ail_prefix is not None:
133
+ self._ail_prefix.assert_healthy()
134
+ report = dict(rank=self.rank, role=self.role, usage=dict(self._ail_usage))
135
+ _save(self._ail_root, "terminal.json", report)
136
+ self._ail_client.worker_completed(**report)
137
+ return report
138
+
139
+ @register(dispatch_mode=Dispatch.ONE_TO_ALL)
140
+ def export_smartsearch_safe_policy(self):
141
+ # The pinned native 'hf_model' checkpoint branch writes config and
142
+ # tokenizer ONLY. Export the ACTUAL trained state while workers
143
+ # are alive, rather than calling that metadata a trained HF model.
144
+ if not self._is_actor:
145
+ raise ValidationError("Only the native trained actor can export the learned policy")
146
+ from torch.distributed.fsdp import FullStateDictConfig, StateDictType
147
+ from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
148
+ destination = Path(descriptor["output_root"]) / "exported-policy"
149
+ if self.rank == 0:
150
+ destination.mkdir(exist_ok=False)
151
+ torch.distributed.barrier()
152
+ with FSDP.state_dict_type(self.actor_module_fsdp, StateDictType.FULL_STATE_DICT,
153
+ FullStateDictConfig(offload_to_cpu=True, rank0_only=True)):
154
+ state = self.actor_module_fsdp.state_dict()
155
+ if self.rank == 0:
156
+ original = self.actor_module_fsdp._fsdp_wrapped_module
157
+ original.save_pretrained(destination, state_dict=state, safe_serialization=True, max_shard_size="4GB")
158
+ self.tokenizer.save_pretrained(destination)
159
+ files = {p.name: _sha(p) for p in destination.iterdir() if p.is_file()}
160
+ if not any(n.endswith(".safetensors") for n in files) or any(
161
+ p.is_symlink() for p in destination.iterdir()
162
+ ):
163
+ raise ExternalDependencyError("SmartSearch native trained state was not safely exported")
164
+ _save(Path(descriptor["output_root"]), "safe-export.json",
165
+ dict(files=files, rank=0, same_live_trained_actor=True, new_optimizer_steps=0))
166
+ torch.distributed.barrier()
167
+ return {"rank": self.rank, "safe_export_completed": True}
168
+
169
+ return ObservedSmartSearchActor
170
+
171
+
172
+ def _colocation_worker_base(actor_class):
173
+ """Keep the native Worker root despite our accounting subclass layer."""
174
+ if not isinstance(actor_class, type):
175
+ raise ExternalDependencyError("SmartSearch colocated actor must be a class")
176
+ native = getattr(actor_class, "_ail_native_worker_class", None)
177
+ if native is None:
178
+ return actor_class.__base__
179
+ if not isinstance(native, type) or not issubclass(actor_class, native) or (
180
+ len(native.__bases__) != 1 or native.__base__ is object
181
+ ):
182
+ raise ExternalDependencyError("SmartSearch colocated actor native-base binding differs")
183
+ return native.__base__
184
+
185
+
186
+ def _colocation_factory_ast(source_text):
187
+ """Change the two base lookups, not delegated role constructors or methods."""
188
+ tree = ast.parse(source_text)
189
+ owners = [node for node in tree.body if isinstance(node, ast.FunctionDef)
190
+ and node.name == "create_colocated_worker_cls"]
191
+ if len(owners) != 1:
192
+ raise ExternalDependencyError("SmartSearch native colocation factory differs")
193
+ expected = ast.dump(ast.parse("cls.cls.__ray_actor_class__.__base__", mode="eval").body)
194
+
195
+ class BindBase(ast.NodeTransformer):
196
+ changed = 0
197
+
198
+ def visit_Attribute(self, node):
199
+ if ast.dump(node) == expected:
200
+ self.changed += 1
201
+ return ast.copy_location(ast.Call(func=ast.Name(id="_ail_colocation_worker_base", ctx=ast.Load()),
202
+ args=[node.value], keywords=[]), node)
203
+ return self.generic_visit(node)
204
+
205
+ binding = BindBase()
206
+ owner = binding.visit(owners[0])
207
+ if binding.changed != 2:
208
+ raise ExternalDependencyError("SmartSearch native colocation base inventory differs")
209
+ calls = [node for node in ast.walk(owner) if isinstance(node, ast.Call)
210
+ and isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name)
211
+ and node.func.value.id == "ray" and node.func.attr == "remote"]
212
+ if len(calls) != 1 or len(calls[0].args) != 1 or calls[0].keywords:
213
+ raise ExternalDependencyError("SmartSearch native colocated actor constructor differs")
214
+ calls[0].func = ast.parse("ray.remote(max_restarts=0, max_task_retries=0)", mode="eval").body
215
+ return ast.fix_missing_locations(owner)
216
+
217
+
218
+ def _clone_init_workers_with_factory(method, factory):
219
+ if not isinstance(method, FunctionType) or not callable(factory):
220
+ raise ExternalDependencyError("SmartSearch native worker initialization surface differs")
221
+ namespace = dict(method.__globals__, create_colocated_worker_cls=factory)
222
+ clone = FunctionType(method.__code__, namespace, "_ail_native_init_workers", method.__defaults__, method.__closure__)
223
+ clone.__kwdefaults__ = None if method.__kwdefaults__ is None else dict(method.__kwdefaults__)
224
+ clone.__annotations__ = dict(method.__annotations__)
225
+ return clone
226
+
227
+
228
+ def _native_colocated_init_workers(native_trainer, source):
229
+ method = native_trainer.init_workers
230
+ if not isinstance(method, FunctionType) or Path(inspect.getfile(method)).resolve() != (
231
+ source / "src/verl/trainer/ppo/ray_trainer.py"
232
+ ):
233
+ raise ExternalDependencyError("SmartSearch worker initialization came from another trainer")
234
+ factory = method.__globals__.get("create_colocated_worker_cls")
235
+ path = source / "src/verl/single_controller/ray/base.py"
236
+ if not isinstance(factory, FunctionType) or Path(inspect.getfile(factory)).resolve() != path or (
237
+ _sha(path) != _NATIVE_COLOCATION_SHA256
238
+ ):
239
+ raise ExternalDependencyError("SmartSearch native colocation source changed")
240
+ namespace = dict(factory.__globals__, _ail_colocation_worker_base=_colocation_worker_base)
241
+ owner = _colocation_factory_ast(path.read_text())
242
+ exec(compile(ast.Module(body=[owner], type_ignores=[]), str(path), "exec"), namespace)
243
+ return _clone_init_workers_with_factory(method, namespace["create_colocated_worker_cls"])
244
+
245
+
246
+ def native_grpo_reward_router(descriptor):
247
+ """One native train scorer and one native dev scorer, no reference mixing."""
248
+ _verify_runtime(descriptor)
249
+ client = SmartSearchGRPOCoordinatorClient(descriptor["coordinator_endpoint"])
250
+ controls = _teacher_controls(descriptor)
251
+ scorers = {}
252
+ for role in ("train", "validation"):
253
+ scorers[role] = SmartSearchNativeGRPOReward(client.generate, checkout=descriptor["checkout"],
254
+ references=descriptor[role + "_references"], model_fingerprint_sha256=descriptor["helper_fingerprint_sha256"],
255
+ controls=controls, output_root=Path(descriptor["output_root"]) / ("reward-" + role), reference_split=role)
256
+
257
+ def score(*, data_source, tokenizer, solution_str, ground_truth):
258
+ if data_source != "re_call":
259
+ raise ValidationError("SmartSearch native reward received a different data source")
260
+ match = re.search(r'<\|im_start\|>user\n(.*?)<\|im_end\|>', solution_str, re.DOTALL)
261
+ question = match.group(1).strip() if match else None
262
+ roles = [role for role, scorer in scorers.items() if question in scorer.references]
263
+ if len(roles) != 1:
264
+ raise ValidationError("SmartSearch native reward question is absent or crosses split roles")
265
+ return scorers[roles[0]](tokenizer, solution_str, ground_truth)
266
+
267
+ def healthy():
268
+ for scorer in scorers.values():
269
+ usage = scorer.usage
270
+ if scorer.failed or usage["score_attempts"] != usage["score_responses"] or (
271
+ usage["model_attempts"] != usage["model_responses"] or usage["unknown_output_token_reservations"]
272
+ ):
273
+ raise ExternalDependencyError("SmartSearch native reward has an unresolved scoring/helper request")
274
+ return {role: dict(scorer.usage) for role, scorer in scorers.items()}
275
+
276
+ score.assert_healthy = healthy
277
+ return score
278
+
279
+
280
+ def _task_runner_ast(source_text):
281
+ """Adapt only worker wiring, once-only reward envelope and return value."""
282
+ tree = ast.parse(source_text)
283
+ owners = [n for n in tree.body if isinstance(n, ast.ClassDef) and n.name == "TaskRunner"]
284
+ if len(owners) != 1:
285
+ raise ExternalDependencyError("SmartSearch native TaskRunner class differs")
286
+ owner = owners[0]
287
+ owner.decorator_list = []
288
+ run = next(n for n in owner.body if isinstance(n, ast.FunctionDef) and n.name == "run")
289
+ changed = 0
290
+ for branch in ast.walk(run):
291
+ if isinstance(branch, ast.If):
292
+ for sequence in (branch.body, branch.orelse):
293
+ for index, node in list(enumerate(sequence)):
294
+ if isinstance(node, ast.ImportFrom) and node.module == "verl.workers.fsdp_workers" and (
295
+ [n.name for n in node.names] == ["ActorRolloutRefWorker", "CriticWorker"]
296
+ ):
297
+ sequence[index + 1:index + 1] = ast.parse(
298
+ "ActorRolloutRefWorker = _ail_actor_class(ActorRolloutRefWorker, _ail_descriptor)").body
299
+ changed += 1
300
+ if changed != 1:
301
+ raise ExternalDependencyError("SmartSearch native FSDP worker binding differs")
302
+ assignments = [(i, n) for i, n in enumerate(run.body) if isinstance(n, ast.Assign)
303
+ and any(isinstance(t, ast.Name) and t.id == "resource_pool_manager" for t in n.targets)]
304
+ if len(assignments) != 1:
305
+ raise ExternalDependencyError("SmartSearch native reward-to-trainer boundary differs")
306
+ run.body[assignments[0][0]:assignments[0][0]] = ast.parse(
307
+ "reward_fn = _ail_reward_contract(reward_fn)\nval_reward_fn = _ail_reward_contract(val_reward_fn)").body
308
+ last = run.body[-1]
309
+ if not isinstance(last, ast.Expr) or ast.unparse(last.value) != "trainer.fit()":
310
+ raise ExternalDependencyError("SmartSearch native trainer terminal call differs")
311
+ run.body[-1] = ast.Return(value=last.value)
312
+ calls = [n for n in ast.walk(run) if isinstance(n, ast.Call) and isinstance(n.func, ast.Attribute)
313
+ and isinstance(n.func.value, ast.Name) and n.func.value.id == "ray" and n.func.attr == "remote"]
314
+ if len(calls) != 4 or any(len(n.args) != 1 or n.keywords for n in calls):
315
+ raise ExternalDependencyError("SmartSearch native Ray worker constructor inventory differs")
316
+ for call in calls:
317
+ call.func = ast.parse("ray.remote(max_restarts=0, max_task_retries=0)", mode="eval").body
318
+ for call in ast.walk(run):
319
+ if isinstance(call, ast.Call) and isinstance(call.func, ast.Name) and call.func.id == "pprint":
320
+ call.args = [ast.Call(func=ast.Name(id="_ail_log_safe", ctx=ast.Load()), args=[arg], keywords=[])
321
+ for arg in call.args]
322
+ return ast.fix_missing_locations(owner)
323
+
324
+
325
+ def native_grpo_task_runner(native_driver, descriptor):
326
+ """Build the pinned native TaskRunner with explicit local runtime seams."""
327
+ _verify_runtime(descriptor)
328
+ source, _ = verify_smartsearch_grpo_source(descriptor["checkout"])
329
+ path = source / "src/verl/trainer/main_ppo.py"
330
+ if Path(native_driver.__file__).resolve() != path:
331
+ raise ExternalDependencyError("SmartSearch GRPO driver was imported from a different installation")
332
+ NativeTrainer = native_driver.RayPPOTrainer
333
+ init_workers = _native_colocated_init_workers(NativeTrainer, source)
334
+
335
+ class ObservedTrainer(NativeTrainer):
336
+ def init_workers(self):
337
+ return init_workers(self)
338
+
339
+ def fit(self):
340
+ super().fit()
341
+ router = self.reward_fn.native_manager.compute_score
342
+ reward_usage = router.assert_healthy()
343
+ actor = self.actor_rollout_wg.finalize_smartsearch_costs()
344
+ reference = self.ref_policy_wg.finalize_smartsearch_costs() if self.use_reference_policy else []
345
+ exported = self.actor_rollout_wg.export_smartsearch_safe_policy()
346
+ return dict(global_steps=self.global_steps, actor=actor, reference=reference,
347
+ reward_usage=reward_usage, safe_export=exported)
348
+
349
+ namespace = dict(native_driver.__dict__, RayPPOTrainer=ObservedTrainer,
350
+ get_custom_reward_fn=lambda _config: native_grpo_reward_router(descriptor),
351
+ _ail_descriptor=descriptor, _ail_actor_class=native_grpo_actor_class,
352
+ _ail_reward_contract=NativeGRPORewardManagerContract, _ail_log_safe=_log_safe)
353
+ owner = _task_runner_ast(path.read_text())
354
+ exec(compile(ast.Module(body=[owner], type_ignores=[]), str(path), "exec"), namespace)
355
+ return namespace["TaskRunner"]
356
+
357
+
358
+ def _log_safe(value):
359
+ if isinstance(value, dict):
360
+ return {key: "<private loopback capability>" if key in {"sandbox_url", "search_url", "coordinator_endpoint"}
361
+ else _log_safe(item) for key, item in value.items()}
362
+ if isinstance(value, (tuple, list)):
363
+ return [_log_safe(item) for item in value]
364
+ return value