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,938 @@
1
+ """External checkpoint bridge for Microsoft STATE-Bench.
2
+
3
+ STATE-Bench owns the task environments, domain tools, user simulator,
4
+ continuation loop, and scorers. This module does not copy or reimplement that
5
+ runtime. It validates an optimizer-visible pre-action checkpoint, derives
6
+ five-family structural eligibility from visible state, and delegates reset,
7
+ continuation, and scoring to an explicitly typed external bridge.
8
+
9
+ The integration is pinned to STATE-Bench v0.8.1 at commit
10
+ ``4efcbf2d4fe60df04878859b692d9391f3d5b33a``. A bridge remains
11
+ ``caller_asserted`` until a future direct runtime integration can attest the
12
+ official execution itself.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import hashlib
18
+ import json
19
+ import math
20
+ import re
21
+ from collections.abc import Callable, Iterable, Mapping
22
+ from dataclasses import dataclass, field
23
+ from importlib.resources import files
24
+ from types import MappingProxyType
25
+ from typing import Any, Protocol, runtime_checkable
26
+
27
+ from agentinputlab.contracts.enums import SemanticFamily
28
+ from agentinputlab.contracts.errors import ValidationError
29
+ from agentinputlab.contracts.serialization import freeze_mapping
30
+ from agentinputlab.contracts.state import ContextBlock, Message
31
+
32
+ from .base import BenchmarkExample, opaque_checkpoint_state_id
33
+
34
+ STATEBENCH_BENCHMARK_ID = "state_bench.common_support"
35
+ STATEBENCH_EXTERNAL_SPLIT = "external_checkpoints"
36
+ STATEBENCH_OFFICIAL_SOURCE_REVISION = "4efcbf2d4fe60df04878859b692d9391f3d5b33a"
37
+ STATEBENCH_OFFICIAL_VERSION = "0.8.1"
38
+ STATEBENCH_OFFICIAL_TASK_MEMBERSHIP_REVISION = (
39
+ "1410974ccd3ea80e1d20425ba4b11539a0883eb2029b3b1023fa8627ed1b2870"
40
+ )
41
+ STATEBENCH_OFFICIAL_PROTOCOL_ID = "state_bench_v0.8.1_gpt54"
42
+ STATEBENCH_OFFICIAL_PROTOCOL_REVISION = (
43
+ "e4a97cab2b2ed31ec180f671f4b5e5760c00cf30cc56d4cf717481e7a0d29a0c"
44
+ )
45
+ STATEBENCH_OFFICIAL_SOURCE_SPLIT = "test"
46
+ STATEBENCH_OFFICIAL_RUNS_PER_TASK = 5
47
+ STATEBENCH_OFFICIAL_MAX_AGENT_TURNS = 15
48
+
49
+ STATEBENCH_OFFICIAL_DOMAIN_TASK_COUNTS: Mapping[str, int] = MappingProxyType(
50
+ {
51
+ "customer_support": 150,
52
+ "shopping_assistant": 150,
53
+ "travel": 150,
54
+ }
55
+ )
56
+
57
+ STATEBENCH_OFFICIAL_TOOL_NAMES: Mapping[str, tuple[str, ...]] = MappingProxyType(
58
+ {
59
+ "travel": (
60
+ "search_flights",
61
+ "get_user_details",
62
+ "get_user_reservations",
63
+ "get_booking",
64
+ "get_flight_status",
65
+ "get_policies",
66
+ "create_booking",
67
+ "update_booking",
68
+ "cancel_booking",
69
+ "search_hotels",
70
+ "book_hotel",
71
+ "get_hotel_reservation",
72
+ "cancel_hotel_reservation",
73
+ "search_car_rentals",
74
+ "book_car_rental",
75
+ "get_car_rental",
76
+ "cancel_car_rental",
77
+ ),
78
+ "customer_support": (
79
+ "get_order",
80
+ "get_customer",
81
+ "search_products",
82
+ "get_product_details",
83
+ "get_policies",
84
+ "get_warranty_status",
85
+ "process_return",
86
+ "process_refund",
87
+ "cancel_order",
88
+ "process_exchange",
89
+ "process_warranty_claim",
90
+ ),
91
+ "shopping_assistant": (
92
+ "search_products",
93
+ "get_product_details",
94
+ "get_variants",
95
+ "get_customer_account",
96
+ "get_cart",
97
+ "check_compatibility",
98
+ "get_promotions",
99
+ "get_policies",
100
+ "validate_promo",
101
+ "add_to_cart",
102
+ "update_cart_item",
103
+ "remove_from_cart",
104
+ "apply_promo",
105
+ "remove_promo",
106
+ "redeem_loyalty_points",
107
+ "cancel_loyalty_redemption",
108
+ "get_shipping_options",
109
+ "set_shipping_option",
110
+ ),
111
+ }
112
+ )
113
+
114
+ _OFFICIAL_READ_TOOL_NAMES: Mapping[str, frozenset[str]] = MappingProxyType(
115
+ {
116
+ "travel": frozenset(
117
+ {
118
+ "search_flights",
119
+ "get_user_details",
120
+ "get_user_reservations",
121
+ "get_booking",
122
+ "get_flight_status",
123
+ "get_policies",
124
+ "search_hotels",
125
+ "get_hotel_reservation",
126
+ "search_car_rentals",
127
+ "get_car_rental",
128
+ }
129
+ ),
130
+ "customer_support": frozenset(
131
+ {
132
+ "get_order",
133
+ "get_customer",
134
+ "search_products",
135
+ "get_product_details",
136
+ "get_policies",
137
+ "get_warranty_status",
138
+ }
139
+ ),
140
+ "shopping_assistant": frozenset(
141
+ {
142
+ "search_products",
143
+ "get_product_details",
144
+ "get_variants",
145
+ "get_customer_account",
146
+ "get_cart",
147
+ "check_compatibility",
148
+ "get_promotions",
149
+ "get_policies",
150
+ "validate_promo",
151
+ "get_shipping_options",
152
+ }
153
+ ),
154
+ }
155
+ )
156
+
157
+ STATEBENCH_OFFICIAL_TOOL_CATALOG_REVISIONS: Mapping[str, str] = MappingProxyType(
158
+ {
159
+ "travel": "8578328f635d01a620f8112ff24b6c9e439dd10e6eb62c688b72d1d1f31162a6",
160
+ "customer_support": ("ac36ecc06cf02c011b262648ed88a53eb00fa33adc99fdd6fb51ec7918c86cbc"),
161
+ "shopping_assistant": ("eeece103dbd3b992d25f0a5dab4c6d9e2670b089f6ed1a4b9972a5b831674f0f"),
162
+ }
163
+ )
164
+
165
+ STATEBENCH_OFFICIAL_TASK_CATALOG_REVISIONS: Mapping[str, str] = MappingProxyType(
166
+ {
167
+ "travel": "b7d92174e35293f7dbcf0b70725caa65e2bc73363d013249caa27d7a4b725ddb",
168
+ "customer_support": ("164c86c890ea26f6a4f942ae4fc4f05c8536619a7071bc588dedbdf98622c41b"),
169
+ "shopping_assistant": ("15aa50a4a4a231d711cfce575827bc4e107894c94583631b2c2a803c86634faa"),
170
+ }
171
+ )
172
+
173
+ STATEBENCH_OFFICIAL_ENVIRONMENT_CATALOG_REVISIONS: Mapping[str, str] = MappingProxyType(
174
+ {
175
+ "travel": "2eaef6d775da6edd1fd2301aac556258abbb992d6e7a28963996ee409e36d5a2",
176
+ "customer_support": ("df6c5fe16d7033f988dede7c6a1bd8f174a467ff8da68998a41eb250c793f152"),
177
+ "shopping_assistant": ("d9007ed2aa16b8effc636b4210c67edaf93dfa9c335a6100f64e03ca42c9b217"),
178
+ }
179
+ )
180
+
181
+ STATEBENCH_OFFICIAL_SPLIT_REVISIONS: Mapping[str, str] = MappingProxyType(
182
+ {
183
+ "travel": "55ba8285139a7edfca25e589562ae72622d0b633c598cbb2963e103b3855cb9f",
184
+ "customer_support": ("2988c8c87d426babf0daa3f342c3110caefb63fa0bac97650a38fc2dcfa7291e"),
185
+ "shopping_assistant": ("bc9be8ae4afce8fc817c5a3e2c3d72373009742d726a853cbcb743d9b4a09938"),
186
+ }
187
+ )
188
+
189
+ STATEBENCH_OFFICIAL_SIMULATOR_PROMPT_REVISIONS: Mapping[str, str] = MappingProxyType(
190
+ {
191
+ "travel": "6a94abedb77e2ec3f3b94a149291bc42a6aeacd5691ef0cb69862b9af923ae3c",
192
+ "customer_support": ("0b58e108ac16469926ee210774e6e3275049d898d35ea23ef40c13ddfbe829d8"),
193
+ "shopping_assistant": ("70a546fce5108cb4381c6c6c6ea0adccd6e3d91b99b90a14f1c09d1b1f2bc5fc"),
194
+ }
195
+ )
196
+
197
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
198
+ _TASK_ID = re.compile(r"^(?P<number>[1-9][0-9]{0,2})-[a-z0-9][a-z0-9_-]*$")
199
+ _CALLER_ASSERTED = "caller_asserted"
200
+ _STRUCTURAL_CANDIDATE = "structural_candidate"
201
+ _EXTERNAL_BRIDGE = "external_single_trajectory"
202
+ _OFFICIAL_COST_BASIS = "agent_reported_usd"
203
+ _ALLOWED_CAPABILITIES = frozenset(
204
+ {
205
+ "clarification_roundtrip_available",
206
+ "continuation_available",
207
+ "fresh_task_reset_available",
208
+ "mid_dialogue_clone_available",
209
+ }
210
+ )
211
+ _FAMILIES = (
212
+ SemanticFamily.REFORMULATE,
213
+ SemanticFamily.DECOMPOSE,
214
+ SemanticFamily.ACQUIRE,
215
+ SemanticFamily.CLARIFY,
216
+ SemanticFamily.CURATE,
217
+ )
218
+
219
+
220
+ def _load_official_task_ids() -> tuple[
221
+ Mapping[str, frozenset[str]],
222
+ Mapping[str, Mapping[str, frozenset[str]]],
223
+ ]:
224
+ resource = files("agentinputlab.benchmarks").joinpath(
225
+ "data",
226
+ "statebench_v0_8_1_task_ids.json",
227
+ )
228
+ payload_bytes = resource.read_bytes()
229
+ if hashlib.sha256(payload_bytes).hexdigest() != STATEBENCH_OFFICIAL_TASK_MEMBERSHIP_REVISION:
230
+ raise RuntimeError("STATE-Bench packaged task membership differs from the pinned revision")
231
+ try:
232
+ payload = json.loads(payload_bytes)
233
+ except (UnicodeDecodeError, json.JSONDecodeError) as exc:
234
+ raise RuntimeError("STATE-Bench packaged task membership is invalid JSON") from exc
235
+ if (
236
+ not isinstance(payload, dict)
237
+ or payload.get("benchmark_version") != STATEBENCH_OFFICIAL_VERSION
238
+ or payload.get("source_revision") != STATEBENCH_OFFICIAL_SOURCE_REVISION
239
+ or payload.get("split_version") != "train_test"
240
+ ):
241
+ raise RuntimeError("STATE-Bench packaged task membership has the wrong source revision")
242
+ domains = payload.get("domains")
243
+ if not isinstance(domains, dict) or set(domains) != set(STATEBENCH_OFFICIAL_DOMAIN_TASK_COUNTS):
244
+ raise RuntimeError("STATE-Bench packaged task membership has the wrong domains")
245
+
246
+ normalized: dict[str, frozenset[str]] = {}
247
+ normalized_by_split: dict[str, dict[str, frozenset[str]]] = {
248
+ "test": {},
249
+ "train": {},
250
+ }
251
+ for domain, expected_count in STATEBENCH_OFFICIAL_DOMAIN_TASK_COUNTS.items():
252
+ domain_splits = domains[domain]
253
+ if not isinstance(domain_splits, dict) or set(domain_splits) != {"test", "train"}:
254
+ raise RuntimeError(
255
+ f"STATE-Bench packaged task membership is invalid for domain {domain!r}"
256
+ )
257
+ split_task_ids: dict[str, frozenset[str]] = {}
258
+ for split, split_count in (("train", 100), ("test", 50)):
259
+ task_ids = domain_splits[split]
260
+ if (
261
+ not isinstance(task_ids, list)
262
+ or any(not isinstance(task_id, str) for task_id in task_ids)
263
+ or len(task_ids) != split_count
264
+ or len(set(task_ids)) != split_count
265
+ or any(_TASK_ID.fullmatch(task_id) is None for task_id in task_ids)
266
+ ):
267
+ raise RuntimeError(
268
+ f"STATE-Bench packaged {split} task membership is invalid for domain {domain!r}"
269
+ )
270
+ split_task_ids[split] = frozenset(task_ids)
271
+ normalized_by_split[split][domain] = split_task_ids[split]
272
+ all_task_ids = split_task_ids["train"] | split_task_ids["test"]
273
+ numeric_prefixes = {int(task_id.split("-", 1)[0]) for task_id in all_task_ids}
274
+ if (
275
+ not split_task_ids["train"].isdisjoint(split_task_ids["test"])
276
+ or len(all_task_ids) != expected_count
277
+ or numeric_prefixes != set(range(1, expected_count + 1))
278
+ ):
279
+ raise RuntimeError(
280
+ f"STATE-Bench packaged task membership is incomplete for domain {domain!r}"
281
+ )
282
+ normalized[domain] = frozenset(all_task_ids)
283
+ return MappingProxyType(normalized), MappingProxyType(
284
+ {
285
+ split: MappingProxyType(task_ids_by_domain)
286
+ for split, task_ids_by_domain in normalized_by_split.items()
287
+ }
288
+ )
289
+
290
+
291
+ STATEBENCH_OFFICIAL_TASK_IDS, STATEBENCH_OFFICIAL_TASK_IDS_BY_SPLIT = _load_official_task_ids()
292
+
293
+
294
+ @dataclass(frozen=True, slots=True)
295
+ class StateBenchFamilyEligibility:
296
+ """Visible-only, caller-asserted support for one STATE-Bench checkpoint."""
297
+
298
+ checkpoint_id: str
299
+ eligibility: Mapping[str, bool]
300
+ reasons: Mapping[str, str]
301
+ provenance_status: str = _CALLER_ASSERTED
302
+ support_status: str = _STRUCTURAL_CANDIDATE
303
+
304
+ def __post_init__(self) -> None:
305
+ expected = {family.value for family in _FAMILIES}
306
+ if set(self.eligibility) != expected or set(self.reasons) != expected:
307
+ raise ValidationError(
308
+ "STATE-Bench family eligibility must cover the five core families"
309
+ )
310
+ if any(not isinstance(value, bool) for value in self.eligibility.values()):
311
+ raise ValidationError("STATE-Bench family eligibility values must be boolean")
312
+ if any(not isinstance(value, str) or not value for value in self.reasons.values()):
313
+ raise ValidationError(
314
+ "STATE-Bench family eligibility reasons must be non-empty strings"
315
+ )
316
+ if self.provenance_status != _CALLER_ASSERTED:
317
+ raise ValidationError("STATE-Bench eligibility provenance must remain caller_asserted")
318
+ if self.support_status != _STRUCTURAL_CANDIDATE:
319
+ raise ValidationError(
320
+ "STATE-Bench eligibility support must remain structural_candidate"
321
+ )
322
+ object.__setattr__(self, "eligibility", MappingProxyType(dict(self.eligibility)))
323
+ object.__setattr__(self, "reasons", MappingProxyType(dict(self.reasons)))
324
+
325
+ @property
326
+ def eligible_families(self) -> tuple[SemanticFamily, ...]:
327
+ return tuple(family for family in _FAMILIES if self.eligibility[family.value])
328
+
329
+ @property
330
+ def supports_full_block(self) -> bool:
331
+ return all(self.eligibility.values())
332
+
333
+
334
+ @dataclass(frozen=True, slots=True)
335
+ class StateBenchCheckpoint:
336
+ """Optimizer-visible state plus opaque bindings to the official runtime.
337
+
338
+ Hidden task summaries, simulator instructions, state requirements, task
339
+ requirements, task-local database rows, and scorer prompts are deliberately
340
+ absent. They remain inside the official external runtime.
341
+ """
342
+
343
+ checkpoint_id: str
344
+ task_id: str = field(repr=False)
345
+ domain: str
346
+ query: str
347
+ instruction: str
348
+ visible_messages: tuple[Message, ...]
349
+ tool_names: tuple[str, ...]
350
+ turn_index: int
351
+ run_index: int
352
+ source_revision: str
353
+ protocol_id: str
354
+ protocol_revision: str
355
+ task_catalog_revision: str
356
+ environment_catalog_revision: str
357
+ split_revision: str
358
+ tool_catalog_revision: str
359
+ simulator_prompt_revision: str
360
+ runtime_snapshot_id: str = field(repr=False)
361
+ initial_environment_revision: str = field(repr=False)
362
+ active_environment_revision: str = field(repr=False)
363
+ simulator_session_identity: str = field(repr=False)
364
+ replay_identity: str = field(repr=False)
365
+ continuation_identity: str = field(repr=False)
366
+ visible_context: tuple[ContextBlock, ...] = ()
367
+ structural_capabilities: Mapping[str, bool] = field(default_factory=dict)
368
+ source_split: str = STATEBENCH_OFFICIAL_SOURCE_SPLIT
369
+
370
+ def __post_init__(self) -> None:
371
+ for label in ("checkpoint_id", "query", "instruction"):
372
+ _require_trimmed_string(getattr(self, label), f"STATE-Bench checkpoint {label}")
373
+ if self.domain not in STATEBENCH_OFFICIAL_DOMAIN_TASK_COUNTS:
374
+ raise ValidationError(
375
+ "STATE-Bench checkpoint domain must be travel, customer_support, "
376
+ "or shopping_assistant"
377
+ )
378
+ if (
379
+ isinstance(self.turn_index, bool)
380
+ or not isinstance(self.turn_index, int)
381
+ or not 0 <= self.turn_index < STATEBENCH_OFFICIAL_MAX_AGENT_TURNS
382
+ ):
383
+ raise ValidationError("STATE-Bench turn_index must be an integer in [0, 14]")
384
+ if (
385
+ isinstance(self.run_index, bool)
386
+ or not isinstance(self.run_index, int)
387
+ or not 1 <= self.run_index <= STATEBENCH_OFFICIAL_RUNS_PER_TASK
388
+ ):
389
+ raise ValidationError("STATE-Bench run_index must be an integer in [1, 5]")
390
+
391
+ expected_values = {
392
+ "source_revision": STATEBENCH_OFFICIAL_SOURCE_REVISION,
393
+ "protocol_id": STATEBENCH_OFFICIAL_PROTOCOL_ID,
394
+ "protocol_revision": STATEBENCH_OFFICIAL_PROTOCOL_REVISION,
395
+ "task_catalog_revision": (STATEBENCH_OFFICIAL_TASK_CATALOG_REVISIONS[self.domain]),
396
+ "environment_catalog_revision": (
397
+ STATEBENCH_OFFICIAL_ENVIRONMENT_CATALOG_REVISIONS[self.domain]
398
+ ),
399
+ "split_revision": STATEBENCH_OFFICIAL_SPLIT_REVISIONS[self.domain],
400
+ "tool_catalog_revision": (STATEBENCH_OFFICIAL_TOOL_CATALOG_REVISIONS[self.domain]),
401
+ "simulator_prompt_revision": (
402
+ STATEBENCH_OFFICIAL_SIMULATOR_PROMPT_REVISIONS[self.domain]
403
+ ),
404
+ "source_split": STATEBENCH_OFFICIAL_SOURCE_SPLIT,
405
+ }
406
+ for label, expected in expected_values.items():
407
+ if getattr(self, label) != expected:
408
+ raise ValidationError(
409
+ f"STATE-Bench checkpoint {label} differs from the pinned v0.8.1 contract"
410
+ )
411
+ _validate_task_id(
412
+ self.task_id,
413
+ domain=self.domain,
414
+ source_split=self.source_split,
415
+ )
416
+
417
+ for label in (
418
+ "runtime_snapshot_id",
419
+ "initial_environment_revision",
420
+ "active_environment_revision",
421
+ "simulator_session_identity",
422
+ "replay_identity",
423
+ "continuation_identity",
424
+ ):
425
+ _require_sha256(getattr(self, label), f"STATE-Bench checkpoint {label}")
426
+
427
+ messages = tuple(self.visible_messages)
428
+ context = tuple(self.visible_context)
429
+ tool_names = tuple(self.tool_names)
430
+ if not messages or not all(isinstance(message, Message) for message in messages):
431
+ raise ValidationError(
432
+ "STATE-Bench checkpoint requires captured visible Message instances"
433
+ )
434
+ if not all(isinstance(block, ContextBlock) for block in context):
435
+ raise ValidationError(
436
+ "STATE-Bench checkpoint visible_context must contain ContextBlock instances"
437
+ )
438
+ user_messages = [message for message in messages if message.role == "user"]
439
+ if not user_messages:
440
+ raise ValidationError("STATE-Bench checkpoint requires a visible user message")
441
+ if user_messages[-1].content != self.query:
442
+ raise ValidationError("STATE-Bench query must equal the latest visible user message")
443
+ if tool_names != STATEBENCH_OFFICIAL_TOOL_NAMES[self.domain]:
444
+ raise ValidationError(
445
+ "STATE-Bench tool_names must preserve the pinned official domain tool order"
446
+ )
447
+
448
+ capabilities = dict(self.structural_capabilities)
449
+ if not set(capabilities) <= _ALLOWED_CAPABILITIES:
450
+ raise ValidationError(
451
+ "STATE-Bench checkpoint contains unknown structural capabilities; "
452
+ "gold, defect labels, and task requirements are not eligibility inputs"
453
+ )
454
+ if any(not isinstance(value, bool) for value in capabilities.values()):
455
+ raise ValidationError("STATE-Bench checkpoint structural capabilities must be boolean")
456
+ object.__setattr__(self, "visible_messages", messages)
457
+ object.__setattr__(self, "visible_context", context)
458
+ object.__setattr__(self, "tool_names", tool_names)
459
+ object.__setattr__(
460
+ self,
461
+ "structural_capabilities",
462
+ MappingProxyType(capabilities),
463
+ )
464
+
465
+ @property
466
+ def replay_ready(self) -> bool:
467
+ continuation = self.structural_capabilities.get("continuation_available", False)
468
+ if self.turn_index == 0:
469
+ reset = self.structural_capabilities.get("fresh_task_reset_available", False)
470
+ else:
471
+ reset = self.structural_capabilities.get("mid_dialogue_clone_available", False)
472
+ return continuation and reset
473
+
474
+ @property
475
+ def family_eligibility(self) -> StateBenchFamilyEligibility:
476
+ replay_ready = self.replay_ready
477
+ read_tool_available = bool(set(self.tool_names) & _OFFICIAL_READ_TOOL_NAMES[self.domain])
478
+ clarification = (
479
+ replay_ready
480
+ and self.turn_index < STATEBENCH_OFFICIAL_MAX_AGENT_TURNS - 1
481
+ and self.structural_capabilities.get(
482
+ "clarification_roundtrip_available",
483
+ False,
484
+ )
485
+ )
486
+ curation_material = len(self.visible_messages) >= 3 or len(self.visible_context) >= 2
487
+ eligibility = {
488
+ SemanticFamily.REFORMULATE.value: replay_ready,
489
+ SemanticFamily.DECOMPOSE.value: replay_ready,
490
+ SemanticFamily.ACQUIRE.value: replay_ready and read_tool_available,
491
+ SemanticFamily.CLARIFY.value: clarification,
492
+ SemanticFamily.CURATE.value: replay_ready and curation_material,
493
+ }
494
+ reset_requirement = (
495
+ "fresh_task_reset_available=true"
496
+ if self.turn_index == 0
497
+ else "mid_dialogue_clone_available=true"
498
+ )
499
+ replay_reason = (
500
+ "checkpoint has a bound continuation and reset/clone contract"
501
+ if replay_ready
502
+ else f"requires continuation_available=true and {reset_requirement}"
503
+ )
504
+ reasons = {
505
+ SemanticFamily.REFORMULATE.value: replay_reason,
506
+ SemanticFamily.DECOMPOSE.value: replay_reason,
507
+ SemanticFamily.ACQUIRE.value: (
508
+ "checkpoint is replayable and exposes official read/domain tools"
509
+ if replay_ready and read_tool_available
510
+ else "requires replayability and at least one pinned official read tool"
511
+ ),
512
+ SemanticFamily.CLARIFY.value: (
513
+ "official user-simulator continuation is caller-asserted and a turn remains"
514
+ if clarification
515
+ else "requires replayability, clarification_roundtrip_available=true, "
516
+ "and turn_index < 14"
517
+ ),
518
+ SemanticFamily.CURATE.value: (
519
+ "checkpoint is replayable and has enough visible history/context to curate"
520
+ if replay_ready and curation_material
521
+ else "requires replayability plus at least three visible messages "
522
+ "or two visible context blocks"
523
+ ),
524
+ }
525
+ return StateBenchFamilyEligibility(self.checkpoint_id, eligibility, reasons)
526
+
527
+
528
+ @dataclass(frozen=True, slots=True)
529
+ class StateBenchEvaluationResult:
530
+ """Official-shaped metrics for one externally evaluated trajectory."""
531
+
532
+ task_completion_pass: int
533
+ state_requirements_met: int
534
+ task_requirements_met: int
535
+ ux_score: float
536
+ cost_usd: float
537
+ turns: int
538
+ tool_calls: int
539
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
540
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_BRIDGE)
541
+ official_runtime_verified: bool = field(init=False, default=False)
542
+
543
+ def __post_init__(self) -> None:
544
+ state = _binary_metric(self.state_requirements_met, "state_requirements_met")
545
+ task = _binary_metric(self.task_requirements_met, "task_requirements_met")
546
+ completion = _binary_metric(self.task_completion_pass, "task_completion_pass")
547
+ if completion != int(state == 1 and task == 1):
548
+ raise ValidationError(
549
+ "STATE-Bench task_completion_pass must be the conjunction of "
550
+ "state_requirements_met and task_requirements_met"
551
+ )
552
+ ux = _finite_number(self.ux_score, "ux_score")
553
+ if not 1.0 <= ux <= 5.0:
554
+ raise ValidationError("STATE-Bench ux_score must be in [1, 5]")
555
+ cost = _finite_number(self.cost_usd, "cost_usd")
556
+ if cost < 0:
557
+ raise ValidationError("STATE-Bench cost_usd must be non-negative")
558
+ turns = _bounded_integer(
559
+ self.turns,
560
+ "turns",
561
+ minimum=1,
562
+ maximum=STATEBENCH_OFFICIAL_MAX_AGENT_TURNS,
563
+ )
564
+ tool_calls = _bounded_integer(self.tool_calls, "tool_calls", minimum=0)
565
+ object.__setattr__(self, "task_completion_pass", completion)
566
+ object.__setattr__(self, "state_requirements_met", state)
567
+ object.__setattr__(self, "task_requirements_met", task)
568
+ object.__setattr__(self, "ux_score", ux)
569
+ object.__setattr__(self, "cost_usd", cost)
570
+ object.__setattr__(self, "turns", turns)
571
+ object.__setattr__(self, "tool_calls", tool_calls)
572
+
573
+ @property
574
+ def metrics(self) -> Mapping[str, float]:
575
+ return MappingProxyType(
576
+ {
577
+ "cost_usd": self.cost_usd,
578
+ "state_requirements_met": float(self.state_requirements_met),
579
+ "task_completion_pass": float(self.task_completion_pass),
580
+ "task_requirements_met": float(self.task_requirements_met),
581
+ "tool_calls": float(self.tool_calls),
582
+ "turns": float(self.turns),
583
+ "ux_score": self.ux_score,
584
+ }
585
+ )
586
+
587
+
588
+ @runtime_checkable
589
+ class StateBenchEvaluationBridge(Protocol):
590
+ """External owner of STATE-Bench reset, continuation, and official scoring."""
591
+
592
+ bridge_id: str
593
+ bridge_revision: str
594
+ source_revision: str
595
+ protocol_id: str
596
+ protocol_revision: str
597
+ cost_basis: str
598
+ provenance_status: str
599
+ evaluation_scope: str
600
+ official_runtime_verified: bool
601
+ preserves_domain_tools: bool
602
+ preserves_user_simulator: bool
603
+ preserves_scorer: bool
604
+ preserves_turn_limit: bool
605
+ supports_fresh_task_reset: bool
606
+ supports_mid_dialogue_clone: bool
607
+ supports_simulator_replay: bool
608
+
609
+ def evaluate(
610
+ self,
611
+ checkpoint: StateBenchCheckpoint,
612
+ prediction: Any,
613
+ ) -> StateBenchEvaluationResult: ...
614
+
615
+
616
+ @dataclass(frozen=True, slots=True)
617
+ class CallerAssertedStateBenchEvaluationBridge:
618
+ """Typed wrapper for an external, not-yet-attested STATE-Bench runtime."""
619
+
620
+ bridge_id: str
621
+ bridge_revision: str
622
+ callback: Callable[[StateBenchCheckpoint, Any], StateBenchEvaluationResult] = field(repr=False)
623
+ supports_fresh_task_reset: bool
624
+ supports_mid_dialogue_clone: bool
625
+ supports_simulator_replay: bool
626
+ preserves_domain_tools: bool
627
+ preserves_user_simulator: bool
628
+ preserves_scorer: bool
629
+ preserves_turn_limit: bool
630
+ source_revision: str = STATEBENCH_OFFICIAL_SOURCE_REVISION
631
+ protocol_id: str = STATEBENCH_OFFICIAL_PROTOCOL_ID
632
+ protocol_revision: str = STATEBENCH_OFFICIAL_PROTOCOL_REVISION
633
+ cost_basis: str = _OFFICIAL_COST_BASIS
634
+ provenance_status: str = field(init=False, default=_CALLER_ASSERTED)
635
+ evaluation_scope: str = field(init=False, default=_EXTERNAL_BRIDGE)
636
+ official_runtime_verified: bool = field(init=False, default=False)
637
+
638
+ def __post_init__(self) -> None:
639
+ _validate_bridge(self)
640
+ if not callable(self.callback):
641
+ raise TypeError("STATE-Bench evaluation bridge callback must be callable")
642
+
643
+ def evaluate(
644
+ self,
645
+ checkpoint: StateBenchCheckpoint,
646
+ prediction: Any,
647
+ ) -> StateBenchEvaluationResult:
648
+ result = self.callback(checkpoint, prediction)
649
+ if not isinstance(result, StateBenchEvaluationResult):
650
+ raise ValidationError(
651
+ "STATE-Bench callback must return StateBenchEvaluationResult; "
652
+ "bare metric mappings are not accepted"
653
+ )
654
+ if (
655
+ result.provenance_status != self.provenance_status
656
+ or result.evaluation_scope != self.evaluation_scope
657
+ or result.official_runtime_verified is not False
658
+ ):
659
+ raise ValidationError(
660
+ "STATE-Bench result provenance differs from its caller-asserted bridge"
661
+ )
662
+ return result
663
+
664
+
665
+ class StateBenchCheckpointAdapter:
666
+ """Adapter over externally captured STATE-Bench pre-action checkpoints."""
667
+
668
+ benchmark_id = STATEBENCH_BENCHMARK_ID
669
+ adapter_metric_names = (
670
+ "task_completion_pass",
671
+ "state_requirements_met",
672
+ "task_requirements_met",
673
+ "ux_score",
674
+ "cost_usd",
675
+ "turns",
676
+ "tool_calls",
677
+ )
678
+ split = STATEBENCH_EXTERNAL_SPLIT
679
+ pairing_mode = "unsupported_external_replay"
680
+
681
+ def __init__(
682
+ self,
683
+ *,
684
+ checkpoints: Iterable[StateBenchCheckpoint],
685
+ evaluation_bridge: StateBenchEvaluationBridge,
686
+ ) -> None:
687
+ if not isinstance(evaluation_bridge, StateBenchEvaluationBridge):
688
+ raise TypeError(
689
+ "evaluation_bridge must implement StateBenchEvaluationBridge; wrap callbacks "
690
+ "with CallerAssertedStateBenchEvaluationBridge"
691
+ )
692
+ _validate_bridge(evaluation_bridge)
693
+ normalized = tuple(checkpoints)
694
+ if not normalized:
695
+ raise ValidationError(
696
+ "STATE-Bench adapter requires at least one captured visible checkpoint"
697
+ )
698
+ if not all(isinstance(item, StateBenchCheckpoint) for item in normalized):
699
+ raise TypeError("STATE-Bench checkpoints must be StateBenchCheckpoint instances")
700
+ checkpoint_ids = [item.checkpoint_id for item in normalized]
701
+ if len(checkpoint_ids) != len(set(checkpoint_ids)):
702
+ raise ValidationError("STATE-Bench checkpoint IDs must be unique")
703
+ experimental_units = [
704
+ (item.domain, item.task_id, item.run_index, item.turn_index) for item in normalized
705
+ ]
706
+ if len(experimental_units) != len(set(experimental_units)):
707
+ raise ValidationError(
708
+ "STATE-Bench experimental units "
709
+ "(domain, task_id, run_index, turn_index) must be unique"
710
+ )
711
+
712
+ examples: list[BenchmarkExample] = []
713
+ checkpoints_by_id: dict[str, StateBenchCheckpoint] = {}
714
+ for checkpoint in sorted(normalized, key=lambda item: item.checkpoint_id):
715
+ _validate_checkpoint_replay_contract(checkpoint, evaluation_bridge)
716
+ support = checkpoint.family_eligibility
717
+ visible_metadata = _frozen_mapping(
718
+ {
719
+ "benchmark_cell": self.benchmark_id,
720
+ "domain": checkpoint.domain,
721
+ "family_eligibility": dict(support.eligibility),
722
+ "family_eligibility_provenance": support.provenance_status,
723
+ "family_eligibility_reasons": dict(support.reasons),
724
+ "family_support_status": support.support_status,
725
+ "official_protocol_id": checkpoint.protocol_id,
726
+ "official_source_revision": checkpoint.source_revision,
727
+ "run_index": checkpoint.run_index,
728
+ "source_split": checkpoint.source_split,
729
+ "turn_index": checkpoint.turn_index,
730
+ },
731
+ label="STATE-Bench visible checkpoint metadata",
732
+ )
733
+ examples.append(
734
+ BenchmarkExample(
735
+ example_id=checkpoint.checkpoint_id,
736
+ query=checkpoint.query,
737
+ instruction=checkpoint.instruction,
738
+ visible_context=checkpoint.visible_context,
739
+ visible_messages=checkpoint.visible_messages,
740
+ visible_tool_names=checkpoint.tool_names,
741
+ visible_metadata=visible_metadata,
742
+ evaluator_gold=MappingProxyType({}),
743
+ optimizer_visible_id=opaque_checkpoint_state_id(
744
+ self.benchmark_id,
745
+ checkpoint.checkpoint_id,
746
+ checkpoint.replay_identity,
747
+ ),
748
+ )
749
+ )
750
+ checkpoints_by_id[checkpoint.checkpoint_id] = checkpoint
751
+
752
+ self._evaluation_bridge = evaluation_bridge
753
+ self._examples = tuple(examples)
754
+ self._examples_by_id = {example.example_id: example for example in examples}
755
+ self._checkpoints = MappingProxyType(checkpoints_by_id)
756
+
757
+ def examples(self, split: str) -> tuple[BenchmarkExample, ...]:
758
+ if split != self.split:
759
+ raise ValidationError(
760
+ f"STATE-Bench adapter exposes split {self.split!r}, not {split!r}"
761
+ )
762
+ return self._examples
763
+
764
+ def family_eligibility(self, checkpoint_id: str) -> StateBenchFamilyEligibility:
765
+ return self._checkpoint(checkpoint_id).family_eligibility
766
+
767
+ def eligible_families(self, checkpoint_id: str) -> tuple[SemanticFamily, ...]:
768
+ return self.family_eligibility(checkpoint_id).eligible_families
769
+
770
+ def supports_full_block(self, checkpoint_id: str) -> bool:
771
+ return self.family_eligibility(checkpoint_id).supports_full_block
772
+
773
+ def score(self, example: BenchmarkExample, prediction: Any) -> Mapping[str, float]:
774
+ if not isinstance(example, BenchmarkExample):
775
+ raise TypeError("example must be a BenchmarkExample")
776
+ if self._examples_by_id.get(example.example_id) is not example:
777
+ raise ValidationError("benchmark example does not belong to this STATE-Bench adapter")
778
+ checkpoint = self._checkpoints[example.example_id]
779
+ result = self._evaluation_bridge.evaluate(checkpoint, prediction)
780
+ if not isinstance(result, StateBenchEvaluationResult):
781
+ raise ValidationError("STATE-Bench evaluation bridge returned an invalid result type")
782
+ return result.metrics
783
+
784
+ @property
785
+ def evaluation_provenance(self) -> Mapping[str, Any]:
786
+ return _frozen_mapping(
787
+ {
788
+ "bridge_id": self._evaluation_bridge.bridge_id,
789
+ "bridge_revision": self._evaluation_bridge.bridge_revision,
790
+ "cost_basis": self._evaluation_bridge.cost_basis,
791
+ "evaluation_scope": self._evaluation_bridge.evaluation_scope,
792
+ "official_runtime_verified": self._evaluation_bridge.official_runtime_verified,
793
+ "preserves_domain_tools": self._evaluation_bridge.preserves_domain_tools,
794
+ "preserves_scorer": self._evaluation_bridge.preserves_scorer,
795
+ "preserves_turn_limit": self._evaluation_bridge.preserves_turn_limit,
796
+ "preserves_user_simulator": (self._evaluation_bridge.preserves_user_simulator),
797
+ "protocol_id": self._evaluation_bridge.protocol_id,
798
+ "protocol_revision": self._evaluation_bridge.protocol_revision,
799
+ "provenance_status": self._evaluation_bridge.provenance_status,
800
+ "source_revision": self._evaluation_bridge.source_revision,
801
+ "supports_fresh_task_reset": (self._evaluation_bridge.supports_fresh_task_reset),
802
+ "supports_mid_dialogue_clone": (
803
+ self._evaluation_bridge.supports_mid_dialogue_clone
804
+ ),
805
+ "supports_simulator_replay": (self._evaluation_bridge.supports_simulator_replay),
806
+ },
807
+ label="STATE-Bench evaluation provenance",
808
+ )
809
+
810
+ def _checkpoint(self, checkpoint_id: str) -> StateBenchCheckpoint:
811
+ try:
812
+ return self._checkpoints[checkpoint_id]
813
+ except KeyError as exc:
814
+ raise ValidationError(f"unknown STATE-Bench checkpoint {checkpoint_id!r}") from exc
815
+
816
+
817
+ def _validate_checkpoint_replay_contract(
818
+ checkpoint: StateBenchCheckpoint,
819
+ bridge: StateBenchEvaluationBridge,
820
+ ) -> None:
821
+ if not checkpoint.replay_ready:
822
+ raise ValidationError(
823
+ "STATE-Bench checkpoint lacks a continuation plus reset/clone contract"
824
+ )
825
+ if checkpoint.turn_index == 0 and not bridge.supports_fresh_task_reset:
826
+ raise ValidationError(
827
+ "STATE-Bench turn-zero checkpoint requires bridge fresh-task reset support"
828
+ )
829
+ if checkpoint.turn_index > 0 and not bridge.supports_mid_dialogue_clone:
830
+ raise ValidationError("STATE-Bench mid-dialogue checkpoint requires bridge clone support")
831
+ if (
832
+ checkpoint.turn_index < STATEBENCH_OFFICIAL_MAX_AGENT_TURNS - 1
833
+ and not bridge.supports_simulator_replay
834
+ ):
835
+ raise ValidationError(
836
+ "STATE-Bench checkpoint with a remaining user turn requires bridge simulator replay"
837
+ )
838
+
839
+
840
+ def _validate_bridge(bridge: StateBenchEvaluationBridge) -> None:
841
+ _require_trimmed_string(bridge.bridge_id, "STATE-Bench evaluation bridge bridge_id")
842
+ _require_sha256(
843
+ bridge.bridge_revision,
844
+ "STATE-Bench evaluation bridge bridge_revision",
845
+ )
846
+ if bridge.source_revision != STATEBENCH_OFFICIAL_SOURCE_REVISION:
847
+ raise ValidationError("STATE-Bench evaluation bridge source revision differs from the pin")
848
+ if bridge.protocol_id != STATEBENCH_OFFICIAL_PROTOCOL_ID:
849
+ raise ValidationError("STATE-Bench evaluation bridge protocol ID differs from the pin")
850
+ if bridge.protocol_revision != STATEBENCH_OFFICIAL_PROTOCOL_REVISION:
851
+ raise ValidationError(
852
+ "STATE-Bench evaluation bridge protocol revision differs from the pin"
853
+ )
854
+ if bridge.cost_basis != _OFFICIAL_COST_BASIS:
855
+ raise ValidationError("STATE-Bench evaluation bridge cost basis must be agent_reported_usd")
856
+ if bridge.provenance_status != _CALLER_ASSERTED:
857
+ raise ValidationError("STATE-Bench bridge provenance must remain caller_asserted")
858
+ if bridge.evaluation_scope != _EXTERNAL_BRIDGE:
859
+ raise ValidationError(
860
+ "STATE-Bench bridge evaluation scope must remain external_single_trajectory"
861
+ )
862
+ if bridge.official_runtime_verified is not False:
863
+ raise ValidationError(
864
+ "the external STATE-Bench bridge cannot claim official runtime verification"
865
+ )
866
+ for label in (
867
+ "preserves_domain_tools",
868
+ "preserves_user_simulator",
869
+ "preserves_scorer",
870
+ "preserves_turn_limit",
871
+ ):
872
+ if getattr(bridge, label) is not True:
873
+ raise ValidationError(f"STATE-Bench evaluation bridge must set {label}=true")
874
+ for label in (
875
+ "supports_fresh_task_reset",
876
+ "supports_mid_dialogue_clone",
877
+ "supports_simulator_replay",
878
+ ):
879
+ if not isinstance(getattr(bridge, label), bool):
880
+ raise ValidationError(f"STATE-Bench evaluation bridge {label} must be boolean")
881
+
882
+
883
+ def _validate_task_id(value: Any, *, domain: str, source_split: str) -> None:
884
+ if not isinstance(value, str) or value != value.strip():
885
+ raise ValidationError("STATE-Bench task_id must be a trimmed official-style ID")
886
+ match = _TASK_ID.fullmatch(value)
887
+ if match is None or not 1 <= int(match.group("number")) <= 150:
888
+ raise ValidationError("STATE-Bench task_id must use an active numeric prefix in [1, 150]")
889
+ if value not in STATEBENCH_OFFICIAL_TASK_IDS_BY_SPLIT[source_split][domain]:
890
+ raise ValidationError(
891
+ f"STATE-Bench task_id is not a pinned v0.8.1 {source_split} task for domain {domain!r}"
892
+ )
893
+
894
+
895
+ def _require_trimmed_string(value: Any, label: str) -> None:
896
+ if not isinstance(value, str) or not value.strip() or value != value.strip():
897
+ raise ValidationError(f"{label} must be a trimmed non-empty string")
898
+
899
+
900
+ def _require_sha256(value: Any, label: str) -> None:
901
+ if not isinstance(value, str) or _SHA256.fullmatch(value) is None:
902
+ raise ValidationError(f"{label} must be a lowercase SHA-256")
903
+
904
+
905
+ def _binary_metric(value: Any, label: str) -> int:
906
+ if isinstance(value, bool) or not isinstance(value, int) or value not in {0, 1}:
907
+ raise ValidationError(f"STATE-Bench {label} must be integer 0 or 1")
908
+ return value
909
+
910
+
911
+ def _finite_number(value: Any, label: str) -> float:
912
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
913
+ raise ValidationError(f"STATE-Bench {label} must be numeric")
914
+ numeric = float(value)
915
+ if not math.isfinite(numeric):
916
+ raise ValidationError(f"STATE-Bench {label} must be finite")
917
+ return numeric
918
+
919
+
920
+ def _bounded_integer(
921
+ value: Any,
922
+ label: str,
923
+ *,
924
+ minimum: int,
925
+ maximum: int | None = None,
926
+ ) -> int:
927
+ if isinstance(value, bool) or not isinstance(value, int) or value < minimum:
928
+ raise ValidationError(f"STATE-Bench {label} must be an integer >= {minimum}")
929
+ if maximum is not None and value > maximum:
930
+ raise ValidationError(f"STATE-Bench {label} must be an integer <= {maximum}")
931
+ return value
932
+
933
+
934
+ def _frozen_mapping(value: Mapping[str, Any], *, label: str) -> Mapping[str, Any]:
935
+ try:
936
+ return freeze_mapping(value)
937
+ except TypeError as exc:
938
+ raise ValidationError(f"{label} must be canonically serializable: {exc}") from exc