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,540 @@
1
+ """Pinned external-transfer bridge for Agents' Last Exam (ALE).
2
+
3
+ ALE owns sandbox provisioning, agent deployment, hidden-reference staging, and
4
+ grading. AgentInputLab exposes only optimizer-visible task checkpoints and a
5
+ typed result boundary. It does not import task graders or claim atomic paired
6
+ replay. Official runs continue to execute through ALE's own CLI.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import math
13
+ import re
14
+ import subprocess
15
+ from collections.abc import Callable, Iterable, Mapping
16
+ from dataclasses import dataclass, field
17
+ from pathlib import Path
18
+ from types import MappingProxyType
19
+ from typing import Any, Protocol, runtime_checkable
20
+
21
+ from agentinputlab.contracts.enums import SemanticFamily
22
+ from agentinputlab.contracts.errors import ExternalDependencyError, ValidationError
23
+ from agentinputlab.contracts.serialization import freeze_mapping
24
+ from agentinputlab.contracts.state import ContextBlock, Message
25
+
26
+ from .base import BenchmarkExample, opaque_checkpoint_state_id
27
+
28
+ ALE_BENCHMARK_ID = "ale.external_transfer"
29
+ ALE_PUBLIC_SPLIT = "public"
30
+ ALE_OFFICIAL_REPOSITORY = "https://github.com/rdi-berkeley/agents-last-exam"
31
+ ALE_OFFICIAL_SOURCE_REVISION = "1e615e456de7cef57706680613cb80ee13c7fc76"
32
+ ALE_SOFTWARE_LICENSE = "Apache-2.0"
33
+ ALE_DATA_LICENSE = "CC-BY-4.0"
34
+ ALE_SOURCE_HASHES = MappingProxyType(
35
+ {
36
+ "LICENSE": "1b69f3cee8b40f3a1b7b4db3341c8b739bab905c9575f89e557e04d7c31a169f",
37
+ "LICENSE-DATA": "bd01b9a2a7413566f3189eb89b8f0a5af19bd9075638260d1b0b56ad48fd643c",
38
+ "ale_run/__main__.py": ("945f001509af2bd72eda35249c4a533de54507dcb6006a44e2ab4c00a063df68"),
39
+ "ale_run/orchestration/runner.py": (
40
+ "25ae61390701a5cd5accefe217c9695165877b138558d278a98102eacc7e67e3"
41
+ ),
42
+ "pyproject.toml": "7fe312e5a4a7ba8cc2084827dea3ba0d76cdcfefb29c1168d3c612607cc5b177",
43
+ }
44
+ )
45
+ ALE_PAIRING_MODE = "external_independent_runs"
46
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
47
+ _CALLER_ASSERTED = "caller_asserted"
48
+ _EXTERNAL_BRIDGE = "external_transfer"
49
+ _FAMILIES = (
50
+ SemanticFamily.REFORMULATE,
51
+ SemanticFamily.DECOMPOSE,
52
+ SemanticFamily.ACQUIRE,
53
+ SemanticFamily.CLARIFY,
54
+ SemanticFamily.CURATE,
55
+ )
56
+
57
+
58
+ @dataclass(frozen=True, slots=True)
59
+ class ALEFamilyEligibility:
60
+ """Family support derived only from the visible pre-run checkpoint."""
61
+
62
+ checkpoint_id: str
63
+ eligibility: Mapping[str, bool]
64
+ reasons: Mapping[str, str]
65
+ provenance_status: str = _CALLER_ASSERTED
66
+ support_status: str = "external_transfer_candidate"
67
+
68
+ def __post_init__(self) -> None:
69
+ expected = {family.value for family in _FAMILIES}
70
+ if set(self.eligibility) != expected or set(self.reasons) != expected:
71
+ raise ValidationError("ALE family eligibility must cover all five family labels")
72
+ if any(not isinstance(value, bool) for value in self.eligibility.values()):
73
+ raise ValidationError("ALE family eligibility values must be boolean")
74
+ if any(not isinstance(value, str) or not value.strip() for value in self.reasons.values()):
75
+ raise ValidationError("ALE family eligibility reasons must be non-empty")
76
+ if self.eligibility[SemanticFamily.CLARIFY.value]:
77
+ raise ValidationError("ALE has no standardized clarification-user oracle")
78
+ object.__setattr__(self, "eligibility", freeze_mapping(self.eligibility))
79
+ object.__setattr__(self, "reasons", freeze_mapping(self.reasons))
80
+
81
+ @property
82
+ def eligible_families(self) -> tuple[SemanticFamily, ...]:
83
+ return tuple(family for family in _FAMILIES if self.eligibility[family.value])
84
+
85
+
86
+ @dataclass(frozen=True, slots=True)
87
+ class ALECheckpoint:
88
+ """Optimizer-visible ALE task state bound to opaque official-run identities."""
89
+
90
+ checkpoint_id: str
91
+ task_id: str
92
+ domain: str
93
+ query: str
94
+ instruction: str
95
+ visible_messages: tuple[Message, ...]
96
+ visible_tool_names: tuple[str, ...]
97
+ visible_read_tool_names: tuple[str, ...]
98
+ run_handle: str = field(repr=False)
99
+ task_source_sha256: str = field(repr=False)
100
+ environment_snapshot_sha256: str = field(repr=False)
101
+ grader_sha256: str = field(repr=False)
102
+ agent_harness_sha256: str = field(repr=False)
103
+ provider_identity_sha256: str = field(repr=False)
104
+ image_identity_sha256: str = field(repr=False)
105
+ visible_context: tuple[ContextBlock, ...] = ()
106
+ source_revision: str = ALE_OFFICIAL_SOURCE_REVISION
107
+ split: str = ALE_PUBLIC_SPLIT
108
+
109
+ def __post_init__(self) -> None:
110
+ for label in (
111
+ "checkpoint_id",
112
+ "task_id",
113
+ "domain",
114
+ "query",
115
+ "instruction",
116
+ "run_handle",
117
+ ):
118
+ value = getattr(self, label)
119
+ if not isinstance(value, str) or not value.strip() or value != value.strip():
120
+ raise ValidationError(f"ALE {label} must be trimmed non-empty text")
121
+ if self.source_revision != ALE_OFFICIAL_SOURCE_REVISION:
122
+ raise ValidationError("ALE checkpoint source revision differs from the audit lock")
123
+ if self.split != ALE_PUBLIC_SPLIT:
124
+ raise ValidationError("ALE bridge currently accepts only the public task split")
125
+ for label in (
126
+ "task_source_sha256",
127
+ "environment_snapshot_sha256",
128
+ "grader_sha256",
129
+ "agent_harness_sha256",
130
+ "provider_identity_sha256",
131
+ "image_identity_sha256",
132
+ ):
133
+ if _SHA256.fullmatch(getattr(self, label)) is None:
134
+ raise ValidationError(f"ALE {label} must be a lowercase SHA-256")
135
+ messages = tuple(self.visible_messages)
136
+ context = tuple(self.visible_context)
137
+ tools = _validated_names(self.visible_tool_names, label="visible tool names")
138
+ read_tools = _validated_names(
139
+ self.visible_read_tool_names,
140
+ label="visible read-tool names",
141
+ allow_empty=True,
142
+ )
143
+ if not messages or not all(isinstance(item, Message) for item in messages):
144
+ raise ValidationError("ALE checkpoint requires captured visible messages")
145
+ if not all(isinstance(item, ContextBlock) for item in context):
146
+ raise ValidationError("ALE visible_context must contain ContextBlock instances")
147
+ user_messages = [message for message in messages if message.role == "user"]
148
+ if not user_messages or user_messages[-1].content != self.query:
149
+ raise ValidationError("ALE query must equal the latest visible user message")
150
+ if not set(read_tools) <= set(tools):
151
+ raise ValidationError("ALE visible read tools must be a subset of visible tools")
152
+ object.__setattr__(self, "visible_messages", messages)
153
+ object.__setattr__(self, "visible_context", context)
154
+ object.__setattr__(self, "visible_tool_names", tools)
155
+ object.__setattr__(self, "visible_read_tool_names", read_tools)
156
+
157
+ @property
158
+ def family_eligibility(self) -> ALEFamilyEligibility:
159
+ acquire = bool(self.visible_read_tool_names)
160
+ curate = bool(self.visible_context) or len(self.visible_messages) >= 3
161
+ eligibility = {
162
+ SemanticFamily.REFORMULATE.value: True,
163
+ SemanticFamily.DECOMPOSE.value: True,
164
+ SemanticFamily.ACQUIRE.value: acquire,
165
+ SemanticFamily.CLARIFY.value: False,
166
+ SemanticFamily.CURATE.value: curate,
167
+ }
168
+ reasons = {
169
+ SemanticFamily.REFORMULATE.value: "the official task exposes a visible instruction",
170
+ SemanticFamily.DECOMPOSE.value: "the visible long-horizon task can be decomposed",
171
+ SemanticFamily.ACQUIRE.value: (
172
+ "the checkpoint exposes a caller-audited read-only tool"
173
+ if acquire
174
+ else "no caller-audited read-only tool is exposed"
175
+ ),
176
+ SemanticFamily.CLARIFY.value: (
177
+ "ALE does not provide a standardized clarification-user oracle"
178
+ ),
179
+ SemanticFamily.CURATE.value: (
180
+ "the checkpoint contains visible context or trajectory history"
181
+ if curate
182
+ else "initial prompt-only checkpoint has no visible context to curate"
183
+ ),
184
+ }
185
+ return ALEFamilyEligibility(self.checkpoint_id, eligibility, reasons)
186
+
187
+
188
+ @dataclass(frozen=True, slots=True)
189
+ class ALEEvaluationResult:
190
+ """Task-level outcome returned after the official hidden grader runs."""
191
+
192
+ task_score: float
193
+ cost_usd: float
194
+ wall_seconds: float
195
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
196
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_BRIDGE)
197
+ official_runtime_verified: bool = field(init=False, default=False)
198
+
199
+ def __post_init__(self) -> None:
200
+ values = {
201
+ "task_score": self.task_score,
202
+ "cost_usd": self.cost_usd,
203
+ "wall_seconds": self.wall_seconds,
204
+ }
205
+ normalized: dict[str, float] = {}
206
+ for label, value in values.items():
207
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
208
+ raise ValidationError(f"ALE {label} must be numeric")
209
+ numeric = float(value)
210
+ if not math.isfinite(numeric):
211
+ raise ValidationError(f"ALE {label} must be finite")
212
+ normalized[label] = numeric
213
+ if not 0.0 <= normalized["task_score"] <= 1.0:
214
+ raise ValidationError("ALE task_score must be in [0, 1]")
215
+ if normalized["cost_usd"] < 0.0 or normalized["wall_seconds"] < 0.0:
216
+ raise ValidationError("ALE cost and wall time must be non-negative")
217
+ for label, value in normalized.items():
218
+ object.__setattr__(self, label, value)
219
+
220
+ @property
221
+ def metrics(self) -> Mapping[str, float]:
222
+ return MappingProxyType(
223
+ {
224
+ "task_score": self.task_score,
225
+ "cost_usd": self.cost_usd,
226
+ "wall_seconds": self.wall_seconds,
227
+ }
228
+ )
229
+
230
+
231
+ @runtime_checkable
232
+ class ALEEvaluationBridge(Protocol):
233
+ ale_bridge_contract: str
234
+ benchmark_id: str
235
+ source_revision: str
236
+ bridge_id: str
237
+ bridge_revision: str
238
+ supports_fresh_environment: bool
239
+ supports_hidden_reference_staging: bool
240
+ provenance_status: str
241
+ evaluation_scope: str
242
+ official_runtime_verified: bool
243
+
244
+ def evaluate(
245
+ self,
246
+ evaluator_payload: Mapping[str, Any],
247
+ checkpoint: ALECheckpoint,
248
+ prediction: Any,
249
+ ) -> ALEEvaluationResult: ...
250
+
251
+
252
+ @dataclass(frozen=True, slots=True)
253
+ class CallerAssertedALEEvaluationBridge:
254
+ """Explicit wrapper for an operator-owned ALE orchestration callback."""
255
+
256
+ bridge_id: str
257
+ bridge_revision: str
258
+ supports_fresh_environment: bool
259
+ supports_hidden_reference_staging: bool
260
+ callback: Callable[[Mapping[str, Any], ALECheckpoint, Any], ALEEvaluationResult] = field(
261
+ repr=False
262
+ )
263
+ ale_bridge_contract: str = field(init=False, default="ale_evaluation_bridge_v1")
264
+ benchmark_id: str = field(init=False, default=ALE_BENCHMARK_ID)
265
+ source_revision: str = field(init=False, default=ALE_OFFICIAL_SOURCE_REVISION)
266
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
267
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_BRIDGE)
268
+ official_runtime_verified: bool = field(init=False, default=False)
269
+
270
+ def __post_init__(self) -> None:
271
+ if not self.bridge_id.strip() or _SHA256.fullmatch(self.bridge_revision) is None:
272
+ raise ValidationError("ALE bridge requires an ID and SHA-256 revision")
273
+ if not callable(self.callback):
274
+ raise TypeError("ALE bridge callback must be callable")
275
+ if not self.supports_fresh_environment or not self.supports_hidden_reference_staging:
276
+ raise ValidationError(
277
+ "ALE bridge must preserve fresh environments and post-run hidden-reference staging"
278
+ )
279
+
280
+ def evaluate(
281
+ self,
282
+ evaluator_payload: Mapping[str, Any],
283
+ checkpoint: ALECheckpoint,
284
+ prediction: Any,
285
+ ) -> ALEEvaluationResult:
286
+ result = self.callback(evaluator_payload, checkpoint, prediction)
287
+ if not isinstance(result, ALEEvaluationResult):
288
+ raise ValidationError("ALE callback must return ALEEvaluationResult")
289
+ return result
290
+
291
+
292
+ class ALEExternalTransferAdapter:
293
+ """Evaluator-blind adapter for official ALE independent-run checkpoints."""
294
+
295
+ benchmark_id = ALE_BENCHMARK_ID
296
+ adapter_metric_names = ("task_score", "cost_usd", "wall_seconds")
297
+ pairing_mode = ALE_PAIRING_MODE
298
+ split = ALE_PUBLIC_SPLIT
299
+
300
+ def __init__(
301
+ self,
302
+ *,
303
+ checkpoints: Iterable[ALECheckpoint],
304
+ evaluation_bridge: ALEEvaluationBridge,
305
+ ) -> None:
306
+ if not isinstance(evaluation_bridge, ALEEvaluationBridge):
307
+ raise TypeError("evaluation_bridge must implement ALEEvaluationBridge")
308
+ _validate_bridge(evaluation_bridge)
309
+ normalized = tuple(checkpoints)
310
+ if not normalized or not all(isinstance(item, ALECheckpoint) for item in normalized):
311
+ raise ValidationError("ALE requires at least one typed checkpoint")
312
+ ids = [item.checkpoint_id for item in normalized]
313
+ task_units = [
314
+ (
315
+ item.task_id,
316
+ item.environment_snapshot_sha256,
317
+ item.agent_harness_sha256,
318
+ item.provider_identity_sha256,
319
+ item.image_identity_sha256,
320
+ )
321
+ for item in normalized
322
+ ]
323
+ if len(ids) != len(set(ids)) or len(task_units) != len(set(task_units)):
324
+ raise ValidationError("ALE checkpoints and protected run units must be unique")
325
+ examples: list[BenchmarkExample] = []
326
+ checkpoints_by_id: dict[str, ALECheckpoint] = {}
327
+ for checkpoint in sorted(normalized, key=lambda item: item.checkpoint_id):
328
+ support = checkpoint.family_eligibility
329
+ evaluator_payload = freeze_mapping(
330
+ {
331
+ "agent_harness_sha256": checkpoint.agent_harness_sha256,
332
+ "environment_snapshot_sha256": checkpoint.environment_snapshot_sha256,
333
+ "grader_sha256": checkpoint.grader_sha256,
334
+ "image_identity_sha256": checkpoint.image_identity_sha256,
335
+ "provider_identity_sha256": checkpoint.provider_identity_sha256,
336
+ "run_handle": checkpoint.run_handle,
337
+ "source_revision": checkpoint.source_revision,
338
+ "source_task_id": checkpoint.task_id,
339
+ "task_source_sha256": checkpoint.task_source_sha256,
340
+ }
341
+ )
342
+ example = BenchmarkExample(
343
+ example_id=checkpoint.checkpoint_id,
344
+ query=checkpoint.query,
345
+ instruction=checkpoint.instruction,
346
+ visible_context=checkpoint.visible_context,
347
+ visible_messages=checkpoint.visible_messages,
348
+ visible_tool_names=checkpoint.visible_tool_names,
349
+ visible_metadata=freeze_mapping(
350
+ {
351
+ "benchmark_cell": self.benchmark_id,
352
+ "domain": checkpoint.domain,
353
+ "family_eligibility": dict(support.eligibility),
354
+ "family_eligibility_reasons": dict(support.reasons),
355
+ "family_support_status": support.support_status,
356
+ "source_split": checkpoint.split,
357
+ }
358
+ ),
359
+ evaluator_gold=evaluator_payload,
360
+ optimizer_visible_id=opaque_checkpoint_state_id(
361
+ self.benchmark_id,
362
+ checkpoint.checkpoint_id,
363
+ checkpoint.environment_snapshot_sha256,
364
+ ),
365
+ )
366
+ examples.append(example)
367
+ checkpoints_by_id[checkpoint.checkpoint_id] = checkpoint
368
+ self._examples = tuple(examples)
369
+ self._examples_by_id = {example.example_id: example for example in examples}
370
+ self._checkpoints = MappingProxyType(checkpoints_by_id)
371
+ self._evaluation_bridge = evaluation_bridge
372
+
373
+ @property
374
+ def available_splits(self) -> tuple[str, ...]:
375
+ return (self.split,)
376
+
377
+ def examples(self, split: str) -> tuple[BenchmarkExample, ...]:
378
+ if split != self.split:
379
+ raise ValidationError(f"ALE adapter exposes {self.split!r}, not {split!r}")
380
+ return self._examples
381
+
382
+ def family_eligibility(self, checkpoint_id: str) -> ALEFamilyEligibility:
383
+ return self._checkpoint(checkpoint_id).family_eligibility
384
+
385
+ def eligible_families(self, checkpoint_id: str) -> tuple[SemanticFamily, ...]:
386
+ return self.family_eligibility(checkpoint_id).eligible_families
387
+
388
+ def supports_full_block(self, checkpoint_id: str) -> bool:
389
+ self._checkpoint(checkpoint_id)
390
+ return False
391
+
392
+ def score(self, example: BenchmarkExample, prediction: Any) -> Mapping[str, float]:
393
+ if self._examples_by_id.get(example.example_id) is not example:
394
+ raise ValidationError("benchmark example does not belong to this ALE adapter")
395
+ return self._evaluation_bridge.evaluate(
396
+ example.evaluator_gold,
397
+ self._checkpoints[example.example_id],
398
+ prediction,
399
+ ).metrics
400
+
401
+ @property
402
+ def source_provenance(self) -> Mapping[str, Any]:
403
+ return freeze_mapping(
404
+ {
405
+ "benchmark_id": self.benchmark_id,
406
+ "data_license": ALE_DATA_LICENSE,
407
+ "repository_url": ALE_OFFICIAL_REPOSITORY,
408
+ "software_license": ALE_SOFTWARE_LICENSE,
409
+ "source_revision": ALE_OFFICIAL_SOURCE_REVISION,
410
+ }
411
+ )
412
+
413
+ def _checkpoint(self, checkpoint_id: str) -> ALECheckpoint:
414
+ try:
415
+ return self._checkpoints[checkpoint_id]
416
+ except KeyError as exc:
417
+ raise ValidationError(f"unknown ALE checkpoint {checkpoint_id!r}") from exc
418
+
419
+
420
+ def build_ale_official_command(
421
+ *,
422
+ checkout: str | Path,
423
+ experiment_config: str | Path,
424
+ dry_run: bool = False,
425
+ uv_executable: str = "uv",
426
+ ) -> tuple[str, ...]:
427
+ """Build ALE's native command after verifying the exact upstream checkout."""
428
+
429
+ validate_ale_checkout(checkout)
430
+ config = Path(experiment_config).expanduser().resolve()
431
+ if not config.is_file() or config.is_symlink():
432
+ raise ExternalDependencyError("ALE experiment config must be a regular file")
433
+ command = (
434
+ uv_executable,
435
+ "run",
436
+ "python",
437
+ "-m",
438
+ "ale_run",
439
+ "run",
440
+ str(config),
441
+ )
442
+ if dry_run:
443
+ return (*command, "--dry-run")
444
+ return command
445
+
446
+
447
+ def validate_ale_checkout(checkout: str | Path) -> Path:
448
+ """Verify the audited ALE commit and critical orchestration files."""
449
+
450
+ source = Path(checkout).expanduser().resolve()
451
+ if not source.is_dir() or source.is_symlink():
452
+ raise ExternalDependencyError("ALE checkout must be a regular directory")
453
+ for relative, expected_hash in ALE_SOURCE_HASHES.items():
454
+ path = source / relative
455
+ if not path.is_file() or path.is_symlink() or _sha256_file(path) != expected_hash:
456
+ raise ExternalDependencyError(f"ALE pinned source hash changed: {relative}")
457
+ try:
458
+ head = subprocess.run(
459
+ ("git", "-C", str(source), "rev-parse", "HEAD"),
460
+ capture_output=True,
461
+ text=True,
462
+ timeout=30,
463
+ check=True,
464
+ ).stdout.strip()
465
+ status = subprocess.run(
466
+ ("git", "-C", str(source), "status", "--porcelain"),
467
+ capture_output=True,
468
+ text=True,
469
+ timeout=30,
470
+ check=True,
471
+ ).stdout.strip()
472
+ except (OSError, subprocess.CalledProcessError, subprocess.TimeoutExpired) as exc:
473
+ raise ExternalDependencyError("ALE Git checkout verification failed") from exc
474
+ if head != ALE_OFFICIAL_SOURCE_REVISION:
475
+ raise ExternalDependencyError("ALE checkout is not at the pinned commit")
476
+ if status:
477
+ raise ExternalDependencyError("ALE pinned checkout must be clean")
478
+ return source
479
+
480
+
481
+ def _validate_bridge(bridge: ALEEvaluationBridge) -> None:
482
+ if (
483
+ bridge.ale_bridge_contract != "ale_evaluation_bridge_v1"
484
+ or bridge.benchmark_id != ALE_BENCHMARK_ID
485
+ or bridge.source_revision != ALE_OFFICIAL_SOURCE_REVISION
486
+ ):
487
+ raise ValidationError("ALE evaluation bridge identity mismatch")
488
+ if bridge.provenance_status != _CALLER_ASSERTED or bridge.evaluation_scope != _EXTERNAL_BRIDGE:
489
+ raise ValidationError("ALE evaluation bridge provenance mismatch")
490
+ if bridge.official_runtime_verified is not False:
491
+ raise ValidationError("caller-asserted ALE bridge cannot claim official verification")
492
+ if not bridge.supports_fresh_environment or not bridge.supports_hidden_reference_staging:
493
+ raise ValidationError("ALE bridge omits a required official runtime boundary")
494
+
495
+
496
+ def _validated_names(
497
+ values: tuple[str, ...],
498
+ *,
499
+ label: str,
500
+ allow_empty: bool = False,
501
+ ) -> tuple[str, ...]:
502
+ normalized = tuple(values)
503
+ if not allow_empty and not normalized:
504
+ raise ValidationError(f"ALE requires {label}")
505
+ if any(
506
+ not isinstance(value, str) or not value.strip() or value != value.strip()
507
+ for value in normalized
508
+ ):
509
+ raise ValidationError(f"ALE {label} must be trimmed non-empty strings")
510
+ if len(normalized) != len(set(normalized)):
511
+ raise ValidationError(f"ALE {label} must be unique")
512
+ return normalized
513
+
514
+
515
+ def _sha256_file(path: Path) -> str:
516
+ digest = hashlib.sha256()
517
+ with path.open("rb") as handle:
518
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
519
+ digest.update(chunk)
520
+ return digest.hexdigest()
521
+
522
+
523
+ __all__ = [
524
+ "ALE_BENCHMARK_ID",
525
+ "ALE_DATA_LICENSE",
526
+ "ALE_OFFICIAL_REPOSITORY",
527
+ "ALE_OFFICIAL_SOURCE_REVISION",
528
+ "ALE_PAIRING_MODE",
529
+ "ALE_PUBLIC_SPLIT",
530
+ "ALE_SOFTWARE_LICENSE",
531
+ "ALE_SOURCE_HASHES",
532
+ "ALECheckpoint",
533
+ "ALEEvaluationBridge",
534
+ "ALEEvaluationResult",
535
+ "ALEExternalTransferAdapter",
536
+ "ALEFamilyEligibility",
537
+ "CallerAssertedALEEvaluationBridge",
538
+ "build_ale_official_command",
539
+ "validate_ale_checkout",
540
+ ]