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,175 @@
1
+ """LongLLMLingua with immutable shared-comparison identities and settings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from dataclasses import asdict, dataclass, replace
7
+ from typing import Any
8
+
9
+ from agentinputlab.contracts import (
10
+ AlgorithmOutputError,
11
+ ExecutionBudget,
12
+ ExternalDependencyError,
13
+ FrozenAgentState,
14
+ InputPatch,
15
+ InterventionContext,
16
+ SemanticFamily,
17
+ TraceEvent,
18
+ TracePhase,
19
+ ValidationError,
20
+ )
21
+ from agentinputlab.contracts.serialization import content_hash, freeze_mapping
22
+
23
+ from .adapters import LongLLMLinguaConfig
24
+ from .budget import parse_context_budget
25
+
26
+ _DEFAULT_CONFIG = LongLLMLinguaConfig()
27
+
28
+
29
+ @dataclass(frozen=True, slots=True)
30
+ class LongLLMLinguaCompressionRequest:
31
+ state: FrozenAgentState
32
+ config: LongLLMLinguaConfig
33
+ seed: int
34
+
35
+ def __post_init__(self):
36
+ if (not isinstance(self.state, FrozenAgentState) or not isinstance(self.config, LongLLMLinguaConfig)
37
+ or type(self.seed) is not int or self.seed < 0):
38
+ raise ValidationError("LongLLMLingua requires a typed compression request")
39
+
40
+
41
+ def _identity(value: Any, label: str) -> Mapping[str, Any]:
42
+ if not isinstance(value, Mapping) or not value:
43
+ raise ValidationError(f"LongLLMLingua {label} fingerprint must be nonempty")
44
+ try:
45
+ result = freeze_mapping(value)
46
+ content_hash(result)
47
+ except (TypeError, ValueError, OverflowError) as exc:
48
+ raise ValidationError(f"LongLLMLingua {label} fingerprint must be canonical JSON") from exc
49
+ return result
50
+
51
+
52
+ def _identities(context: InterventionContext) -> dict[str, Mapping[str, Any]]:
53
+ values = {}
54
+ for name, dependency, operation in (
55
+ ("compressor", context.external_runtime, "run"),
56
+ ("reader", context.backend, "generate"),
57
+ ):
58
+ fingerprint = getattr(dependency, "fingerprint", None)
59
+ if not callable(fingerprint) or not callable(getattr(dependency, operation, None)):
60
+ raise ExternalDependencyError(
61
+ f"controlled LongLLMLingua requires {name} with {operation}() and fingerprint()"
62
+ )
63
+ values[name] = _identity(fingerprint(), name)
64
+ return values
65
+
66
+
67
+ @dataclass(frozen=True, slots=True)
68
+ class LongLLMLinguaControlledBindings:
69
+ """Operator identities, not a certificate of weights or a paired experiment.
70
+
71
+ The compressor identity includes its helper model and tokenizer. The reader
72
+ is checked but not called here: its benchmark driver must preserve the same
73
+ reader, generation policy and remaining budget for all comparison arms.
74
+ """
75
+
76
+ compressor: Mapping[str, Any]
77
+ reader: Mapping[str, Any]
78
+ budget: ExecutionBudget
79
+ config: LongLLMLinguaConfig = _DEFAULT_CONFIG
80
+ seed: int = 0
81
+
82
+ def __post_init__(self) -> None:
83
+ if not isinstance(self.budget, ExecutionBudget) or not isinstance(self.config, LongLLMLinguaConfig):
84
+ raise ValidationError("controlled LongLLMLingua requires typed budget/config")
85
+ if type(self.seed) is not int or self.seed < 0:
86
+ raise ValidationError("controlled LongLLMLingua seed must be nonnegative")
87
+ object.__setattr__(self, "config", replace(self.config,
88
+ context_budget=parse_context_budget(self.config.context_budget)))
89
+ for name in ("compressor", "reader"):
90
+ object.__setattr__(self, name, _identity(getattr(self, name), name))
91
+ for name in ("model", "tokenizer", "source"):
92
+ _identity(self.compressor.get(name), f"compressor {name}")
93
+
94
+ @classmethod
95
+ def from_context(cls, context: InterventionContext, *, budget: ExecutionBudget,
96
+ config: LongLLMLinguaConfig = _DEFAULT_CONFIG) -> LongLLMLinguaControlledBindings:
97
+ if not isinstance(context, InterventionContext):
98
+ raise ValidationError("controlled LongLLMLingua requires an InterventionContext")
99
+ return cls(**_identities(context), budget=budget, config=config, seed=context.seed)
100
+
101
+ @classmethod
102
+ def from_mapping(cls, value: Mapping[str, Any]) -> LongLLMLinguaControlledBindings:
103
+ required = {"compressor", "reader", "budget"}
104
+ if not required.issubset(value) or set(value) - required - {"config", "seed"}:
105
+ raise ValidationError("invalid controlled LongLLMLingua binding fields")
106
+ try:
107
+ return cls(compressor=value["compressor"], reader=value["reader"],
108
+ budget=ExecutionBudget(**value["budget"]),
109
+ config=LongLLMLinguaConfig(**value.get("config", {})), seed=value.get("seed", 0))
110
+ except TypeError as exc:
111
+ raise ValidationError("invalid controlled LongLLMLingua binding settings") from exc
112
+
113
+ @property
114
+ def binding_hash(self) -> str:
115
+ return content_hash(self)
116
+
117
+ def require_match(self, context: InterventionContext) -> None:
118
+ if context.seed != self.seed:
119
+ raise ValidationError("controlled LongLLMLingua seed differs from binding")
120
+ for name, value in _identities(context).items():
121
+ if content_hash(value) != content_hash(getattr(self, name)):
122
+ raise ValidationError(f"controlled LongLLMLingua {name} differs from binding")
123
+
124
+
125
+ @dataclass(frozen=True, slots=True)
126
+ class LongLLMLinguaControlled:
127
+ bindings: LongLLMLinguaControlledBindings | Mapping[str, Any]
128
+ profile_kind: str = "controlled_adapter"
129
+ method_id: str = "longllmlingua"
130
+ release_id: str = "curate.longllmlingua.controlled"
131
+ family: SemanticFamily = SemanticFamily.CURATE
132
+
133
+ def __post_init__(self) -> None:
134
+ if isinstance(self.bindings, Mapping):
135
+ object.__setattr__(self, "bindings", LongLLMLinguaControlledBindings.from_mapping(self.bindings))
136
+ if not isinstance(self.bindings, LongLLMLinguaControlledBindings):
137
+ raise ValidationError("controlled LongLLMLingua requires frozen bindings")
138
+ if self.profile_kind not in {"controlled_adapter", "factorial_adapter"}:
139
+ raise ValidationError("controlled LongLLMLingua requires controlled or factorial mode")
140
+ if (self.method_id != "longllmlingua" or self.release_id != "curate.longllmlingua.controlled"
141
+ or self.family is not SemanticFamily.CURATE):
142
+ raise ValidationError("controlled LongLLMLingua identity differs from its registry")
143
+
144
+ def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
145
+ if state.budget != self.bindings.budget:
146
+ raise ValidationError("controlled LongLLMLingua state budget differs from binding")
147
+ self.bindings.require_match(context)
148
+ result = context.external_runtime.run(LongLLMLinguaCompressionRequest(
149
+ state, self.bindings.config, context.seed))
150
+ native = result.get("patch") if isinstance(result, Mapping) else None
151
+ self.bindings.require_match(context)
152
+ if (not isinstance(native, InputPatch) or native.method_id != self.method_id
153
+ or native.release_id != "curate.longllmlingua.official"
154
+ or native.source_state_hash != state.state_hash):
155
+ raise AlgorithmOutputError("LongLLMLingua runtime returned a different native patch identity")
156
+ configs = [e.payload.get("config") for e in native.trace.events if e.name == "official_runtime_config"]
157
+ if len(configs) != 1 or content_hash(configs[0]) != content_hash(asdict(self.bindings.config)):
158
+ raise AlgorithmOutputError("LongLLMLingua runtime used different method settings")
159
+ model = self.bindings.compressor["model"]
160
+ if (native.metadata.get("model_name") != model.get("locator")
161
+ or native.metadata.get("model_revision") != model.get("revision")):
162
+ raise AlgorithmOutputError("LongLLMLingua native patch uses a different helper model")
163
+ return replace(native, release_id=self.release_id, profile_kind=self.profile_kind,
164
+ trace=replace(native.trace, release_id=self.release_id, events=(
165
+ TraceEvent(TracePhase.PREPARE, "controlled_dependency_binding", {
166
+ "binding_sha256": self.bindings.binding_hash, "budget": self.bindings.budget,
167
+ "seed": self.bindings.seed, "identity_verification": "operator_fingerprint_equality",
168
+ "reader_bound_not_invoked": True}), *native.trace.events)),
169
+ metadata={**native.metadata, "native_source_release": native.release_id,
170
+ "controlled_binding_sha256": self.bindings.binding_hash,
171
+ "reader_generation_performed": False, "helper_compute_accounting": "separate_from_reader_generation",
172
+ "original_paper_result_parity_claimed": False})
173
+
174
+
175
+ __all__ = ["LongLLMLinguaCompressionRequest", "LongLLMLinguaControlled", "LongLLMLinguaControlledBindings"]
@@ -0,0 +1,105 @@
1
+ """Official LLMLingua-2 multilingual BERT, with an exact asset closure.
2
+
3
+ The token classifier is a fixed auxiliary model, independent of the evaluated
4
+ reader. No XLM-R weights or downstream-backbone weights are substituted.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from dataclasses import dataclass
10
+ from functools import lru_cache
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+ from agentinputlab.artifacts import sha256_file
15
+ from agentinputlab.contracts import ExternalDependencyError, ValidationError
16
+
17
+ from .adapters import LLMLingua2OfficialAdapter, _OfficialAdapterBase
18
+
19
+ BERT_MULTILINGUAL_MODEL = "microsoft/llmlingua-2-bert-base-multilingual-cased-meetingbank"
20
+ BERT_MULTILINGUAL_REVISION = "5f0c82792b7ea14c6484e015b6a072009496b7f2"
21
+ BERT_MULTILINGUAL_FILES = (
22
+ ("config.json", "e6c33ec2f099e659e125efaa8b7bb07a6e65b7d9fc36211c6fa3206e1c399085"),
23
+ ("tokenizer_config.json", "214f78f6c5d034a8b405632d301ee3710eb6f075b3f5faf8241a273a13908746"),
24
+ ("tokenizer.json", "bf1b59b7b11c95f194f51708d918eea378e09d05f84c0e1656dc5180e8117088"),
25
+ ("vocab.txt", "fe0fda7c425b48c516fc8f160d594c8022a0808447475c1a7c6d6479763f310c"),
26
+ ("special_tokens_map.json", "b6d346be366a7d1d48332dbc9fdf3bf8960b5d879522b7799ddba59e76237ee3"),
27
+ ("model.safetensors", "22b9ecde52fec5c97e8c54a293be768727df95a81c6c8dccb03f262a50c58324"),
28
+ )
29
+
30
+
31
+ @lru_cache(maxsize=8)
32
+ def _verify_snapshot(snapshot: str, identities: tuple[tuple[str, int, int], ...]) -> None:
33
+ """Hash immutable weights once per local path/size/mtime identity."""
34
+ del identities
35
+ for name, expected in BERT_MULTILINGUAL_FILES:
36
+ if sha256_file(Path(snapshot) / name) != expected:
37
+ raise ExternalDependencyError(f"multilingual BERT asset checksum differs: {name}")
38
+
39
+
40
+ @dataclass(slots=True)
41
+ class LLMLingua2BertMultilingualOfficialAdapter(LLMLingua2OfficialAdapter):
42
+ """Pinned author checkpoint and unchanged upstream compression dispatcher.
43
+
44
+ Pass an existing snapshot as ``model_name`` for offline use. Otherwise the
45
+ built-in loader downloads only the six pinned model/tokenizer files. An
46
+ injected compressor factory is caller-owned code, not accepted-model proof.
47
+ """
48
+
49
+ model_name: str = BERT_MULTILINGUAL_MODEL
50
+ model_revision: str = BERT_MULTILINGUAL_REVISION
51
+ release_id: str = "curate.llmlingua2.bert_multilingual_official"
52
+
53
+ def __post_init__(self) -> None:
54
+ _OfficialAdapterBase.__post_init__(self)
55
+ if self.model_revision != BERT_MULTILINGUAL_REVISION:
56
+ raise ValidationError("multilingual BERT requires its pinned checkpoint revision")
57
+ if self.release_id != "curate.llmlingua2.bert_multilingual_official":
58
+ raise ValidationError("multilingual BERT release identity cannot be replaced")
59
+ if self.profile_kind not in {"official_native", "factorial_adapter"}:
60
+ raise ValidationError("multilingual BERT requires an official or factorial profile")
61
+ allowed = {"revision", "trust_remote_code", "local_files_only", "torch_dtype"}
62
+ if set(self.model_config) - allowed:
63
+ raise ValidationError("unsupported multilingual BERT loading option")
64
+ if self.model_config.get("revision", self.model_revision) != self.model_revision:
65
+ raise ValidationError("multilingual BERT revision cannot be overridden")
66
+ if self.model_config.get("trust_remote_code") not in {None, False}:
67
+ raise ValidationError("multilingual BERT disables remote code")
68
+ if not isinstance(self.model_config.get("local_files_only", False), bool):
69
+ raise ValidationError("local_files_only must be boolean")
70
+ self._validate_torch_dtype(self.model_config.get("torch_dtype", "auto"))
71
+ if self.model_name != BERT_MULTILINGUAL_MODEL and not Path(self.model_name).is_dir():
72
+ raise ValidationError("model_name must be the official BERT ID or a local snapshot")
73
+
74
+ def _load(self, *, use_llmlingua2: bool) -> Any:
75
+ if not use_llmlingua2:
76
+ raise ValidationError("multilingual BERT requires LLMLingua-2 token classification")
77
+ if self.compressor_factory is None:
78
+ try:
79
+ snapshot = Path(self.model_name)
80
+ if self.model_name == BERT_MULTILINGUAL_MODEL:
81
+ from huggingface_hub import snapshot_download
82
+
83
+ snapshot = Path(snapshot_download(
84
+ self.model_name,
85
+ revision=self.model_revision,
86
+ allow_patterns=[name for name, _ in BERT_MULTILINGUAL_FILES],
87
+ local_files_only=self.model_config.get("local_files_only", False),
88
+ ))
89
+ identities = tuple(
90
+ (name, (snapshot / name).stat().st_size, (snapshot / name).stat().st_mtime_ns)
91
+ for name, _ in BERT_MULTILINGUAL_FILES
92
+ )
93
+ _verify_snapshot(str(snapshot.resolve()), identities)
94
+ except (ImportError, OSError, ValueError) as exc:
95
+ raise ExternalDependencyError(
96
+ "multilingual BERT needs its complete pinned safetensors/tokenizer snapshot "
97
+ "and `pip install agentinputlab[compression]`"
98
+ ) from exc
99
+ return _OfficialAdapterBase._load(self, use_llmlingua2=True)
100
+
101
+
102
+ __all__ = [
103
+ "BERT_MULTILINGUAL_FILES", "BERT_MULTILINGUAL_MODEL", "BERT_MULTILINGUAL_REVISION",
104
+ "LLMLingua2BertMultilingualOfficialAdapter",
105
+ ]
@@ -0,0 +1,167 @@
1
+ """Conservative exact-span provenance for compressed context."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from bisect import bisect_left
7
+ from collections.abc import Sequence
8
+ from dataclasses import dataclass
9
+ from difflib import SequenceMatcher
10
+
11
+ from agentinputlab.contracts import ContextBlock
12
+
13
+ # Character-level difflib is useful for short inputs but quadratic on the long,
14
+ # repetitive contexts these compressors are meant to handle. Longer pairs use
15
+ # literal indexed anchors instead; this changes provenance choices, not text.
16
+ _DIFF_PRODUCT_LIMIT = 2_000_000
17
+ _TOKENS = re.compile(r"[A-Za-z0-9_]+|[^\s]")
18
+
19
+
20
+ def _indexed_matches(
21
+ source: str, output: str, output_tokens: Sequence[tuple[int, int]], minimum_match: int,
22
+ ) -> list[tuple[int, int, int]]:
23
+ """Find exact runs without a source-by-output character comparison matrix.
24
+
25
+ One-, two- and three-token anchors include the original intervening spaces.
26
+ Sorted occurrence lists keep even repeated anchors cheap. Reordered source
27
+ text is allowed; partial words fall back to indexed character runs. Neither
28
+ path normalizes text or attributes a span to a merely similar substring.
29
+ """
30
+
31
+ source_tokens = [match.span() for match in _TOKENS.finditer(source)]
32
+ anchors: list[dict[str, list[int]]] = [{}, {}, {}]
33
+ for width, index in enumerate(anchors, start=1):
34
+ for offset in range(len(source_tokens) - width + 1):
35
+ start = source_tokens[offset][0]
36
+ end = source_tokens[offset + width - 1][1]
37
+ index.setdefault(source[start:end], []).append(start)
38
+ character_anchors: dict[str, list[int]] | None = None
39
+ character_width = min(3, minimum_match)
40
+ matches: list[tuple[int, int, int]] = []
41
+
42
+ def append(source_start: int, output_start: int, size: int) -> None:
43
+ if matches:
44
+ last_source, last_output, last_size = matches[-1]
45
+ source_end, output_end = last_source + last_size, last_output + last_size
46
+ if (source_start >= source_end and output_start >= output_end
47
+ and source_start - source_end == output_start - output_end
48
+ and source[source_end:source_start] == output[output_end:output_start]):
49
+ matches[-1] = (last_source, last_output, output_start + size - last_output)
50
+ return
51
+ matches.append((source_start, output_start, size))
52
+
53
+ source_cursor = 0
54
+ offset = 0
55
+ while offset < len(output_tokens):
56
+ for width in range(min(3, len(output_tokens) - offset), 0, -1):
57
+ start, end = output_tokens[offset][0], output_tokens[offset + width - 1][1]
58
+ positions = anchors[width - 1].get(output[start:end])
59
+ if positions:
60
+ position_index = bisect_left(positions, source_cursor)
61
+ source_start = positions[position_index if position_index < len(positions) else 0]
62
+ append(source_start, start, end - start)
63
+ source_cursor = source_start + end - start
64
+ offset += width
65
+ break
66
+ else:
67
+ # Token compression can keep only part of a word. Short literal
68
+ # anchors locate those runs without rescanning the source per word.
69
+ if character_anchors is None:
70
+ character_anchors = {}
71
+ for position in range(len(source) - character_width + 1):
72
+ key = source[position:position + character_width]
73
+ character_anchors.setdefault(key, []).append(position)
74
+ start, end = output_tokens[offset]
75
+ output_start = start
76
+ while output_start + character_width <= end:
77
+ positions = character_anchors.get(output[output_start:output_start + character_width])
78
+ if not positions:
79
+ output_start += 1
80
+ continue
81
+ position_index = bisect_left(positions, source_cursor)
82
+ source_start = positions[position_index if position_index < len(positions) else 0]
83
+ size = character_width
84
+ while (output_start + size < end and source_start + size < len(source)
85
+ and output[output_start + size] == source[source_start + size]):
86
+ size += 1
87
+ append(source_start, output_start, size)
88
+ source_cursor = source_start + size
89
+ output_start += size
90
+ offset += 1
91
+ return matches
92
+
93
+
94
+ @dataclass(frozen=True, slots=True)
95
+ class SpanMapping:
96
+ output_start: int
97
+ output_end: int
98
+ source_block_id: str
99
+ source_start: int
100
+ source_end: int
101
+ exact: bool = True
102
+
103
+
104
+ def build_span_map(
105
+ compressed_text: str,
106
+ source_blocks: Sequence[ContextBlock],
107
+ *,
108
+ minimum_match: int = 3,
109
+ ) -> tuple[SpanMapping, ...]:
110
+ """Map only exact matching spans and leave generated/unmatched text unmapped.
111
+
112
+ Per-block matching supports context reorder. Overlapping output matches are
113
+ resolved longest-first; the function never invents provenance for a token
114
+ that cannot be located exactly in a source block. Large pairs use indexed
115
+ literal anchors instead of quadratic character diffing; ambiguous locations
116
+ can therefore differ from the short-input matcher. This is provenance, not
117
+ a reconstruction of the compressor's internal token-selection decisions.
118
+ """
119
+
120
+ if minimum_match < 1:
121
+ raise ValueError("minimum_match must be positive")
122
+ if not compressed_text:
123
+ return ()
124
+ output_tokens: list[tuple[int, int]] | None = None
125
+ candidates: list[SpanMapping] = []
126
+ for index, block in enumerate(source_blocks):
127
+ block_id = block.block_id or f"context-{index}"
128
+ contained = block.text.find(compressed_text)
129
+ if contained >= 0:
130
+ matches = [(contained, 0, len(compressed_text))]
131
+ elif len(block.text) * len(compressed_text) <= _DIFF_PRODUCT_LIMIT:
132
+ matcher = SequenceMatcher(None, block.text, compressed_text, autojunk=False)
133
+ matches = matcher.get_matching_blocks()
134
+ else:
135
+ if output_tokens is None:
136
+ output_tokens = [match.span() for match in _TOKENS.finditer(compressed_text)]
137
+ matches = _indexed_matches(block.text, compressed_text, output_tokens, minimum_match)
138
+ for source_start, output_start, size in matches:
139
+ if size < minimum_match:
140
+ continue
141
+ candidates.append(
142
+ SpanMapping(
143
+ output_start=output_start,
144
+ output_end=output_start + size,
145
+ source_block_id=block_id,
146
+ source_start=source_start,
147
+ source_end=source_start + size,
148
+ )
149
+ )
150
+ candidates.sort(
151
+ key=lambda item: (
152
+ -(item.output_end - item.output_start),
153
+ item.output_start,
154
+ item.source_block_id,
155
+ item.source_start,
156
+ )
157
+ )
158
+ occupied = bytearray(len(compressed_text))
159
+ selected: list[SpanMapping] = []
160
+ for candidate in candidates:
161
+ if any(occupied[candidate.output_start : candidate.output_end]):
162
+ continue
163
+ occupied[candidate.output_start : candidate.output_end] = b"\x01" * (
164
+ candidate.output_end - candidate.output_start
165
+ )
166
+ selected.append(candidate)
167
+ return tuple(sorted(selected, key=lambda item: (item.output_start, item.output_end)))
@@ -0,0 +1,47 @@
1
+ """RECOMP compressor-component adapters."""
2
+
3
+ from .external import (
4
+ RECOMP_ABSTRACTIVE_INPUT_TEMPLATE,
5
+ RECOMP_ABSTRACTIVE_INPUT_TEMPLATE_SHA256,
6
+ RECOMP_CANDIDATE_UNIT_KIND,
7
+ RECOMP_COMMON_SUPPORT_RELEASE,
8
+ RECOMP_COMMON_SUPPORT_SPLITTER,
9
+ RECOMP_UPSTREAM_COMMIT,
10
+ RECOMPAbstractiveControls,
11
+ RECOMPAbstractiveExternal,
12
+ RECOMPExtractiveCommonSupport,
13
+ RECOMPExtractiveControls,
14
+ RECOMPExtractiveExternal,
15
+ RECOMPSentenceScore,
16
+ prepare_recomp_sentence_state,
17
+ )
18
+ from .selective import (
19
+ RECOMP_QUERY_DECODER_ID,
20
+ RECOMP_QUERY_DECODER_SHA256,
21
+ RECOMP_SELECTIVE_ASSEMBLY,
22
+ RECOMP_SELECTIVE_RELEASE,
23
+ RECOMPSelectiveRuntime,
24
+ parse_recomp_query_reader_answer,
25
+ )
26
+
27
+ __all__ = [
28
+ "RECOMP_ABSTRACTIVE_INPUT_TEMPLATE",
29
+ "RECOMP_ABSTRACTIVE_INPUT_TEMPLATE_SHA256",
30
+ "RECOMP_CANDIDATE_UNIT_KIND",
31
+ "RECOMP_COMMON_SUPPORT_RELEASE",
32
+ "RECOMP_COMMON_SUPPORT_SPLITTER",
33
+ "RECOMP_QUERY_DECODER_ID",
34
+ "RECOMP_QUERY_DECODER_SHA256",
35
+ "RECOMP_SELECTIVE_ASSEMBLY",
36
+ "RECOMP_SELECTIVE_RELEASE",
37
+ "RECOMP_UPSTREAM_COMMIT",
38
+ "RECOMPAbstractiveControls",
39
+ "RECOMPAbstractiveExternal",
40
+ "RECOMPExtractiveCommonSupport",
41
+ "RECOMPExtractiveControls",
42
+ "RECOMPExtractiveExternal",
43
+ "RECOMPSelectiveRuntime",
44
+ "RECOMPSentenceScore",
45
+ "parse_recomp_query_reader_answer",
46
+ "prepare_recomp_sentence_state",
47
+ ]