weft-rag 2.4.0__tar.gz

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 (282) hide show
  1. weft_rag-2.4.0/.gitignore +85 -0
  2. weft_rag-2.4.0/LICENSE +21 -0
  3. weft_rag-2.4.0/NOTICE +77 -0
  4. weft_rag-2.4.0/PKG-INFO +108 -0
  5. weft_rag-2.4.0/README.md +66 -0
  6. weft_rag-2.4.0/pyproject.toml +256 -0
  7. weft_rag-2.4.0/src/weft_agent/__init__.py +69 -0
  8. weft_rag-2.4.0/src/weft_agent/command.py +147 -0
  9. weft_rag-2.4.0/src/weft_agent/command_tools.py +164 -0
  10. weft_rag-2.4.0/src/weft_agent/loop.py +214 -0
  11. weft_rag-2.4.0/src/weft_agent/payload.py +110 -0
  12. weft_rag-2.4.0/src/weft_agent/prompts.py +55 -0
  13. weft_rag-2.4.0/src/weft_agent/py.typed +0 -0
  14. weft_rag-2.4.0/src/weft_agent/render.py +53 -0
  15. weft_rag-2.4.0/src/weft_agent/tools.py +120 -0
  16. weft_rag-2.4.0/src/weft_blob/__init__.py +106 -0
  17. weft_rag-2.4.0/src/weft_blob/contract.py +76 -0
  18. weft_rag-2.4.0/src/weft_blob/filesystem_store.py +241 -0
  19. weft_rag-2.4.0/src/weft_blob/keys.py +81 -0
  20. weft_rag-2.4.0/src/weft_blob/payload.py +32 -0
  21. weft_rag-2.4.0/src/weft_blob/py.typed +0 -0
  22. weft_rag-2.4.0/src/weft_chunk/__init__.py +61 -0
  23. weft_rag-2.4.0/src/weft_chunk/carry.py +35 -0
  24. weft_rag-2.4.0/src/weft_chunk/contract.py +81 -0
  25. weft_rag-2.4.0/src/weft_chunk/fixed_size.py +161 -0
  26. weft_rag-2.4.0/src/weft_chunk/payload.py +34 -0
  27. weft_rag-2.4.0/src/weft_chunk/property.py +27 -0
  28. weft_rag-2.4.0/src/weft_chunk/py.typed +0 -0
  29. weft_rag-2.4.0/src/weft_chunk/table_rows.py +134 -0
  30. weft_rag-2.4.0/src/weft_clean/__init__.py +75 -0
  31. weft_rag-2.4.0/src/weft_clean/artifact_remover.py +136 -0
  32. weft_rag-2.4.0/src/weft_clean/contract.py +78 -0
  33. weft_rag-2.4.0/src/weft_clean/dictionary_spacing.py +145 -0
  34. weft_rag-2.4.0/src/weft_clean/hyphenation.py +98 -0
  35. weft_rag-2.4.0/src/weft_clean/language.py +36 -0
  36. weft_rag-2.4.0/src/weft_clean/property.py +77 -0
  37. weft_rag-2.4.0/src/weft_clean/py.typed +0 -0
  38. weft_rag-2.4.0/src/weft_clean/table_linearizer.py +116 -0
  39. weft_rag-2.4.0/src/weft_clean/unicode_normalizer.py +90 -0
  40. weft_rag-2.4.0/src/weft_clean/whitespace.py +94 -0
  41. weft_rag-2.4.0/src/weft_cli/__init__.py +5 -0
  42. weft_rag-2.4.0/src/weft_cli/answer_envelope.py +112 -0
  43. weft_rag-2.4.0/src/weft_cli/argparse_gen.py +150 -0
  44. weft_rag-2.4.0/src/weft_cli/ask.py +238 -0
  45. weft_rag-2.4.0/src/weft_cli/cli.py +848 -0
  46. weft_rag-2.4.0/src/weft_cli/command_table.py +130 -0
  47. weft_rag-2.4.0/src/weft_cli/commands.py +1383 -0
  48. weft_rag-2.4.0/src/weft_cli/compile.py +424 -0
  49. weft_rag-2.4.0/src/weft_cli/config_commands.py +175 -0
  50. weft_rag-2.4.0/src/weft_cli/config_surface.py +431 -0
  51. weft_rag-2.4.0/src/weft_cli/confirm.py +214 -0
  52. weft_rag-2.4.0/src/weft_cli/contract_reference.py +623 -0
  53. weft_rag-2.4.0/src/weft_cli/deletion.py +148 -0
  54. weft_rag-2.4.0/src/weft_cli/error_envelope.py +117 -0
  55. weft_rag-2.4.0/src/weft_cli/eval_commands.py +1132 -0
  56. weft_rag-2.4.0/src/weft_cli/eval_scoring.py +357 -0
  57. weft_rag-2.4.0/src/weft_cli/exit_codes.py +175 -0
  58. weft_rag-2.4.0/src/weft_cli/fanout.py +151 -0
  59. weft_rag-2.4.0/src/weft_cli/ingest.py +1087 -0
  60. weft_rag-2.4.0/src/weft_cli/installed_versions.py +47 -0
  61. weft_rag-2.4.0/src/weft_cli/llm_roles.py +228 -0
  62. weft_rag-2.4.0/src/weft_cli/output.py +33 -0
  63. weft_rag-2.4.0/src/weft_cli/pack_attribution.py +299 -0
  64. weft_rag-2.4.0/src/weft_cli/participation.py +175 -0
  65. weft_rag-2.4.0/src/weft_cli/permission_policy.py +144 -0
  66. weft_rag-2.4.0/src/weft_cli/pipeline_catalogue.py +324 -0
  67. weft_rag-2.4.0/src/weft_cli/pipeline_commands.py +439 -0
  68. weft_rag-2.4.0/src/weft_cli/pipeline_diff.py +149 -0
  69. weft_rag-2.4.0/src/weft_cli/plugins_report.py +362 -0
  70. weft_rag-2.4.0/src/weft_cli/preview.py +223 -0
  71. weft_rag-2.4.0/src/weft_cli/py.typed +0 -0
  72. weft_rag-2.4.0/src/weft_cli/reconcile.py +215 -0
  73. weft_rag-2.4.0/src/weft_cli/reconcile_policy.py +114 -0
  74. weft_rag-2.4.0/src/weft_cli/registry_bootstrap.py +616 -0
  75. weft_rag-2.4.0/src/weft_cli/render.py +1128 -0
  76. weft_rag-2.4.0/src/weft_cli/repl.py +425 -0
  77. weft_rag-2.4.0/src/weft_cli/route_ask.py +669 -0
  78. weft_rag-2.4.0/src/weft_cli/run_services.py +994 -0
  79. weft_rag-2.4.0/src/weft_cli/service_roles.py +98 -0
  80. weft_rag-2.4.0/src/weft_cli/services.py +276 -0
  81. weft_rag-2.4.0/src/weft_cli/session.py +145 -0
  82. weft_rag-2.4.0/src/weft_cli/sinks.py +300 -0
  83. weft_rag-2.4.0/src/weft_cli/skew.py +154 -0
  84. weft_rag-2.4.0/src/weft_cli/tracing_status.py +48 -0
  85. weft_rag-2.4.0/src/weft_command/__init__.py +47 -0
  86. weft_rag-2.4.0/src/weft_command/catalogue.py +97 -0
  87. weft_rag-2.4.0/src/weft_command/contract.py +221 -0
  88. weft_rag-2.4.0/src/weft_command/invocation.py +85 -0
  89. weft_rag-2.4.0/src/weft_command/permission.py +44 -0
  90. weft_rag-2.4.0/src/weft_command/py.typed +0 -0
  91. weft_rag-2.4.0/src/weft_command/render.py +67 -0
  92. weft_rag-2.4.0/src/weft_docling/__init__.py +107 -0
  93. weft_rag-2.4.0/src/weft_docling/pdf_layout_model.py +230 -0
  94. weft_rag-2.4.0/src/weft_docling/pipelines/index-pdf-learned.yaml +48 -0
  95. weft_rag-2.4.0/src/weft_docling/py.typed +0 -0
  96. weft_rag-2.4.0/src/weft_docling/weights.py +66 -0
  97. weft_rag-2.4.0/src/weft_embed/__init__.py +52 -0
  98. weft_rag-2.4.0/src/weft_embed/contract.py +74 -0
  99. weft_rag-2.4.0/src/weft_embed/hash_embedder.py +100 -0
  100. weft_rag-2.4.0/src/weft_embed/py.typed +0 -0
  101. weft_rag-2.4.0/src/weft_enhance/__init__.py +47 -0
  102. weft_rag-2.4.0/src/weft_enhance/contract.py +86 -0
  103. weft_rag-2.4.0/src/weft_enhance/keybert_stand_in.py +144 -0
  104. weft_rag-2.4.0/src/weft_enhance/keywords.py +19 -0
  105. weft_rag-2.4.0/src/weft_enhance/py.typed +0 -0
  106. weft_rag-2.4.0/src/weft_eval/__init__.py +316 -0
  107. weft_rag-2.4.0/src/weft_eval/aggregate.py +306 -0
  108. weft_rag-2.4.0/src/weft_eval/at_threshold.py +79 -0
  109. weft_rag-2.4.0/src/weft_eval/contract.py +263 -0
  110. weft_rag-2.4.0/src/weft_eval/embedding_metrics.py +124 -0
  111. weft_rag-2.4.0/src/weft_eval/embedding_support.py +55 -0
  112. weft_rag-2.4.0/src/weft_eval/falsify.py +288 -0
  113. weft_rag-2.4.0/src/weft_eval/harness.py +180 -0
  114. weft_rag-2.4.0/src/weft_eval/ir_metrics.py +163 -0
  115. weft_rag-2.4.0/src/weft_eval/judges.py +432 -0
  116. weft_rag-2.4.0/src/weft_eval/lexical.py +256 -0
  117. weft_rag-2.4.0/src/weft_eval/offline.py +155 -0
  118. weft_rag-2.4.0/src/weft_eval/pricing.py +150 -0
  119. weft_rag-2.4.0/src/weft_eval/prompts.py +353 -0
  120. weft_rag-2.4.0/src/weft_eval/py.typed +0 -0
  121. weft_rag-2.4.0/src/weft_eval/qa_metrics.py +130 -0
  122. weft_rag-2.4.0/src/weft_eval/run_record.py +249 -0
  123. weft_rag-2.4.0/src/weft_extract/__init__.py +101 -0
  124. weft_rag-2.4.0/src/weft_extract/accept.py +70 -0
  125. weft_rag-2.4.0/src/weft_extract/contract.py +163 -0
  126. weft_rag-2.4.0/src/weft_extract/payload.py +210 -0
  127. weft_rag-2.4.0/src/weft_extract/py.typed +0 -0
  128. weft_rag-2.4.0/src/weft_extract/render.py +162 -0
  129. weft_rag-2.4.0/src/weft_extract/table_text.py +98 -0
  130. weft_rag-2.4.0/src/weft_extract/text.py +118 -0
  131. weft_rag-2.4.0/src/weft_generate/__init__.py +115 -0
  132. weft_rag-2.4.0/src/weft_generate/cited_answer.py +274 -0
  133. weft_rag-2.4.0/src/weft_generate/contract.py +58 -0
  134. weft_rag-2.4.0/src/weft_generate/contradiction.py +294 -0
  135. weft_rag-2.4.0/src/weft_generate/page.py +61 -0
  136. weft_rag-2.4.0/src/weft_generate/payload.py +148 -0
  137. weft_rag-2.4.0/src/weft_generate/prompts.py +279 -0
  138. weft_rag-2.4.0/src/weft_generate/py.typed +0 -0
  139. weft_rag-2.4.0/src/weft_generate/refine.py +399 -0
  140. weft_rag-2.4.0/src/weft_generate/representation.py +72 -0
  141. weft_rag-2.4.0/src/weft_index/__init__.py +102 -0
  142. weft_rag-2.4.0/src/weft_index/adrap.py +638 -0
  143. weft_rag-2.4.0/src/weft_index/contract.py +141 -0
  144. weft_rag-2.4.0/src/weft_index/hypothetical_questions.py +163 -0
  145. weft_rag-2.4.0/src/weft_index/payload.py +170 -0
  146. weft_rag-2.4.0/src/weft_index/prompts.py +157 -0
  147. weft_rag-2.4.0/src/weft_index/py.typed +0 -0
  148. weft_rag-2.4.0/src/weft_index/raptor.py +1122 -0
  149. weft_rag-2.4.0/src/weft_kg/__init__.py +255 -0
  150. weft_rag-2.4.0/src/weft_kg/adjudication.py +123 -0
  151. weft_rag-2.4.0/src/weft_kg/atomicity.py +121 -0
  152. weft_rag-2.4.0/src/weft_kg/bridges.py +267 -0
  153. weft_rag-2.4.0/src/weft_kg/commands.py +474 -0
  154. weft_rag-2.4.0/src/weft_kg/contract.py +168 -0
  155. weft_rag-2.4.0/src/weft_kg/cooccurrence.py +83 -0
  156. weft_rag-2.4.0/src/weft_kg/extraction.py +371 -0
  157. weft_rag-2.4.0/src/weft_kg/names.py +117 -0
  158. weft_rag-2.4.0/src/weft_kg/payload.py +229 -0
  159. weft_rag-2.4.0/src/weft_kg/pipelines/graph-2hop-then-generate.yaml +26 -0
  160. weft_rag-2.4.0/src/weft_kg/pipelines/graph-and-vector-rrf.yaml +38 -0
  161. weft_rag-2.4.0/src/weft_kg/pipelines/graph-then-generate.yaml +28 -0
  162. weft_rag-2.4.0/src/weft_kg/pipelines/graph-then-rerank.yaml +25 -0
  163. weft_rag-2.4.0/src/weft_kg/pipelines/index-with-cooccurrence.yaml +15 -0
  164. weft_rag-2.4.0/src/weft_kg/pipelines/index-with-facts-openai.yaml +47 -0
  165. weft_rag-2.4.0/src/weft_kg/pipelines/index-with-facts.yaml +19 -0
  166. weft_rag-2.4.0/src/weft_kg/pipelines/index-with-graph.yaml +20 -0
  167. weft_rag-2.4.0/src/weft_kg/prompts.py +355 -0
  168. weft_rag-2.4.0/src/weft_kg/py.typed +0 -0
  169. weft_rag-2.4.0/src/weft_kg/resolution.py +360 -0
  170. weft_rag-2.4.0/src/weft_kg/retrieval.py +176 -0
  171. weft_rag-2.4.0/src/weft_kg/schema.py +315 -0
  172. weft_rag-2.4.0/src/weft_kg/store.py +1742 -0
  173. weft_rag-2.4.0/src/weft_kg/traversal.py +221 -0
  174. weft_rag-2.4.0/src/weft_llm/__init__.py +91 -0
  175. weft_rag-2.4.0/src/weft_llm/client.py +318 -0
  176. weft_rag-2.4.0/src/weft_llm/contract.py +158 -0
  177. weft_rag-2.4.0/src/weft_llm/errors.py +229 -0
  178. weft_rag-2.4.0/src/weft_llm/loop_guard.py +238 -0
  179. weft_rag-2.4.0/src/weft_llm/models.py +156 -0
  180. weft_rag-2.4.0/src/weft_llm/payload.py +169 -0
  181. weft_rag-2.4.0/src/weft_llm/py.typed +0 -0
  182. weft_rag-2.4.0/src/weft_llm/retry.py +179 -0
  183. weft_rag-2.4.0/src/weft_llm/roles.py +83 -0
  184. weft_rag-2.4.0/src/weft_llm/scripted.py +99 -0
  185. weft_rag-2.4.0/src/weft_openai/__init__.py +144 -0
  186. weft_rag-2.4.0/src/weft_openai/embedder.py +362 -0
  187. weft_rag-2.4.0/src/weft_openai/llm.py +434 -0
  188. weft_rag-2.4.0/src/weft_openai/py.typed +0 -0
  189. weft_rag-2.4.0/src/weft_openai/settings.py +54 -0
  190. weft_rag-2.4.0/src/weft_openai/vision.py +235 -0
  191. weft_rag-2.4.0/src/weft_otel/__init__.py +107 -0
  192. weft_rag-2.4.0/src/weft_otel/provider.py +100 -0
  193. weft_rag-2.4.0/src/weft_otel/py.typed +0 -0
  194. weft_rag-2.4.0/src/weft_otel/settings.py +88 -0
  195. weft_rag-2.4.0/src/weft_pdf/__init__.py +79 -0
  196. weft_rag-2.4.0/src/weft_pdf/document.py +567 -0
  197. weft_rag-2.4.0/src/weft_pdf/pdf_layout.py +384 -0
  198. weft_rag-2.4.0/src/weft_pdf/pdf_text.py +314 -0
  199. weft_rag-2.4.0/src/weft_pdf/py.typed +0 -0
  200. weft_rag-2.4.0/src/weft_prompts/__init__.py +61 -0
  201. weft_rag-2.4.0/src/weft_prompts/cascade.py +231 -0
  202. weft_rag-2.4.0/src/weft_prompts/contract.py +80 -0
  203. weft_rag-2.4.0/src/weft_prompts/errors.py +58 -0
  204. weft_rag-2.4.0/src/weft_prompts/py.typed +0 -0
  205. weft_rag-2.4.0/src/weft_prompts/registry.py +73 -0
  206. weft_rag-2.4.0/src/weft_prompts/rescue.py +65 -0
  207. weft_rag-2.4.0/src/weft_prompts/template.py +84 -0
  208. weft_rag-2.4.0/src/weft_prompts/typed_prompt.py +121 -0
  209. weft_rag-2.4.0/src/weft_qdrant/__init__.py +70 -0
  210. weft_rag-2.4.0/src/weft_qdrant/py.typed +0 -0
  211. weft_rag-2.4.0/src/weft_qdrant/settings.py +54 -0
  212. weft_rag-2.4.0/src/weft_qdrant/store.py +688 -0
  213. weft_rag-2.4.0/src/weft_retrieve/__init__.py +666 -0
  214. weft_rag-2.4.0/src/weft_retrieve/boolean.py +461 -0
  215. weft_rag-2.4.0/src/weft_retrieve/collapse.py +283 -0
  216. weft_rag-2.4.0/src/weft_retrieve/contract.py +302 -0
  217. weft_rag-2.4.0/src/weft_retrieve/corrective.py +263 -0
  218. weft_rag-2.4.0/src/weft_retrieve/engine.py +223 -0
  219. weft_rag-2.4.0/src/weft_retrieve/fusion.py +616 -0
  220. weft_rag-2.4.0/src/weft_retrieve/graded.py +228 -0
  221. weft_rag-2.4.0/src/weft_retrieve/hybrid.py +221 -0
  222. weft_rag-2.4.0/src/weft_retrieve/iterative.py +422 -0
  223. weft_rag-2.4.0/src/weft_retrieve/multi_arm.py +145 -0
  224. weft_rag-2.4.0/src/weft_retrieve/multi_retriever.py +164 -0
  225. weft_rag-2.4.0/src/weft_retrieve/no_retrieval.py +62 -0
  226. weft_rag-2.4.0/src/weft_retrieve/payload.py +441 -0
  227. weft_rag-2.4.0/src/weft_retrieve/pipelines/boolean-then-retrieve.yaml +29 -0
  228. weft_rag-2.4.0/src/weft_retrieve/pipelines/broad-and-refined-rrf.yaml +66 -0
  229. weft_rag-2.4.0/src/weft_retrieve/pipelines/contradiction-aware.yaml +24 -0
  230. weft_rag-2.4.0/src/weft_retrieve/pipelines/corrective-retrieve.yaml +56 -0
  231. weft_rag-2.4.0/src/weft_retrieve/pipelines/draft-then-refine.yaml +31 -0
  232. weft_rag-2.4.0/src/weft_retrieve/pipelines/grade-then-generate.yaml +24 -0
  233. weft_rag-2.4.0/src/weft_retrieve/pipelines/hybrid-then-generate.yaml +49 -0
  234. weft_rag-2.4.0/src/weft_retrieve/pipelines/hyde-then-retrieve.yaml +27 -0
  235. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-messy-text.yaml +36 -0
  236. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-openai.yaml +32 -0
  237. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-pdf-described.yaml +21 -0
  238. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-pdf-rows.yaml +22 -0
  239. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-pdf-text.yaml +20 -0
  240. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-pdf-undescribed.yaml +12 -0
  241. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-pdf.yaml +27 -0
  242. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-polish.yaml +21 -0
  243. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-qdrant.yaml +21 -0
  244. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-text.yaml +64 -0
  245. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-with-adrap.yaml +42 -0
  246. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-with-deep-raptor.yaml +56 -0
  247. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-with-keywords.yaml +15 -0
  248. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-with-questions.yaml +23 -0
  249. weft_rag-2.4.0/src/weft_retrieve/pipelines/index-with-raptor.yaml +95 -0
  250. weft_rag-2.4.0/src/weft_retrieve/pipelines/iterative-retrieve.yaml +32 -0
  251. weft_rag-2.4.0/src/weft_retrieve/pipelines/multi-query-then-retrieve.yaml +27 -0
  252. weft_rag-2.4.0/src/weft_retrieve/pipelines/no-retrieval.yaml +9 -0
  253. weft_rag-2.4.0/src/weft_retrieve/pipelines/preview-markdown.yaml +18 -0
  254. weft_rag-2.4.0/src/weft_retrieve/pipelines/preview-plain.yaml +25 -0
  255. weft_rag-2.4.0/src/weft_retrieve/pipelines/raptor-and-leaves-rrf.yaml +78 -0
  256. weft_rag-2.4.0/src/weft_retrieve/pipelines/rerank-then-generate.yaml +24 -0
  257. weft_rag-2.4.0/src/weft_retrieve/pipelines/retrieve-then-generate.yaml +9 -0
  258. weft_rag-2.4.0/src/weft_retrieve/pipelines/rewrite-then-retrieve.yaml +25 -0
  259. weft_rag-2.4.0/src/weft_retrieve/pipelines/route-by-score.yaml +24 -0
  260. weft_rag-2.4.0/src/weft_retrieve/pipelines/route-fixed.yaml +23 -0
  261. weft_rag-2.4.0/src/weft_retrieve/pipelines/route.yaml +4 -0
  262. weft_rag-2.4.0/src/weft_retrieve/pipelines/step-back-then-retrieve.yaml +22 -0
  263. weft_rag-2.4.0/src/weft_retrieve/pipelines/summarise-then-generate.yaml +45 -0
  264. weft_rag-2.4.0/src/weft_retrieve/postqfrap.py +372 -0
  265. weft_rag-2.4.0/src/weft_retrieve/prompts.py +1090 -0
  266. weft_rag-2.4.0/src/weft_retrieve/py.typed +0 -0
  267. weft_rag-2.4.0/src/weft_retrieve/repack.py +171 -0
  268. weft_rag-2.4.0/src/weft_retrieve/rerank.py +216 -0
  269. weft_rag-2.4.0/src/weft_retrieve/routing.py +682 -0
  270. weft_rag-2.4.0/src/weft_retrieve/sufficiency.py +262 -0
  271. weft_rag-2.4.0/src/weft_retrieve/transforms.py +742 -0
  272. weft_rag-2.4.0/src/weft_retrieve/vector_top_k.py +280 -0
  273. weft_rag-2.4.0/src/weft_store/__init__.py +152 -0
  274. weft_rag-2.4.0/src/weft_store/contract.py +964 -0
  275. weft_rag-2.4.0/src/weft_store/fields.py +249 -0
  276. weft_rag-2.4.0/src/weft_store/pgvector_store.py +1105 -0
  277. weft_rag-2.4.0/src/weft_store/py.typed +0 -0
  278. weft_rag-2.4.0/src/weft_store/rehydrate.py +178 -0
  279. weft_rag-2.4.0/src/weft_vision/__init__.py +66 -0
  280. weft_rag-2.4.0/src/weft_vision/contract.py +69 -0
  281. weft_rag-2.4.0/src/weft_vision/describe_figure.py +203 -0
  282. weft_rag-2.4.0/src/weft_vision/py.typed +0 -0
