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,164 @@
1
+ """Lifecycle-aware intervention protocols.
2
+
3
+ The semantic protocols are deliberately distinct even though all of them return
4
+ an :class:`InputPatch`. This prevents stateful retrieval or clarification from
5
+ being mislabeled as a one-shot string rewriter.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Mapping
11
+ from dataclasses import dataclass, field
12
+ from typing import Any, Protocol, runtime_checkable
13
+
14
+ from .enums import SemanticFamily
15
+ from .errors import ValidationError
16
+ from .intent import IntentContract
17
+ from .patch import InputPatch
18
+ from .serialization import content_hash, freeze_mapping, to_jsonable
19
+ from .state import ContextBlock, FrozenAgentState
20
+ from .trace import ExecutionTrace
21
+
22
+
23
+ @dataclass(frozen=True, slots=True)
24
+ class InterventionContext:
25
+ backend: Any = None
26
+ dense_embedder: Any = None
27
+ retriever: Any = None
28
+ vector_searcher: Any = None
29
+ tools: Any = None
30
+ external_runtime: Any = None
31
+ artifact_manager: Any = None
32
+ seed: int = 0
33
+ run_config: Mapping[str, Any] = field(default_factory=dict)
34
+ intent_contract: IntentContract | None = None
35
+ budget_ledger: Any = None
36
+ monitor: Any = None
37
+ pricing_catalog: Any = None
38
+ strict_intent: bool = True
39
+
40
+ def __post_init__(self) -> None:
41
+ object.__setattr__(self, "run_config", freeze_mapping(self.run_config))
42
+ if isinstance(self.seed, bool) or not isinstance(self.seed, int) or self.seed < 0:
43
+ raise ValidationError("seed must be a non-negative integer")
44
+ if self.intent_contract is not None and not isinstance(
45
+ self.intent_contract, IntentContract
46
+ ):
47
+ raise TypeError("intent_contract must be an IntentContract")
48
+
49
+
50
+ @runtime_checkable
51
+ class Intervention(Protocol):
52
+ method_id: str
53
+ release_id: str
54
+ family: SemanticFamily
55
+
56
+ def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
57
+ """Propose a patch without mutating the frozen state."""
58
+
59
+
60
+ @runtime_checkable
61
+ class Reformulator(Intervention, Protocol):
62
+ family: SemanticFamily
63
+
64
+
65
+ @runtime_checkable
66
+ class Decomposer(Intervention, Protocol):
67
+ family: SemanticFamily
68
+
69
+
70
+ @runtime_checkable
71
+ class EvidenceAcquirer(Intervention, Protocol):
72
+ family: SemanticFamily
73
+
74
+
75
+ @runtime_checkable
76
+ class Clarifier(Intervention, Protocol):
77
+ family: SemanticFamily
78
+
79
+
80
+ @runtime_checkable
81
+ class ContextCurator(Intervention, Protocol):
82
+ family: SemanticFamily
83
+
84
+
85
+ @dataclass(frozen=True, slots=True)
86
+ class CompositeResult:
87
+ """Terminal result of a full agent/search architecture.
88
+
89
+ Composite methods keep their final answer and multi-step trajectory instead
90
+ of pretending to be a one-shot input patch. A downstream experiment may
91
+ separately derive a controlled evidence patch, but that is a different
92
+ release profile and estimand.
93
+ """
94
+
95
+ method_id: str
96
+ release_id: str
97
+ source_state_hash: str
98
+ final_answer: str
99
+ evidence: tuple[ContextBlock, ...]
100
+ trace: ExecutionTrace
101
+ implementation_identity: str
102
+ profile_kind: str
103
+ metadata: Mapping[str, Any] = field(default_factory=dict)
104
+
105
+ def __post_init__(self) -> None:
106
+ evidence = tuple(self.evidence)
107
+ if (
108
+ not isinstance(self.method_id, str)
109
+ or not self.method_id.strip()
110
+ or not isinstance(self.release_id, str)
111
+ or not self.release_id.strip()
112
+ ):
113
+ raise ValidationError("composite result requires method and release IDs")
114
+ if not isinstance(self.source_state_hash, str) or not self.source_state_hash.strip():
115
+ raise ValidationError("composite result requires source_state_hash")
116
+ if not isinstance(self.final_answer, str) or not self.final_answer.strip():
117
+ raise ValidationError("composite final_answer must be non-empty text")
118
+ if not all(isinstance(block, ContextBlock) for block in evidence):
119
+ raise ValidationError("composite evidence must contain ContextBlock instances")
120
+ if not isinstance(self.trace, ExecutionTrace):
121
+ raise ValidationError("composite result requires an ExecutionTrace")
122
+ if self.trace.method_id != self.method_id or self.trace.release_id != self.release_id:
123
+ raise ValidationError("composite trace identity does not match result identity")
124
+ if (
125
+ not isinstance(self.implementation_identity, str)
126
+ or not self.implementation_identity.strip()
127
+ or not isinstance(self.profile_kind, str)
128
+ or not self.profile_kind.strip()
129
+ ):
130
+ raise ValidationError("composite implementation/profile identity must not be empty")
131
+ object.__setattr__(self, "evidence", evidence)
132
+ object.__setattr__(self, "metadata", freeze_mapping(self.metadata))
133
+
134
+ @property
135
+ def result_hash(self) -> str:
136
+ return content_hash(self)
137
+
138
+ def as_dict(self) -> dict[str, Any]:
139
+ return to_jsonable(self)
140
+
141
+
142
+ @runtime_checkable
143
+ class CompositeIntervention(Protocol):
144
+ method_id: str
145
+ release_id: str
146
+ family: SemanticFamily
147
+
148
+ def run(self, state: FrozenAgentState, context: InterventionContext) -> CompositeResult:
149
+ """Run a full architecture and return its terminal outcome and trace."""
150
+
151
+
152
+ @runtime_checkable
153
+ class OfflineRecipe(Protocol):
154
+ method_id: str
155
+ release_id: str
156
+
157
+ def fit(
158
+ self,
159
+ train_examples: tuple[Any, ...],
160
+ *,
161
+ validation_examples: tuple[Any, ...] = (),
162
+ context: InterventionContext,
163
+ ) -> Any:
164
+ """Produce a versioned, replayable artifact without consulting test data."""
@@ -0,0 +1,167 @@
1
+ """Typed, auditable input patches and deterministic materialization."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from dataclasses import dataclass, field, replace
7
+ from typing import Any
8
+
9
+ from .enums import PatchOp
10
+ from .errors import StateConflictError, ValidationError
11
+ from .serialization import content_hash, deep_freeze_jsonable, freeze_mapping, to_jsonable
12
+ from .state import ContextBlock, FrozenAgentState, Message
13
+ from .trace import ExecutionTrace
14
+
15
+
16
+ @dataclass(frozen=True, slots=True)
17
+ class PatchOperation:
18
+ op: PatchOp
19
+ value: Any = None
20
+ target: str = ""
21
+ rationale: str = ""
22
+
23
+ def __post_init__(self) -> None:
24
+ object.__setattr__(self, "value", _freeze_patch_value(self.value))
25
+ if self.op is PatchOp.NO_OP and self.value not in (None, ""):
26
+ raise ValidationError("NO_OP cannot carry a replacement value")
27
+
28
+
29
+ @dataclass(frozen=True, slots=True)
30
+ class InputPatch:
31
+ method_id: str
32
+ release_id: str
33
+ source_state_hash: str
34
+ operations: tuple[PatchOperation, ...]
35
+ trace: ExecutionTrace
36
+ implementation_identity: str
37
+ profile_kind: str
38
+ metadata: Mapping[str, Any] = field(default_factory=dict)
39
+
40
+ def __post_init__(self) -> None:
41
+ operations = tuple(self.operations)
42
+ if not all(isinstance(operation, PatchOperation) for operation in operations):
43
+ raise ValidationError("patch operations must be PatchOperation instances")
44
+ if not isinstance(self.trace, ExecutionTrace):
45
+ raise ValidationError("patch trace must be an ExecutionTrace")
46
+ object.__setattr__(self, "operations", operations)
47
+ object.__setattr__(self, "metadata", freeze_mapping(self.metadata))
48
+ if not self.operations:
49
+ raise ValidationError("patch requires at least one operation; use NO_OP explicitly")
50
+ if self.trace.method_id != self.method_id or self.trace.release_id != self.release_id:
51
+ raise ValidationError("trace identity does not match patch identity")
52
+
53
+ @classmethod
54
+ def no_op(
55
+ cls,
56
+ state: FrozenAgentState,
57
+ *,
58
+ method_id: str = "no_op",
59
+ release_id: str = "baseline.no_op",
60
+ rationale: str = "",
61
+ profile_kind: str = "controlled_adapter",
62
+ ) -> InputPatch:
63
+ trace = ExecutionTrace(method_id=method_id, release_id=release_id)
64
+ return cls(
65
+ method_id=method_id,
66
+ release_id=release_id,
67
+ source_state_hash=state.state_hash,
68
+ operations=(PatchOperation(PatchOp.NO_OP, rationale=rationale),),
69
+ trace=trace,
70
+ implementation_identity="builtin",
71
+ profile_kind=profile_kind,
72
+ )
73
+
74
+ @property
75
+ def patch_hash(self) -> str:
76
+ return content_hash(self)
77
+
78
+ def as_dict(self) -> dict[str, Any]:
79
+ return to_jsonable(self)
80
+
81
+ def apply(self, state: FrozenAgentState) -> FrozenAgentState:
82
+ """Apply operations in order after checking the paired-state identity."""
83
+
84
+ if state.state_hash != self.source_state_hash:
85
+ raise StateConflictError(
86
+ f"patch expected state {self.source_state_hash}, got {state.state_hash}"
87
+ )
88
+ current = state
89
+ for operation in self.operations:
90
+ current = _apply_operation(current, operation)
91
+ return current
92
+
93
+
94
+ def _apply_operation(state: FrozenAgentState, operation: PatchOperation) -> FrozenAgentState:
95
+ if operation.op is PatchOp.NO_OP:
96
+ return state
97
+ if operation.op is PatchOp.REPLACE_QUERY:
98
+ return replace(state, query=str(operation.value))
99
+ if operation.op is PatchOp.APPEND_QUERY:
100
+ separator = "\n\n" if state.query else ""
101
+ return replace(state, query=f"{state.query}{separator}{operation.value}")
102
+ if operation.op is PatchOp.REPLACE_INSTRUCTION:
103
+ return replace(state, instruction=str(operation.value))
104
+ if operation.op is PatchOp.APPEND_INSTRUCTION:
105
+ separator = "\n\n" if state.instruction else ""
106
+ return replace(state, instruction=f"{state.instruction}{separator}{operation.value}")
107
+ if operation.op is PatchOp.ADD_CONTEXT:
108
+ blocks = _coerce_context(operation.value)
109
+ return replace(state, context=(*state.context, *blocks))
110
+ if operation.op is PatchOp.REPLACE_CONTEXT:
111
+ return replace(state, context=_coerce_context(operation.value))
112
+ if operation.op is PatchOp.ADD_MESSAGE:
113
+ message = operation.value
114
+ if isinstance(message, dict):
115
+ message = Message(**message)
116
+ if not isinstance(message, Message):
117
+ raise ValidationError("ADD_MESSAGE requires Message or mapping")
118
+ return replace(state, messages=(*state.messages, message))
119
+ if operation.op is PatchOp.REPLACE_MESSAGES:
120
+ return replace(state, messages=_coerce_messages(operation.value))
121
+ if operation.op is PatchOp.SET_METADATA:
122
+ if not isinstance(operation.value, Mapping):
123
+ raise ValidationError("SET_METADATA requires a mapping")
124
+ merged = dict(state.metadata)
125
+ merged.update(operation.value)
126
+ return replace(state, metadata=merged)
127
+ if operation.op is PatchOp.REQUEST_CLARIFICATION:
128
+ merged = dict(state.metadata)
129
+ merged["clarification_request"] = str(operation.value)
130
+ return replace(state, metadata=merged)
131
+ raise ValidationError(f"unsupported patch operation: {operation.op}")
132
+
133
+
134
+ def _coerce_context(value: Any) -> tuple[ContextBlock, ...]:
135
+ values = value if isinstance(value, (tuple, list)) else (value,)
136
+ blocks: list[ContextBlock] = []
137
+ for item in values:
138
+ if isinstance(item, ContextBlock):
139
+ blocks.append(item)
140
+ elif isinstance(item, str):
141
+ blocks.append(ContextBlock(text=item))
142
+ elif isinstance(item, Mapping):
143
+ blocks.append(ContextBlock(**item))
144
+ else:
145
+ raise ValidationError("context operation requires ContextBlock/string/mapping")
146
+ return tuple(blocks)
147
+
148
+
149
+ def _coerce_messages(value: Any) -> tuple[Message, ...]:
150
+ values = value if isinstance(value, (tuple, list)) else (value,)
151
+ messages: list[Message] = []
152
+ for item in values:
153
+ if isinstance(item, Message):
154
+ messages.append(item)
155
+ elif isinstance(item, Mapping):
156
+ messages.append(Message(**item))
157
+ else:
158
+ raise ValidationError("REPLACE_MESSAGES requires Message instances or mappings")
159
+ return tuple(messages)
160
+
161
+
162
+ def _freeze_patch_value(value: Any) -> Any:
163
+ if isinstance(value, (ContextBlock, Message)):
164
+ return value
165
+ if isinstance(value, (tuple, list)):
166
+ return tuple(_freeze_patch_value(item) for item in value)
167
+ return deep_freeze_jsonable(value)
@@ -0,0 +1,93 @@
1
+ """Canonical serialization and hashing helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import dataclasses
6
+ import hashlib
7
+ import json
8
+ from collections.abc import Mapping
9
+ from enum import Enum
10
+ from pathlib import Path
11
+ from types import MappingProxyType
12
+ from typing import Any
13
+
14
+
15
+ def deep_freeze_jsonable(value: Any) -> Any:
16
+ """Detach and recursively freeze a canonically serializable value.
17
+
18
+ Mutable caller-owned containers must never be able to change a state,
19
+ dependency, trace, or patch hash after construction.
20
+ """
21
+
22
+ if dataclasses.is_dataclass(value):
23
+ return deep_freeze_jsonable(to_jsonable(value))
24
+ if isinstance(value, Enum):
25
+ return deep_freeze_jsonable(value.value)
26
+ if isinstance(value, Mapping):
27
+ frozen: dict[str, Any] = {}
28
+ for key, item in value.items():
29
+ if not isinstance(key, str):
30
+ raise TypeError("canonical mapping keys must be strings")
31
+ frozen[key] = deep_freeze_jsonable(item)
32
+ return MappingProxyType(frozen)
33
+ if isinstance(value, (set, frozenset)):
34
+ raise TypeError("sets are not permitted in canonical serialized values")
35
+ if isinstance(value, (tuple, list)):
36
+ return tuple(deep_freeze_jsonable(item) for item in value)
37
+ if isinstance(value, Path):
38
+ return str(value)
39
+ if value is None or isinstance(value, (str, int, float, bool)):
40
+ return value
41
+ raise TypeError(f"Unsupported canonical value: {type(value).__name__}")
42
+
43
+
44
+ def freeze_mapping(value: Mapping[str, Any] | None) -> Mapping[str, Any]:
45
+ """Return a detached, recursively immutable string-keyed mapping."""
46
+
47
+ frozen = deep_freeze_jsonable(dict(value or {}))
48
+ if not isinstance(frozen, Mapping): # pragma: no cover - construction invariant
49
+ raise TypeError("freeze_mapping did not produce a mapping")
50
+ return frozen
51
+
52
+
53
+ def to_jsonable(value: Any) -> Any:
54
+ """Convert public dataclasses and common immutable containers to JSON values."""
55
+
56
+ if dataclasses.is_dataclass(value):
57
+ return {
58
+ field.name: to_jsonable(getattr(value, field.name))
59
+ for field in dataclasses.fields(value)
60
+ }
61
+ if isinstance(value, Enum):
62
+ return value.value
63
+ if isinstance(value, dict):
64
+ return {str(key): to_jsonable(item) for key, item in value.items()}
65
+ if hasattr(value, "items"):
66
+ return {str(key): to_jsonable(item) for key, item in value.items()}
67
+ if isinstance(value, (set, frozenset)):
68
+ raise TypeError("sets are not permitted in canonical serialized values")
69
+ if isinstance(value, (tuple, list)):
70
+ return [to_jsonable(item) for item in value]
71
+ if isinstance(value, Path):
72
+ return str(value)
73
+ if value is None or isinstance(value, (str, int, float, bool)):
74
+ return value
75
+ raise TypeError(f"Unsupported canonical value: {type(value).__name__}")
76
+
77
+
78
+ def canonical_json(value: Any) -> str:
79
+ """Serialize without platform- or insertion-order-dependent variation."""
80
+
81
+ return json.dumps(
82
+ to_jsonable(value),
83
+ ensure_ascii=False,
84
+ sort_keys=True,
85
+ separators=(",", ":"),
86
+ allow_nan=False,
87
+ )
88
+
89
+
90
+ def content_hash(value: Any) -> str:
91
+ """Return a SHA-256 content identity for a canonical value."""
92
+
93
+ return hashlib.sha256(canonical_json(value).encode("utf-8")).hexdigest()
@@ -0,0 +1,127 @@
1
+ """Immutable input state presented to an intervention."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from collections.abc import Mapping
7
+ from dataclasses import dataclass, field
8
+ from typing import Any
9
+
10
+ from .errors import ValidationError
11
+ from .serialization import content_hash, freeze_mapping, to_jsonable
12
+
13
+
14
+ def _frozen_mapping(value: Mapping[str, Any] | None) -> Mapping[str, Any]:
15
+ try:
16
+ return freeze_mapping(value)
17
+ except TypeError as exc:
18
+ raise ValidationError(f"state metadata must be canonically serializable: {exc}") from exc
19
+
20
+
21
+ @dataclass(frozen=True, slots=True)
22
+ class Message:
23
+ role: str
24
+ content: str
25
+ name: str | None = None
26
+
27
+ def __post_init__(self) -> None:
28
+ if not self.role.strip():
29
+ raise ValidationError("message.role must not be empty")
30
+
31
+
32
+ @dataclass(frozen=True, slots=True)
33
+ class ContextBlock:
34
+ text: str
35
+ block_id: str = ""
36
+ source: str = ""
37
+ score: float | None = None
38
+ metadata: Mapping[str, Any] = field(default_factory=dict)
39
+
40
+ def __post_init__(self) -> None:
41
+ object.__setattr__(self, "metadata", _frozen_mapping(self.metadata))
42
+ if not self.text:
43
+ raise ValidationError("context block text must not be empty")
44
+
45
+
46
+ @dataclass(frozen=True, slots=True)
47
+ class ExecutionBudget:
48
+ """Per-run resource ceilings.
49
+
50
+ ``max_context_tokens`` is the cumulative number of provider-reported LLM
51
+ input tokens across every model call in one run. It is not a per-request
52
+ window-size limit; a run with two 600-token requests consumes 1,200 context
53
+ tokens for this budget.
54
+ """
55
+
56
+ max_model_calls: int = 8
57
+ max_retrieval_calls: int = 8
58
+ max_tool_calls: int = 8
59
+ max_output_tokens: int = 4096
60
+ max_context_tokens: int | None = None
61
+ max_cost_usd: float | None = None
62
+
63
+ def __post_init__(self) -> None:
64
+ for name in (
65
+ "max_model_calls",
66
+ "max_retrieval_calls",
67
+ "max_tool_calls",
68
+ "max_output_tokens",
69
+ ):
70
+ value = getattr(self, name)
71
+ if isinstance(value, bool) or not isinstance(value, int) or value < 0:
72
+ raise ValidationError(f"{name} must be a non-negative integer")
73
+ if self.max_context_tokens is not None and (
74
+ isinstance(self.max_context_tokens, bool)
75
+ or not isinstance(self.max_context_tokens, int)
76
+ or self.max_context_tokens < 0
77
+ ):
78
+ raise ValidationError("max_context_tokens must be a non-negative integer or None")
79
+ if self.max_cost_usd is not None and (
80
+ isinstance(self.max_cost_usd, bool)
81
+ or not isinstance(self.max_cost_usd, (int, float))
82
+ or not math.isfinite(self.max_cost_usd)
83
+ or self.max_cost_usd < 0
84
+ ):
85
+ raise ValidationError("max_cost_usd must be finite and non-negative or None")
86
+
87
+
88
+ @dataclass(frozen=True, slots=True)
89
+ class FrozenAgentState:
90
+ """A hash-addressed snapshot used for paired pre-action experiments."""
91
+
92
+ query: str
93
+ task_id: str = ""
94
+ instruction: str = ""
95
+ context: tuple[ContextBlock, ...] = ()
96
+ messages: tuple[Message, ...] = ()
97
+ tool_names: tuple[str, ...] = ()
98
+ metadata: Mapping[str, Any] = field(default_factory=dict)
99
+ budget: ExecutionBudget = field(default_factory=ExecutionBudget)
100
+
101
+ def __post_init__(self) -> None:
102
+ if not isinstance(self.query, str) or not isinstance(self.instruction, str):
103
+ raise ValidationError("state query and instruction must be strings")
104
+ if not self.query.strip() and not self.instruction.strip():
105
+ raise ValidationError("state requires a non-empty query or instruction")
106
+ context = tuple(self.context)
107
+ messages = tuple(self.messages)
108
+ tool_names = tuple(self.tool_names)
109
+ if not all(isinstance(item, ContextBlock) for item in context):
110
+ raise ValidationError("state context entries must be ContextBlock instances")
111
+ if not all(isinstance(item, Message) for item in messages):
112
+ raise ValidationError("state messages must be Message instances")
113
+ if not all(isinstance(item, str) and item for item in tool_names):
114
+ raise ValidationError("state tool_names must contain non-empty strings")
115
+ if not isinstance(self.budget, ExecutionBudget):
116
+ raise ValidationError("state budget must be an ExecutionBudget")
117
+ object.__setattr__(self, "context", context)
118
+ object.__setattr__(self, "messages", messages)
119
+ object.__setattr__(self, "tool_names", tool_names)
120
+ object.__setattr__(self, "metadata", _frozen_mapping(self.metadata))
121
+
122
+ def canonical_dict(self) -> dict[str, Any]:
123
+ return to_jsonable(self)
124
+
125
+ @property
126
+ def state_hash(self) -> str:
127
+ return content_hash(self)
@@ -0,0 +1,59 @@
1
+ """Serializable method-specific execution traces."""
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 TracePhase
10
+ from .serialization import content_hash, freeze_mapping, to_jsonable
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class TraceEvent:
15
+ phase: TracePhase
16
+ name: str
17
+ payload: Mapping[str, Any] = field(default_factory=dict)
18
+
19
+ def __post_init__(self) -> None:
20
+ object.__setattr__(self, "payload", freeze_mapping(self.payload))
21
+
22
+ def as_dict(self) -> dict[str, Any]:
23
+ return to_jsonable(self)
24
+
25
+
26
+ @dataclass(frozen=True, slots=True)
27
+ class ExecutionTrace:
28
+ method_id: str
29
+ release_id: str
30
+ events: tuple[TraceEvent, ...] = ()
31
+ counters: Mapping[str, int | float] = field(default_factory=dict)
32
+ warnings: tuple[str, ...] = ()
33
+
34
+ def __post_init__(self) -> None:
35
+ events = tuple(self.events)
36
+ warnings = tuple(self.warnings)
37
+ if not all(isinstance(event, TraceEvent) for event in events):
38
+ raise TypeError("trace events must be TraceEvent instances")
39
+ if not all(isinstance(warning, str) for warning in warnings):
40
+ raise TypeError("trace warnings must be strings")
41
+ object.__setattr__(self, "events", events)
42
+ object.__setattr__(self, "counters", freeze_mapping(self.counters))
43
+ object.__setattr__(self, "warnings", warnings)
44
+
45
+ def append(self, event: TraceEvent) -> ExecutionTrace:
46
+ return ExecutionTrace(
47
+ method_id=self.method_id,
48
+ release_id=self.release_id,
49
+ events=(*self.events, event),
50
+ counters=dict(self.counters),
51
+ warnings=self.warnings,
52
+ )
53
+
54
+ @property
55
+ def trace_hash(self) -> str:
56
+ return content_hash(self)
57
+
58
+ def as_dict(self) -> dict[str, Any]:
59
+ return to_jsonable(self)
@@ -0,0 +1,42 @@
1
+ """Versioned external-worker request and response envelopes."""
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 .errors import ValidationError
10
+ from .serialization import freeze_mapping
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class WorkerRequest:
15
+ schema_version: int
16
+ release_id: str
17
+ request_id: str
18
+ payload: Mapping[str, Any]
19
+ dependency_hashes: Mapping[str, str] = field(default_factory=dict)
20
+
21
+ def __post_init__(self) -> None:
22
+ if self.schema_version != 1:
23
+ raise ValidationError(f"unsupported worker request schema: {self.schema_version}")
24
+ object.__setattr__(self, "payload", freeze_mapping(self.payload))
25
+ object.__setattr__(self, "dependency_hashes", freeze_mapping(self.dependency_hashes))
26
+
27
+
28
+ @dataclass(frozen=True, slots=True)
29
+ class WorkerResponse:
30
+ schema_version: int
31
+ request_id: str
32
+ status: str
33
+ payload: Mapping[str, Any] = field(default_factory=dict)
34
+ error_code: str = ""
35
+ error_message: str = ""
36
+
37
+ def __post_init__(self) -> None:
38
+ if self.schema_version != 1:
39
+ raise ValidationError(f"unsupported worker response schema: {self.schema_version}")
40
+ if self.status not in {"ok", "error"}:
41
+ raise ValidationError(f"invalid worker response status: {self.status}")
42
+ object.__setattr__(self, "payload", freeze_mapping(self.payload))
@@ -0,0 +1,7 @@
1
+ """Compatibility exports for the pre-implementation repository layout.
2
+
3
+ New code should import from :mod:`agentinputlab.contracts`.
4
+ """
5
+
6
+ from agentinputlab.contracts import * # noqa: F403
7
+ from agentinputlab.contracts import __all__ as __all__
@@ -0,0 +1,32 @@
1
+ """Data acquisition, checksum, preprocessing, index, and overlap utilities."""
2
+
3
+ from .downloader import (
4
+ DownloadPolicy,
5
+ DownloadResponse,
6
+ DownloadTransport,
7
+ StreamingDownloadResponse,
8
+ StreamingDownloadTransport,
9
+ ValidatedDownloadTarget,
10
+ download_artifact,
11
+ download_artifact_streamed,
12
+ validate_download_url,
13
+ )
14
+ from .http import PinnedHTTPSDownloadTransport
15
+ from .overlap import OverlapRecord, detect_id_overlap
16
+ from .trec_sample import prepare_trec_dl_sample
17
+
18
+ __all__ = [
19
+ "DownloadPolicy",
20
+ "DownloadResponse",
21
+ "DownloadTransport",
22
+ "OverlapRecord",
23
+ "PinnedHTTPSDownloadTransport",
24
+ "StreamingDownloadResponse",
25
+ "StreamingDownloadTransport",
26
+ "ValidatedDownloadTarget",
27
+ "detect_id_overlap",
28
+ "download_artifact",
29
+ "download_artifact_streamed",
30
+ "prepare_trec_dl_sample",
31
+ "validate_download_url",
32
+ ]