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,711 @@
1
+ """Explicitly transductive, source-pinned ACE online execution.
2
+
3
+ The unchanged native online loop evaluates a window before updating on its
4
+ feedback. Initial evaluation, adaptation and post-update generations all count.
5
+ This is not an offline or held-out evaluation protocol.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import contextlib
11
+ import functools
12
+ import hashlib
13
+ import json
14
+ import os
15
+ import random
16
+ import sys
17
+ import threading
18
+ import time
19
+ from collections.abc import Mapping, Sequence
20
+ from dataclasses import asdict, dataclass
21
+ from pathlib import Path
22
+ from types import SimpleNamespace
23
+
24
+ from agentinputlab.contracts import ValidationError
25
+ from agentinputlab.contracts.serialization import content_hash, to_jsonable
26
+
27
+ from .ace import ACEExample
28
+
29
+ RELEASE = "recipe.ace.online_transductive"
30
+ PROTOCOL = "agentinputlab.ace.native-online.v1"
31
+ _LOCK = threading.RLock()
32
+
33
+
34
+ def _save(path, value):
35
+ with path.open("x", encoding="utf-8") as stream:
36
+ json.dump(value, stream, indent=2, sort_keys=True, allow_nan=False)
37
+
38
+
39
+ def _sha(path):
40
+ return hashlib.sha256(path.read_bytes()).hexdigest()
41
+
42
+
43
+ @dataclass(frozen=True, slots=True)
44
+ class ACEOnlineControls:
45
+ max_rounds: int = 1
46
+ per_case_model_calls: int = 8
47
+ per_case_output_tokens: int = 4096
48
+ per_call_output_tokens: int = 512
49
+ window_size: int = 1
50
+ max_stream_examples: int = 128
51
+ playbook_token_budget: int = 4096
52
+ timeout_seconds: int = 3600
53
+ seed: int = 17
54
+
55
+ def __post_init__(self):
56
+ for name, value in asdict(self).items():
57
+ if type(value) is not int or value < (0 if name == "seed" else 1):
58
+ raise ValidationError(f"ACE online {name} must be an integer in range")
59
+ if self.per_call_output_tokens > self.per_case_output_tokens:
60
+ raise ValidationError("ACE online per-call cap must fit its shared case budget")
61
+
62
+
63
+ def audit_online_stream(examples, controls):
64
+ if not isinstance(examples, Sequence) or isinstance(examples, (str, bytes)):
65
+ raise ValidationError("ACE online needs an ordered example sequence")
66
+ rows = tuple(ACEExample.from_value(row, split="test") for row in examples)
67
+ if not rows or len(rows) > controls.max_stream_examples or controls.window_size > len(rows):
68
+ raise ValidationError("ACE online stream size or window exceeds its explicit bound")
69
+ if any(row.expected_output is None for row in rows):
70
+ raise ValidationError("ACE online requires explicitly acknowledged feedback labels")
71
+ if len({row.example_id for row in rows}) != len(rows):
72
+ raise ValidationError("ACE online stream IDs must be unique")
73
+ from workers.ace.driver import adapt_example
74
+
75
+ adapted = tuple(adapt_example(row.as_dict()) for row in rows)
76
+ # Summarization/code tasks can repeat a question for different documents.
77
+ # Native sample callbacks expose both original fields; neither field needs
78
+ # rewriting just to attribute usage to its stable source example.
79
+ if len({(row["question"], row["context"]) for row in adapted}) != len(rows):
80
+ raise ValidationError(
81
+ "ACE online callback attribution requires unique question/context inputs"
82
+ )
83
+ return rows, adapted
84
+
85
+
86
+ class _Journal:
87
+ def __init__(self, root):
88
+ self.stream = (root / "events.jsonl").open("x", encoding="utf-8")
89
+ self.previous = "0" * 64
90
+ self.count = 0
91
+ self.lock = threading.RLock()
92
+
93
+ def event(self, kind, **data):
94
+ with self.lock:
95
+ row = dict(index=self.count, previous_sha256=self.previous, kind=kind, **data)
96
+ digest = content_hash(row)
97
+ self.stream.write(
98
+ json.dumps({**row, "sha256": digest}, sort_keys=True, allow_nan=False) + "\n"
99
+ )
100
+ self.stream.flush()
101
+ self.previous, self.count = digest, self.count + 1
102
+
103
+ def close(self):
104
+ self.stream.close()
105
+
106
+
107
+ def _tracker_type():
108
+ from workers.ace.driver import UsageTracker, WorkerFailure
109
+
110
+ class OnlineTracker(UsageTracker):
111
+ def __init__(self, controls, config, online, ids, journal):
112
+ super().__init__(controls, config)
113
+ self.online, self.journal = online, journal
114
+ self._lock, self.local = threading.RLock(), threading.local()
115
+ self.started = time.monotonic()
116
+ self.phase = "initial_evaluation"
117
+ self.input_to_id = {
118
+ (key if isinstance(key, tuple) else (key, "")): value for key, value in ids.items()
119
+ }
120
+ self.question_to_ids = {}
121
+ for (question, _), case in self.input_to_id.items():
122
+ self.question_to_ids.setdefault(question, set()).add(case)
123
+ # Budget keys remain stable source IDs, including repeated queries.
124
+ self.by_case = {
125
+ key: dict(
126
+ model_calls=0, input_tokens=0, output_tokens=0, provider_usage_responses=0
127
+ )
128
+ for key in ids.values()
129
+ }
130
+ self.budget_rejections = []
131
+
132
+ def select(self, question, context=None):
133
+ candidates = self.question_to_ids.get(question, set())
134
+ if context is not None:
135
+ case = self.input_to_id.get((question, context))
136
+ elif len(candidates) == 1:
137
+ case = next(iter(candidates))
138
+ else:
139
+ # Component callbacks inside an already selected native sample
140
+ # may expose only question; never guess between distinct inputs.
141
+ case = getattr(self.local, "case_id", None)
142
+ if case not in candidates:
143
+ case = None
144
+ if case is None:
145
+ raise WorkerFailure(
146
+ "EXAMPLE_ATTRIBUTION_FAILED",
147
+ "native ACE question/context differs from the frozen stream or is ambiguous",
148
+ )
149
+ self.local.case_id = case
150
+
151
+ def case_for(self, item):
152
+ key = (item["question"], item.get("context", ""))
153
+ if key not in self.input_to_id:
154
+ raise WorkerFailure(
155
+ "EXAMPLE_ATTRIBUTION_FAILED", "native sample differs from frozen stream"
156
+ )
157
+ return self.input_to_id[key]
158
+
159
+ def _wrap(self, component, method_name, role):
160
+ original = getattr(component, method_name)
161
+
162
+ @functools.wraps(original)
163
+ def observed(*args, **kwargs):
164
+ if "question" in kwargs:
165
+ self.select(kwargs["question"])
166
+ return base(*args, **kwargs)
167
+
168
+ super()._wrap(component, method_name, role)
169
+ base = getattr(component, method_name)
170
+ setattr(component, method_name, observed)
171
+
172
+ def before_provider_attempt(self, role):
173
+ with self._lock:
174
+ case = getattr(self.local, "case_id", None)
175
+ if case not in self.by_case:
176
+ raise WorkerFailure(
177
+ "EXAMPLE_ATTRIBUTION_FAILED", "provider attempt has no source example"
178
+ )
179
+ usage = self.by_case[case]
180
+ if (
181
+ usage["model_calls"] >= self.online.per_case_model_calls
182
+ or usage["output_tokens"] + self.online.per_call_output_tokens
183
+ > self.online.per_case_output_tokens
184
+ or time.monotonic() - self.started >= self.online.timeout_seconds
185
+ ):
186
+ self.budget_rejections.append(dict(case_id=case, role=role, phase=self.phase))
187
+ raise WorkerFailure(
188
+ "ONLINE_BUDGET_EXHAUSTED",
189
+ "ACE online shared case budget exhausted before dispatch",
190
+ )
191
+ super().before_provider_attempt(role)
192
+ usage["model_calls"] += 1
193
+ self.journal.event(
194
+ "provider_attempt",
195
+ case_id=case,
196
+ role=role,
197
+ phase=self.phase,
198
+ per_case_attempt=usage["model_calls"],
199
+ seed=self.online.seed,
200
+ )
201
+
202
+ def after_provider_response(self, role, response):
203
+ usage = (
204
+ response.get("usage")
205
+ if isinstance(response, Mapping)
206
+ else getattr(response, "usage", None)
207
+ )
208
+ if usage is None:
209
+ raise WorkerFailure(
210
+ "UPSTREAM_USAGE_UNAVAILABLE", "online provider omitted actual usage"
211
+ )
212
+ getter = (
213
+ usage.get if isinstance(usage, Mapping) else lambda key: getattr(usage, key, None)
214
+ )
215
+ incoming, outgoing = getter("prompt_tokens"), getter("completion_tokens")
216
+ if (
217
+ type(incoming) is not int
218
+ or incoming < 0
219
+ or type(outgoing) is not int
220
+ or outgoing < 0
221
+ ):
222
+ raise WorkerFailure(
223
+ "UPSTREAM_USAGE_UNAVAILABLE", "online provider usage is invalid"
224
+ )
225
+ with self._lock:
226
+ row = self.by_case[self.local.case_id]
227
+ row["input_tokens"] += incoming
228
+ row["output_tokens"] += outgoing
229
+ row["provider_usage_responses"] += 1
230
+ super().after_provider_response(role, response)
231
+ if (
232
+ outgoing > self.online.per_call_output_tokens
233
+ or row["output_tokens"] > self.online.per_case_output_tokens
234
+ ):
235
+ raise WorkerFailure(
236
+ "PROVIDER_BUDGET_BREACH", "online provider exceeded the declared output cap"
237
+ )
238
+
239
+ return OnlineTracker
240
+
241
+
242
+ class _RecordingCompletions:
243
+ def __init__(self, delegate, tracker, role, calls):
244
+ self.delegate, self.tracker, self.role, self.calls = delegate, tracker, role, calls
245
+
246
+ def create(self, *args, **kwargs):
247
+ if args:
248
+ raise ValidationError("native ACE completion must use named arguments")
249
+ if "seed" in kwargs and kwargs["seed"] != self.tracker.online.seed:
250
+ raise ValidationError("native ACE supplied a different provider seed")
251
+ kwargs = dict(kwargs, seed=self.tracker.online.seed)
252
+ row = dict(
253
+ case_id=self.tracker.local.case_id,
254
+ role=self.role,
255
+ phase=self.tracker.phase,
256
+ request=to_jsonable(kwargs),
257
+ started=time.time(),
258
+ )
259
+ self.calls.append(row)
260
+ try:
261
+ response = self.delegate.create(**kwargs)
262
+ row["response"] = (
263
+ response.model_dump(mode="json")
264
+ if callable(getattr(response, "model_dump", None))
265
+ else to_jsonable(response)
266
+ )
267
+ return response
268
+ except Exception as exc:
269
+ row["error_type"] = type(exc).__name__
270
+ raise
271
+ finally:
272
+ row["wall_seconds"] = time.time() - row["started"]
273
+ self.tracker.journal.event("provider_return", call=row)
274
+
275
+ def __getattr__(self, name):
276
+ return getattr(self.delegate, name)
277
+
278
+
279
+ class _RecordingClient:
280
+ def __init__(self, delegate, tracker, role, calls):
281
+ self.delegate = delegate
282
+ self.chat = SimpleNamespace(
283
+ completions=_RecordingCompletions(delegate.chat.completions, tracker, role, calls)
284
+ )
285
+
286
+ def __getattr__(self, name):
287
+ return getattr(self.delegate, name)
288
+
289
+
290
+ @dataclass(frozen=True, slots=True)
291
+ class ACEOnlineResult:
292
+ root: Path
293
+ artifact_id: str
294
+ terminal: Mapping
295
+
296
+ @classmethod
297
+ def load(cls, root):
298
+ folder = Path(root).expanduser()
299
+ if folder.is_symlink() or not folder.is_dir():
300
+ raise ValidationError("ACE online result requires a regular run directory")
301
+ names = (
302
+ "plan.json",
303
+ "terminal.json",
304
+ "provider-calls.json",
305
+ "events.jsonl",
306
+ "final-playbook.txt",
307
+ "native-files.json",
308
+ "manifest.json",
309
+ )
310
+ if any((folder / name).is_symlink() or not (folder / name).is_file() for name in names):
311
+ raise ValidationError("ACE online result closure is incomplete")
312
+ metadata = json.loads((folder / "manifest.json").read_text())
313
+ identity = metadata.pop("artifact_id", None)
314
+ if identity != content_hash(metadata) or metadata.get("protocol") != PROTOCOL:
315
+ raise ValidationError("ACE online result identity differs")
316
+ if set(metadata.get("files", {})) != set(names) - {"manifest.json"} or any(
317
+ _sha(folder / name) != sha for name, sha in metadata["files"].items()
318
+ ):
319
+ raise ValidationError("ACE online result file hashes differ")
320
+ previous = "0" * 64
321
+ for index, line in enumerate((folder / "events.jsonl").read_text().splitlines()):
322
+ row = json.loads(line)
323
+ digest = row.pop("sha256")
324
+ if (
325
+ row["index"] != index
326
+ or row["previous_sha256"] != previous
327
+ or content_hash(row) != digest
328
+ ):
329
+ raise ValidationError("ACE online event chain is invalid")
330
+ previous = digest
331
+ terminal = json.loads((folder / "terminal.json").read_text())
332
+ if (
333
+ terminal.get("protocol") != PROTOCOL
334
+ or terminal.get("event_chain_final_sha256") != previous
335
+ ):
336
+ raise ValidationError("ACE online terminal event binding differs")
337
+ native_files = json.loads((folder / "native-files.json").read_text())
338
+ from pathlib import PurePosixPath
339
+
340
+ for name, digest in native_files.items():
341
+ path = PurePosixPath(name)
342
+ target = folder / name
343
+ if (
344
+ path.is_absolute()
345
+ or ".." in path.parts
346
+ or str(path) != name
347
+ or target.is_symlink()
348
+ or not target.is_file()
349
+ or not target.resolve().is_relative_to(folder.resolve())
350
+ or _sha(target) != digest
351
+ ):
352
+ raise ValidationError("ACE native output closure differs")
353
+ return cls(folder.resolve(), identity, terminal)
354
+
355
+
356
+ class ACEOnlineRecipe:
357
+ release_id = RELEASE
358
+
359
+ def __init__(self, controls=None):
360
+ self.controls = (
361
+ ACEOnlineControls(**controls)
362
+ if isinstance(controls, Mapping)
363
+ else controls or ACEOnlineControls()
364
+ )
365
+ if not isinstance(self.controls, ACEOnlineControls):
366
+ raise ValidationError("ACE online requires typed controls")
367
+
368
+ def run_stream(
369
+ self,
370
+ examples,
371
+ *,
372
+ checkout,
373
+ llm_config,
374
+ output_root,
375
+ allow_test_feedback=False,
376
+ source_and_asset_acknowledged=False,
377
+ data_processor=None,
378
+ ):
379
+ if allow_test_feedback is not True or source_and_asset_acknowledged is not True:
380
+ raise ValidationError(
381
+ "ACE online requires explicit transductive feedback and source acknowledgement"
382
+ )
383
+ from workers.ace.driver import (
384
+ ACEWorkerRuntime,
385
+ BoundedHashSink,
386
+ Controls,
387
+ GenericTextProcessor,
388
+ LLMConfig,
389
+ )
390
+
391
+ c = self.controls
392
+ rows, adapted = audit_online_stream(examples, c)
393
+ task_fingerprint = None
394
+ if data_processor is not None:
395
+ for name in (
396
+ "answer_is_correct",
397
+ "evaluate_accuracy",
398
+ "fingerprint",
399
+ "validate_online_examples",
400
+ ):
401
+ if not callable(getattr(data_processor, name, None)):
402
+ raise ValidationError(f"ACE online task processor lacks {name}()")
403
+ value = data_processor.fingerprint()
404
+ if not isinstance(value, Mapping) or not value:
405
+ raise ValidationError(
406
+ "ACE online task processor fingerprint must be a nonempty object"
407
+ )
408
+ task_fingerprint = to_jsonable(value)
409
+ data_processor.validate_online_examples(tuple(row.as_dict() for row in rows))
410
+ if not isinstance(llm_config, Mapping):
411
+ raise ValidationError("ACE online needs an explicit data-only LLM deployment mapping")
412
+ config = LLMConfig.from_json(json.dumps(to_jsonable(llm_config), allow_nan=False))
413
+ if config.max_tokens_per_call != c.per_call_output_tokens or config.base_url is None:
414
+ raise ValidationError(
415
+ "ACE online requires an explicit no-retry OpenAI-compatible deployment and matching cap"
416
+ )
417
+ root = Path(output_root).expanduser()
418
+ if root.exists() or root.is_symlink():
419
+ raise ValidationError(
420
+ "ACE online output must be create-only; consumed streams are not retried"
421
+ )
422
+ root = root.absolute()
423
+ root.mkdir(parents=True)
424
+ controls = Controls(
425
+ max_rounds=c.max_rounds,
426
+ max_model_calls=c.per_case_model_calls * len(rows),
427
+ max_tokens=2_000_000_000,
428
+ max_cost_usd=1e12,
429
+ seed=c.seed,
430
+ )
431
+ plan = dict(
432
+ protocol=PROTOCOL,
433
+ release_id=RELEASE,
434
+ controls=asdict(c),
435
+ stream=[row.as_dict() for row in rows],
436
+ deployment=to_jsonable(llm_config),
437
+ transductive_not_offline_or_heldout=True,
438
+ order_preserved=True,
439
+ initial_evaluation_and_all_adaptation_costs_in_shared_case_budget=True,
440
+ generated_artifact_must_not_be_reused_as_offline_heldout_evidence=True,
441
+ automatic_retry=False,
442
+ )
443
+ if task_fingerprint is not None:
444
+ plan["native_task_processor"] = task_fingerprint
445
+ _save(root / "plan.json", plan)
446
+ journal = _Journal(root)
447
+ calls, predictions, windows, updates = [], [], [], []
448
+ tracker = runtime = ace_system = None
449
+ started, cpu = time.monotonic(), time.process_time()
450
+ error = None
451
+ diagnostics = BoundedHashSink()
452
+ try:
453
+ with _LOCK:
454
+ runtime = (
455
+ ACEWorkerRuntime(Path(checkout), config, data_processor=data_processor)
456
+ if data_processor is not None
457
+ else ACEWorkerRuntime(Path(checkout), config)
458
+ )
459
+ roles = config.roles
460
+ if not os.environ.get(config.api_key_env, ""):
461
+ raise ValidationError(
462
+ "ACE online configured API-key environment variable is unset"
463
+ )
464
+ bootstrap = "OPENAI_API_KEY" not in os.environ
465
+ if bootstrap:
466
+ # Native construction creates clients but performs no API
467
+ # call; immediately bind the caller's actual deployment.
468
+ os.environ["OPENAI_API_KEY"] = "native-constructor-bootstrap-not-a-secret"
469
+ with contextlib.redirect_stdout(diagnostics):
470
+ try:
471
+ ace_system = runtime.ace_class(
472
+ api_provider=config.api_provider,
473
+ generator_model=roles["target"].model,
474
+ reflector_model=roles["reflector"].model,
475
+ curator_model=roles["curator"].model,
476
+ max_tokens=c.per_call_output_tokens,
477
+ use_bulletpoint_analyzer=False,
478
+ )
479
+ runtime._bind_openai_compatible_clients(ace_system, seed=c.seed)
480
+ finally:
481
+ if bootstrap:
482
+ os.environ.pop("OPENAI_API_KEY", None)
483
+ tracker = _tracker_type()(
484
+ controls,
485
+ config,
486
+ c,
487
+ {
488
+ (row["question"], row["context"]): item.example_id
489
+ for item, row in zip(rows, adapted, strict=True)
490
+ },
491
+ journal,
492
+ )
493
+ for role, component in (
494
+ ("target", ace_system.generator),
495
+ ("reflector", ace_system.reflector),
496
+ ("curator", ace_system.curator),
497
+ ):
498
+ component.api_client = _RecordingClient(
499
+ component.api_client, tracker, role, calls
500
+ )
501
+ tracker.install(ace_system)
502
+ ace_module = sys.modules[runtime.ace_class.__module__]
503
+ utils = sys.modules["utils"]
504
+ native_eval, native_sample = (
505
+ ace_module.evaluate_test_set,
506
+ utils.evaluate_single_test_sample,
507
+ )
508
+ native_train = ace_system._train_single_sample
509
+ native_initial = ace_system._run_test
510
+ evaluations = 0
511
+
512
+ def observed_sample(args_tuple, data_processor):
513
+ if (
514
+ task_fingerprint is not None
515
+ and to_jsonable(data_processor.fingerprint()) != task_fingerprint
516
+ ):
517
+ raise ValidationError("ACE online task processor fingerprint changed")
518
+ item = args_tuple[1]
519
+ tracker.select(item["question"], item.get("context", ""))
520
+ result, sample_error = native_sample(args_tuple, data_processor)
521
+ record = dict(
522
+ case_id=tracker.case_for(item),
523
+ phase=tracker.phase,
524
+ native_result=to_jsonable(result),
525
+ native_error=sample_error,
526
+ )
527
+ predictions.append(record)
528
+ journal.event("native_sample_evaluated", **record)
529
+ return result, sample_error
530
+
531
+ def evaluate(*args, **kwargs):
532
+ nonlocal evaluations
533
+ phase = "initial_evaluation" if evaluations == 0 else "pre_window_evaluation"
534
+ tracker.phase = phase
535
+ evaluations += 1
536
+ playbook = args[2]
537
+ window = dict(
538
+ phase=phase,
539
+ case_ids=[tracker.case_for(x) for x in args[3]],
540
+ before_playbook_sha256=content_hash(playbook),
541
+ )
542
+ journal.event("evaluation_window_started", **window)
543
+ result = native_eval(*args, **kwargs)
544
+ window["native_statistics"] = to_jsonable(result)
545
+ windows.append(window)
546
+ journal.event("evaluation_window_finished", **window)
547
+ return result
548
+
549
+ def train(*args, **kwargs):
550
+ item = kwargs["task_dict"]
551
+ tracker.select(item["question"], item.get("context", ""))
552
+ tracker.phase = "feedback_adaptation"
553
+ record = dict(
554
+ case_id=tracker.local.case_id,
555
+ before_playbook_sha256=content_hash(ace_system.playbook),
556
+ )
557
+ journal.event("feedback_update_started", **record)
558
+ result = native_train(*args, **kwargs)
559
+ record.update(
560
+ after_playbook_sha256=content_hash(ace_system.playbook),
561
+ native_tracking=to_jsonable(result),
562
+ )
563
+ updates.append(record)
564
+ journal.event("feedback_update_finished", **record)
565
+ return result
566
+
567
+ # Observation only: every native call receives its original
568
+ # arguments and every native return value is passed unchanged.
569
+ ace_module.evaluate_test_set = evaluate
570
+ utils.evaluate_single_test_sample = observed_sample
571
+ ace_system._train_single_sample = train
572
+ state = random.getstate()
573
+ try:
574
+ random.seed(c.seed)
575
+ with contextlib.redirect_stdout(diagnostics):
576
+ native_result = ace_system.run(
577
+ mode="online",
578
+ train_samples=None,
579
+ val_samples=None,
580
+ test_samples=list(adapted),
581
+ data_processor=(
582
+ data_processor
583
+ if data_processor is not None
584
+ else GenericTextProcessor()
585
+ ),
586
+ config=dict(
587
+ num_epochs=1,
588
+ max_num_rounds=c.max_rounds,
589
+ curator_frequency=1,
590
+ online_eval_frequency=c.window_size,
591
+ eval_steps=len(rows),
592
+ save_steps=len(rows) + 1,
593
+ playbook_token_budget=c.playbook_token_budget,
594
+ task_name="toolkit_explicit_online",
595
+ json_mode=config.json_mode,
596
+ no_ground_truth=False,
597
+ save_dir=str(root / "native"),
598
+ test_workers=1,
599
+ use_bulletpoint_analyzer=False,
600
+ ),
601
+ )
602
+ finally:
603
+ random.setstate(state)
604
+ ace_module.evaluate_test_set = native_eval
605
+ utils.evaluate_single_test_sample = native_sample
606
+ ace_system._train_single_sample = native_train
607
+ ace_system._run_test = native_initial
608
+ _save(root / "native-result.json", to_jsonable(native_result))
609
+ except Exception as exc:
610
+ error = dict(error_type=type(exc).__name__, message=str(exc))
611
+ primary = []
612
+ for row in rows:
613
+ records = [
614
+ p
615
+ for p in predictions
616
+ if p["case_id"] == row.example_id and p["phase"] == "pre_window_evaluation"
617
+ ]
618
+ if len(records) > 1:
619
+ raise ValidationError("ACE online primary prediction was evaluated twice")
620
+ record = records[0] if records else None
621
+ result = record["native_result"] if record else None
622
+ valid = (
623
+ isinstance(result, dict)
624
+ and result.get("success") is True
625
+ and isinstance(result.get("final_answer"), str)
626
+ and bool(result["final_answer"].strip())
627
+ and result["final_answer"] != "No final answer found"
628
+ )
629
+ primary.append(
630
+ dict(
631
+ case_id=row.example_id,
632
+ status=(
633
+ "native_prediction_returned"
634
+ if valid
635
+ else "failed_primary_prediction"
636
+ if record
637
+ else "not_reached_after_native_failure"
638
+ if tracker and tracker.by_case[row.example_id]["model_calls"]
639
+ else "never_started"
640
+ ),
641
+ native_prediction=result,
642
+ raw_primary_observation=record,
643
+ feedback_completed=any(u["case_id"] == row.example_id for u in updates),
644
+ )
645
+ )
646
+ journal.event("stream_terminal", native_returned=error is None, error=error)
647
+ journal.close()
648
+ _save(root / "provider-calls.json", calls)
649
+ with (root / "final-playbook.txt").open("x", encoding="utf-8") as stream:
650
+ stream.write(ace_system.playbook if ace_system is not None else "")
651
+ terminal = dict(
652
+ protocol=PROTOCOL,
653
+ release_id=RELEASE,
654
+ status=(
655
+ "native_online_returned"
656
+ if error is None
657
+ else "native_failed_terminal"
658
+ if tracker and tracker.model_calls
659
+ else "execution_failed_before_model"
660
+ ),
661
+ error=error,
662
+ expected_positions=len(rows),
663
+ primary_outcomes=primary,
664
+ predictions_before_current_window_feedback=True,
665
+ post_update_predictions_are_not_primary=True,
666
+ upstream_results_may_exclude_failures_denominator_preserved=len(rows),
667
+ windows=windows,
668
+ updates=updates,
669
+ usage=tracker.as_dict() if tracker else {},
670
+ per_case_usage=tracker.by_case if tracker else {},
671
+ budget_rejections=tracker.budget_rejections if tracker else [],
672
+ event_chain_final_sha256=journal.previous,
673
+ event_count=journal.count,
674
+ wall_seconds=time.monotonic() - started,
675
+ cpu_seconds=time.process_time() - cpu,
676
+ monetary_prices_unconfigured=all(
677
+ not r.input_cost_per_million and not r.output_cost_per_million
678
+ for r in config.roles.values()
679
+ ),
680
+ automatic_retry=False,
681
+ transductive_not_offline_or_heldout=True,
682
+ paper_results_changed=False,
683
+ native_source_commit=runtime.policy.commit if runtime else None,
684
+ verified_native_source_files=dict(runtime.policy.source_hashes) if runtime else {},
685
+ )
686
+ _save(root / "terminal.json", terminal)
687
+ native_files = {
688
+ str(p.relative_to(root)): _sha(p) for p in (root / "native").rglob("*") if p.is_file()
689
+ }
690
+ if (root / "native-result.json").exists():
691
+ native_files["native-result.json"] = _sha(root / "native-result.json")
692
+ _save(root / "native-files.json", native_files)
693
+ files = {
694
+ name: _sha(root / name)
695
+ for name in (
696
+ "plan.json",
697
+ "terminal.json",
698
+ "provider-calls.json",
699
+ "events.jsonl",
700
+ "final-playbook.txt",
701
+ "native-files.json",
702
+ )
703
+ }
704
+ manifest = dict(
705
+ protocol=PROTOCOL, release_id=RELEASE, files=files, offline_reuse_allowed=False
706
+ )
707
+ _save(root / "manifest.json", {**manifest, "artifact_id": content_hash(manifest)})
708
+ return ACEOnlineResult.load(root)
709
+
710
+
711
+ __all__ = ["ACEOnlineControls", "ACEOnlineRecipe", "ACEOnlineResult", "audit_online_stream"]