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,448 @@
1
+ """Controlled Plan-and-Budget adaptation with live, evaluator-blind planning.
2
+
3
+ The official repository prepares decompositions and credit assignments before
4
+ answer generation. Its released caches cover MATH-500, NaturalInstructions,
5
+ and TravelPlanner, so they cannot be reused for a new benchmark such as
6
+ QASPER. This module preserves the released two-stage preparation protocol and
7
+ the original weighted soft-word allocation, while regenerating the two cached
8
+ fields from the visible input only. It is therefore a controlled adapter, not
9
+ an official-native or paper-parity claim.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import re
16
+ from dataclasses import dataclass
17
+ from typing import Any
18
+
19
+ from agentinputlab.backends.llm import GenerationRequest, LLMBackend, ModelCapability
20
+ from agentinputlab.contracts import (
21
+ AlgorithmOutputError,
22
+ BudgetExceededError,
23
+ CapabilityError,
24
+ ExecutionTrace,
25
+ ExternalDependencyError,
26
+ FrozenAgentState,
27
+ InputPatch,
28
+ InterventionContext,
29
+ PatchOp,
30
+ PatchOperation,
31
+ SemanticFamily,
32
+ TraceEvent,
33
+ TracePhase,
34
+ ValidationError,
35
+ )
36
+ from agentinputlab.contracts.serialization import content_hash
37
+
38
+ from .cached_soft_budget import (
39
+ P_AND_B_UPSTREAM_REVISION,
40
+ CachedPlanBudgetRecord,
41
+ DecaySchedule,
42
+ allocate_tokens,
43
+ render_soft_budget_instruction,
44
+ )
45
+
46
+ _NUMBERED_ITEM = re.compile(r"(?ms)^\s*(?P<index>\d+)\.\s*(?P<text>.*?)(?=^\s*\d+\.\s|\Z)")
47
+
48
+
49
+ @dataclass(frozen=True, slots=True)
50
+ class RegeneratedPlanBudgetConfig:
51
+ """Frozen controls for the general-benchmark P&B preparation calls."""
52
+
53
+ domain: str = "general question answering"
54
+ initial_level: int = 3
55
+ total_word_budget: int = 512
56
+ schedule: DecaySchedule | str = DecaySchedule.CONSTANT
57
+ decomposition_max_tokens: int = 768
58
+ assessment_max_tokens: int = 768
59
+ temperature: float = 0.0
60
+
61
+ def __post_init__(self) -> None:
62
+ if not isinstance(self.domain, str) or not self.domain.strip():
63
+ raise ValidationError("Plan-and-Budget domain must be non-empty")
64
+ if not 1 <= self.initial_level <= 5:
65
+ raise ValidationError("Plan-and-Budget initial_level must be in [1, 5]")
66
+ if self.total_word_budget < 1:
67
+ raise ValidationError("Plan-and-Budget total_word_budget must be positive")
68
+ for label, value in (
69
+ ("decomposition_max_tokens", self.decomposition_max_tokens),
70
+ ("assessment_max_tokens", self.assessment_max_tokens),
71
+ ):
72
+ if isinstance(value, bool) or not isinstance(value, int) or value < 1:
73
+ raise ValidationError(f"Plan-and-Budget {label} must be positive")
74
+ if self.temperature < 0:
75
+ raise ValidationError("Plan-and-Budget temperature must be non-negative")
76
+ object.__setattr__(self, "schedule", DecaySchedule.parse(self.schedule))
77
+
78
+
79
+ class PlanAndBudgetRegeneratedSoftBudget:
80
+ """Regenerate official cache fields from visible state, then apply P&B."""
81
+
82
+ method_id = "plan_and_budget"
83
+ release_id = "plan.plan_and_budget.native_regenerated_soft_budget"
84
+ family = SemanticFamily.DECOMPOSE
85
+
86
+ def __init__(
87
+ self,
88
+ *,
89
+ domain: str = "general question answering",
90
+ initial_level: int = 3,
91
+ total_word_budget: int = 512,
92
+ schedule: str | DecaySchedule = DecaySchedule.CONSTANT,
93
+ decomposition_max_tokens: int = 768,
94
+ assessment_max_tokens: int = 768,
95
+ temperature: float = 0.0,
96
+ ) -> None:
97
+ self.config = RegeneratedPlanBudgetConfig(
98
+ domain=domain,
99
+ initial_level=initial_level,
100
+ total_word_budget=total_word_budget,
101
+ schedule=schedule,
102
+ decomposition_max_tokens=decomposition_max_tokens,
103
+ assessment_max_tokens=assessment_max_tokens,
104
+ temperature=temperature,
105
+ )
106
+
107
+ @staticmethod
108
+ def _backend(context: InterventionContext) -> LLMBackend:
109
+ backend = context.backend
110
+ if backend is None:
111
+ raise ExternalDependencyError(
112
+ "regenerated Plan-and-Budget requires an injected LLMBackend"
113
+ )
114
+ if not isinstance(backend, LLMBackend):
115
+ raise CapabilityError("Plan-and-Budget backend does not implement LLMBackend")
116
+ capabilities = set(backend.capabilities)
117
+ if ModelCapability.COMPLETION not in capabilities:
118
+ raise CapabilityError("Plan-and-Budget backend lacks capability: completion")
119
+ if not capabilities.intersection(
120
+ {ModelCapability.JSON_OBJECT, ModelCapability.JSON_SCHEMA}
121
+ ):
122
+ raise CapabilityError(
123
+ "Plan-and-Budget backend requires json_object or json_schema capability"
124
+ )
125
+ return backend
126
+
127
+ def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
128
+ if not state.query.strip():
129
+ raise ValidationError("Plan-and-Budget requires a non-empty query")
130
+ if state.budget.max_model_calls < 2:
131
+ raise BudgetExceededError("regenerated Plan-and-Budget requires two model calls")
132
+ if state.budget.max_output_tokens < 2:
133
+ raise BudgetExceededError("regenerated Plan-and-Budget has no output-token budget")
134
+ backend = self._backend(context)
135
+
136
+ decomposition_system = _decomposition_system(self.config.domain)
137
+ decomposition_prompt = _decomposition_prompt(
138
+ state.query,
139
+ level=self.config.initial_level,
140
+ )
141
+ first_cap = min(
142
+ self.config.decomposition_max_tokens,
143
+ max(1, state.budget.max_output_tokens // 2),
144
+ )
145
+ decomposition = backend.generate(
146
+ GenerationRequest(
147
+ prompt=decomposition_prompt,
148
+ system=decomposition_system,
149
+ temperature=self.config.temperature,
150
+ max_tokens=first_cap,
151
+ seed=context.seed,
152
+ metadata={
153
+ "method_id": self.method_id,
154
+ "release_id": self.release_id,
155
+ "stage": "decomposition",
156
+ "upstream_revision": P_AND_B_UPSTREAM_REVISION,
157
+ },
158
+ )
159
+ )
160
+ steps, decomposition_warnings = _parse_decomposition(decomposition.text)
161
+
162
+ remaining_output = state.budget.max_output_tokens - decomposition.usage.output_tokens
163
+ if remaining_output < 1:
164
+ raise BudgetExceededError(
165
+ "Plan-and-Budget decomposition exhausted the output-token budget"
166
+ )
167
+ assessment_system = _assessment_system(self.config.domain)
168
+ assessment_prompt = _assessment_prompt(state.query, steps)
169
+ assessment_response_format = _assessment_response_format(
170
+ len(steps),
171
+ use_json_schema=ModelCapability.JSON_SCHEMA in backend.capabilities,
172
+ )
173
+ assessment = backend.generate(
174
+ GenerationRequest(
175
+ prompt=assessment_prompt,
176
+ system=assessment_system,
177
+ temperature=self.config.temperature,
178
+ max_tokens=min(self.config.assessment_max_tokens, remaining_output),
179
+ seed=context.seed + 1,
180
+ response_format=assessment_response_format,
181
+ metadata={
182
+ "method_id": self.method_id,
183
+ "release_id": self.release_id,
184
+ "stage": "credit_assessment",
185
+ "upstream_revision": P_AND_B_UPSTREAM_REVISION,
186
+ },
187
+ )
188
+ )
189
+ level, credits, assessment_warnings = _parse_assessment(
190
+ assessment.text,
191
+ step_count=len(steps),
192
+ )
193
+ audit_warnings = (*decomposition_warnings, *assessment_warnings)
194
+ record = CachedPlanBudgetRecord(
195
+ record_id=state.task_id or state.state_hash,
196
+ query=state.query,
197
+ steps=steps,
198
+ credits=credits,
199
+ level=level,
200
+ audit_warnings=audit_warnings,
201
+ )
202
+ allocations = allocate_tokens(
203
+ record.credits,
204
+ self.config.total_word_budget,
205
+ self.config.schedule,
206
+ )
207
+ instruction = render_soft_budget_instruction(record, allocations)
208
+ input_tokens = decomposition.usage.input_tokens + assessment.usage.input_tokens
209
+ output_tokens = decomposition.usage.output_tokens + assessment.usage.output_tokens
210
+ trace = ExecutionTrace(
211
+ method_id=self.method_id,
212
+ release_id=self.release_id,
213
+ events=(
214
+ TraceEvent(
215
+ TracePhase.PREPARE,
216
+ "live_decomposition",
217
+ {
218
+ "steps": steps,
219
+ "initial_level": self.config.initial_level,
220
+ "decomposition_request_sha256": content_hash(
221
+ {
222
+ "system": decomposition_system,
223
+ "prompt": decomposition_prompt,
224
+ }
225
+ ),
226
+ "gold_visible_to_optimizer": False,
227
+ },
228
+ ),
229
+ TraceEvent(
230
+ TracePhase.OBSERVE,
231
+ "live_credit_assessment",
232
+ {
233
+ "evaluated_level": level,
234
+ "credits": credits,
235
+ "credit_sum": sum(credits),
236
+ "assessment_request_sha256": content_hash(
237
+ {"system": assessment_system, "prompt": assessment_prompt}
238
+ ),
239
+ "assessment_response_format": assessment_response_format["type"],
240
+ },
241
+ ),
242
+ TraceEvent(
243
+ TracePhase.PROPOSE,
244
+ "soft_word_budget_allocation",
245
+ {
246
+ "schedule": self.config.schedule.value,
247
+ "total_budget": self.config.total_word_budget,
248
+ "budget_unit": "soft_words",
249
+ "allocation_tie_policy": "stable_source_index",
250
+ "allocations": allocations,
251
+ "decoder_hard_cap_applied": False,
252
+ "instruction": instruction,
253
+ },
254
+ ),
255
+ ),
256
+ counters={
257
+ "model_calls": 2,
258
+ "optimizer_model_calls": 2,
259
+ "input_tokens": input_tokens,
260
+ "output_tokens": output_tokens,
261
+ "planned_steps": len(steps),
262
+ "allocated_soft_words": sum(allocations),
263
+ },
264
+ warnings=audit_warnings,
265
+ )
266
+ return InputPatch(
267
+ method_id=self.method_id,
268
+ release_id=self.release_id,
269
+ source_state_hash=state.state_hash,
270
+ operations=(
271
+ PatchOperation(
272
+ PatchOp.APPEND_INSTRUCTION,
273
+ value=instruction,
274
+ target="instruction",
275
+ rationale="Plan-and-Budget live decomposition and weighted soft-word budgets",
276
+ ),
277
+ ),
278
+ trace=trace,
279
+ implementation_identity=(
280
+ f"official_mit_generalized_adapter:junhongmit/P-and-B@{P_AND_B_UPSTREAM_REVISION}"
281
+ ),
282
+ profile_kind="controlled_adapter",
283
+ metadata={
284
+ "implementation_origin": "official_mit_controlled_generalization",
285
+ "cached_decomposition": False,
286
+ "live_decomposition": True,
287
+ "budget_unit": "soft_words",
288
+ "allocation_tie_policy": "stable_source_index",
289
+ "numpy_tie_order_parity_claimed": False,
290
+ "hard_decoder_cap": False,
291
+ "gold_fields_visible_to_optimizer": False,
292
+ "paper_result_parity_claimed": False,
293
+ },
294
+ )
295
+
296
+
297
+ def _decomposition_system(domain: str) -> str:
298
+ # Faithfully preserves the released prompt's role, 2--5 step constraint,
299
+ # hint requirement, and prohibition on exposing a solution.
300
+ return (
301
+ f"You are an experienced expert in {domain} and an exam question designer. "
302
+ "Break a challenging problem into 2 to 5 high-level sub-questions. Each "
303
+ "sub-question should build on the previous one, and each must include a "
304
+ "brief Hint explaining its purpose. Do not reveal internal chain-of-thought "
305
+ "or the final answer. Do not solve the problem. Output only numbered items "
306
+ "in the form '1. ...\nHint: ...'."
307
+ )
308
+
309
+
310
+ def _decomposition_prompt(query: str, *, level: int) -> str:
311
+ return (
312
+ "A student has presented the following problem:\n"
313
+ f"Problem: {query}\n"
314
+ f"Initial difficulty level: {level} out of 5\n"
315
+ "Decomposed Sub-questions:"
316
+ )
317
+
318
+
319
+ def _assessment_system(domain: str) -> str:
320
+ # This is the released credit-assessment schema without dataset-specific
321
+ # benchmark examples. Omitting those examples is explicit in the adapter
322
+ # identity and prevents cross-dataset gold or label leakage.
323
+ return (
324
+ f"You are an experienced expert in {domain} and an exam question designer. "
325
+ "Evaluate the overall problem and the supplied sub-questions. Assign the "
326
+ "problem an integer difficulty from 1 to 5 and assign each sub-question a "
327
+ "positive integer credit. Credits must sum exactly to 100. Do not add, "
328
+ "remove, or solve sub-questions. Return only one JSON object in exactly this "
329
+ 'shape: {"problem":{"evaluated_level":3},'
330
+ '"1":{"evaluated_level":2,"credit":40},'
331
+ '"2":{"evaluated_level":3,"credit":60}}. The numeric keys must be '
332
+ "top-level siblings of 'problem', never children of 'problem'. Include one "
333
+ "numeric key for every supplied sub-question and no other keys."
334
+ )
335
+
336
+
337
+ def _assessment_prompt(query: str, steps: tuple[str, ...]) -> str:
338
+ rendered = "\n".join(f"{index}. {step}" for index, step in enumerate(steps, 1))
339
+ return f"Problem: {query}\nSub-questions:\n{rendered}\nOutput:"
340
+
341
+
342
+ def _assessment_response_format(
343
+ step_count: int,
344
+ *,
345
+ use_json_schema: bool,
346
+ ) -> dict[str, Any]:
347
+ if not use_json_schema:
348
+ return {"type": "json_object"}
349
+ step_schema = {
350
+ "type": "object",
351
+ "additionalProperties": False,
352
+ "required": ["evaluated_level", "credit"],
353
+ "properties": {
354
+ "evaluated_level": {"type": "integer"},
355
+ "credit": {"type": "integer"},
356
+ },
357
+ }
358
+ properties: dict[str, Any] = {
359
+ "problem": {
360
+ "type": "object",
361
+ "additionalProperties": False,
362
+ "required": ["evaluated_level"],
363
+ "properties": {"evaluated_level": {"type": "integer"}},
364
+ }
365
+ }
366
+ properties.update({str(index): step_schema for index in range(1, step_count + 1)})
367
+ return {
368
+ "type": "json_schema",
369
+ "json_schema": {
370
+ "name": "plan_and_budget_credit_assessment",
371
+ "strict": True,
372
+ "schema": {
373
+ "type": "object",
374
+ "additionalProperties": False,
375
+ "required": ["problem", *(str(index) for index in range(1, step_count + 1))],
376
+ "properties": properties,
377
+ },
378
+ },
379
+ }
380
+
381
+
382
+ def _parse_decomposition(text: str) -> tuple[tuple[str, ...], tuple[str, ...]]:
383
+ if not isinstance(text, str) or not text.strip():
384
+ raise AlgorithmOutputError("Plan-and-Budget decomposition returned empty text")
385
+ matches = tuple(_NUMBERED_ITEM.finditer(text.strip()))
386
+ steps = tuple(match.group("text").strip() for match in matches if match.group("text").strip())
387
+ warnings: list[str] = []
388
+ if not steps:
389
+ # Matches the released preprocessing fallback exactly.
390
+ steps = ("Directly solve the problem. Hint: None.",)
391
+ warnings.append("decomposition_parse_fallback_to_direct_solve")
392
+ elif len(steps) > 5:
393
+ raise AlgorithmOutputError("Plan-and-Budget decomposition returned more than five steps")
394
+ if not 2 <= len(steps) <= 5:
395
+ warnings.append("generated_step_count_outside_prompt_intended_2_to_5")
396
+ return steps, tuple(warnings)
397
+
398
+
399
+ def _parse_assessment(
400
+ text: str,
401
+ *,
402
+ step_count: int,
403
+ ) -> tuple[int, tuple[float, ...], tuple[str, ...]]:
404
+ data = _json_object(text)
405
+ problem = data.get("problem")
406
+ if not isinstance(problem, dict):
407
+ raise AlgorithmOutputError("Plan-and-Budget assessment lacks problem metadata")
408
+ level = _integer(problem.get("evaluated_level"), label="problem evaluated_level")
409
+ if not 1 <= level <= 5:
410
+ raise AlgorithmOutputError("Plan-and-Budget evaluated problem level must be in [1, 5]")
411
+ credits: list[float] = []
412
+ for index in range(1, step_count + 1):
413
+ item = data.get(str(index))
414
+ if not isinstance(item, dict):
415
+ raise AlgorithmOutputError(f"Plan-and-Budget assessment lacks sub-question {index}")
416
+ sublevel = _integer(item.get("evaluated_level"), label=f"step {index} evaluated_level")
417
+ credit = _integer(item.get("credit"), label=f"step {index} credit")
418
+ if not 1 <= sublevel <= 5 or not 1 <= credit <= 100:
419
+ raise AlgorithmOutputError(
420
+ "Plan-and-Budget step level/credit is outside the released range"
421
+ )
422
+ credits.append(float(credit))
423
+ if set(data) != {"problem", *(str(index) for index in range(1, step_count + 1))}:
424
+ raise AlgorithmOutputError("Plan-and-Budget assessment returned unexpected step keys")
425
+ warnings = () if sum(credits) == 100 else ("generated_credit_sum_not_100",)
426
+ return level, tuple(credits), warnings
427
+
428
+
429
+ def _json_object(text: str) -> dict[str, Any]:
430
+ if not isinstance(text, str) or not text.strip():
431
+ raise AlgorithmOutputError("Plan-and-Budget assessment returned empty text")
432
+ start = text.find("{")
433
+ end = text.rfind("}")
434
+ if start < 0 or end < start:
435
+ raise AlgorithmOutputError("Plan-and-Budget assessment did not return JSON")
436
+ try:
437
+ value = json.loads(text[start : end + 1])
438
+ except json.JSONDecodeError as exc:
439
+ raise AlgorithmOutputError("Plan-and-Budget assessment returned invalid JSON") from exc
440
+ if not isinstance(value, dict):
441
+ raise AlgorithmOutputError("Plan-and-Budget assessment JSON must be an object")
442
+ return value
443
+
444
+
445
+ def _integer(value: Any, *, label: str) -> int:
446
+ if isinstance(value, bool) or not isinstance(value, int):
447
+ raise AlgorithmOutputError(f"Plan-and-Budget {label} must be an integer")
448
+ return value
@@ -0,0 +1,33 @@
1
+ """Plan-and-Solve PS and PS+ prompt profiles."""
2
+
3
+ from .plan_component import (
4
+ PLAN_AND_SOLVE_PLAN_CONTRACT,
5
+ PLAN_AND_SOLVE_PLAN_TRIGGER,
6
+ PlanAndSolvePlanComponent,
7
+ render_plan_component_prompt,
8
+ )
9
+ from .ps_prompt import (
10
+ PLAN_AND_SOLVE_PLUS_PROMPT_ID,
11
+ PLAN_AND_SOLVE_PLUS_TRIGGER,
12
+ PLAN_AND_SOLVE_PROMPT_ID,
13
+ PLAN_AND_SOLVE_TRIGGER,
14
+ PLAN_AND_SOLVE_UPSTREAM_REVISION,
15
+ PlanAndSolvePSPlusPrompt,
16
+ PlanAndSolvePSPrompt,
17
+ render_plan_and_solve_prompt,
18
+ )
19
+
20
+ __all__ = [
21
+ "PLAN_AND_SOLVE_PLAN_CONTRACT",
22
+ "PLAN_AND_SOLVE_PLAN_TRIGGER",
23
+ "PLAN_AND_SOLVE_PLUS_PROMPT_ID",
24
+ "PLAN_AND_SOLVE_PLUS_TRIGGER",
25
+ "PLAN_AND_SOLVE_PROMPT_ID",
26
+ "PLAN_AND_SOLVE_TRIGGER",
27
+ "PLAN_AND_SOLVE_UPSTREAM_REVISION",
28
+ "PlanAndSolvePSPlusPrompt",
29
+ "PlanAndSolvePSPrompt",
30
+ "PlanAndSolvePlanComponent",
31
+ "render_plan_and_solve_prompt",
32
+ "render_plan_component_prompt",
33
+ ]
@@ -0,0 +1,192 @@
1
+ """Controlled planning-clause component, separate from full PS prompting.
2
+
3
+ The fixed first sentence of PS 201 requests a plan. One generation is attached
4
+ as advisory input for the caller's unchanged downstream reader/environment.
5
+ No solver, arithmetic answer extraction, tool action or plan-quality judge is
6
+ executed here. This is a declared component adaptation, not upstream parity.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+
13
+ from agentinputlab.backends.llm import GenerationRequest, LLMBackend, ModelCapability
14
+ from agentinputlab.contracts import (
15
+ AlgorithmOutputError,
16
+ BudgetExceededError,
17
+ CapabilityError,
18
+ ExecutionTrace,
19
+ ExternalDependencyError,
20
+ FrozenAgentState,
21
+ InputPatch,
22
+ InterventionContext,
23
+ PatchOp,
24
+ PatchOperation,
25
+ SemanticFamily,
26
+ TraceEvent,
27
+ TracePhase,
28
+ ValidationError,
29
+ )
30
+ from agentinputlab.contracts.serialization import content_hash
31
+
32
+ from .ps_prompt import (
33
+ PLAN_AND_SOLVE_PROMPT_ID,
34
+ PLAN_AND_SOLVE_TRIGGER,
35
+ PLAN_AND_SOLVE_UPSTREAM_REVISION,
36
+ render_plan_and_solve_prompt,
37
+ )
38
+
39
+ PLAN_AND_SOLVE_PLAN_TRIGGER = (
40
+ "Let's first understand the problem and devise a plan to solve the problem."
41
+ )
42
+ PLAN_AND_SOLVE_PLAN_CONTRACT = "ps201.first-clause.raw-advisory-plan.v1"
43
+
44
+
45
+ def render_plan_component_prompt(question: str) -> str:
46
+ return render_plan_and_solve_prompt(question, trigger=PLAN_AND_SOLVE_PLAN_TRIGGER)
47
+
48
+
49
+ class PlanAndSolvePlanComponent:
50
+ """Generate an evaluator-blind planning suggestion in one counted call.
51
+
52
+ Nonempty generated text is preserved verbatim apart from outer whitespace.
53
+ It is not asserted to be an answer-free plan or independently verified.
54
+ Empty output remains a paid failure; there is no fallback or second call.
55
+ """
56
+
57
+ method_id = "plan_and_solve"
58
+ release_id = "plan.plan_and_solve.plan_component"
59
+ family = SemanticFamily.DECOMPOSE
60
+
61
+ def __init__(self, *, max_tokens=512, temperature=0.0, profile_kind="controlled_adapter"):
62
+ if isinstance(max_tokens, bool) or not isinstance(max_tokens, int) or max_tokens < 1:
63
+ raise ValidationError("PS planning max_tokens must be a positive integer")
64
+ if (
65
+ isinstance(temperature, bool)
66
+ or not isinstance(temperature, (int, float))
67
+ or not math.isfinite(temperature)
68
+ or temperature < 0
69
+ ):
70
+ raise ValidationError("PS planning temperature must be finite and non-negative")
71
+ if profile_kind not in {"controlled_adapter", "factorial_adapter"}:
72
+ raise ValidationError("PS planning is a controlled/factorial component")
73
+ self.max_tokens = max_tokens
74
+ self.temperature = temperature
75
+ self.profile_kind = profile_kind
76
+
77
+ def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
78
+ if not state.query.strip():
79
+ raise ValidationError("PS planning requires a non-empty visible query")
80
+ if state.budget.max_model_calls < 1 or state.budget.max_output_tokens < 1:
81
+ raise BudgetExceededError("PS planning has no generation budget")
82
+ backend = context.backend
83
+ if backend is None:
84
+ raise ExternalDependencyError("PS planning requires an injected LLMBackend")
85
+ if (
86
+ not isinstance(backend, LLMBackend)
87
+ or ModelCapability.COMPLETION not in backend.capabilities
88
+ ):
89
+ raise CapabilityError("PS planning requires completion capability")
90
+ prompt = render_plan_component_prompt(state.query)
91
+ request = GenerationRequest(
92
+ prompt=prompt,
93
+ max_tokens=min(self.max_tokens, state.budget.max_output_tokens),
94
+ temperature=self.temperature,
95
+ seed=context.seed,
96
+ metadata={
97
+ "method_id": self.method_id,
98
+ "release_id": self.release_id,
99
+ "stage": "planning_component",
100
+ "source_prompt_id": PLAN_AND_SOLVE_PROMPT_ID,
101
+ "component_contract": PLAN_AND_SOLVE_PLAN_CONTRACT,
102
+ },
103
+ )
104
+ response = backend.generate(request)
105
+ if not isinstance(response.text, str) or not response.text.strip():
106
+ raise AlgorithmOutputError("PS planning returned no final advisory text")
107
+ plan = response.text.strip()
108
+ trace = ExecutionTrace(
109
+ method_id=self.method_id,
110
+ release_id=self.release_id,
111
+ events=(
112
+ TraceEvent(
113
+ TracePhase.PREPARE,
114
+ "fixed_planning_clause",
115
+ {
116
+ "component_contract": PLAN_AND_SOLVE_PLAN_CONTRACT,
117
+ "source_prompt_id": PLAN_AND_SOLVE_PROMPT_ID,
118
+ "source_full_trigger_hash": content_hash(PLAN_AND_SOLVE_TRIGGER),
119
+ "planner_trigger": PLAN_AND_SOLVE_PLAN_TRIGGER,
120
+ "rendered_prompt_hash": content_hash(prompt),
121
+ "generation_request_hash": request.request_hash,
122
+ "upstream_revision_for_audit": PLAN_AND_SOLVE_UPSTREAM_REVISION,
123
+ "optimizer_input_projection": "query_only",
124
+ },
125
+ ),
126
+ TraceEvent(
127
+ TracePhase.PROPOSE,
128
+ "raw_advisory_plan",
129
+ {
130
+ "plan": plan,
131
+ "raw_response_hash": content_hash(response.text),
132
+ "finish_reason": response.finish_reason,
133
+ "downstream_execution_required": True,
134
+ "plan_quality_judged": False,
135
+ "solver_executed": False,
136
+ },
137
+ ),
138
+ ),
139
+ counters={
140
+ "model_calls": 1,
141
+ "optimizer_model_calls": 1,
142
+ "input_tokens": response.usage.input_tokens,
143
+ "output_tokens": response.usage.output_tokens,
144
+ **(
145
+ {"cost_usd": response.usage.cost_usd}
146
+ if response.usage.cost_usd is not None
147
+ else {}
148
+ ),
149
+ },
150
+ warnings=("planning_clause_component_not_full_ps_pipeline",),
151
+ )
152
+ return InputPatch(
153
+ method_id=self.method_id,
154
+ release_id=self.release_id,
155
+ source_state_hash=state.state_hash,
156
+ operations=(
157
+ PatchOperation(
158
+ PatchOp.APPEND_INSTRUCTION,
159
+ value="Suggested plan:\n" + plan,
160
+ target="instruction",
161
+ rationale="one-call PS planning-clause advisory component",
162
+ ),
163
+ ),
164
+ trace=trace,
165
+ implementation_identity=f"controlled_ps201_planning_clause@{PLAN_AND_SOLVE_UPSTREAM_REVISION}",
166
+ profile_kind=self.profile_kind,
167
+ metadata={
168
+ "component_only": True,
169
+ "component_contract": PLAN_AND_SOLVE_PLAN_CONTRACT,
170
+ "full_system": False,
171
+ "source_prompt_id": PLAN_AND_SOLVE_PROMPT_ID,
172
+ "plan": plan,
173
+ "plan_quality_judged": False,
174
+ "response_finish_reason": response.finish_reason,
175
+ "raw_response_preserved_except_outer_whitespace": True,
176
+ "answer_free_plan_guaranteed": False,
177
+ "optimizer_input_projection": "query_only",
178
+ "gold_fields_visible_to_optimizer": False,
179
+ "downstream_execution_required": True,
180
+ "solver_executed": False,
181
+ "tool_actions_executed": False,
182
+ "paper_result_parity_claimed": False,
183
+ },
184
+ )
185
+
186
+
187
+ __all__ = [
188
+ "PLAN_AND_SOLVE_PLAN_CONTRACT",
189
+ "PLAN_AND_SOLVE_PLAN_TRIGGER",
190
+ "PlanAndSolvePlanComponent",
191
+ "render_plan_component_prompt",
192
+ ]