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,102 @@
1
+ """Immutable, schema-only tool connector for planning interventions.
2
+
3
+ The connector exposes an audited snapshot of an arena's tool declarations but
4
+ cannot execute them. Execution remains inside the official arena after the
5
+ input intervention has been materialized.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Mapping, Sequence
11
+ from dataclasses import dataclass
12
+ from typing import Any
13
+
14
+ from agentinputlab.contracts.errors import ValidationError
15
+ from agentinputlab.contracts.serialization import content_hash
16
+
17
+ from .base import ToolCall, ToolConnector, ToolResult, ToolSpec
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class SchemaOnlyToolConnector(ToolConnector):
22
+ """Expose frozen tool schemas while denying every execution request."""
23
+
24
+ specs: tuple[ToolSpec, ...]
25
+ connector_id: str = "schema-only-tools"
26
+
27
+ def __post_init__(self) -> None:
28
+ if not self.connector_id.strip():
29
+ raise ValidationError("schema-only connector requires a non-empty ID")
30
+ object.__setattr__(self, "specs", tuple(self.specs))
31
+ if not self.specs:
32
+ raise ValidationError("schema-only connector requires at least one tool")
33
+ if any(not isinstance(spec, ToolSpec) for spec in self.specs):
34
+ raise TypeError("schema-only connector specs must contain ToolSpec values")
35
+ names = tuple(spec.name for spec in self.specs)
36
+ if len(names) != len(set(names)):
37
+ raise ValidationError("schema-only connector tool names must be unique")
38
+
39
+ def list_tools(self) -> tuple[ToolSpec, ...]:
40
+ return self.specs
41
+
42
+ def call(self, request: ToolCall) -> ToolResult:
43
+ if not isinstance(request, ToolCall):
44
+ raise TypeError("schema-only connector requires ToolCall")
45
+ return ToolResult(
46
+ call_id=request.call_id,
47
+ error=(
48
+ "schema-only connector cannot execute tools; execution belongs to "
49
+ "the official downstream arena"
50
+ ),
51
+ metadata={"denied": True, "connector_id": self.connector_id},
52
+ )
53
+
54
+ def fingerprint(self) -> Mapping[str, Any]:
55
+ return {
56
+ "implementation": "agentinputlab.schema_only_tool_connector.v1",
57
+ "connector_id": self.connector_id,
58
+ "execution_policy": "deny_all.v1",
59
+ "tool_schema_hash": content_hash(self.specs),
60
+ }
61
+
62
+ @classmethod
63
+ def from_openai_definitions(
64
+ cls,
65
+ definitions: Sequence[Mapping[str, Any]],
66
+ *,
67
+ connector_id: str = "schema-only-tools",
68
+ ) -> SchemaOnlyToolConnector:
69
+ """Normalize OpenAI-style or bare function declarations."""
70
+
71
+ if isinstance(definitions, (str, bytes)) or not isinstance(definitions, Sequence):
72
+ raise ValidationError("tool definitions must be a sequence")
73
+ specs: list[ToolSpec] = []
74
+ for index, raw in enumerate(definitions):
75
+ if not isinstance(raw, Mapping):
76
+ raise ValidationError(f"tool definition {index} must be an object")
77
+ function = raw.get("function", raw)
78
+ if not isinstance(function, Mapping):
79
+ raise ValidationError(f"tool definition {index} function must be an object")
80
+ name = function.get("name")
81
+ description = function.get("description")
82
+ parameters = function.get("parameters", function.get("input_schema", {}))
83
+ if not isinstance(name, str) or not name.strip():
84
+ raise ValidationError(f"tool definition {index} requires a name")
85
+ if not isinstance(description, str) or not description.strip():
86
+ raise ValidationError(f"tool definition {index} requires a description")
87
+ if not isinstance(parameters, Mapping):
88
+ raise ValidationError(f"tool definition {index} parameters must be an object")
89
+ specs.append(
90
+ ToolSpec(
91
+ name=name,
92
+ description=description,
93
+ input_schema=dict(parameters),
94
+ # Schema-only snapshots do not assert mutability or networking.
95
+ read_only=False,
96
+ network=False,
97
+ )
98
+ )
99
+ return cls(tuple(specs), connector_id=connector_id)
100
+
101
+
102
+ __all__ = ["SchemaOnlyToolConnector"]
@@ -0,0 +1,91 @@
1
+ """Core state, patch, contract, provenance, materialization, and trace APIs."""
2
+
3
+ from .availability import RunnerKind, RuntimeProbe
4
+ from .dependency import DependencyBinding, DependencyRole, TreatmentDefinition
5
+ from .enums import (
6
+ ExecutionKind,
7
+ ImplementationKind,
8
+ PatchOp,
9
+ ProfileKind,
10
+ ReleaseTier,
11
+ SemanticFamily,
12
+ SupportStatus,
13
+ TracePhase,
14
+ )
15
+ from .errors import (
16
+ AgentInputLabError,
17
+ AlgorithmOutputError,
18
+ AlgorithmUnavailableError,
19
+ ArmExecutionError,
20
+ ArtifactError,
21
+ BalanceError,
22
+ BudgetExceededError,
23
+ CapabilityError,
24
+ ExternalDependencyError,
25
+ IntentViolationError,
26
+ RegistryError,
27
+ StateConflictError,
28
+ ValidationError,
29
+ )
30
+ from .evidence import Evidence, EvidenceKind
31
+ from .intent import IntentCheck, IntentContract, check_intent_contract
32
+ from .lifecycle import (
33
+ CompositeIntervention,
34
+ CompositeResult,
35
+ Intervention,
36
+ InterventionContext,
37
+ OfflineRecipe,
38
+ )
39
+ from .patch import InputPatch, PatchOperation
40
+ from .state import ContextBlock, ExecutionBudget, FrozenAgentState, Message
41
+ from .trace import ExecutionTrace, TraceEvent
42
+ from .worker import WorkerRequest, WorkerResponse
43
+
44
+ __all__ = [
45
+ "AgentInputLabError",
46
+ "AlgorithmOutputError",
47
+ "AlgorithmUnavailableError",
48
+ "ArmExecutionError",
49
+ "ArtifactError",
50
+ "BalanceError",
51
+ "BudgetExceededError",
52
+ "CapabilityError",
53
+ "CompositeIntervention",
54
+ "CompositeResult",
55
+ "ContextBlock",
56
+ "DependencyBinding",
57
+ "DependencyRole",
58
+ "Evidence",
59
+ "EvidenceKind",
60
+ "ExecutionBudget",
61
+ "ExecutionKind",
62
+ "ExecutionTrace",
63
+ "ExternalDependencyError",
64
+ "FrozenAgentState",
65
+ "ImplementationKind",
66
+ "InputPatch",
67
+ "IntentCheck",
68
+ "IntentContract",
69
+ "IntentViolationError",
70
+ "Intervention",
71
+ "InterventionContext",
72
+ "Message",
73
+ "OfflineRecipe",
74
+ "PatchOp",
75
+ "PatchOperation",
76
+ "ProfileKind",
77
+ "RegistryError",
78
+ "ReleaseTier",
79
+ "RunnerKind",
80
+ "RuntimeProbe",
81
+ "SemanticFamily",
82
+ "StateConflictError",
83
+ "SupportStatus",
84
+ "TraceEvent",
85
+ "TracePhase",
86
+ "TreatmentDefinition",
87
+ "ValidationError",
88
+ "WorkerRequest",
89
+ "WorkerResponse",
90
+ "check_intent_contract",
91
+ ]
@@ -0,0 +1,24 @@
1
+ """Runtime availability is separate from source-audit status."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from .enums import StrEnum
8
+
9
+
10
+ class RunnerKind(StrEnum):
11
+ CORE = "core"
12
+ OPTIONAL_EXTRA = "optional_extra"
13
+ EXTERNAL_WORKER = "external_worker"
14
+ REPLAY_ONLY = "replay_only"
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class RuntimeProbe:
19
+ available: bool
20
+ runner_kind: RunnerKind
21
+ missing_extras: tuple[str, ...] = ()
22
+ missing_artifacts: tuple[str, ...] = ()
23
+ upstream_revision: str | None = None
24
+ reason: str = ""
@@ -0,0 +1,58 @@
1
+ """Dependency-slot identities used by controlled and factorial comparisons."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from dataclasses import dataclass, field
7
+ from typing import Any
8
+
9
+ from .enums import StrEnum
10
+ from .errors import ValidationError
11
+ from .serialization import content_hash, freeze_mapping
12
+
13
+
14
+ class DependencyRole(StrEnum):
15
+ TREATMENT = "treatment"
16
+ NUISANCE = "nuisance"
17
+ CROSSED = "crossed"
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class DependencyBinding:
22
+ slot: str
23
+ role: DependencyRole
24
+ implementation_id: str
25
+ revision: str
26
+ config: Mapping[str, Any] = field(default_factory=dict)
27
+
28
+ def __post_init__(self) -> None:
29
+ if not self.slot or not self.implementation_id:
30
+ raise ValidationError("dependency binding requires slot and implementation_id")
31
+ try:
32
+ object.__setattr__(self, "config", freeze_mapping(self.config))
33
+ except TypeError as exc:
34
+ raise ValidationError(
35
+ f"dependency binding config must be canonically serializable: {exc}"
36
+ ) from exc
37
+
38
+ @property
39
+ def resolved_hash(self) -> str:
40
+ return content_hash(self)
41
+
42
+
43
+ @dataclass(frozen=True, slots=True)
44
+ class TreatmentDefinition:
45
+ method_id: str
46
+ release_id: str
47
+ treatment_slots: tuple[str, ...]
48
+ nuisance_slots: tuple[str, ...] = ()
49
+ crossed_slots: tuple[str, ...] = ()
50
+
51
+ def __post_init__(self) -> None:
52
+ groups = [
53
+ set(self.treatment_slots),
54
+ set(self.nuisance_slots),
55
+ set(self.crossed_slots),
56
+ ]
57
+ if any(groups[i] & groups[j] for i in range(3) for j in range(i + 1, 3)):
58
+ raise ValidationError("treatment, nuisance, and crossed slots must be disjoint")
@@ -0,0 +1,82 @@
1
+ """Stable public enums used by manifests, traces, and result files."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+
7
+
8
+ class StrEnum(str, Enum):
9
+ """Python 3.10-compatible string enum."""
10
+
11
+ def __str__(self) -> str:
12
+ return self.value
13
+
14
+
15
+ class SemanticFamily(StrEnum):
16
+ REFORMULATE = "reformulate"
17
+ DECOMPOSE = "decompose"
18
+ ACQUIRE = "acquire"
19
+ CLARIFY = "clarify"
20
+ CURATE = "curate"
21
+ COMPOSITE = "composite"
22
+ NO_OP = "no_op"
23
+
24
+
25
+ class ReleaseTier(StrEnum):
26
+ CORE = "core"
27
+ OPTIONAL = "optional"
28
+
29
+
30
+ class ExecutionKind(StrEnum):
31
+ RUNTIME = "runtime"
32
+ COMPONENT = "component"
33
+ COMPOSITE = "composite"
34
+ TRAINING_RECIPE = "training_recipe"
35
+ ARTIFACT_REPLAY = "artifact_replay"
36
+
37
+
38
+ class ImplementationKind(StrEnum):
39
+ OFFICIAL_ADAPTER = "official_adapter"
40
+ COMMUNITY_IMPLEMENTATION = "community_implementation"
41
+ PAPER_REIMPLEMENTATION = "paper_reimplementation"
42
+ THIN_EXTERNAL_WRAPPER = "thin_external_wrapper"
43
+ ARTIFACT_REPLAY = "artifact_replay"
44
+
45
+
46
+ class ProfileKind(StrEnum):
47
+ OFFICIAL_NATIVE = "official_native"
48
+ CONTROLLED_ADAPTER = "controlled_adapter"
49
+ FACTORIAL_ADAPTER = "factorial_adapter"
50
+
51
+
52
+ class SupportStatus(StrEnum):
53
+ SOURCE_AUDITED = "source_audited"
54
+ PLANNED = "planned"
55
+ EXTERNAL_ONLY = "external_only"
56
+ NATIVE_ONLY = "native_only"
57
+ RETRAIN_REQUIRED = "retrain_required"
58
+ BLOCKED = "blocked"
59
+ EXPERIMENTAL = "experimental"
60
+ SUPPORTED = "supported"
61
+
62
+
63
+ class PatchOp(StrEnum):
64
+ REPLACE_QUERY = "replace_query"
65
+ APPEND_QUERY = "append_query"
66
+ REPLACE_INSTRUCTION = "replace_instruction"
67
+ APPEND_INSTRUCTION = "append_instruction"
68
+ ADD_CONTEXT = "add_context"
69
+ REPLACE_CONTEXT = "replace_context"
70
+ ADD_MESSAGE = "add_message"
71
+ REPLACE_MESSAGES = "replace_messages"
72
+ SET_METADATA = "set_metadata"
73
+ REQUEST_CLARIFICATION = "request_clarification"
74
+ NO_OP = "no_op"
75
+
76
+
77
+ class TracePhase(StrEnum):
78
+ PREPARE = "prepare"
79
+ PROPOSE = "propose"
80
+ OBSERVE = "observe"
81
+ FINALIZE = "finalize"
82
+ ERROR = "error"
@@ -0,0 +1,63 @@
1
+ """Public exception hierarchy.
2
+
3
+ The library uses typed errors instead of silent fallbacks. A benchmark run must
4
+ be able to distinguish an unavailable upstream asset from an algorithm deciding
5
+ to return ``NO_OP``.
6
+ """
7
+
8
+
9
+ class AgentInputLabError(Exception):
10
+ """Base class for all expected library errors."""
11
+
12
+
13
+ class ValidationError(AgentInputLabError, ValueError):
14
+ """A state, patch, manifest, or configuration violates its schema."""
15
+
16
+
17
+ class ArmExecutionError(ValidationError):
18
+ """An expected execution failure invalidates one experimental arm only.
19
+
20
+ This marker remains a :class:`ValidationError` for API compatibility, but
21
+ paired-study orchestration can distinguish it from invalid experiment
22
+ configuration without inspecting exception messages or traceback text.
23
+ """
24
+
25
+
26
+ class AlgorithmOutputError(ArmExecutionError):
27
+ """A model, embedder, retriever, or algorithm emitted an invalid result."""
28
+
29
+
30
+ class StateConflictError(AgentInputLabError):
31
+ """A patch was applied to a state other than the one it was proposed for."""
32
+
33
+
34
+ class CapabilityError(AgentInputLabError):
35
+ """A backend or connector lacks a capability required by a profile."""
36
+
37
+
38
+ class AlgorithmUnavailableError(AgentInputLabError):
39
+ """A registered profile cannot run in the current environment."""
40
+
41
+
42
+ class ExternalDependencyError(AlgorithmUnavailableError):
43
+ """An optional upstream checkout, package, model, or service is unavailable."""
44
+
45
+
46
+ class ArtifactError(AgentInputLabError):
47
+ """An artifact is absent, corrupt, unsafe, or has the wrong lineage."""
48
+
49
+
50
+ class RegistryError(AgentInputLabError):
51
+ """The algorithm registry is inconsistent or cannot be resolved."""
52
+
53
+
54
+ class BalanceError(AgentInputLabError):
55
+ """A claimed controlled comparison differs on an undeclared dependency."""
56
+
57
+
58
+ class BudgetExceededError(AgentInputLabError):
59
+ """A profile attempted to exceed a declared execution budget."""
60
+
61
+
62
+ class IntentViolationError(AgentInputLabError):
63
+ """An intervention violated a runner-enforced observable intent contract."""
@@ -0,0 +1,43 @@
1
+ """Evidence types that keep synthetic retrieval surrogates distinct from sources."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from dataclasses import dataclass, field
7
+ from typing import Any
8
+
9
+ from .enums import StrEnum
10
+ from .errors import ValidationError
11
+ from .serialization import freeze_mapping
12
+
13
+
14
+ class EvidenceKind(StrEnum):
15
+ RETRIEVED_DOCUMENT = "retrieved_document"
16
+ SYNTHETIC_QUERY_SURROGATE = "synthetic_query_surrogate"
17
+ TOOL_OBSERVATION = "tool_observation"
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class Evidence:
22
+ kind: EvidenceKind
23
+ text: str
24
+ evidence_id: str
25
+ source_revision: str = ""
26
+ score: float | None = None
27
+ metadata: Mapping[str, Any] = field(default_factory=dict)
28
+
29
+ def __post_init__(self) -> None:
30
+ object.__setattr__(self, "metadata", freeze_mapping(self.metadata))
31
+ if not self.text:
32
+ raise ValidationError("evidence text must not be empty")
33
+ if self.kind is EvidenceKind.RETRIEVED_DOCUMENT and (
34
+ not self.evidence_id or not self.source_revision
35
+ ):
36
+ raise ValidationError("retrieved evidence requires document id and source revision")
37
+
38
+ @property
39
+ def citable(self) -> bool:
40
+ return self.kind in {
41
+ EvidenceKind.RETRIEVED_DOCUMENT,
42
+ EvidenceKind.TOOL_OBSERVATION,
43
+ }
@@ -0,0 +1,110 @@
1
+ """Intent constraints and evaluator-safe state projection."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from dataclasses import dataclass
7
+
8
+ from .enums import PatchOp
9
+ from .patch import InputPatch
10
+ from .state import FrozenAgentState
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class IntentContract:
15
+ """Observable constraints an intervention must preserve.
16
+
17
+ The contract intentionally contains no evaluator answer or hidden simulator
18
+ state. Gold data belongs to the benchmark evaluator process.
19
+ """
20
+
21
+ required_entities: tuple[str, ...] = ()
22
+ required_constraints: tuple[str, ...] = ()
23
+ forbidden_assumptions: tuple[str, ...] = ()
24
+ may_request_clarification: bool = True
25
+
26
+ def __post_init__(self) -> None:
27
+ for field_name in (
28
+ "required_entities",
29
+ "required_constraints",
30
+ "forbidden_assumptions",
31
+ ):
32
+ values = tuple(getattr(self, field_name))
33
+ if not all(isinstance(value, str) and value.strip() for value in values):
34
+ raise ValueError(f"{field_name} must contain only non-empty strings")
35
+ if len({value.casefold() for value in values}) != len(values):
36
+ raise ValueError(f"{field_name} must not contain duplicate clauses")
37
+ object.__setattr__(self, field_name, values)
38
+ if not isinstance(self.may_request_clarification, bool):
39
+ raise TypeError("may_request_clarification must be a bool")
40
+
41
+
42
+ @dataclass(frozen=True, slots=True)
43
+ class IntentCheck:
44
+ preserved: bool
45
+ missing_entities: tuple[str, ...] = ()
46
+ missing_constraints: tuple[str, ...] = ()
47
+ introduced_assumptions: tuple[str, ...] = ()
48
+
49
+
50
+ def check_intent_contract(
51
+ contract: IntentContract,
52
+ state: FrozenAgentState,
53
+ patch: InputPatch,
54
+ output: FrozenAgentState,
55
+ ) -> IntentCheck:
56
+ """Apply conservative, observable checks without consulting benchmark gold.
57
+
58
+ This is a hard safety gate, not a semantic judge. It only enforces explicit
59
+ strings supplied by the benchmark adapter and the clarification permission.
60
+ Learned or LLM-based intent metrics belong in secondary evaluation.
61
+ """
62
+
63
+ del state
64
+ visible = "\n".join(
65
+ (
66
+ output.query,
67
+ output.instruction,
68
+ *(block.text for block in output.context),
69
+ *(message.content for message in output.messages),
70
+ )
71
+ )
72
+ missing_entities = tuple(
73
+ entity for entity in contract.required_entities if not _contains_phrase(visible, entity)
74
+ )
75
+ missing_constraints = tuple(
76
+ constraint
77
+ for constraint in contract.required_constraints
78
+ if not _contains_phrase(visible, constraint)
79
+ )
80
+ introduced_assumptions = tuple(
81
+ assumption
82
+ for assumption in contract.forbidden_assumptions
83
+ if _contains_phrase(visible, assumption)
84
+ )
85
+ requested_clarification = any(
86
+ operation.op is PatchOp.REQUEST_CLARIFICATION for operation in patch.operations
87
+ )
88
+ clarification_violation = requested_clarification and not contract.may_request_clarification
89
+ if clarification_violation:
90
+ introduced_assumptions = (*introduced_assumptions, "<clarification-not-permitted>")
91
+ return IntentCheck(
92
+ preserved=not missing_entities and not missing_constraints and not introduced_assumptions,
93
+ missing_entities=missing_entities,
94
+ missing_constraints=missing_constraints,
95
+ introduced_assumptions=introduced_assumptions,
96
+ )
97
+
98
+
99
+ def _contains_phrase(text: str, phrase: str) -> bool:
100
+ """Match a normalized contiguous token phrase, never an arbitrary substring."""
101
+
102
+ visible_tokens = tuple(re.findall(r"\w+", text.casefold(), flags=re.UNICODE))
103
+ phrase_tokens = tuple(re.findall(r"\w+", phrase.casefold(), flags=re.UNICODE))
104
+ if not phrase_tokens:
105
+ return False
106
+ width = len(phrase_tokens)
107
+ return any(
108
+ visible_tokens[index : index + width] == phrase_tokens
109
+ for index in range(len(visible_tokens) - width + 1)
110
+ )