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,619 @@
1
+ #!/usr/bin/env python3
2
+ """Strict atomic worker for official stateful benchmark runtimes.
3
+
4
+ The host sends one baseline/treatment request. This worker loads a
5
+ checksum-locked protected replay inventory, starts two distinct official
6
+ runtime instances, injects the already materialized intervention state, calls
7
+ the upstream scorer, and returns one indivisible receipt.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import importlib
14
+ import json
15
+ import os
16
+ import re
17
+ import sys
18
+ import tempfile
19
+ from collections.abc import Mapping, Sequence
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+ try:
24
+ from .protocol import (
25
+ REPLAY_INVENTORY_PROTOCOL,
26
+ OfficialArenaError,
27
+ OfficialArenaProvider,
28
+ content_hash,
29
+ intervention_usage,
30
+ materialized_state,
31
+ merge_usage,
32
+ sha256_file,
33
+ )
34
+ except ImportError: # direct script execution
35
+ from protocol import ( # type: ignore[no-redef]
36
+ REPLAY_INVENTORY_PROTOCOL,
37
+ OfficialArenaError,
38
+ OfficialArenaProvider,
39
+ content_hash,
40
+ intervention_usage,
41
+ materialized_state,
42
+ merge_usage,
43
+ sha256_file,
44
+ )
45
+
46
+ REQUEST_PROTOCOL = "agentinputlab.atomic-process-request.v1"
47
+ RESPONSE_PROTOCOL = "agentinputlab.atomic-process-response.v1"
48
+ WORKER_PROTOCOL = "agentinputlab.official-arena-worker.v1"
49
+
50
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
51
+ _ENV = re.compile(r"^[A-Z_][A-Z0-9_]*$")
52
+ _ROOT_FIELDS = frozenset(
53
+ {
54
+ "schema_version",
55
+ "protocol",
56
+ "atomic_request",
57
+ "worker_parameters",
58
+ "request_hash",
59
+ }
60
+ )
61
+ _PARAMETER_FIELDS = frozenset(
62
+ {
63
+ "schema_version",
64
+ "protocol",
65
+ "provider_entrypoint",
66
+ "provider_config",
67
+ "replay_inventory_environment",
68
+ "replay_inventory_sha256_environment",
69
+ "expected_replay_inventory_sha256",
70
+ "bridge_id",
71
+ "bridge_revision",
72
+ "scorer_id",
73
+ "scorer_revision",
74
+ }
75
+ )
76
+ _REQUEST_FIELDS = frozenset(
77
+ {
78
+ "benchmark_id",
79
+ "checkpoint_id",
80
+ "source_revision",
81
+ "origin_state_hash",
82
+ "replay_identity",
83
+ "seed",
84
+ "locked_dependency_hashes",
85
+ "arms",
86
+ }
87
+ )
88
+ _USAGE_FIELDS = (
89
+ "model_calls",
90
+ "retrieval_calls",
91
+ "tool_calls",
92
+ "embedding_calls",
93
+ "unpriced_model_calls",
94
+ "input_tokens",
95
+ "output_tokens",
96
+ "cpu_seconds",
97
+ "accelerator_seconds",
98
+ "cost_usd",
99
+ "compute_cost_usd",
100
+ )
101
+
102
+
103
+ def _provider(entrypoint: str) -> OfficialArenaProvider:
104
+ if not isinstance(entrypoint, str) or ":" not in entrypoint or entrypoint.startswith("_"):
105
+ raise OfficialArenaError("provider_entrypoint must use module:factory syntax")
106
+ module_name, attribute = entrypoint.split(":", 1)
107
+ if not module_name.startswith("workers.official_arenas.providers."):
108
+ raise OfficialArenaError("provider_entrypoint is outside the official provider allowlist")
109
+ repository_root = Path(__file__).resolve().parents[2]
110
+ if str(repository_root) not in sys.path:
111
+ sys.path.insert(0, str(repository_root))
112
+ try:
113
+ factory = getattr(importlib.import_module(module_name), attribute)
114
+ provider = factory()
115
+ except Exception as exc:
116
+ raise OfficialArenaError("cannot load official arena provider") from exc
117
+ if not isinstance(provider, OfficialArenaProvider):
118
+ raise OfficialArenaError("official arena provider does not implement the protocol")
119
+ return provider
120
+
121
+
122
+ def _parameters(value: Any) -> Mapping[str, Any]:
123
+ if not isinstance(value, Mapping) or set(value) != _PARAMETER_FIELDS:
124
+ raise OfficialArenaError("official arena worker parameters are invalid")
125
+ if value["schema_version"] != 1 or value["protocol"] != WORKER_PROTOCOL:
126
+ raise OfficialArenaError("unsupported official arena worker protocol")
127
+ for name in (
128
+ "expected_replay_inventory_sha256",
129
+ "bridge_revision",
130
+ "scorer_revision",
131
+ ):
132
+ if not isinstance(value[name], str) or _SHA256.fullmatch(value[name]) is None:
133
+ raise OfficialArenaError(f"worker parameter {name} must be a SHA-256 digest")
134
+ for name in (
135
+ "replay_inventory_environment",
136
+ "replay_inventory_sha256_environment",
137
+ ):
138
+ if not isinstance(value[name], str) or _ENV.fullmatch(value[name]) is None:
139
+ raise OfficialArenaError(f"worker parameter {name} is invalid")
140
+ if not isinstance(value["provider_config"], Mapping):
141
+ raise OfficialArenaError("provider_config must be an object")
142
+ for name in ("bridge_id", "scorer_id"):
143
+ if not isinstance(value[name], str) or not value[name].strip():
144
+ raise OfficialArenaError(f"worker parameter {name} must be non-empty")
145
+ return value
146
+
147
+
148
+ def _inventory(parameters: Mapping[str, Any]) -> Mapping[str, Mapping[str, Any]]:
149
+ path_text = os.environ.get(parameters["replay_inventory_environment"])
150
+ digest_text = os.environ.get(parameters["replay_inventory_sha256_environment"])
151
+ expected = parameters["expected_replay_inventory_sha256"]
152
+ if not path_text or digest_text != expected:
153
+ raise OfficialArenaError("protected replay inventory environment is absent or changed")
154
+ path = Path(path_text).expanduser()
155
+ if path.is_symlink() or not path.is_file() or sha256_file(path) != expected:
156
+ raise OfficialArenaError("protected replay inventory is absent or changed")
157
+ try:
158
+ value = json.loads(path.read_text(encoding="utf-8"))
159
+ except (OSError, UnicodeError, json.JSONDecodeError) as exc:
160
+ raise OfficialArenaError("protected replay inventory is not valid JSON") from exc
161
+ if (
162
+ not isinstance(value, Mapping)
163
+ or set(value)
164
+ != {
165
+ "schema_version",
166
+ "protocol",
167
+ "benchmark_id",
168
+ "source_revision",
169
+ "record_count",
170
+ "records",
171
+ }
172
+ or value["schema_version"] != 1
173
+ or value["protocol"] != REPLAY_INVENTORY_PROTOCOL
174
+ or not isinstance(value["records"], list)
175
+ or value["record_count"] != len(value["records"])
176
+ or not value["records"]
177
+ ):
178
+ raise OfficialArenaError("protected replay inventory schema is invalid")
179
+ records: dict[str, Mapping[str, Any]] = {}
180
+ for item in value["records"]:
181
+ if (
182
+ not isinstance(item, Mapping)
183
+ or set(item)
184
+ != {
185
+ "checkpoint_id",
186
+ "origin_state_hash",
187
+ "replay_identity",
188
+ "protected",
189
+ }
190
+ or not isinstance(item["checkpoint_id"], str)
191
+ or not isinstance(item["protected"], Mapping)
192
+ ):
193
+ raise OfficialArenaError("protected replay record schema is invalid")
194
+ if item["checkpoint_id"] in records:
195
+ raise OfficialArenaError("protected replay inventory contains duplicate checkpoints")
196
+ for name in ("origin_state_hash", "replay_identity"):
197
+ if not isinstance(item[name], str) or _SHA256.fullmatch(item[name]) is None:
198
+ raise OfficialArenaError("protected replay record identity is invalid")
199
+ records[item["checkpoint_id"]] = item
200
+ return {
201
+ "__inventory__": {
202
+ "benchmark_id": value["benchmark_id"],
203
+ "source_revision": value["source_revision"],
204
+ },
205
+ **records,
206
+ }
207
+
208
+
209
+ def _atomic_request(value: Any) -> Mapping[str, Any]:
210
+ if not isinstance(value, Mapping) or set(value) != _REQUEST_FIELDS:
211
+ raise OfficialArenaError("atomic request schema is invalid")
212
+ if (
213
+ not isinstance(value["seed"], int)
214
+ or isinstance(value["seed"], bool)
215
+ or value["seed"] < 0
216
+ or not isinstance(value["locked_dependency_hashes"], Mapping)
217
+ ):
218
+ raise OfficialArenaError("atomic request seed or dependency locks are invalid")
219
+ for name in ("origin_state_hash", "replay_identity"):
220
+ if not isinstance(value[name], str) or _SHA256.fullmatch(value[name]) is None:
221
+ raise OfficialArenaError(f"atomic request {name} is invalid")
222
+ arms = value["arms"]
223
+ if isinstance(arms, (str, bytes)) or not isinstance(arms, Sequence) or len(arms) != 2:
224
+ raise OfficialArenaError("atomic request requires two arms")
225
+ roles: set[str] = set()
226
+ arm_ids: set[str] = set()
227
+ for arm in arms:
228
+ if (
229
+ not isinstance(arm, Mapping)
230
+ or set(arm) != {"role", "arm_id", "payload"}
231
+ or arm["role"] not in {"baseline", "treatment"}
232
+ or not isinstance(arm["arm_id"], str)
233
+ or not isinstance(arm["payload"], Mapping)
234
+ ):
235
+ raise OfficialArenaError("atomic request arm schema is invalid")
236
+ roles.add(arm["role"])
237
+ arm_ids.add(arm["arm_id"])
238
+ if roles != {"baseline", "treatment"} or len(arm_ids) != 2:
239
+ raise OfficialArenaError("atomic request arms must be distinct baseline and treatment")
240
+ return value
241
+
242
+
243
+ def _validate_dependency_binding(
244
+ *,
245
+ request: Mapping[str, Any],
246
+ parameters: Mapping[str, Any],
247
+ replay_record: Mapping[str, Any],
248
+ ) -> None:
249
+ provider_dependencies = parameters["provider_config"].get("locked_dependency_hashes")
250
+ protected = replay_record.get("protected")
251
+ protected_dependencies = (
252
+ protected.get("locked_dependency_hashes") if isinstance(protected, Mapping) else None
253
+ )
254
+ if (
255
+ not isinstance(provider_dependencies, Mapping)
256
+ or not provider_dependencies
257
+ or not isinstance(protected_dependencies, Mapping)
258
+ or not protected_dependencies
259
+ ):
260
+ raise OfficialArenaError(
261
+ "provider and protected replay must bind non-empty dependency hashes"
262
+ )
263
+ if dict(provider_dependencies) != dict(protected_dependencies):
264
+ raise OfficialArenaError("provider and protected replay dependency locks differ")
265
+ request_dependencies = request["locked_dependency_hashes"]
266
+ for name, digest in provider_dependencies.items():
267
+ if (
268
+ not isinstance(name, str)
269
+ or not name
270
+ or not isinstance(digest, str)
271
+ or _SHA256.fullmatch(digest) is None
272
+ or request_dependencies.get(name) != digest
273
+ ):
274
+ raise OfficialArenaError(
275
+ "provider dependency locks are not a matching subset of the arm locks"
276
+ )
277
+
278
+
279
+ def _validate_shared_budget_usage(
280
+ arm_payload: Mapping[str, Any],
281
+ usage: Mapping[str, int | float],
282
+ ) -> None:
283
+ """Reject any completed arm that escaped its materialized cumulative caps."""
284
+
285
+ state = materialized_state(arm_payload)
286
+ budget = state.get("budget")
287
+ if not isinstance(budget, Mapping):
288
+ raise OfficialArenaError("materialized arm has no budget for usage validation")
289
+ caps = {
290
+ "model_calls": "max_model_calls",
291
+ "retrieval_calls": "max_retrieval_calls",
292
+ "tool_calls": "max_tool_calls",
293
+ "output_tokens": "max_output_tokens",
294
+ "input_tokens": "max_context_tokens",
295
+ }
296
+ for usage_name, budget_name in caps.items():
297
+ cap = budget.get(budget_name)
298
+ if cap is None:
299
+ continue
300
+ if (
301
+ isinstance(cap, bool)
302
+ or not isinstance(cap, int)
303
+ or cap < 1
304
+ or float(usage[usage_name]) > cap
305
+ ):
306
+ raise OfficialArenaError(
307
+ "official arm exceeded materialized "
308
+ f"{budget_name}: actual={usage[usage_name]} cap={cap}"
309
+ )
310
+
311
+
312
+ def _intervention_failure(arm_payload: Mapping[str, Any]) -> Mapping[str, Any] | None:
313
+ execution = arm_payload.get("intervention_execution")
314
+ if not isinstance(execution, Mapping):
315
+ raise OfficialArenaError("intervention_execution is missing")
316
+ status = execution.get("status")
317
+ failure = execution.get("failure")
318
+ if status == "failed":
319
+ required = {"scope", "category", "exception_type", "message", "monitor_run_id"}
320
+ if (
321
+ not isinstance(failure, Mapping)
322
+ or not required <= set(failure)
323
+ or failure.get("scope") != "algorithm"
324
+ or any(not isinstance(failure.get(name), str) for name in required)
325
+ ):
326
+ raise OfficialArenaError("failed intervention has no typed algorithm failure")
327
+ return dict(failure)
328
+ if failure is not None:
329
+ raise OfficialArenaError("successful intervention cannot carry a failure receipt")
330
+ return None
331
+
332
+
333
+ def _tool_call_names(row: Mapping[str, Any]) -> tuple[str, ...]:
334
+ raw = row.get("tool_calls")
335
+ names: list[str] = []
336
+ if isinstance(raw, Sequence) and not isinstance(raw, (str, bytes)):
337
+ for call in raw:
338
+ if not isinstance(call, Mapping):
339
+ continue
340
+ function = call.get("function")
341
+ name = function.get("name") if isinstance(function, Mapping) else call.get("name")
342
+ if isinstance(name, str) and name.strip():
343
+ names.append(name.strip())
344
+ sender = str(row.get("sender", "")).lower()
345
+ recipient = str(row.get("recipient", "")).lower()
346
+ content = row.get("content")
347
+ if (
348
+ sender.endswith("agent")
349
+ and recipient.endswith("execution_environment")
350
+ and isinstance(content, str)
351
+ ):
352
+ match = re.match(r"\s*([A-Za-z_][A-Za-z0-9_.-]*)\s*\(", content)
353
+ if match is not None:
354
+ names.append(match.group(1))
355
+ return tuple(names)
356
+
357
+
358
+ def _potentially_irreversible(name: str) -> bool:
359
+ """Conservatively separate read-only retrieval from environment mutation."""
360
+
361
+ normalized = name.casefold().replace("-", "_").replace(".", "_")
362
+ read_only_prefixes = (
363
+ "get_",
364
+ "list_",
365
+ "search_",
366
+ "retrieve_",
367
+ "find_",
368
+ "lookup_",
369
+ "read_",
370
+ "check_",
371
+ "inspect_",
372
+ "view_",
373
+ "calculate_",
374
+ "compute_",
375
+ )
376
+ return not normalized.startswith(read_only_prefixes)
377
+
378
+
379
+ def _is_environment_result(row: Mapping[str, Any]) -> bool:
380
+ role = str(row.get("role", "")).lower()
381
+ sender = str(row.get("sender", "")).lower()
382
+ return role.endswith("tool") or sender.endswith("execution_environment")
383
+
384
+
385
+ def _result_succeeded(row: Mapping[str, Any]) -> bool:
386
+ content = row.get("content", row)
387
+ text = json.dumps(content, ensure_ascii=False, sort_keys=True, default=str).casefold()
388
+ failure_markers = (
389
+ '"success": false',
390
+ '"ok": false',
391
+ "traceback",
392
+ "exception",
393
+ "tool error",
394
+ "execution failed",
395
+ )
396
+ return not any(marker in text for marker in failure_markers)
397
+
398
+
399
+ def _safe_trace_measurement(trace: Mapping[str, Any]) -> Mapping[str, Any]:
400
+ """Return auditable trajectory signals without exporting protected traces."""
401
+
402
+ provider = str(trace.get("provider", "unknown"))
403
+ raw_messages = trace.get("messages", trace.get("conversation", ()))
404
+ if provider == "toolsandbox":
405
+ ending = trace.get("ending_context")
406
+ databases = ending.get("_dbs") if isinstance(ending, Mapping) else None
407
+ raw_messages = databases.get("SANDBOX", ()) if isinstance(databases, Mapping) else ()
408
+ messages = (
409
+ tuple(row for row in raw_messages if isinstance(row, Mapping))
410
+ if isinstance(raw_messages, Sequence) and not isinstance(raw_messages, (str, bytes))
411
+ else ()
412
+ )
413
+
414
+ def is_assistant(row: Mapping[str, Any]) -> bool:
415
+ role = str(row.get("role", row.get("sender", ""))).lower()
416
+ return role.endswith("assistant") or role.endswith("agent")
417
+
418
+ assistant = tuple(row for row in messages if is_assistant(row))
419
+ first = assistant[0] if assistant else None
420
+ content = first.get("content") if isinstance(first, Mapping) else None
421
+ tool_calls = first.get("tool_calls") if isinstance(first, Mapping) else None
422
+ first_has_content = isinstance(content, str) and bool(content.strip())
423
+ first_tool_count = (
424
+ len(tool_calls)
425
+ if isinstance(tool_calls, Sequence) and not isinstance(tool_calls, (str, bytes))
426
+ else 0
427
+ )
428
+ controls = trace.get("generation_controls")
429
+ hard_stops = controls.get("hard_stops", 0) if isinstance(controls, Mapping) else 0
430
+ termination = trace.get("termination_reason")
431
+ irreversible_index: int | None = None
432
+ irreversible_name: str | None = None
433
+ for index, row in enumerate(messages):
434
+ names = _tool_call_names(row)
435
+ selected = next((name for name in names if _potentially_irreversible(name)), None)
436
+ if selected is not None:
437
+ irreversible_index = index
438
+ irreversible_name = selected
439
+ break
440
+ irreversible_succeeded = False
441
+ if irreversible_index is not None:
442
+ result_row = next(
443
+ (row for row in messages[irreversible_index + 1 :] if _is_environment_result(row)),
444
+ None,
445
+ )
446
+ irreversible_succeeded = result_row is not None and _result_succeeded(result_row)
447
+ return {
448
+ "measurement_protocol": "agentinputlab.safe-trajectory-structure.v2",
449
+ "irreversible_action_rule": "conservative-read-prefix-v1",
450
+ "provider": provider,
451
+ "message_count": len(messages),
452
+ "assistant_turn_count": len(assistant),
453
+ "first_action_present": bool(first_has_content or first_tool_count),
454
+ "first_action_tool_calls": first_tool_count,
455
+ "first_irreversible_action_present": irreversible_index is not None,
456
+ "first_irreversible_action_succeeded": irreversible_succeeded,
457
+ "first_irreversible_action_message_index": irreversible_index,
458
+ "first_irreversible_action_name_hash": (
459
+ content_hash({"tool_name": irreversible_name})
460
+ if irreversible_name is not None
461
+ else None
462
+ ),
463
+ "structurally_completed": bool(assistant) and int(hard_stops or 0) == 0,
464
+ "hard_stops": int(hard_stops or 0),
465
+ "termination_reason": str(termination) if termination is not None else "not_exposed",
466
+ "protected_trace_exported": False,
467
+ }
468
+
469
+
470
+ def run(value: Any) -> Mapping[str, Any]:
471
+ if not isinstance(value, Mapping) or set(value) != _ROOT_FIELDS:
472
+ raise OfficialArenaError("official arena request fields are invalid")
473
+ if value["schema_version"] != 1 or value["protocol"] != REQUEST_PROTOCOL:
474
+ raise OfficialArenaError("unsupported atomic process request protocol")
475
+ base = {
476
+ "schema_version": value["schema_version"],
477
+ "protocol": value["protocol"],
478
+ "atomic_request": value["atomic_request"],
479
+ "worker_parameters": value["worker_parameters"],
480
+ }
481
+ if value["request_hash"] != content_hash(base):
482
+ raise OfficialArenaError("atomic process request hash differs")
483
+ parameters = _parameters(value["worker_parameters"])
484
+ request = _atomic_request(value["atomic_request"])
485
+ records = _inventory(parameters)
486
+ inventory_identity = records["__inventory__"]
487
+ if (
488
+ inventory_identity["benchmark_id"] != request["benchmark_id"]
489
+ or inventory_identity["source_revision"] != request["source_revision"]
490
+ ):
491
+ raise OfficialArenaError("protected inventory identity differs from atomic request")
492
+ try:
493
+ replay_record = records[request["checkpoint_id"]]
494
+ except KeyError as exc:
495
+ raise OfficialArenaError("checkpoint is absent from protected replay inventory") from exc
496
+ if (
497
+ replay_record["origin_state_hash"] != request["origin_state_hash"]
498
+ or replay_record["replay_identity"] != request["replay_identity"]
499
+ ):
500
+ raise OfficialArenaError("protected replay identity differs from atomic request")
501
+ _validate_dependency_binding(
502
+ request=request,
503
+ parameters=parameters,
504
+ replay_record=replay_record,
505
+ )
506
+
507
+ provider = _provider(parameters["provider_entrypoint"])
508
+ if (
509
+ provider.benchmark_id != request["benchmark_id"]
510
+ or provider.source_revision != request["source_revision"]
511
+ or provider.scorer_id != parameters["scorer_id"]
512
+ or provider.scorer_revision != parameters["scorer_revision"]
513
+ ):
514
+ raise OfficialArenaError("official provider identity differs from worker lock")
515
+ blockers = provider.doctor(parameters["provider_config"])
516
+ if blockers:
517
+ raise OfficialArenaError("official provider preflight failed: " + "; ".join(blockers))
518
+
519
+ arm_results: list[dict[str, Any]] = []
520
+ arm_receipts: list[dict[str, Any]] = []
521
+ runtime_ids: set[str] = set()
522
+ with tempfile.TemporaryDirectory(prefix="agentinputlab-official-arena-") as temporary:
523
+ root = Path(temporary)
524
+ for arm in request["arms"]:
525
+ role = arm["role"]
526
+ work_dir = root / role
527
+ work_dir.mkdir()
528
+ result = provider.run_arm(
529
+ parameters["provider_config"],
530
+ replay_record=replay_record,
531
+ arm_payload=arm["payload"],
532
+ seed=request["seed"],
533
+ role=role,
534
+ work_dir=work_dir,
535
+ )
536
+ if result.runtime_instance_id in runtime_ids:
537
+ raise OfficialArenaError(
538
+ "official provider reused a runtime instance across paired arms"
539
+ )
540
+ runtime_ids.add(result.runtime_instance_id)
541
+ usage = merge_usage(intervention_usage(arm["payload"]), result.usage)
542
+ _validate_shared_budget_usage(arm["payload"], usage)
543
+ intervention_failure = _intervention_failure(arm["payload"])
544
+ arm_results.append(
545
+ {
546
+ "role": role,
547
+ "arm_id": arm["arm_id"],
548
+ "metrics": dict(result.metrics),
549
+ "trace_hash": content_hash(result.trace),
550
+ "trace_measurement": _safe_trace_measurement(result.trace),
551
+ "usage": {name: usage[name] for name in _USAGE_FIELDS},
552
+ "intervention_failure": intervention_failure,
553
+ }
554
+ )
555
+ arm_receipts.append(
556
+ {
557
+ "role": role,
558
+ "arm_id": arm["arm_id"],
559
+ "origin_state_hash": request["origin_state_hash"],
560
+ "replay_identity": request["replay_identity"],
561
+ "seed": request["seed"],
562
+ "locked_dependency_hashes": request["locked_dependency_hashes"],
563
+ "runtime_instance_id": result.runtime_instance_id,
564
+ "completed": True,
565
+ }
566
+ )
567
+
568
+ receipt = {
569
+ "benchmark_id": request["benchmark_id"],
570
+ "checkpoint_id": request["checkpoint_id"],
571
+ "source_revision": request["source_revision"],
572
+ "bridge_id": parameters["bridge_id"],
573
+ "bridge_revision": parameters["bridge_revision"],
574
+ "scorer_id": parameters["scorer_id"],
575
+ "scorer_revision": parameters["scorer_revision"],
576
+ "origin_state_hash": request["origin_state_hash"],
577
+ "replay_identity": request["replay_identity"],
578
+ "seed": request["seed"],
579
+ "locked_dependency_hashes": request["locked_dependency_hashes"],
580
+ "arms": arm_receipts,
581
+ }
582
+ return {
583
+ "schema_version": 1,
584
+ "protocol": RESPONSE_PROTOCOL,
585
+ "request_hash": value["request_hash"],
586
+ "receipt": receipt,
587
+ "arms": arm_results,
588
+ }
589
+
590
+
591
+ def main() -> int:
592
+ parser = argparse.ArgumentParser(description="Run one official atomic arena pair")
593
+ parser.add_argument("--doctor", action="store_true")
594
+ args = parser.parse_args()
595
+ if args.doctor:
596
+ print(json.dumps({"protocol": WORKER_PROTOCOL, "ready": True}, sort_keys=True))
597
+ return 0
598
+ try:
599
+ request = json.load(sys.stdin)
600
+ response = run(request)
601
+ except Exception as exc:
602
+ print(
603
+ json.dumps(
604
+ {
605
+ "error": type(exc).__name__,
606
+ "message": str(exc),
607
+ },
608
+ ensure_ascii=False,
609
+ sort_keys=True,
610
+ ),
611
+ file=sys.stderr,
612
+ )
613
+ return 2
614
+ print(json.dumps(response, ensure_ascii=False, sort_keys=True))
615
+ return 0
616
+
617
+
618
+ if __name__ == "__main__":
619
+ raise SystemExit(main())