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,626 @@
1
+ """Fail-closed bridge for ToolSandbox common-support experiments.
2
+
3
+ ToolSandbox owns the scenario runtime and evaluator. AgentInputLab only
4
+ normalizes an externally captured, optimizer-visible checkpoint and a typed
5
+ result returned after the official milestone/minefield evaluator has run. It
6
+ does not reimplement ToolSandbox's state transition or matching logic.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import json
13
+ import math
14
+ import re
15
+ from collections.abc import Callable, Iterable, Mapping
16
+ from dataclasses import dataclass, field
17
+ from importlib import resources
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 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
+ BENCHMARK_ID = "toolsandbox.common_support"
29
+ OFFICIAL_REPOSITORY = "https://github.com/apple/ToolSandbox"
30
+ OFFICIAL_SOURCE_REVISION = "165848b9a78cead7ca7fe7c89c688b58e6501219"
31
+ OFFICIAL_BASE_SCENARIO_COUNT = 129
32
+ OFFICIAL_VARIANT_SCENARIO_COUNT = 1032
33
+ OFFICIAL_SCENARIO_MEMBERSHIP_ASSET = "toolsandbox_165848b_scenario_names.json"
34
+ OFFICIAL_SCENARIO_MEMBERSHIP_SHA256 = (
35
+ "4de99f83ae5972b4556308e793e57db3e34e0dbd8b3da60d4a30d4c484358673"
36
+ )
37
+
38
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
39
+ _CALLER_ASSERTED = "caller_asserted"
40
+ _EXTERNAL_OFFICIAL_SEMANTICS = "external_official_semantics"
41
+ _STRUCTURAL_CANDIDATE = "structural_candidate"
42
+ _EXPECTED_VARIANT_SUFFIXES = (
43
+ "",
44
+ "_3_distraction_tools",
45
+ "_10_distraction_tools",
46
+ "_all_tools",
47
+ "_3_distraction_tools_tool_description_scrambled",
48
+ "_3_distraction_tools_arg_type_scrambled",
49
+ "_3_distraction_tools_arg_description_scrambled",
50
+ "_3_distraction_tools_tool_name_scrambled",
51
+ )
52
+ _FAMILIES = (
53
+ SemanticFamily.REFORMULATE,
54
+ SemanticFamily.DECOMPOSE,
55
+ SemanticFamily.ACQUIRE,
56
+ SemanticFamily.CLARIFY,
57
+ SemanticFamily.CURATE,
58
+ )
59
+
60
+
61
+ def _load_official_scenario_membership(
62
+ *,
63
+ asset_name: str = OFFICIAL_SCENARIO_MEMBERSHIP_ASSET,
64
+ ) -> tuple[tuple[str, ...], tuple[str, ...], frozenset[str]]:
65
+ """Load and verify the scenario names extracted from the pinned source tree."""
66
+
67
+ try:
68
+ payload_bytes = (
69
+ resources.files("agentinputlab.benchmarks").joinpath("data", asset_name).read_bytes()
70
+ )
71
+ except OSError as exc:
72
+ raise RuntimeError("ToolSandbox scenario membership asset is unavailable") from exc
73
+ actual_sha256 = hashlib.sha256(payload_bytes).hexdigest()
74
+ if actual_sha256 != OFFICIAL_SCENARIO_MEMBERSHIP_SHA256:
75
+ raise RuntimeError("ToolSandbox scenario membership asset failed its SHA-256 lock")
76
+ try:
77
+ payload = json.loads(payload_bytes)
78
+ except (UnicodeDecodeError, json.JSONDecodeError) as exc:
79
+ raise RuntimeError("ToolSandbox scenario membership asset is not valid JSON") from exc
80
+ if not isinstance(payload, dict) or set(payload) != {
81
+ "base_names",
82
+ "source_revision",
83
+ "variant_suffixes",
84
+ }:
85
+ raise RuntimeError("ToolSandbox scenario membership asset has an invalid schema")
86
+ if payload["source_revision"] != OFFICIAL_SOURCE_REVISION:
87
+ raise RuntimeError("ToolSandbox scenario membership asset has the wrong source revision")
88
+
89
+ raw_base_names = payload["base_names"]
90
+ raw_suffixes = payload["variant_suffixes"]
91
+ if not isinstance(raw_base_names, list) or not all(
92
+ isinstance(name, str) and name and name == name.strip() for name in raw_base_names
93
+ ):
94
+ raise RuntimeError("ToolSandbox base scenario names must be trimmed strings")
95
+ if not isinstance(raw_suffixes, list) or not all(
96
+ isinstance(suffix, str) and suffix == suffix.strip() for suffix in raw_suffixes
97
+ ):
98
+ raise RuntimeError("ToolSandbox variant suffixes must be strings")
99
+
100
+ base_names = tuple(raw_base_names)
101
+ variant_suffixes = tuple(raw_suffixes)
102
+ if len(base_names) != OFFICIAL_BASE_SCENARIO_COUNT or len(set(base_names)) != len(base_names):
103
+ raise RuntimeError("ToolSandbox base scenario membership is not the audited 129-name set")
104
+ if variant_suffixes != _EXPECTED_VARIANT_SUFFIXES:
105
+ raise RuntimeError("ToolSandbox variant suffixes differ from the pinned generator")
106
+
107
+ variant_names = tuple(
108
+ f"{base_name}{suffix}" for base_name in base_names for suffix in variant_suffixes
109
+ )
110
+ variant_name_set = frozenset(variant_names)
111
+ if len(variant_names) != OFFICIAL_VARIANT_SCENARIO_COUNT or len(variant_name_set) != len(
112
+ variant_names
113
+ ):
114
+ raise RuntimeError(
115
+ "ToolSandbox generated scenario membership is not the audited 1032-name set"
116
+ )
117
+ return base_names, variant_suffixes, variant_name_set
118
+
119
+
120
+ (
121
+ _OFFICIAL_BASE_SCENARIO_NAMES,
122
+ _OFFICIAL_VARIANT_SUFFIXES,
123
+ _OFFICIAL_SCENARIO_NAMES,
124
+ ) = _load_official_scenario_membership()
125
+
126
+
127
+ @dataclass(frozen=True, slots=True)
128
+ class ToolSandboxScenarioInventory:
129
+ """Audited identity of the official repository's generated scenario set."""
130
+
131
+ source_revision: str = OFFICIAL_SOURCE_REVISION
132
+ base_scenario_count: int = OFFICIAL_BASE_SCENARIO_COUNT
133
+ variant_scenario_count: int = OFFICIAL_VARIANT_SCENARIO_COUNT
134
+ membership_revision: str = field(
135
+ init=False,
136
+ default=OFFICIAL_SCENARIO_MEMBERSHIP_SHA256,
137
+ )
138
+
139
+ def __post_init__(self) -> None:
140
+ if self.source_revision != OFFICIAL_SOURCE_REVISION:
141
+ raise ValidationError("ToolSandbox inventory must use the audited source revision")
142
+ if self.base_scenario_count != OFFICIAL_BASE_SCENARIO_COUNT:
143
+ raise ValidationError("ToolSandbox base-scenario count differs from the source lock")
144
+ if self.variant_scenario_count != OFFICIAL_VARIANT_SCENARIO_COUNT:
145
+ raise ValidationError("ToolSandbox variant count differs from the source lock")
146
+
147
+ @property
148
+ def base_scenario_names(self) -> tuple[str, ...]:
149
+ return _OFFICIAL_BASE_SCENARIO_NAMES
150
+
151
+ @property
152
+ def variant_suffixes(self) -> tuple[str, ...]:
153
+ return _OFFICIAL_VARIANT_SUFFIXES
154
+
155
+ @property
156
+ def scenario_names(self) -> frozenset[str]:
157
+ return _OFFICIAL_SCENARIO_NAMES
158
+
159
+ def contains(self, scenario_name: str) -> bool:
160
+ return scenario_name in _OFFICIAL_SCENARIO_NAMES
161
+
162
+
163
+ @dataclass(frozen=True, slots=True)
164
+ class ToolSandboxFamilyEligibility:
165
+ """Checkpoint-conditional support, not an official benchmark certification."""
166
+
167
+ checkpoint_id: str
168
+ eligibility: Mapping[str, bool]
169
+ reasons: Mapping[str, str]
170
+ provenance_status: str = _CALLER_ASSERTED
171
+ support_status: str = _STRUCTURAL_CANDIDATE
172
+
173
+ def __post_init__(self) -> None:
174
+ expected = {family.value for family in _FAMILIES}
175
+ if set(self.eligibility) != expected or set(self.reasons) != expected:
176
+ raise ValidationError("ToolSandbox eligibility must cover the five core families")
177
+ if any(not isinstance(value, bool) for value in self.eligibility.values()):
178
+ raise ValidationError("ToolSandbox eligibility values must be boolean")
179
+ if any(not isinstance(reason, str) or not reason for reason in self.reasons.values()):
180
+ raise ValidationError("ToolSandbox eligibility reasons must be non-empty strings")
181
+ if self.provenance_status != _CALLER_ASSERTED:
182
+ raise ValidationError("ToolSandbox eligibility provenance must remain caller_asserted")
183
+ if self.support_status != _STRUCTURAL_CANDIDATE:
184
+ raise ValidationError(
185
+ "ToolSandbox eligibility support must remain structural_candidate"
186
+ )
187
+ object.__setattr__(self, "eligibility", MappingProxyType(dict(self.eligibility)))
188
+ object.__setattr__(self, "reasons", MappingProxyType(dict(self.reasons)))
189
+
190
+ @property
191
+ def eligible_families(self) -> tuple[SemanticFamily, ...]:
192
+ return tuple(family for family in _FAMILIES if self.eligibility[family.value])
193
+
194
+ @property
195
+ def supports_full_block(self) -> bool:
196
+ return all(self.eligibility.values())
197
+
198
+
199
+ @dataclass(frozen=True, slots=True)
200
+ class ToolSandboxCheckpoint:
201
+ """Optimizer-visible state bound to one external ToolSandbox snapshot.
202
+
203
+ Snapshot and replay hashes are opaque. They must not expose evaluator
204
+ milestones, minefields, hidden simulator instructions, or database rows.
205
+ """
206
+
207
+ checkpoint_id: str
208
+ scenario_name: str
209
+ query: str
210
+ instruction: str
211
+ visible_messages: tuple[Message, ...]
212
+ tool_names: tuple[str, ...]
213
+ runtime_snapshot_id: str = field(repr=False)
214
+ replay_identity: str = field(repr=False)
215
+ source_revision: str = OFFICIAL_SOURCE_REVISION
216
+ visible_context: tuple[ContextBlock, ...] = ()
217
+ visible_evidence_tool_names: tuple[str, ...] = ()
218
+ snapshot_restore_available: bool = False
219
+ user_simulator_continuation_available: bool = False
220
+
221
+ def __post_init__(self) -> None:
222
+ for label in ("checkpoint_id", "scenario_name", "query", "instruction"):
223
+ value = getattr(self, label)
224
+ if not isinstance(value, str) or not value.strip() or value != value.strip():
225
+ raise ValidationError(
226
+ f"ToolSandbox checkpoint {label} must be a trimmed non-empty string"
227
+ )
228
+ if self.source_revision != OFFICIAL_SOURCE_REVISION:
229
+ raise ValidationError("ToolSandbox checkpoint source revision is not audited")
230
+ if self.scenario_name not in _OFFICIAL_SCENARIO_NAMES:
231
+ raise ValidationError(
232
+ "ToolSandbox checkpoint scenario_name is not in the pinned official inventory"
233
+ )
234
+ for label in ("runtime_snapshot_id", "replay_identity"):
235
+ value = getattr(self, label)
236
+ if not isinstance(value, str) or _SHA256.fullmatch(value) is None:
237
+ raise ValidationError(f"ToolSandbox checkpoint {label} must be a lowercase SHA-256")
238
+ messages = tuple(self.visible_messages)
239
+ context = tuple(self.visible_context)
240
+ tools = tuple(self.tool_names)
241
+ evidence_tools = tuple(self.visible_evidence_tool_names)
242
+ if not messages or not all(isinstance(message, Message) for message in messages):
243
+ raise ValidationError("ToolSandbox checkpoint requires visible Message instances")
244
+ if not all(isinstance(block, ContextBlock) for block in context):
245
+ raise ValidationError("ToolSandbox context must contain ContextBlock instances")
246
+ if not tools or not all(
247
+ isinstance(name, str) and name.strip() and name == name.strip() for name in tools
248
+ ):
249
+ raise ValidationError("ToolSandbox checkpoint requires visible tool names")
250
+ if len(tools) != len(set(tools)):
251
+ raise ValidationError("ToolSandbox checkpoint tool names must be unique")
252
+ if len(evidence_tools) != len(set(evidence_tools)):
253
+ raise ValidationError("ToolSandbox evidence tool names must be unique")
254
+ if any(name not in tools for name in evidence_tools):
255
+ raise ValidationError(
256
+ "ToolSandbox evidence tool names must be an audited subset of visible tools"
257
+ )
258
+ user_messages = [message for message in messages if message.role == "user"]
259
+ if not user_messages or user_messages[-1].content != self.query:
260
+ raise ValidationError("ToolSandbox query must equal the latest visible user message")
261
+ for label in (
262
+ "snapshot_restore_available",
263
+ "user_simulator_continuation_available",
264
+ ):
265
+ if not isinstance(getattr(self, label), bool):
266
+ raise ValidationError(f"ToolSandbox {label} must be boolean")
267
+ object.__setattr__(self, "visible_messages", messages)
268
+ object.__setattr__(self, "visible_context", context)
269
+ object.__setattr__(self, "tool_names", tools)
270
+ object.__setattr__(self, "visible_evidence_tool_names", evidence_tools)
271
+
272
+ @property
273
+ def family_eligibility(self) -> ToolSandboxFamilyEligibility:
274
+ restore = self.snapshot_restore_available
275
+ evidence_channel = bool(self.visible_evidence_tool_names)
276
+ clarification = restore and self.user_simulator_continuation_available
277
+ curation_material = len(self.visible_messages) >= 3 or len(self.visible_context) >= 2
278
+ eligibility = {
279
+ SemanticFamily.REFORMULATE.value: restore,
280
+ SemanticFamily.DECOMPOSE.value: restore,
281
+ SemanticFamily.ACQUIRE.value: restore and evidence_channel,
282
+ SemanticFamily.CLARIFY.value: clarification,
283
+ SemanticFamily.CURATE.value: restore and curation_material,
284
+ }
285
+ reasons = {
286
+ SemanticFamily.REFORMULATE.value: (
287
+ "explicit visible query and snapshot restoration are available"
288
+ if restore
289
+ else "requires an official-state restore path for matched arms"
290
+ ),
291
+ SemanticFamily.DECOMPOSE.value: (
292
+ "explicit visible query and snapshot restoration are available"
293
+ if restore
294
+ else "requires an official-state restore path for matched arms"
295
+ ),
296
+ SemanticFamily.ACQUIRE.value: (
297
+ "restorable checkpoint exposes a visible search/evidence tool"
298
+ if restore and evidence_channel
299
+ else "requires restoration plus a visible search/evidence tool"
300
+ ),
301
+ SemanticFamily.CLARIFY.value: (
302
+ "restorable checkpoint exposes on-policy user-simulator continuation"
303
+ if clarification
304
+ else "requires restoration plus replayable user-simulator continuation"
305
+ ),
306
+ SemanticFamily.CURATE.value: (
307
+ "restorable checkpoint has sufficient visible history/context"
308
+ if restore and curation_material
309
+ else "requires restoration plus three messages or two context blocks"
310
+ ),
311
+ }
312
+ return ToolSandboxFamilyEligibility(self.checkpoint_id, eligibility, reasons)
313
+
314
+
315
+ @dataclass(frozen=True, slots=True)
316
+ class ToolSandboxEvaluationResult:
317
+ """Official-shaped values produced by an external ToolSandbox evaluator."""
318
+
319
+ milestone_similarity: float
320
+ minefield_similarity: float
321
+ similarity: float
322
+ turn_count: int
323
+ cost: float
324
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
325
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_OFFICIAL_SEMANTICS)
326
+ official_runtime_verified: bool = field(init=False, default=False)
327
+
328
+ def __post_init__(self) -> None:
329
+ for label in ("milestone_similarity", "minefield_similarity", "similarity"):
330
+ value = _unit_interval(getattr(self, label), label=label)
331
+ object.__setattr__(self, label, value)
332
+ if isinstance(self.turn_count, bool) or not isinstance(self.turn_count, int):
333
+ raise ValidationError("ToolSandbox turn_count must be an integer")
334
+ if self.turn_count < 0:
335
+ raise ValidationError("ToolSandbox turn_count must be non-negative")
336
+ if isinstance(self.cost, bool) or not isinstance(self.cost, (int, float)):
337
+ raise ValidationError("ToolSandbox cost must be numeric")
338
+ cost = float(self.cost)
339
+ if not math.isfinite(cost) or cost < 0:
340
+ raise ValidationError("ToolSandbox cost must be finite and non-negative")
341
+ object.__setattr__(self, "cost", cost)
342
+ expected_similarity = self.milestone_similarity if self.minefield_similarity == 0.0 else 0.0
343
+ if not math.isclose(self.similarity, expected_similarity, abs_tol=1e-12):
344
+ raise ValidationError(
345
+ "ToolSandbox similarity must follow official minefield-nullification semantics"
346
+ )
347
+
348
+ @property
349
+ def metrics(self) -> Mapping[str, float]:
350
+ return MappingProxyType(
351
+ {
352
+ "cost": self.cost,
353
+ "milestone_similarity": self.milestone_similarity,
354
+ "minefield_similarity": self.minefield_similarity,
355
+ "official_similarity": self.similarity,
356
+ "turn_count": float(self.turn_count),
357
+ }
358
+ )
359
+
360
+
361
+ @runtime_checkable
362
+ class ToolSandboxEvaluationBridge(Protocol):
363
+ """Typed bridge to the pinned official runtime and evaluator."""
364
+
365
+ bridge_id: str
366
+ bridge_revision: str
367
+ cost_basis: str
368
+ source_revision: str
369
+ supports_snapshot_restore: bool
370
+ supports_user_simulator_replay: bool
371
+ provenance_status: str
372
+ evaluation_scope: str
373
+ official_runtime_verified: bool
374
+
375
+ def evaluate(
376
+ self,
377
+ checkpoint: ToolSandboxCheckpoint,
378
+ prediction: Any,
379
+ ) -> ToolSandboxEvaluationResult: ...
380
+
381
+
382
+ @dataclass(frozen=True, slots=True)
383
+ class CallerAssertedToolSandboxEvaluationBridge:
384
+ """Explicit wrapper for an unverified external official-runtime callback."""
385
+
386
+ bridge_id: str
387
+ bridge_revision: str
388
+ cost_basis: str
389
+ supports_snapshot_restore: bool
390
+ supports_user_simulator_replay: bool
391
+ callback: Callable[
392
+ [ToolSandboxCheckpoint, Any],
393
+ ToolSandboxEvaluationResult,
394
+ ] = field(repr=False)
395
+ source_revision: str = field(init=False, default=OFFICIAL_SOURCE_REVISION)
396
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
397
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_OFFICIAL_SEMANTICS)
398
+ official_runtime_verified: bool = field(init=False, default=False)
399
+
400
+ def __post_init__(self) -> None:
401
+ for label in ("bridge_id", "cost_basis"):
402
+ value = getattr(self, label)
403
+ if not isinstance(value, str) or not value.strip() or value != value.strip():
404
+ raise ValidationError(f"ToolSandbox bridge {label} must be non-empty")
405
+ if (
406
+ not isinstance(self.bridge_revision, str)
407
+ or _SHA256.fullmatch(self.bridge_revision) is None
408
+ ):
409
+ raise ValidationError("ToolSandbox bridge revision must be a lowercase SHA-256")
410
+ if not callable(self.callback):
411
+ raise TypeError("ToolSandbox bridge callback must be callable")
412
+ for label in (
413
+ "supports_snapshot_restore",
414
+ "supports_user_simulator_replay",
415
+ ):
416
+ if not isinstance(getattr(self, label), bool):
417
+ raise ValidationError(f"ToolSandbox bridge {label} must be boolean")
418
+
419
+ def evaluate(
420
+ self,
421
+ checkpoint: ToolSandboxCheckpoint,
422
+ prediction: Any,
423
+ ) -> ToolSandboxEvaluationResult:
424
+ result = self.callback(checkpoint, prediction)
425
+ if not isinstance(result, ToolSandboxEvaluationResult):
426
+ raise ValidationError("ToolSandbox callback must return ToolSandboxEvaluationResult")
427
+ return result
428
+
429
+
430
+ class ToolSandboxCommonSupportAdapter:
431
+ """Adapter for externally captured ToolSandbox checkpoint experiments."""
432
+
433
+ benchmark_id = BENCHMARK_ID
434
+ adapter_metric_names = (
435
+ "milestone_similarity",
436
+ "minefield_similarity",
437
+ "official_similarity",
438
+ "turn_count",
439
+ "cost",
440
+ )
441
+ split = "external_checkpoints"
442
+ pairing_mode = "unsupported_external_replay"
443
+
444
+ def __init__(
445
+ self,
446
+ *,
447
+ checkpoints: Iterable[ToolSandboxCheckpoint],
448
+ evaluation_bridge: ToolSandboxEvaluationBridge,
449
+ inventory: ToolSandboxScenarioInventory | None = None,
450
+ ) -> None:
451
+ if not isinstance(evaluation_bridge, ToolSandboxEvaluationBridge):
452
+ raise TypeError(
453
+ "evaluation_bridge must implement ToolSandboxEvaluationBridge; "
454
+ "wrap callbacks with CallerAssertedToolSandboxEvaluationBridge"
455
+ )
456
+ _validate_bridge(evaluation_bridge)
457
+ self.inventory = inventory or ToolSandboxScenarioInventory()
458
+ if not isinstance(self.inventory, ToolSandboxScenarioInventory):
459
+ raise TypeError("inventory must be ToolSandboxScenarioInventory")
460
+ checkpoints_tuple = tuple(checkpoints)
461
+ if not checkpoints_tuple:
462
+ raise ValidationError("ToolSandbox adapter requires at least one checkpoint")
463
+ if not all(isinstance(item, ToolSandboxCheckpoint) for item in checkpoints_tuple):
464
+ raise TypeError("ToolSandbox checkpoints must be ToolSandboxCheckpoint instances")
465
+ checkpoint_ids = [item.checkpoint_id for item in checkpoints_tuple]
466
+ if len(checkpoint_ids) != len(set(checkpoint_ids)):
467
+ raise ValidationError("ToolSandbox checkpoint IDs must be unique")
468
+ experimental_units = [
469
+ (item.scenario_name, item.runtime_snapshot_id, item.replay_identity)
470
+ for item in checkpoints_tuple
471
+ ]
472
+ if len(experimental_units) != len(set(experimental_units)):
473
+ raise ValidationError("ToolSandbox experimental units must be unique")
474
+
475
+ examples: list[BenchmarkExample] = []
476
+ checkpoints_by_id: dict[str, ToolSandboxCheckpoint] = {}
477
+ for checkpoint in sorted(checkpoints_tuple, key=lambda item: item.checkpoint_id):
478
+ if (
479
+ checkpoint.snapshot_restore_available
480
+ and not evaluation_bridge.supports_snapshot_restore
481
+ ):
482
+ raise ValidationError(
483
+ "checkpoint claims snapshot restoration not supported by its bridge"
484
+ )
485
+ if (
486
+ checkpoint.user_simulator_continuation_available
487
+ and not evaluation_bridge.supports_user_simulator_replay
488
+ ):
489
+ raise ValidationError(
490
+ "checkpoint claims user-simulator continuation not supported by its bridge"
491
+ )
492
+ support = checkpoint.family_eligibility
493
+ metadata = freeze_mapping(
494
+ {
495
+ "benchmark_cell": self.benchmark_id,
496
+ "family_eligibility": dict(support.eligibility),
497
+ "family_eligibility_provenance": support.provenance_status,
498
+ "family_eligibility_reasons": dict(support.reasons),
499
+ "family_support_status": support.support_status,
500
+ "source_revision": OFFICIAL_SOURCE_REVISION,
501
+ }
502
+ )
503
+ example = BenchmarkExample(
504
+ example_id=checkpoint.checkpoint_id,
505
+ query=checkpoint.query,
506
+ instruction=checkpoint.instruction,
507
+ visible_context=checkpoint.visible_context,
508
+ visible_messages=checkpoint.visible_messages,
509
+ visible_tool_names=checkpoint.tool_names,
510
+ visible_metadata=metadata,
511
+ evaluator_gold=MappingProxyType({}),
512
+ optimizer_visible_id=opaque_checkpoint_state_id(
513
+ self.benchmark_id,
514
+ checkpoint.checkpoint_id,
515
+ checkpoint.replay_identity,
516
+ ),
517
+ )
518
+ examples.append(example)
519
+ checkpoints_by_id[checkpoint.checkpoint_id] = checkpoint
520
+
521
+ self._bridge = evaluation_bridge
522
+ self._examples = tuple(examples)
523
+ self._examples_by_id = {example.example_id: example for example in examples}
524
+ self._checkpoints = MappingProxyType(checkpoints_by_id)
525
+
526
+ def examples(self, split: str) -> tuple[BenchmarkExample, ...]:
527
+ if split != self.split:
528
+ raise ValidationError(
529
+ f"ToolSandbox adapter exposes split {self.split!r}, not {split!r}"
530
+ )
531
+ return self._examples
532
+
533
+ def family_eligibility(self, checkpoint_id: str) -> ToolSandboxFamilyEligibility:
534
+ return self._checkpoint(checkpoint_id).family_eligibility
535
+
536
+ def eligible_families(self, checkpoint_id: str) -> tuple[SemanticFamily, ...]:
537
+ return self.family_eligibility(checkpoint_id).eligible_families
538
+
539
+ def supports_full_block(self, checkpoint_id: str) -> bool:
540
+ return self.family_eligibility(checkpoint_id).supports_full_block
541
+
542
+ def score(self, example: BenchmarkExample, prediction: Any) -> Mapping[str, float]:
543
+ if not isinstance(example, BenchmarkExample):
544
+ raise TypeError("example must be a BenchmarkExample")
545
+ if self._examples_by_id.get(example.example_id) is not example:
546
+ raise ValidationError("benchmark example does not belong to this adapter")
547
+ result = self._bridge.evaluate(self._checkpoint(example.example_id), prediction)
548
+ if not isinstance(result, ToolSandboxEvaluationResult):
549
+ raise ValidationError("ToolSandbox bridge returned an invalid result type")
550
+ return result.metrics
551
+
552
+ @property
553
+ def evaluation_provenance(self) -> Mapping[str, Any]:
554
+ return freeze_mapping(
555
+ {
556
+ "bridge_id": self._bridge.bridge_id,
557
+ "bridge_revision": self._bridge.bridge_revision,
558
+ "cost_basis": self._bridge.cost_basis,
559
+ "evaluation_scope": self._bridge.evaluation_scope,
560
+ "official_runtime_verified": self._bridge.official_runtime_verified,
561
+ "pairing_mode": self.pairing_mode,
562
+ "provenance_status": self._bridge.provenance_status,
563
+ "supports_snapshot_restore": self._bridge.supports_snapshot_restore,
564
+ "source_revision": self._bridge.source_revision,
565
+ "supports_user_simulator_replay": (self._bridge.supports_user_simulator_replay),
566
+ }
567
+ )
568
+
569
+ def _checkpoint(self, checkpoint_id: str) -> ToolSandboxCheckpoint:
570
+ try:
571
+ return self._checkpoints[checkpoint_id]
572
+ except KeyError as exc:
573
+ raise ValidationError(f"unknown ToolSandbox checkpoint {checkpoint_id!r}") from exc
574
+
575
+
576
+ def _unit_interval(value: Any, *, label: str) -> float:
577
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
578
+ raise ValidationError(f"ToolSandbox {label} must be numeric")
579
+ numeric = float(value)
580
+ if not math.isfinite(numeric) or not 0.0 <= numeric <= 1.0:
581
+ raise ValidationError(f"ToolSandbox {label} must be finite and in [0, 1]")
582
+ return numeric
583
+
584
+
585
+ def _validate_bridge(bridge: ToolSandboxEvaluationBridge) -> None:
586
+ if bridge.source_revision != OFFICIAL_SOURCE_REVISION:
587
+ raise ValidationError("ToolSandbox bridge source revision is not audited")
588
+ if bridge.provenance_status != _CALLER_ASSERTED:
589
+ raise ValidationError("ToolSandbox bridge provenance must remain caller_asserted")
590
+ if bridge.evaluation_scope != _EXTERNAL_OFFICIAL_SEMANTICS:
591
+ raise ValidationError("ToolSandbox bridge scope must remain external_official_semantics")
592
+ if bridge.official_runtime_verified is not False:
593
+ raise ValidationError("current ToolSandbox bridge cannot claim runtime verification")
594
+ for label in (
595
+ "supports_snapshot_restore",
596
+ "supports_user_simulator_replay",
597
+ ):
598
+ if not isinstance(getattr(bridge, label), bool):
599
+ raise ValidationError(f"ToolSandbox bridge {label} must be boolean")
600
+ for label in ("bridge_id", "cost_basis"):
601
+ value = getattr(bridge, label)
602
+ if not isinstance(value, str) or not value.strip() or value != value.strip():
603
+ raise ValidationError(f"ToolSandbox bridge {label} must be non-empty")
604
+ if (
605
+ not isinstance(bridge.bridge_revision, str)
606
+ or _SHA256.fullmatch(bridge.bridge_revision) is None
607
+ ):
608
+ raise ValidationError("ToolSandbox bridge revision must be a lowercase SHA-256")
609
+
610
+
611
+ __all__ = [
612
+ "BENCHMARK_ID",
613
+ "OFFICIAL_BASE_SCENARIO_COUNT",
614
+ "OFFICIAL_REPOSITORY",
615
+ "OFFICIAL_SCENARIO_MEMBERSHIP_ASSET",
616
+ "OFFICIAL_SCENARIO_MEMBERSHIP_SHA256",
617
+ "OFFICIAL_SOURCE_REVISION",
618
+ "OFFICIAL_VARIANT_SCENARIO_COUNT",
619
+ "CallerAssertedToolSandboxEvaluationBridge",
620
+ "ToolSandboxCheckpoint",
621
+ "ToolSandboxCommonSupportAdapter",
622
+ "ToolSandboxEvaluationBridge",
623
+ "ToolSandboxEvaluationResult",
624
+ "ToolSandboxFamilyEligibility",
625
+ "ToolSandboxScenarioInventory",
626
+ ]