@@ -0,0 +1,85 @@
1
+ # A sibling checkout, reachable for reading only.
2
+ # Never a build input: see CLAUDE.md and docs/README.md.
3
+ /_external-src
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ .venv/
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+
13
+ # Tooling
14
+ .pytest_cache/
15
+ .ruff_cache/
16
+ .pyright/
17
+
18
+ # `uv.lock` was here, filed between two caches. It is not a cache: `ci.yml` runs
19
+ # `uv sync --frozen` in three of its four jobs, and every one of them died at that step
20
+ # the first time CI ever ran. It is tracked now — the resolution CI installs and the
21
+ # resolution a developer installs must be one artefact, which is the same argument
22
+ # `docs/README.md` makes about single-sourcing anything two readers can disagree about.
23
+ #
24
+ # It constrains nobody downstream. A lockfile is not a dependency bound; what a consumer
25
+ # resolves is decided by each distribution's `pyproject.toml`.
26
+
27
+ # Session-local attempt counter for the guard_quality_gates.py PreToolUse hook — per-session
28
+ # scratch, not a record anyone should read later. See the hook's module docstring.
29
+ .claude/.gate-attempts.json
30
+
31
+ # Secrets. `.env` holds live provider keys; only the documented, valueless
32
+ # example is tracked. Listed before any tooling rule so a stray `git add -A`
33
+ # cannot reach it.
34
+ .env
35
+ .env.*
36
+ !.env.example
37
+
38
+ # Corpus payload. Every subdirectory of /corpus is a materialised document set and
39
+ # is deliberately untracked; `corpus/manifest.toml` and `scripts/fetch_corpus.py`
40
+ # are the tracked artefact. `09` §4 V1 permits exactly this:
41
+ # a corpus is "either redistributable or fetched by a pinned, checksummed script",
42
+ # and the mRMR papers are published under publisher copyright, so committing them
43
+ # would be redistribution this repository has no right to perform. The manifest
44
+ # carries a sha256 per document, which is what makes the set reproducible without
45
+ # the bytes being here. The pattern is a directory glob rather than a list of names
46
+ # so that scaling the corpus up cannot silently start tracking a paper.
47
+ /corpus/*/
48
+
49
+ # Where a baseline run stages the corpus it indexes and writes the `weft.toml` it measures
50
+ # through (`eval/run_baseline.py`). The staged copies are the same untracked papers one
51
+ # directory over, and the configuration is reproduced by the harness rather than kept — what
52
+ # is tracked is the run it produced, under `eval/baselines/`.
53
+ /.baseline-run/
54
+
55
+ # Working artefacts of a build session — a generated map of the codebase and a design
56
+ # record produced while planning. Untracked on purpose: `docs/README.md` routes every
57
+ # document this project owns, and a design that matters belongs in the `docs/` file
58
+ # that owns its content, not in a root-level file nothing points at.
59
+ /.phase2-*.md
60
+ /.phase3-*.md
61
+ /.phase4-*.md
62
+
63
+ # Gate-session preparation: the Bring lists of `docs/05-grilling-sessions.md`, measured on the day
64
+ # a session is about to run. Untracked for the same reason — the session's outcome belongs in
65
+ # `docs/README.md`'s decision log and in the reference document the decision changes, never here.
66
+ /.gate-brief-*.md
67
+
68
+ # Claude Code local state
69
+ .claude/settings.local.json
70
+
71
+ .DS_Store
72
+
73
+ # The build harness driving Phase 2, alongside its brief, findings and design record.
74
+ /.phase2-build.js
75
+
76
+ # Transient: harvested subagent findings, promoted into docs/lessons.md by implement-ll.
77
+ # Never committed — its content belongs in the queue or nowhere.
78
+ .claude/lessons-spool.md
79
+
80
+ # Reading material and design records about codebases this project does not own.
81
+ # Kept on disk, deliberately outside version control: nothing tracked here refers to
82
+ # them, and a write to any of them would leave no trace in a diff.
83
+ /docs/_external-reading/
84
+
85
+ /tmp/
weft_rag-2.4.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adam Krysztopa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
weft_rag-2.4.0/NOTICE ADDED
@@ -0,0 +1,77 @@
1
+ Weft
2
+ Copyright (c) 2026 Adam Krysztopa
3
+
4
+ This product is licensed under the MIT License. See the LICENSE file at the root
5
+ of this repository.
6
+
7
+ --------------------------------------------------------------------------------
8
+ Original work
9
+ --------------------------------------------------------------------------------
10
+
11
+ **Weft carries no third party's source text.** Every line of this project's own
12
+ code is written for it, against its own contracts. Nothing here depends on a
13
+ licence granted by anyone else.
14
+
15
+ That is a rule, not a description: no file may be copied or adapted from another
16
+ project's source, and no third-party source text may be pasted into this
17
+ repository. Where a prior system informed a design, what was carried across is
18
+ understanding — an approach, an ordering, a measurement, a reason a guard exists
19
+ — restated in this project's own words and implemented fresh. Copyright does not
20
+ reach any of that.
21
+
22
+ What was learned from prior work, and what was deliberately not taken, is a
23
+ design record kept outside version control. Nothing in it authorises a copy of a
24
+ third party's text, because that is not permitted here at all.
25
+
26
+ --------------------------------------------------------------------------------
27
+ Three cases, because the sentence above used to be absolute and was not accurate
28
+ --------------------------------------------------------------------------------
29
+
30
+ This section was added on 2026-09-05. It previously read "Weft contains no source
31
+ text from any other codebase", and two separate things made that literally false
32
+ while nothing about the project's substance had changed. Both are stated here
33
+ rather than left for a reader to discover, because a founding claim that is
34
+ almost true is worse than a narrower one that is exactly true.
35
+
36
+ 1. **A third party's code — never.** Somebody else's work is somebody else's:
37
+ not a file, a function body, a docstring, a comment, a prompt string, a word
38
+ list or a test fixture. Read to understand, then closed. This is the rule
39
+ above and it has not moved.
40
+
41
+ 2. **The copyright holder's own prior work — permitted, and marked.** Material
42
+ written by this project's own author before this project began carries no
43
+ third party's rights. Copying it violates nobody's licence, and forbidding it
44
+ would be a rule about tidiness dressed as a rule about ownership. Where such
45
+ material is carried across, the file carrying it says so, naming the source
46
+ work — so a reader can always tell the two origins apart without asking.
47
+
48
+ **How it says so, because "says so" was a sentence and not a convention until
49
+ 2026-09-09.** The carried lines are delimited in place, by a comment in
50
+ whatever syntax the file is written in: `weft-prior-work begin: <source work>`
51
+ opens the span and names the source work it came from, and
52
+ `weft-prior-work end` closes it and takes no argument. Spans do not nest — a
53
+ span inside a span makes *which lines are that work* answerable two ways,
54
+ which is the one question this convention exists to answer. Every source work
55
+ carried this way is enumerated on the repository's own README.md, where a
56
+ reader looks first, and tests/architecture/test_release_licensing.py fails
57
+ the build when the marked spans and that enumeration disagree. The obligation
58
+ falls in the same commit as the copied line and never after it, which is why
59
+ the check exists before the first copy rather than behind it.
60
+
61
+ 3. **Short attributed quotation of a stated rationale — permitted, and bounded.**
62
+ A handful of docstrings in this repository quote a sentence of a third party's
63
+ *reasoning* — why one cleaning stage must run before another — attributed with
64
+ a path and a line number, immediately beside this project's own restatement of
65
+ the same reasoning. Nothing executable was ever carried this way: no
66
+ expression, no algorithm, no data. This is ordinary attributed quotation of a
67
+ published rationale, of the kind a comment citing a paper makes, and the
68
+ previous absolute wording forbade it in words while the repository practised
69
+ it. It is bounded rather than open: a quotation must be a sentence or two, it
70
+ must be attributed at the point of use, and it must sit next to the project's
71
+ own words on the same point — never stand in for them.
72
+
73
+ The distinction that matters, and it is the same test the rest of this project
74
+ uses: **if you could not have written it without the other file open, it is a
75
+ copy.** Case 1 forbids that outright. Case 2 permits it because the other file is
76
+ the author's own. Case 3 is not that at all — it is quoting someone, with their
77
+ name on it, beside your own argument.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.5
2
+ Name: weft-rag
3
+ Version: 2.4.0
4
+ Summary: Weft — a RAG engine built as a microkernel. The default install: the kernel's packs, and the weft command.
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: ftfy>=6.2
10
+ Requires-Dist: opentelemetry-api
11
+ Requires-Dist: packaging>=24
12
+ Requires-Dist: pgvector>=0.3
13
+ Requires-Dist: psycopg[binary]>=3.2
14
+ Requires-Dist: pyyaml
15
+ Requires-Dist: rouge-score>=0.1
16
+ Requires-Dist: weft-kernel<1.0.0,>=0.1.0
17
+ Provides-Extra: all
18
+ Requires-Dist: docling-slim[convert-core,feat-ocr-rapidocr-onnx,format-pdf,models-local]>=2.55; extra == 'all'
19
+ Requires-Dist: openai>=3.1; extra == 'all'
20
+ Requires-Dist: opentelemetry-sdk>=1.28; extra == 'all'
21
+ Requires-Dist: pdfplumber>=0.11.10; extra == 'all'
22
+ Requires-Dist: pillow>=10.0; extra == 'all'
23
+ Requires-Dist: pypdf>=6.16; extra == 'all'
24
+ Requires-Dist: qdrant-client>=1.12; extra == 'all'
25
+ Provides-Extra: bertscore
26
+ Requires-Dist: bert-score>=0.3; extra == 'bertscore'
27
+ Provides-Extra: docling
28
+ Requires-Dist: docling-slim[convert-core,feat-ocr-rapidocr-onnx,format-pdf,models-local]>=2.55; extra == 'docling'
29
+ Provides-Extra: openai
30
+ Requires-Dist: openai>=3.1; extra == 'openai'
31
+ Requires-Dist: pillow>=10.0; extra == 'openai'
32
+ Provides-Extra: otel
33
+ Requires-Dist: opentelemetry-sdk>=1.28; extra == 'otel'
34
+ Provides-Extra: pdf
35
+ Requires-Dist: pdfplumber>=0.11.10; extra == 'pdf'
36
+ Requires-Dist: pypdf>=6.16; extra == 'pdf'
37
+ Provides-Extra: qdrant
38
+ Requires-Dist: qdrant-client>=1.12; extra == 'qdrant'
39
+ Provides-Extra: reference
40
+ Requires-Dist: ruff>=0.16.0; extra == 'reference'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # weft-rag
44
+
45
+ Weft — a RAG engine built as a microkernel. This is the default install: the packs that index a
46
+ directory and answer a question about it, and the `weft` command.
47
+
48
+ **The distribution is `weft-rag`; the command is `weft`** — the name `weft` belongs to an unrelated
49
+ project on PyPI, so what you install and what you run are spelled differently:
50
+
51
+ ```bash
52
+ uvx --from weft-rag weft --help
53
+ ```
54
+
55
+ ## What is in it, and what is not
56
+
57
+ Twenty-one packs ship here and each keeps its own identity: `weft plugins list` prints one row per
58
+ pack, and `weft.toml` configures one at a time — `[packs.store]`, not `[packs.weft-rag]`.
59
+
60
+ One distribution publishes **beside** this one, and it is separate for a single reason:
61
+
62
+ | | |
63
+ |---|---|
64
+ | `weft-kernel` | the registry, discovery, the pipeline model and the payload types. Depends on `pydantic` and `opentelemetry-api` and nothing else, and installs and imports alone — which is what proves the kernel names no capability |
65
+
66
+ Six packs that used to be their own distributions now ship inside this wheel instead, each behind
67
+ an extra that keeps its outside library declinable — G19, 2026-09-09:
68
+
69
+ | extra | pack | needs |
70
+ |---|---|---|
71
+ | `[openai]` | an `Embedder` and an `LLMProvider` against the OpenAI API | `openai`, `pillow`, and a credential |
72
+ | `[pdf]` | two PDF extraction backends | `pypdf`, `pdfplumber` |
73
+ | `[qdrant]` | a Qdrant store backend, beside the pgvector one shipped here | `qdrant-client` |
74
+ | `[otel]` | sets the OpenTelemetry TracerProvider the registration seam already emits spans into | `opentelemetry-sdk` |
75
+ | `[docling]` | a learned-layout PDF extraction backend | `docling-slim` |
76
+ | — | `agent`, the first-party agentic front end. Imports nothing outside this wheel, so it needs no extra | none |
77
+
78
+ `weft-rag[all]` installs every one of those libraries at once. `graph` — the Postgres-backed
79
+ graph-traversal pack added at ledger task 11.5 — was never a separate distribution either and
80
+ needs no extra.
81
+
82
+ None of these seven packs is needed to index a directory and query it. A pack neither we nor you
83
+ wrote installs beside this wheel on exactly the same terms and is discovered the same way, with no
84
+ edit to anything here — that is the extension model, not a courtesy.
85
+
86
+ See `docs/09-release.md` §1 for why this is one wheel rather than many — fourteen packs at G10
87
+ (2026-08-22), six more folded in by G19 (2026-09-09).
88
+
89
+ ## What installing this trusts
90
+
91
+ **A pack runs with your full privileges, and installing one is trusting it.** Weft discovers packs
92
+ through Python entry points and calls their `register()` in this process, so a pack can do anything
93
+ the interpreter can do. That is stated rather than mitigated, because the mitigations are not
94
+ available: **signature verification, sandboxing, per-pack privilege separation, and any defence
95
+ against a pack that is hostile once running are all out of reach without a process boundary**,
96
+ which Weft does not have.
97
+
98
+ What Weft does give you is visibility and refusal, not containment:
99
+
100
+ - `weft plugins doctor` names every distribution that is installed, at what version, and what each
101
+ one *discloses* about the network, filesystem and subprocess access it uses. A disclosure is what
102
+ the pack says about itself; nothing checks it.
103
+ - `[packs] allow` in `weft.toml` is an exhaustive pin. Anything not listed is **never imported** —
104
+ refusal before any of its code runs, which is the one control that does work without a process
105
+ boundary.
106
+
107
+ A control that looked like enforcement but was not would be worse than an acknowledged gap, because
108
+ people build policy on it. `docs/02-extension-model.md` §2 is the argument in full.
@@ -0,0 +1,66 @@
1
+ # weft-rag
2
+
3
+ Weft — a RAG engine built as a microkernel. This is the default install: the packs that index a
4
+ directory and answer a question about it, and the `weft` command.
5
+
6
+ **The distribution is `weft-rag`; the command is `weft`** — the name `weft` belongs to an unrelated
7
+ project on PyPI, so what you install and what you run are spelled differently:
8
+
9
+ ```bash
10
+ uvx --from weft-rag weft --help
11
+ ```
12
+
13
+ ## What is in it, and what is not
14
+
15
+ Twenty-one packs ship here and each keeps its own identity: `weft plugins list` prints one row per
16
+ pack, and `weft.toml` configures one at a time — `[packs.store]`, not `[packs.weft-rag]`.
17
+
18
+ One distribution publishes **beside** this one, and it is separate for a single reason:
19
+
20
+ | | |
21
+ |---|---|
22
+ | `weft-kernel` | the registry, discovery, the pipeline model and the payload types. Depends on `pydantic` and `opentelemetry-api` and nothing else, and installs and imports alone — which is what proves the kernel names no capability |
23
+
24
+ Six packs that used to be their own distributions now ship inside this wheel instead, each behind
25
+ an extra that keeps its outside library declinable — G19, 2026-09-09:
26
+
27
+ | extra | pack | needs |
28
+ |---|---|---|
29
+ | `[openai]` | an `Embedder` and an `LLMProvider` against the OpenAI API | `openai`, `pillow`, and a credential |
30
+ | `[pdf]` | two PDF extraction backends | `pypdf`, `pdfplumber` |
31
+ | `[qdrant]` | a Qdrant store backend, beside the pgvector one shipped here | `qdrant-client` |
32
+ | `[otel]` | sets the OpenTelemetry TracerProvider the registration seam already emits spans into | `opentelemetry-sdk` |
33
+ | `[docling]` | a learned-layout PDF extraction backend | `docling-slim` |
34
+ | — | `agent`, the first-party agentic front end. Imports nothing outside this wheel, so it needs no extra | none |
35
+
36
+ `weft-rag[all]` installs every one of those libraries at once. `graph` — the Postgres-backed
37
+ graph-traversal pack added at ledger task 11.5 — was never a separate distribution either and
38
+ needs no extra.
39
+
40
+ None of these seven packs is needed to index a directory and query it. A pack neither we nor you
41
+ wrote installs beside this wheel on exactly the same terms and is discovered the same way, with no
42
+ edit to anything here — that is the extension model, not a courtesy.
43
+
44
+ See `docs/09-release.md` §1 for why this is one wheel rather than many — fourteen packs at G10
45
+ (2026-08-22), six more folded in by G19 (2026-09-09).
46
+
47
+ ## What installing this trusts
48
+
49
+ **A pack runs with your full privileges, and installing one is trusting it.** Weft discovers packs
50
+ through Python entry points and calls their `register()` in this process, so a pack can do anything
51
+ the interpreter can do. That is stated rather than mitigated, because the mitigations are not
52
+ available: **signature verification, sandboxing, per-pack privilege separation, and any defence
53
+ against a pack that is hostile once running are all out of reach without a process boundary**,
54
+ which Weft does not have.
55
+
56
+ What Weft does give you is visibility and refusal, not containment:
57
+
58
+ - `weft plugins doctor` names every distribution that is installed, at what version, and what each
59
+ one *discloses* about the network, filesystem and subprocess access it uses. A disclosure is what
60
+ the pack says about itself; nothing checks it.
61
+ - `[packs] allow` in `weft.toml` is an exhaustive pin. Anything not listed is **never imported** —
62
+ refusal before any of its code runs, which is the one control that does work without a process
63
+ boundary.
64
+
65
+ A control that looked like enforcement but was not would be worse than an acknowledged gap, because
66
+ people build policy on it. `docs/02-extension-model.md` §2 is the argument in full.
@@ -0,0 +1,256 @@
1
+ # `weft-rag` — the default install, and the bundle. Ledger task 6.1; `docs/09-release.md` §1,
2
+ # settled by G10 (2026-08-22) and **re-settled 2026-09-05** after v0.1.0's first contact with a
3
+ # real index. **Named `weft-rag` and not `weft` since ledger task 6.13**: `weft` is taken on PyPI
4
+ # — "The durable task substrate for agent systems", 99 releases — so the name G10 chose is
5
+ # unpublishable. `docs/lessons.md` L6.33.
6
+ #
7
+ # **The command a user types is still `weft`.** It is this distribution's console script, so the
8
+ # rename touches what you install and not what you run: `uvx --from weft-rag weft --help`.
9
+ #
10
+ # ---------------------------------------------------------------------------------------------
11
+ # What this is, and what it stopped being
12
+ # ---------------------------------------------------------------------------------------------
13
+ #
14
+ # It was a meta-distribution: no code, fifteen exact pins, and one job — naming a tested
15
+ # combination. It now **ships twenty-three packs' code and their twenty-one entry points in one
16
+ # wheel** — the fourteen from G10, six more folded in by G19, and `graph` from ledger task
17
+ # 11.5 — and none of them are separate distributions any longer.
18
+ #
19
+ # The measurement that decided it, taken from the twenty `pyproject.toml` files with a parser
20
+ # rather than a regex: **ten of the twenty declared no external dependency whatsoever**.
21
+ # Installing without one of them avoided nothing. They were separate distributions for
22
+ # architectural symmetry, and symmetry is not a user-visible benefit — while twenty names cost
23
+ # twenty trusted-publisher forms, twenty version numbers to keep coherent, and, on the day
24
+ # `v0.1.0` asked PyPI to create nineteen projects, fifteen refusals with
25
+ # `429 Too many new projects created` (`docs/lessons.md` L7.3).
26
+ #
27
+ # **Two distributions ship, and that is G19's count (2026-09-09) — down from the six G10 first
28
+ # left.** `weft-kernel` (`pydantic`, `opentelemetry-api` — and separate for fitness function 1,
29
+ # which installs it alone and imports it; bundling it would demote the check that proves the
30
+ # kernel names no capability) is the one distribution beside this wheel now. `weft-openai`,
31
+ # `weft-pdf`, `weft-qdrant`, `weft-otel`, `weft-agent` and `weft-docling` each carried a
32
+ # dependency somebody may decline as their own distribution; each is now an extra on this wheel
33
+ # instead — `[openai]`, `[pdf]`, `[qdrant]`, `[otel]`, `[docling]` — except `agent`, which needs
34
+ # none at all.
35
+ #
36
+ # **What was given up, stated because the argument is only honest with the cost on the table:**
37
+ #
38
+ # * **Independent semver for the fourteen.** They versioned separately (`weft-command` at
39
+ # 2.1.0, `weft-store` at 2.0.0, eleven at 1.0.0) and now share this file's version. G9's
40
+ # deprecation machinery largely existed to manage skew *between* these packs; most of that
41
+ # skew stops existing. Contract versions (`STORE_CONTRACT_VERSION` and its siblings) are a
42
+ # separate axis and are **not** affected — a pack outside this wheel still checks them.
43
+ # * **Per-pack isolated-install proof.** Task 6.6 generalised fitness function 1 to every
44
+ # published distribution. Twenty of them are no longer separately installable — the fourteen
45
+ # G10 folded in, and the six more G19 folded in on top — so that check narrows to the two.
46
+ # What covers the twenty instead is an import assertion against
47
+ # the built wheel, which is **weaker**, and is labelled weaker in
48
+ # `scripts/check_isolated_installs.py` rather than counted as the same coverage.
49
+ # * **Four already-published names become vestigial.** `weft-command`, `weft-embed`,
50
+ # `weft-generate` and `weft-llm` reached PyPI before the rate limit stopped the rest. PyPI
51
+ # cannot delete a project. They stay claimed, receive no further versions, and are recorded
52
+ # here so a future reader does not think they were lost.
53
+ #
54
+ # **What did not change, and it is the point.** The Python packages did not move relative to
55
+ # each other, no import changed, every pack still registers through the same public `weft.packs`
56
+ # entry point a third party uses, and a third-party pack installs beside this wheel exactly as
57
+ # `weft-canary` does. What changed is how the code is *wheeled*, not how it is written.
58
+ #
59
+ # **A pack's identity is its entry-point name, not this distribution's name.** `weft plugins
60
+ # list|doctor` prints twenty-one distinguishable rows, and `[packs.store]` configures the store
61
+ # and nothing else — see `weft_kernel.discovery`'s own module docstring for where the two
62
+ # identities part. That separation is what made this file possible; without it, bundling would
63
+ # have collapsed twenty-one settings namespaces into one.
64
+
65
+ [project]
66
+ name = "weft-rag"
67
+ # **`2.1.0`, and it is a mechanical fact rather than a promise.** `docs/09-release.md` §2.3's
68
+ # binding rule — G9, 2026-08-21 — forces a distribution's version to track the maximum contract
69
+ # version it publishes, and fitness function 6 enforces it. This wheel publishes sixteen contract
70
+ # constants, and `COMMAND_CONTRACT_VERSION` is `2.1.0`; `weft-command` and `weft-store` already
71
+ # carried `2.x` for exactly this reason before they were bundled, so the number is inherited, not
72
+ # invented. §2.2 answers the objection in advance: "fitness function 6 enforces the binding, not
73
+ # the leading digit... a distribution can carry a major digit above `0` before the project has
74
+ # decided it is *1.0-ready*". The 1.0 milestone is G10's substantive judgment and its precondition
75
+ # table is untouched by this digit.
76
+ # **2.1.0 → 2.2.0 at Phase 7's close, and the bump is a correction rather than a routine
77
+ # increment.** Tasks 7.0 and 7.2a added two *public* modules — `weft_command.invocation` (the
78
+ # invocation seam, where a library caller now enters) and `weft_command.catalogue` (the command
79
+ # walk, moved out of `weft_cli`) — and the version did not move. `v2.1.0` is a git tag, and
80
+ # `git ls-tree v2.1.0` shows neither module, so `2.1.0` named two different APIs and
81
+ # `weft-agent`'s own `weft-rag>=2.0.0` would have resolved, from an index, to a published
82
+ # distribution that cannot satisfy `from weft_command.invocation import invoke`. **Minor, per
83
+ # G9's two-audience rule**: a new module is additive for a caller and changes no Protocol, so an
84
+ # implementer owes nothing. Found by Phase 7's close review; `docs/lessons.md` `L8.40`.
85
+ # **2.3.0 → 2.4.0 at ledger task 11.5** — `weft_kg` gained a `register()`, a new `weft.packs`
86
+ # entry point (`graph`) and two new plugin names. Minor, per the identical G9 rule immediately
87
+ # above: additive for a caller, no Protocol changed.
88
+ version = "2.4.0"
89
+ description = "Weft — a RAG engine built as a microkernel. The default install: the kernel's packs, and the weft command."
90
+ requires-python = ">=3.12"
91
+ license = "MIT"
92
+ license-files = ["LICENSE", "NOTICE"]
93
+ readme = "README.md"
94
+
95
+ # The kernel, and every external dependency the fourteen bundled packs declared between them.
96
+ # Ten of the fourteen declared none at all; these are the rest, each kept with the floor its
97
+ # own distribution set and the reason its own manifest gave:
98
+ #
99
+ # * `ftfy` — `weft_clean`'s mojibake repair.
100
+ # * `rouge-score` — `weft_eval`'s lexical-overlap metrics.
101
+ # * `psycopg[binary]` + `pgvector` — `weft_store`'s pgvector backend. The heaviest thing here,
102
+ # and the one genuine argument against a single wheel: an operator who only wants Qdrant
103
+ # still gets a Postgres driver. Kept in rather than made an extra, because `pgvector` is the
104
+ # default store every quickstart, every fixture and the one `compose.yaml` container assume,
105
+ # and an extra that everything defaults to needing is a footgun with a flag on it.
106
+ # * `pyyaml` — `weft_cli.pipeline_catalogue`, the one module that opens a pipeline document.
107
+ # G1 fixes `weft-kernel`'s dependencies at `pydantic` and `opentelemetry-api`, so a YAML
108
+ # parser can never live there.
109
+ # * `opentelemetry-api` — `weft_cli.tracing_status` reads `get_tracer_provider()` directly, to
110
+ # answer `weft plugins doctor`'s "are my spans going anywhere?" as a fact about the process.
111
+ # Declared explicitly rather than left to arrive through `weft-kernel`.
112
+ # * `packaging` — `weft_cli.skew` parses PEP 508 requirements and version specifiers.
113
+ dependencies = [
114
+ "weft-kernel>=0.1.0,<1.0.0",
115
+ "ftfy>=6.2",
116
+ "rouge-score>=0.1",
117
+ "psycopg[binary]>=3.2",
118
+ "pgvector>=0.3",
119
+ "pyyaml",
120
+ "opentelemetry-api",
121
+ "packaging>=24",
122
+ ]
123
+
124
+ # Both extras are inherited unchanged from the distributions that declared them, and both exist
125
+ # for the same reason: a dependency that only one surface needs, which nothing on the
126
+ # index-and-ask path ever reaches.
127
+ #
128
+ # * `bertscore` — `weft_eval.embedding_metrics`' optional judge. A model download.
129
+ # * `reference` — `weft_cli.contract_reference` pipes generated Markdown through the real
130
+ # `ruff format`, so the checked-in file is byte-identical to what `poe ci-checks`' own `fmt`
131
+ # step produces. The floor is >=0.16.0, the first release that formats Python code blocks in
132
+ # Markdown by default, which is the behaviour it relies on. **Declared at task 6.7 and
133
+ # declared nowhere before**: it worked only because the workspace root's dev group carries
134
+ # `ruff` (`docs/lessons.md` L6.24).
135
+ [project.optional-dependencies]
136
+ bertscore = ["bert-score>=0.3"]
137
+ reference = ["ruff>=0.16.0"]
138
+
139
+ # **The six capability extras — G19, 2026-09-09.** Each was its own published distribution until
140
+ # that session, on G10's criterion that a pack "carrying a dependency somebody may decline" ships
141
+ # separately. An extra makes the dependency declinable at a fraction of the cost, so the code now
142
+ # ships in this wheel and only the outside library is optional. What a user declines is what they
143
+ # were ever declining: `docling-slim` is 897 MB and `weft_docling` is a few kilobytes.
144
+ #
145
+ # **A pack whose extra is not installed reports `failed`, and that is by design rather than by
146
+ # luck.** `weft_kernel.discovery` folds any import error into a `FAILED` report — its own comment:
147
+ # "a pack's import can raise anything; that is FAILED, not a crash" — so `weft plugins doctor`
148
+ # names the pack and what is missing, and the run continues without it.
149
+ #
150
+ # `agent` has no extra and needs none: `weft_agent` imports nothing outside this wheel, so it is
151
+ # always available. It is listed here in the comment rather than in the table because an empty
152
+ # extra would be a knob that does nothing.
153
+ pdf = ["pypdf>=6.16", "pdfplumber>=0.11.10"]
154
+ openai = ["openai>=3.1", "pillow>=10.0"]
155
+ qdrant = ["qdrant-client>=1.12"]
156
+ otel = ["opentelemetry-sdk>=1.28"]
157
+ docling = ["docling-slim[convert-core,format-pdf,models-local,feat-ocr-rapidocr-onnx]>=2.55"]
158
+ # `all` lists the libraries rather than referring to this distribution's own extras. A
159
+ # self-reference (`weft-rag[pdf,openai,...]`) is a requirement on a sibling with no version
160
+ # bound, which fitness function 10(b) refuses for the reason it refuses every other one: an
161
+ # unbounded requirement permits any pack against any kernel. Listing them is also the honest
162
+ # form — a reader sees what `all` costs without resolving anything.
163
+ all = [
164
+ "pypdf>=6.16",
165
+ "pdfplumber>=0.11.10",
166
+ "openai>=3.1",
167
+ "pillow>=10.0",
168
+ "qdrant-client>=1.12",
169
+ "opentelemetry-sdk>=1.28",
170
+ "docling-slim[convert-core,format-pdf,models-local,feat-ocr-rapidocr-onnx]>=2.55",
171
+ ]
172
+
173
+ [project.scripts]
174
+ weft = "weft_cli.cli:main"
175
+
176
+ # The twenty-one packs this wheel registers. **The name on the left is the pack's identity** — the
177
+ # row `weft plugins list|doctor` prints, and the key a `[packs.<pack>]` settings block uses — so
178
+ # these twenty-one are what an operator writes in `weft.toml`, never `weft-rag`.
179
+ #
180
+ # Twenty-three packages ship; twenty-one register. `weft_command` and `weft_prompts` deliberately declare
181
+ # no entry point and register nothing: fitness function 2 requires a distribution declaring one
182
+ # to be active *and contributing*, and every first-party prompt belongs to the plugin that asks
183
+ # it a question. They are libraries other packs publish contracts from, which is a real thing to
184
+ # be, and a pack that registers nothing is one fitness function 2 would have to waive.
185
+ [project.entry-points."weft.packs"]
186
+ blob = "weft_blob:register"
187
+ chunk = "weft_chunk:register"
188
+ clean = "weft_clean:register"
189
+ cli = "weft_cli.commands:register"
190
+ embed = "weft_embed:register"
191
+ enhance = "weft_enhance:register"
192
+ eval = "weft_eval:register"
193
+ extract = "weft_extract:register"
194
+ generate = "weft_generate:register"
195
+ index = "weft_index:register"
196
+ llm = "weft_llm:register"
197
+ retrieve = "weft_retrieve:register"
198
+ store = "weft_store:register"
199
+ vision = "weft_vision:register"
200
+
201
+ # The six that arrived with G19 (2026-09-09), each formerly its own distribution. A pack's
202
+ # identity is its name on the left, and those names are unchanged — `pdf`, `openai`, `qdrant`,
203
+ # `otel`, `agent`, `docling` are what an operator already writes in `weft.toml`, so no
204
+ # `[packs.*]` block, no `[services]` selection and no `plugins doctor` row moves. Only the wheel
205
+ # they arrive in changed.
206
+ agent = "weft_agent:register"
207
+ docling = "weft_docling:register"
208
+ openai = "weft_openai:register"
209
+ otel = "weft_otel:register"
210
+ pdf = "weft_pdf:register"
211
+ qdrant = "weft_qdrant:register"
212
+ # Ledger task 11.5 — `weft_kg` was already carried in this wheel's own package list (11.4
213
+ # published its contract with no entry point at all); this is the line that makes it reachable.
214
+ graph = "weft_kg:register"
215
+
216
+ [build-system]
217
+ requires = ["hatchling"]
218
+ build-backend = "hatchling.build"
219
+
220
+ # Twenty-three top-level packages in one wheel, listed rather than globbed: a glob would silently
221
+ # ship whatever happened to be under `src/`, and what this distribution ships is a decision.
222
+ #
223
+ # **They live under this project's own `src/`, and that placement is load-bearing.** The first
224
+ # attempt pointed `[tool.hatch.build.targets.wheel.force-include]` at `../weft-chunk/src/...` and
225
+ # left the fourteen where they were. The wheel built and worked; `uv build` — which builds the
226
+ # sdist and then builds a wheel *from* it, in an isolated directory where `../` does not exist —
227
+ # failed outright, so task 6.7's "every sdist carries what the checkout has" could never hold.
228
+ # A path outside the project root is not a packaging detail one backend flag away; it is outside
229
+ # what a source distribution can contain. Moving the trees here costs nothing at all — the
230
+ # top-level module names are unchanged, so no import in the tree, and no test, changed.
231
+ [tool.hatch.build.targets.wheel]
232
+ packages = [
233
+ "src/weft_agent",
234
+ "src/weft_blob",
235
+ "src/weft_chunk",
236
+ "src/weft_clean",
237
+ "src/weft_cli",
238
+ "src/weft_command",
239
+ "src/weft_docling",
240
+ "src/weft_embed",
241
+ "src/weft_enhance",
242
+ "src/weft_eval",
243
+ "src/weft_extract",
244
+ "src/weft_generate",
245
+ "src/weft_index",
246
+ "src/weft_kg",
247
+ "src/weft_llm",
248
+ "src/weft_openai",
249
+ "src/weft_otel",
250
+ "src/weft_pdf",
251
+ "src/weft_prompts",
252
+ "src/weft_qdrant",
253
+ "src/weft_retrieve",
254
+ "src/weft_store",
255
+ "src/weft_vision",
256
+ ]