TalkPipe 1.1.0__tar.gz → 1.2.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 (350) hide show
  1. {talkpipe-1.1.0 → talkpipe-1.2.0}/.pre-commit-config.yaml +1 -1
  2. {talkpipe-1.1.0 → talkpipe-1.2.0}/CHANGELOG.md +53 -0
  3. {talkpipe-1.1.0 → talkpipe-1.2.0}/PKG-INFO +8 -4
  4. {talkpipe-1.1.0 → talkpipe-1.2.0}/pyproject.toml +15 -3
  5. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_reference_generator.py +11 -12
  6. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/chatterlang/compiler.py +47 -8
  7. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipelines/vector_databases.py +29 -12
  8. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/config.py +8 -0
  9. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/PKG-INFO +8 -4
  10. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/requires.txt +7 -3
  11. talkpipe-1.2.0/src/talkpipe.egg-info/scm_version.json +8 -0
  12. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_chatterlang_reference_generator.py +30 -0
  13. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_compiler.py +25 -0
  14. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipelines/test_vector_databases.py +42 -0
  15. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_util.py +14 -0
  16. {talkpipe-1.1.0 → talkpipe-1.2.0}/uv.lock +119 -105
  17. talkpipe-1.1.0/src/talkpipe.egg-info/scm_version.json +0 -8
  18. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/changelog-update/SKILL.md +0 -0
  19. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/doc-example-formatting/SKILL.md +0 -0
  20. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/run-documentation-examples/SKILL.md +0 -0
  21. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/run-documentation-examples/scripts/run_documentation_examples.py +0 -0
  22. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/test-driven-development/SKILL.md +0 -0
  23. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/update-entry-points/SKILL.md +0 -0
  24. {talkpipe-1.1.0 → talkpipe-1.2.0}/.cursor/skills/update-entry-points/scripts/update_entry_points.py +0 -0
  25. {talkpipe-1.1.0 → talkpipe-1.2.0}/.dockerignore +0 -0
  26. {talkpipe-1.1.0 → talkpipe-1.2.0}/.gitea/default_merge_message/MERGE_TEMPLATE.md +0 -0
  27. {talkpipe-1.1.0 → talkpipe-1.2.0}/.gitea/default_merge_message/SQUASH_TEMPLATE.md +0 -0
  28. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/CICD.md +0 -0
  29. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/ISSUE_TEMPLATE/release-checklist.md +0 -0
  30. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/SECURITY.md +0 -0
  31. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/copilot-instructions.md +0 -0
  32. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/dependabot.yml +0 -0
  33. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/prompts/add-segment.prompt.md +0 -0
  34. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/prompts/changelog.prompt.md +0 -0
  35. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/prompts/doc-examples.prompt.md +0 -0
  36. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/prompts/tdd.prompt.md +0 -0
  37. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/prompts/update-entry-points.prompt.md +0 -0
  38. {talkpipe-1.1.0 → talkpipe-1.2.0}/.github/workflows/ci-cd.yml +0 -0
  39. {talkpipe-1.1.0 → talkpipe-1.2.0}/.gitignore +0 -0
  40. {talkpipe-1.1.0 → talkpipe-1.2.0}/.safety-policy.yml +0 -0
  41. {talkpipe-1.1.0 → talkpipe-1.2.0}/.safety-project.ini +0 -0
  42. {talkpipe-1.1.0 → talkpipe-1.2.0}/.vscode/settings.json +0 -0
  43. {talkpipe-1.1.0 → talkpipe-1.2.0}/.vscode/tasks.json +0 -0
  44. {talkpipe-1.1.0 → talkpipe-1.2.0}/AGENTS.md +0 -0
  45. {talkpipe-1.1.0 → talkpipe-1.2.0}/COPYRIGHT +0 -0
  46. {talkpipe-1.1.0 → talkpipe-1.2.0}/Dockerfile +0 -0
  47. {talkpipe-1.1.0 → talkpipe-1.2.0}/LICENSE +0 -0
  48. {talkpipe-1.1.0 → talkpipe-1.2.0}/README.md +0 -0
  49. {talkpipe-1.1.0 → talkpipe-1.2.0}/RELEASING.md +0 -0
  50. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/.gitignore +0 -0
  51. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/LLMChat.png +0 -0
  52. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/LLMEvaluateWebPage.png +0 -0
  53. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/README.md +0 -0
  54. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/TalkPipe.png +0 -0
  55. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/TalkPipe.xcf +0 -0
  56. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/README.md +0 -0
  57. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/chatterlang-script.md +0 -0
  58. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/chatterlang-server.md +0 -0
  59. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/chatterlang-workbench.md +0 -0
  60. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/lazy-loading.md +0 -0
  61. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/talkpipe-plugin-manager.md +0 -0
  62. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/api-reference/talkpipe-ref.md +0 -0
  63. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/README.md +0 -0
  64. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/chatterlang.md +0 -0
  65. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/configuration.md +0 -0
  66. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/documentation-formatting.md +0 -0
  67. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/extending-talkpipe.md +0 -0
  68. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/metadata-stream.md +0 -0
  69. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/pipe-api.md +0 -0
  70. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/protocol.md +0 -0
  71. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/security.md +0 -0
  72. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/architecture/streaming.md +0 -0
  73. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/chatterlang_workbench_screenshot.png +0 -0
  74. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/contributing/developer-handbook.md +0 -0
  75. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/guides/container-images.md +0 -0
  76. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/guides/makevectordatabase-and-serverag.md +0 -0
  77. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/guides/model-and-source-configuration.md +0 -0
  78. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/guides/model2vec-embeddings.md +0 -0
  79. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/make_structure_diagram.sh +0 -0
  80. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/quickstart.md +0 -0
  81. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/structure.tex +0 -0
  82. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/talkpipe_architecture.png +0 -0
  83. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/talkpipe_architecture.tex +0 -0
  84. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/talkpipe_diagram.png +0 -0
  85. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/.gitignore +0 -0
  86. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/README.md +0 -0
  87. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/README.md +0 -0
  88. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.bat +0 -0
  89. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.script +0 -0
  90. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.sh +0 -0
  91. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.bat +0 -0
  92. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.script +0 -0
  93. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.sh +0 -0
  94. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.bat +0 -0
  95. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.script +0 -0
  96. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.sh +0 -0
  97. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/stories.json +0 -0
  98. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_1-Document_Indexing/story_search_ui.yml +0 -0
  99. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/README.md +0 -0
  100. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.bat +0 -0
  101. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.script +0 -0
  102. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.sh +0 -0
  103. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.bat +0 -0
  104. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.script +0 -0
  105. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.sh +0 -0
  106. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.bat +0 -0
  107. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.script +0 -0
  108. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.sh +0 -0
  109. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/step_3_extras.py +0 -0
  110. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/story_by_example_ui.yml +0 -0
  111. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/README.md +0 -0
  112. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.bat +0 -0
  113. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.script +0 -0
  114. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.sh +0 -0
  115. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.bat +0 -0
  116. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.script +0 -0
  117. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.sh +0 -0
  118. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.bat +0 -0
  119. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.script +0 -0
  120. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.sh +0 -0
  121. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/file_structure.md +0 -0
  122. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/multi_format_ui.yml +0 -0
  123. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/report_topic_ui.yml +0 -0
  124. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/step_1_extras.py +0 -0
  125. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/step_2_extras.py +0 -0
  126. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/tutorials/Tutorial_3_Report_Writing/step_3_extras.py +0 -0
  127. {talkpipe-1.1.0 → talkpipe-1.2.0}/docs/workbench_demo.mp4 +0 -0
  128. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/.gitignore +0 -0
  129. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/README.md +0 -0
  130. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/build.mjs +0 -0
  131. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/package-lock.json +0 -0
  132. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/package.json +0 -0
  133. {talkpipe-1.1.0 → talkpipe-1.2.0}/frontend/src/cm.js +0 -0
  134. {talkpipe-1.1.0 → talkpipe-1.2.0}/pytest.ini +0 -0
  135. {talkpipe-1.1.0 → talkpipe-1.2.0}/scripts/extract_documentation_examples.py +0 -0
  136. {talkpipe-1.1.0 → talkpipe-1.2.0}/setup.cfg +0 -0
  137. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/__init__.py +0 -0
  138. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/__init__.py +0 -0
  139. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_generate_entry_points.py +0 -0
  140. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_reference_browser.py +0 -0
  141. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_script.py +0 -0
  142. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_serve.py +0 -0
  143. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/chatterlang_workbench.py +0 -0
  144. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/doc_examples.py +0 -0
  145. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/makevectordatabase.py +0 -0
  146. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/precache_model2vec.py +0 -0
  147. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/server_common.py +0 -0
  148. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/serverag.py +0 -0
  149. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/favicon.ico +0 -0
  150. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/common.js +0 -0
  151. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/index.css +0 -0
  152. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/index.js +0 -0
  153. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/stream.css +0 -0
  154. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/stream.js +0 -0
  155. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/vendor/LICENSES.txt +0 -0
  156. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/vendor/marked.min.js +0 -0
  157. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/serve/vendor/purify.min.js +0 -0
  158. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/talkpipe_logo.png +0 -0
  159. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/app.js +0 -0
  160. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/editor.js +0 -0
  161. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/index.html +0 -0
  162. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/styles.css +0 -0
  163. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/suggest.js +0 -0
  164. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/vendor/LICENSES.txt +0 -0
  165. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/vendor/codemirror.js +0 -0
  166. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/static/workbench/workspace.js +0 -0
  167. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/talkpipe_plugin_manager.py +0 -0
  168. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/templates/chatterlang_serve/index.html +0 -0
  169. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/templates/chatterlang_serve/stream.html +0 -0
  170. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/__init__.py +0 -0
  171. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/corpus.py +0 -0
  172. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/reference_api.py +0 -0
  173. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/suggest.py +0 -0
  174. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/suggest_api.py +0 -0
  175. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/workspace.py +0 -0
  176. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench/workspace_api.py +0 -0
  177. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/README.md +0 -0
  178. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_1_createsyntheticdata.script +0 -0
  179. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_2_indexstories.script +0 -0
  180. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_3_searchstories.script +0 -0
  181. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_1_createvectordatabase.script +0 -0
  182. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_2_searchbyexample.script +0 -0
  183. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_3_specializedrag.script +0 -0
  184. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_1_executivesummarygeneration.script +0 -0
  185. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_2_detailedanalysisreportgeneration.script +0 -0
  186. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_3_multiformatreportgeneration.script +0 -0
  187. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/chatterlang/__init__.py +0 -0
  188. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/chatterlang/parsers.py +0 -0
  189. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/chatterlang/registry.py +0 -0
  190. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/__init__.py +0 -0
  191. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/email.py +0 -0
  192. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/extraction.py +0 -0
  193. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/html.py +0 -0
  194. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/image.py +0 -0
  195. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/mongo.py +0 -0
  196. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/rss.py +0 -0
  197. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/text/__init__.py +0 -0
  198. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/text/chunking_units.py +0 -0
  199. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/text/cleaning.py +0 -0
  200. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/text/englishnormalize.py +0 -0
  201. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/data/text/operations.py +0 -0
  202. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/__init__.py +0 -0
  203. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/_ollama_common.py +0 -0
  204. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/chat.py +0 -0
  205. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/config.py +0 -0
  206. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/content.py +0 -0
  207. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/embedding.py +0 -0
  208. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/embedding_adapters.py +0 -0
  209. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/embedding_adapters_model2vec.py +0 -0
  210. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/embedding_adapters_openai.py +0 -0
  211. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/embedding_errors.py +0 -0
  212. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/model2vec_embeddings.py +0 -0
  213. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/multimodal.py +0 -0
  214. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapter_base.py +0 -0
  215. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapter_memory.py +0 -0
  216. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapters.py +0 -0
  217. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapters_anthropic.py +0 -0
  218. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapters_eliza.py +0 -0
  219. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapters_ollama.py +0 -0
  220. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/prompt_adapters_openai.py +0 -0
  221. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/llm/vision.py +0 -0
  222. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/operations/__init__.py +0 -0
  223. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/operations/filtering.py +0 -0
  224. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/operations/matrices.py +0 -0
  225. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/operations/thread_ops.py +0 -0
  226. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/operations/transforms.py +0 -0
  227. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/__init__.py +0 -0
  228. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/basic.py +0 -0
  229. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/collect.py +0 -0
  230. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/core.py +0 -0
  231. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/debug.py +0 -0
  232. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/fields.py +0 -0
  233. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/filters.py +0 -0
  234. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/flow.py +0 -0
  235. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/fork.py +0 -0
  236. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/hashing.py +0 -0
  237. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/io.py +0 -0
  238. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/math.py +0 -0
  239. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/metadata.py +0 -0
  240. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipe/shell.py +0 -0
  241. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipelines/__init__.py +0 -0
  242. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/pipelines/basic_rag.py +0 -0
  243. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/py.typed +0 -0
  244. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/search/__init__.py +0 -0
  245. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/search/abstract.py +0 -0
  246. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/search/lancedb.py +0 -0
  247. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/search/whoosh.py +0 -0
  248. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/__init__.py +0 -0
  249. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/collections.py +0 -0
  250. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/constants.py +0 -0
  251. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/data_manipulation.py +0 -0
  252. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/doc_extraction.py +0 -0
  253. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/iterators.py +0 -0
  254. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/os.py +0 -0
  255. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe/util/plugin_loader.py +0 -0
  256. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/SOURCES.txt +0 -0
  257. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/dependency_links.txt +0 -0
  258. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/entry_points.txt +0 -0
  259. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/scm_file_list.json +0 -0
  260. {talkpipe-1.1.0 → talkpipe-1.2.0}/src/talkpipe.egg-info/top_level.txt +0 -0
  261. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/conftest.py +0 -0
  262. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/embedding_adapter_contract_suite.py +0 -0
  263. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/prompt_adapter_contract_suite.py +0 -0
  264. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_chatterlang_generate_entry_points.py +0 -0
  265. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_chatterlang_reference_browser.py +0 -0
  266. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_chatterlang_script.py +0 -0
  267. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_chatterlang_serve.py +0 -0
  268. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_makevectordatabase.py +0 -0
  269. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_precache_model2vec.py +0 -0
  270. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_serve_static.py +0 -0
  271. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_server_common.py +0 -0
  272. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_server_hardening.py +0 -0
  273. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_serverag.py +0 -0
  274. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_talkpipe_plugin_manager.py +0 -0
  275. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_corpus.py +0 -0
  276. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_load_module.py +0 -0
  277. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_reference_api.py +0 -0
  278. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_static.py +0 -0
  279. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_suggest.py +0 -0
  280. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/app/test_workbench_workspace.py +0 -0
  281. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_chatterlang_workbench.py +0 -0
  282. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_entry_point_drift.py +0 -0
  283. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_entry_points.py +0 -0
  284. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_parsers.py +0 -0
  285. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/chatterlang/test_registry.py +0 -0
  286. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/sample_feed.pkl +0 -0
  287. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test.docx +0 -0
  288. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_email.py +0 -0
  289. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_extraction.py +0 -0
  290. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_html.py +0 -0
  291. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_html_exceptions.py +0 -0
  292. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_image.py +0 -0
  293. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_mogomock.py +0 -0
  294. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_mongo.py +0 -0
  295. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_mongo_integration.py +0 -0
  296. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_mongo_timeouts.py +0 -0
  297. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/test_rss.py +0 -0
  298. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/text/test_chunking_units.py +0 -0
  299. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/text/test_cleaning.py +0 -0
  300. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/text/test_englishnormalize.py +0 -0
  301. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/data/text/test_operations.py +0 -0
  302. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_chat.py +0 -0
  303. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_content.py +0 -0
  304. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_embedding.py +0 -0
  305. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_embedding_adapters_contract.py +0 -0
  306. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_embedding_batch.py +0 -0
  307. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_embedding_model2vec.py +0 -0
  308. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_embedding_token_overflow.py +0 -0
  309. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_multimodal.py +0 -0
  310. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_anthropic.py +0 -0
  311. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_base.py +0 -0
  312. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_eliza.py +0 -0
  313. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_memory.py +0 -0
  314. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_ollama.py +0 -0
  315. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_prompt_adapters_openai.py +0 -0
  316. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_timeouts.py +0 -0
  317. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_vision.py +0 -0
  318. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/llm/test_vision_adapters.py +0 -0
  319. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/operations/test_filtering.py +0 -0
  320. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/operations/test_matrices.py +0 -0
  321. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/operations/test_threading.py +0 -0
  322. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/operations/test_transforms.py +0 -0
  323. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_basic.py +0 -0
  324. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_basic_split.py +0 -0
  325. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_core.py +0 -0
  326. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_fork.py +0 -0
  327. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_io.py +0 -0
  328. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_math.py +0 -0
  329. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipe/test_metadata.py +0 -0
  330. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/pipelines/test_basic_rag.py +0 -0
  331. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/search/test_abstract.py +0 -0
  332. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/search/test_lancedb.py +0 -0
  333. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/search/test_lancedb_cache.py +0 -0
  334. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/search/test_whoosh.py +0 -0
  335. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/test_documentation_examples.py +0 -0
  336. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/test_heavy_imports_are_lazy.py +0 -0
  337. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/test_py_typed.py +0 -0
  338. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/test_version.py +0 -0
  339. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_collections.py +0 -0
  340. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_config.py +0 -0
  341. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_data_manipulation.py +0 -0
  342. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_doc_extraction.py +0 -0
  343. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_iterators.py +0 -0
  344. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_os.py +0 -0
  345. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/talkpipe/util/test_plugin_loader.py +0 -0
  346. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/test_config_keys_documented.py +0 -0
  347. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/test_doc_examples.py +0 -0
  348. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/test_security_vulnerabilities.py +0 -0
  349. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/test_tutorial_scripts.py +0 -0
  350. {talkpipe-1.1.0 → talkpipe-1.2.0}/tests/testutils.py +0 -0
@@ -2,7 +2,7 @@
2
2
  # per clone; `pre-commit run --all-files` reproduces the gate locally.
3
3
  repos:
4
4
  - repo: https://github.com/astral-sh/ruff-pre-commit
5
- rev: v0.16.3 # keep in step with the ruff pin in pyproject.toml
5
+ rev: v0.17.0 # keep in step with the ruff pin in pyproject.toml
6
6
  hooks:
7
7
  - id: ruff-check
8
8
  args: [--fix, --show-fixes]
@@ -2,6 +2,59 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.2.0 (2026-10-24)
6
+
7
+ - `build_rag_database` accepts pre-made chunks: a new keyword-only
8
+ `chunks=` argument (an iterable of dicts shaped like
9
+ `ProcessDocumentsSegment` output) is embedded and stored directly, with
10
+ `source_pattern` passed as `None`. The preflight, dimension check,
11
+ overflow truncation and skip accounting apply unchanged. This lets a
12
+ caller chunk documents once, index the chunks for keyword search, and
13
+ embed the same chunks later. Passing both or neither raises
14
+ `ValueError`; existing calls are unaffected.
15
+ - **Security: raised the `Pillow` floor** in the `pillow` extra (and so in
16
+ `all`) to `Pillow>=13.0.0`, clearing six advisories against earlier
17
+ releases. `uv.lock` moves `pillow` to 13.0.0.
18
+ - **Security: raised dependency floors** to clear advisories against
19
+ earlier releases: `pypdf>=6.21.2` in the `pypdf` extra (and so in `all`);
20
+ `certifi>=2026.10.19` in the core dependencies (it arrives through
21
+ `requests` and `httpx`); `filelock>=4.2.1` in the `model2vec` extra (it
22
+ arrives through `huggingface-hub`); and `virtualenv>=21.14.9` and
23
+ `filelock>=4.2.1` in the `dev` extra (they arrive through `pre-commit`).
24
+ `uv.lock` moves `certifi` to 2026.10.23, `filelock` to 4.2.4, `pypdf` to
25
+ 6.21.2, `virtualenv` to 21.14.13, and `packaging` to 26.3.
26
+
27
+ ## 1.1.1 (2026-10-16)
28
+
29
+ - A bare word in a chatterlang parameter that names no `CONST` (for
30
+ example `tools=[lookup_ticket]` instead of `tools=["lookup_ticket"]`)
31
+ now fails compilation with `Segment 'llmAgent': unknown constant
32
+ 'lookup_ticket' in tools=. A bare word refers to a CONST; quote it for
33
+ the string "lookup_ticket", or declare it first (CONST lookup_ticket =
34
+ ...)`. It used to surface as the raw `KeyError` text, `Segment
35
+ 'llmAgent' could not be created: 'lookup_ticket'`. The error is a
36
+ `bad_param` `CompileError` naming the segment or source, so the workbench
37
+ lint shows it like other parameter errors.
38
+ - `--logger_levels` (and `configure_logger` / the `configureLogger`
39
+ segment) no longer prints every log line twice. A named logger got its
40
+ own console handler and its records also propagated to the handler
41
+ `logging.basicConfig` had put on the root logger; the named logger now
42
+ stops propagating. A `logger_files` entry for the root logger therefore
43
+ does not receive a named logger's records: name the same logger in
44
+ `logger_files` (the docstring says so).
45
+ - `chatterlang_reference_generator` no longer drops the first parameter of
46
+ every plain segment from the `.html` and `.txt` references it writes.
47
+ The extractor already removes the data parameter (`items` / `item`) by
48
+ name, and the generator then removed the first remaining parameter by
49
+ position as well, so `cast` was documented without `cast_type`,
50
+ `llmPrompt` without `model`, `print` without `pprint`, and so on.
51
+ `chatterlang_reference_browser` and the workbench, which do not apply
52
+ that second filter, were already correct.
53
+ - The `dev` extra moves ruff to the 0.17 series (`>=0.17.0,<0.18`), with
54
+ the ruff-pre-commit hook on v0.17.0 to match; a dependency update had
55
+ widened the pin to `<0.18` without moving the hook. The code needed no
56
+ changes for the new release's rules or formatting.
57
+
5
58
  ## 1.1.0 (2026-10-12)
6
59
 
7
60
  - Added `talkpipe.llm.config.resolve_source_and_model(source, model)`: applies
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: talkpipe
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Python internal and external DSL for writing generative AI analytics
5
5
  Author-email: Travis Bauer <tlbauer@sandia.gov>
6
6
  Maintainer-email: Travis Bauer <tlbauer@sandia.gov>
@@ -41,14 +41,17 @@ Requires-Dist: pyyaml>=5.4
41
41
  Requires-Dist: greenlet
42
42
  Requires-Dist: networkx
43
43
  Requires-Dist: starlette>=1.3.1
44
+ Requires-Dist: certifi>=2026.10.19
44
45
  Provides-Extra: dev
45
46
  Requires-Dist: pytest>=9.0.3; extra == "dev"
46
47
  Requires-Dist: pytest-mock; extra == "dev"
47
48
  Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
48
49
  Requires-Dist: mongomock; extra == "dev"
49
- Requires-Dist: ruff<0.18,>=0.16.3; extra == "dev"
50
+ Requires-Dist: ruff<0.18,>=0.17.0; extra == "dev"
50
51
  Requires-Dist: mypy<3,>=2.3; extra == "dev"
51
52
  Requires-Dist: pre-commit>=4.0; extra == "dev"
53
+ Requires-Dist: virtualenv>=21.14.9; extra == "dev"
54
+ Requires-Dist: filelock>=4.2.1; extra == "dev"
52
55
  Provides-Extra: ollama
53
56
  Requires-Dist: ollama; extra == "ollama"
54
57
  Provides-Extra: openai
@@ -56,11 +59,12 @@ Requires-Dist: openai; extra == "openai"
56
59
  Provides-Extra: anthropic
57
60
  Requires-Dist: anthropic>=0.87.0; extra == "anthropic"
58
61
  Provides-Extra: pypdf
59
- Requires-Dist: pypdf>=6.19.0; extra == "pypdf"
62
+ Requires-Dist: pypdf>=6.21.2; extra == "pypdf"
60
63
  Provides-Extra: pillow
61
- Requires-Dist: Pillow>=12.2.0; extra == "pillow"
64
+ Requires-Dist: Pillow>=13.0.0; extra == "pillow"
62
65
  Provides-Extra: model2vec
63
66
  Requires-Dist: model2vec>=0.3.4; extra == "model2vec"
67
+ Requires-Dist: filelock>=4.2.1; extra == "model2vec"
64
68
  Provides-Extra: all
65
69
  Requires-Dist: talkpipe[anthropic,model2vec,ollama,openai,pillow,pypdf]; extra == "all"
66
70
  Dynamic: license-file
@@ -60,6 +60,10 @@ dependencies = [
60
60
  # covers the advisories published since, the latest being CVE-2026-54283,
61
61
  # which is first fixed in 1.3.1.
62
62
  "starlette>=1.3.1",
63
+ # Security override: certifi is a transitive dependency of requests and
64
+ # httpx, floored here because neither sets one that clears its
65
+ # advisories: <2026.10.19 has known advisories.
66
+ "certifi>=2026.10.19",
63
67
  ]
64
68
  dynamic = ["version"]
65
69
 
@@ -73,9 +77,14 @@ dev = [
73
77
  # new rules and mypy adds checks in minor releases, and CI resolves fresh,
74
78
  # so an open floor would turn a tool release into a red build. Bump the
75
79
  # pins deliberately (and the ruff-pre-commit rev with them).
76
- "ruff>=0.16.3,<0.18",
80
+ "ruff>=0.17.0,<0.18",
77
81
  "mypy>=2.3,<3",
78
82
  "pre-commit>=4.0",
83
+ # Security overrides: virtualenv and filelock arrive through pre-commit,
84
+ # floored here because it sets no floor that clears their advisories
85
+ # (<21.14.9 and <4.2.1 respectively have known advisories).
86
+ "virtualenv>=21.14.9",
87
+ "filelock>=4.2.1",
79
88
  ]
80
89
  ollama = [
81
90
  'ollama'
@@ -87,13 +96,16 @@ anthropic = [
87
96
  'anthropic>=0.87.0'
88
97
  ]
89
98
  pypdf = [
90
- 'pypdf>=6.19.0' # security floor: <6.19.0 has several crafted-PDF runtime and memory exhaustion advisories
99
+ 'pypdf>=6.21.2' # security floor: <6.21.2 has several crafted-PDF runtime and memory exhaustion advisories
91
100
  ]
92
101
  pillow = [
93
- 'Pillow>=12.2.0'
102
+ 'Pillow>=13.0.0' # security floor: <13.0.0 has six known advisories
94
103
  ]
95
104
  model2vec = [
96
105
  'model2vec>=0.3.4',
106
+ # Security override: filelock arrives through huggingface-hub, which sets
107
+ # no floor that clears its advisories (<4.2.1 has known advisories).
108
+ 'filelock>=4.2.1',
97
109
  ]
98
110
  all = [
99
111
  'talkpipe[openai,ollama,anthropic,pypdf,pillow,model2vec]'
@@ -177,24 +177,23 @@ def _display_type(item: AnalyzedItem) -> str:
177
177
 
178
178
 
179
179
  def _visible_params(item: AnalyzedItem, skip: list[str]) -> list[ParamSpec]:
180
- """Parameters to document: drop the ``skip`` names, then drop the leading
181
- data parameter for plain segments.
180
+ """Parameters to document: the item's parameters without the ``skip``
181
+ names.
182
182
 
183
183
  The two renderers skip different names, so the caller supplies the list.
184
+ The data parameter (``items`` / ``item``) is already gone by the time an
185
+ item gets here, because ``extract_component_info`` skips it by name, so
186
+ nothing is dropped by position: doing so removed the first real
187
+ parameter of every plain segment (``cast``'s ``cast_type``,
188
+ ``llmPrompt``'s ``model``).
184
189
  """
185
- filtered_params = [p for p in item.parameters if p.name not in skip]
186
- if item.is_segment and len(filtered_params) > 0:
187
- # For segments, the first param is often the data being processed
188
- filtered_params = (
189
- filtered_params[1:] if len(filtered_params) > 1 else filtered_params
190
- )
191
- return filtered_params
190
+ return [p for p in item.parameters if p.name not in skip]
192
191
 
193
192
 
194
193
  def generate_html(analyzed_items: list[AnalyzedItem], output_file: str) -> None:
195
194
  """
196
195
  Generate a styled HTML file with a table of contents, raw HTML docstrings,
197
- skipping 'self', and skipping first param for segment functions.
196
+ skipping 'self', 'items' and 'item'.
198
197
  """
199
198
  # Group by type (Source/Segment), then sort by chatterlang name
200
199
  items_by_type = _group_by_type(analyzed_items)
@@ -368,7 +367,7 @@ def generate_html(analyzed_items: list[AnalyzedItem], output_file: str) -> None:
368
367
  f" <div><pre>{html.escape(item.docstring)}</pre></div>\n"
369
368
  )
370
369
 
371
- # Process parameters - skip 'self' and for segments skip first param if it's the data param
370
+ # Process parameters - skip 'self' and the data parameter names
372
371
  filtered_params = _visible_params(item, ["self", "items", "item"])
373
372
 
374
373
  if filtered_params:
@@ -403,7 +402,7 @@ def generate_html(analyzed_items: list[AnalyzedItem], output_file: str) -> None:
403
402
  def generate_text(analyzed_items: list[AnalyzedItem], output_file: str) -> None:
404
403
  """
405
404
  Write a nicely formatted plain-text version of the same documentation.
406
- Group by type, sorted, omit 'self', skip first param for segment functions.
405
+ Group by type, sorted, omit 'self'.
407
406
  No table of contents here - just a linear, grouped listing.
408
407
  """
409
408
  # Group by type (Source/Segment), then sort by chatterlang name
@@ -473,20 +473,49 @@ def compile(
473
473
  return Script(final_pipelines)
474
474
 
475
475
 
476
- def _resolve_value(value: Any, runtime: RuntimeComponent) -> Any:
476
+ def _unknown_constant_message(kind: str, name: str, param: str, word: str) -> str:
477
+ """Build a CompileError message for a bare word that names no constant.
478
+
479
+ A bare word in a parameter value is a reference to a ``CONST``; a
480
+ newcomer who writes ``tools=[lookup_ticket]`` meaning the string gets
481
+ ``KeyError: 'lookup_ticket'`` otherwise, which says nothing about quoting.
482
+ """
483
+ return (
484
+ f"{kind} '{name}': unknown constant '{word}' in {param}=. A bare word "
485
+ f'refers to a CONST; quote it for the string "{word}", or declare it '
486
+ f"first (CONST {word} = ...)"
487
+ )
488
+
489
+
490
+ def _resolve_value(
491
+ value: Any, runtime: RuntimeComponent, *, kind: str, name: str, param: str
492
+ ) -> Any:
477
493
  """Resolve a single parameter value, handling constants and arrays recursively."""
478
494
  if isinstance(value, Identifier):
479
- return runtime.const_store[value.name]
495
+ try:
496
+ return runtime.const_store[value.name]
497
+ except KeyError:
498
+ raise CompileError(
499
+ _unknown_constant_message(kind, name, param, value.name),
500
+ kind="bad_param",
501
+ bad_name=name,
502
+ ) from None
480
503
  if isinstance(value, list):
481
- return [_resolve_value(elem, runtime) for elem in value]
504
+ return [
505
+ _resolve_value(elem, runtime, kind=kind, name=name, param=param)
506
+ for elem in value
507
+ ]
482
508
  return value
483
509
 
484
510
 
485
511
  def _resolve_params(
486
- params: dict[Any, Any], runtime: RuntimeComponent
512
+ params: dict[Any, Any], runtime: RuntimeComponent, *, kind: str, name: str
487
513
  ) -> dict[str, Any]:
488
- """Resolve the parameters for a segment"""
489
- return {k: _resolve_value(params[k], runtime) for k in params}
514
+ """Resolve the parameters for the *kind* (Source / Segment) named *name*."""
515
+ return {
516
+ k: _resolve_value(params[k], runtime, kind=kind, name=name, param=k)
517
+ for k in params
518
+ }
490
519
 
491
520
 
492
521
  @compile.register(ParsedPipeline)
@@ -522,7 +551,12 @@ def _(
522
551
  ) from None
523
552
  try:
524
553
  ans = source_cls(
525
- **_resolve_params(pipeline.input_node.params, runtime=runtime)
554
+ **_resolve_params(
555
+ pipeline.input_node.params,
556
+ runtime=runtime,
557
+ kind="Source",
558
+ name=source_name,
559
+ )
526
560
  )
527
561
  except TypeError as e:
528
562
  raise CompileError(
@@ -560,7 +594,12 @@ def _(
560
594
  ) from None
561
595
  try:
562
596
  next_transform = segment_cls(
563
- **_resolve_params(transform.params, runtime=runtime)
597
+ **_resolve_params(
598
+ transform.params,
599
+ runtime=runtime,
600
+ kind="Segment",
601
+ name=segment_name,
602
+ )
564
603
  )
565
604
  except TypeError as e:
566
605
  raise CompileError(
@@ -348,7 +348,7 @@ def _tally_stored_chunks(
348
348
 
349
349
 
350
350
  def build_rag_database(
351
- source_pattern: str | Iterable[str],
351
+ source_pattern: str | Iterable[str] | None,
352
352
  path: str,
353
353
  embedding_model: str | None = None,
354
354
  embedding_source: str | None = None,
@@ -366,6 +366,7 @@ def build_rag_database(
366
366
  expected_dimension: int | None = None,
367
367
  preflight: bool = True,
368
368
  progress: Callable[[int, int, str], None] | None = None,
369
+ chunks: Iterable[dict[str, Any]] | None = None,
369
370
  ) -> RagIngestResult:
370
371
  """Build a RAG vector database from documents matching a glob pattern.
371
372
 
@@ -393,7 +394,16 @@ def build_rag_database(
393
394
 
394
395
  The optional progress callback receives (chunks_done, files_done,
395
396
  current_source_path) as chunks are stored.
397
+
398
+ chunks, when given, replaces reading and chunking: the dicts (already
399
+ shaped like ProcessDocumentsSegment output, with embedding_field and a
400
+ "source" field) are embedded and stored directly, and source_pattern
401
+ must be None. Callers that chunk documents themselves, for example to
402
+ build a keyword index from the same chunks first, keep the preflight,
403
+ dimension check, overflow handling, and skip accounting above.
396
404
  """
405
+ if (chunks is None) == (source_pattern is None):
406
+ raise ValueError("pass exactly one of source_pattern and chunks")
397
407
  config = get_config()
398
408
  embedding_model = embedding_model or config.get(TALKPIPE_EMBEDDING_MODEL_NAME)
399
409
  embedding_source = embedding_source or config.get(TALKPIPE_EMBEDDING_MODEL_SOURCE)
@@ -431,14 +441,18 @@ def build_rag_database(
431
441
  )
432
442
 
433
443
  tally = _IngestTally()
434
- pipeline = (
435
- ProcessDocumentsSegment(
436
- chunk_size=chunk_size,
437
- shingle_size=shingle_size,
438
- overlap=overlap,
444
+ tally_and_embed = _tally_extracted_chunks(tally=tally) | embed_segment
445
+ if chunks is None:
446
+ tally_and_embed = (
447
+ ProcessDocumentsSegment(
448
+ chunk_size=chunk_size,
449
+ shingle_size=shingle_size,
450
+ overlap=overlap,
451
+ )
452
+ | tally_and_embed
439
453
  )
440
- | _tally_extracted_chunks(tally=tally)
441
- | embed_segment
454
+ pipeline = (
455
+ tally_and_embed
442
456
  | add_to_lancedb(
443
457
  path=path,
444
458
  table_name=table_name,
@@ -449,10 +463,13 @@ def build_rag_database(
449
463
  | _tally_stored_chunks(tally=tally, progress=progress)
450
464
  )
451
465
 
452
- patterns = (
453
- [source_pattern] if isinstance(source_pattern, str) else list(source_pattern)
454
- )
455
- for _ in pipeline.transform(patterns):
466
+ if chunks is not None:
467
+ inputs: Iterable[Any] = chunks
468
+ elif isinstance(source_pattern, str):
469
+ inputs = [source_pattern]
470
+ else:
471
+ inputs = list(source_pattern or [])
472
+ for _ in pipeline.transform(inputs):
456
473
  pass
457
474
  # Chunks consumed after the last stored one also failed to embed.
458
475
  tally.chunks_skipped += tally.chunks_extracted - tally.extracted_at_last_store
@@ -257,6 +257,10 @@ def configure_logger(
257
257
  This reconfigures the calling process's logging: it calls
258
258
  ``logging.basicConfig`` and clears the existing handlers of every
259
259
  logger named in ``logger_levels`` before attaching a console handler.
260
+ A named (non-root) logger then stops propagating to the root
261
+ logger, so each record is printed once; a ``logger_files`` entry
262
+ for the root logger therefore does not receive that logger's
263
+ records (name the same logger in ``logger_files``).
260
264
  Applications embedding talkpipe that manage their own logging should
261
265
  not call it (or use the ``configureLogger`` segment).
262
266
  """
@@ -289,6 +293,10 @@ def configure_logger(
289
293
  console_handler.setLevel(level)
290
294
  console_handler.setFormatter(formatter)
291
295
  logger.addHandler(console_handler)
296
+ # The console handler above is this logger's output; without
297
+ # this, every record also propagated to the root handler that
298
+ # basicConfig installed and printed a second time.
299
+ logger.propagate = logger_name == "root"
292
300
 
293
301
  if logger_files:
294
302
  for logger_name, file_name in parse_key_value_str(logger_files).items():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: talkpipe
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Python internal and external DSL for writing generative AI analytics
5
5
  Author-email: Travis Bauer <tlbauer@sandia.gov>
6
6
  Maintainer-email: Travis Bauer <tlbauer@sandia.gov>
@@ -41,14 +41,17 @@ Requires-Dist: pyyaml>=5.4
41
41
  Requires-Dist: greenlet
42
42
  Requires-Dist: networkx
43
43
  Requires-Dist: starlette>=1.3.1
44
+ Requires-Dist: certifi>=2026.10.19
44
45
  Provides-Extra: dev
45
46
  Requires-Dist: pytest>=9.0.3; extra == "dev"
46
47
  Requires-Dist: pytest-mock; extra == "dev"
47
48
  Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
48
49
  Requires-Dist: mongomock; extra == "dev"
49
- Requires-Dist: ruff<0.18,>=0.16.3; extra == "dev"
50
+ Requires-Dist: ruff<0.18,>=0.17.0; extra == "dev"
50
51
  Requires-Dist: mypy<3,>=2.3; extra == "dev"
51
52
  Requires-Dist: pre-commit>=4.0; extra == "dev"
53
+ Requires-Dist: virtualenv>=21.14.9; extra == "dev"
54
+ Requires-Dist: filelock>=4.2.1; extra == "dev"
52
55
  Provides-Extra: ollama
53
56
  Requires-Dist: ollama; extra == "ollama"
54
57
  Provides-Extra: openai
@@ -56,11 +59,12 @@ Requires-Dist: openai; extra == "openai"
56
59
  Provides-Extra: anthropic
57
60
  Requires-Dist: anthropic>=0.87.0; extra == "anthropic"
58
61
  Provides-Extra: pypdf
59
- Requires-Dist: pypdf>=6.19.0; extra == "pypdf"
62
+ Requires-Dist: pypdf>=6.21.2; extra == "pypdf"
60
63
  Provides-Extra: pillow
61
- Requires-Dist: Pillow>=12.2.0; extra == "pillow"
64
+ Requires-Dist: Pillow>=13.0.0; extra == "pillow"
62
65
  Provides-Extra: model2vec
63
66
  Requires-Dist: model2vec>=0.3.4; extra == "model2vec"
67
+ Requires-Dist: filelock>=4.2.1; extra == "model2vec"
64
68
  Provides-Extra: all
65
69
  Requires-Dist: talkpipe[anthropic,model2vec,ollama,openai,pillow,pypdf]; extra == "all"
66
70
  Dynamic: license-file
@@ -19,6 +19,7 @@ pyyaml>=5.4
19
19
  greenlet
20
20
  networkx
21
21
  starlette>=1.3.1
22
+ certifi>=2026.10.19
22
23
 
23
24
  [all]
24
25
  talkpipe[anthropic,model2vec,ollama,openai,pillow,pypdf]
@@ -31,12 +32,15 @@ pytest>=9.0.3
31
32
  pytest-mock
32
33
  pytest-cov>=2.0.0
33
34
  mongomock
34
- ruff<0.18,>=0.16.3
35
+ ruff<0.18,>=0.17.0
35
36
  mypy<3,>=2.3
36
37
  pre-commit>=4.0
38
+ virtualenv>=21.14.9
39
+ filelock>=4.2.1
37
40
 
38
41
  [model2vec]
39
42
  model2vec>=0.3.4
43
+ filelock>=4.2.1
40
44
 
41
45
  [ollama]
42
46
  ollama
@@ -45,7 +49,7 @@ ollama
45
49
  openai
46
50
 
47
51
  [pillow]
48
- Pillow>=12.2.0
52
+ Pillow>=13.0.0
49
53
 
50
54
  [pypdf]
51
- pypdf>=6.19.0
55
+ pypdf>=6.21.2
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.2.0",
3
+ "distance": 0,
4
+ "node": "g5833aeff5bb8a583ea48888a7ee283f541c3c28c",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-24"
8
+ }
@@ -250,6 +250,36 @@ class TestGeneration:
250
250
  finally:
251
251
  os.unlink(temp_file)
252
252
 
253
+ def test_segments_keep_their_first_parameter(self):
254
+ """Every parameter the extractor returns is rendered. The data
255
+ parameter is already skipped by name upstream, so dropping the first
256
+ remaining one by position removed a real parameter from every plain
257
+ segment (``cast`` was documented without ``cast_type``)."""
258
+ item = AnalyzedItem(
259
+ type="Segment",
260
+ name="Cast",
261
+ docstring="Casts the input data.",
262
+ parameters=[
263
+ ParamSpec("cast_type", "str"),
264
+ ParamSpec("fail_silently", "bool", "True"),
265
+ ],
266
+ chatterlang_name="cast",
267
+ decorator_type="segment",
268
+ is_segment=True,
269
+ )
270
+ with tempfile.TemporaryDirectory() as tmp:
271
+ html_file = os.path.join(tmp, "ref.html")
272
+ text_file = os.path.join(tmp, "ref.txt")
273
+ generate_html([item], html_file)
274
+ generate_text([item], text_file)
275
+ with open(html_file, encoding="utf-8") as f:
276
+ html_content = f.read()
277
+ with open(text_file, encoding="utf-8") as f:
278
+ text_content = f.read()
279
+ for content in (html_content, text_content):
280
+ assert "cast_type" in content
281
+ assert "fail_silently" in content
282
+
253
283
 
254
284
  class TestMainFunctions:
255
285
  """Test main entry points."""
@@ -593,6 +593,31 @@ def test_compile_error_when_component_rejects_its_options():
593
593
  assert excinfo.value.__suppress_context__
594
594
 
595
595
 
596
+ def test_compile_error_names_an_unknown_constant():
597
+ """A bare word in a parameter is a CONST reference. Unknown, it used to
598
+ surface as the KeyError text (``could not be created: 'foo'``), which
599
+ says nothing about quoting or CONST."""
600
+ with pytest.raises(compiler.CompileError) as excinfo:
601
+ compiler.compile('INPUT FROM echo[data="a,b"] | firstN[n=[foo]]')
602
+ msg = str(excinfo.value)
603
+ assert "Segment 'firstN': unknown constant 'foo' in n=" in msg
604
+ assert 'quote it for the string "foo"' in msg
605
+ assert "CONST foo = ..." in msg
606
+ assert excinfo.value.kind == "bad_param"
607
+ assert excinfo.value.bad_name == "firstN"
608
+ assert excinfo.value.__cause__ is None
609
+
610
+ with pytest.raises(compiler.CompileError) as excinfo:
611
+ compiler.compile("INPUT FROM echo[data=foo] | print")
612
+ assert "Source 'echo': unknown constant 'foo' in data=" in str(excinfo.value)
613
+
614
+ # A declared constant still resolves, in a list as well as bare.
615
+ script = compiler.compile(
616
+ 'CONST foo = 1; INPUT FROM echo[data="a,b"] | firstN[n=foo] | firstN[n=[foo]]'
617
+ )
618
+ assert script is not None
619
+
620
+
596
621
  def test_compile_error_when_source_rejects_its_options():
597
622
  """The same wrapping applies to a source constructor."""
598
623
 
@@ -966,6 +966,48 @@ def test_build_rag_database_raises_when_nothing_embeds(
966
966
  )
967
967
 
968
968
 
969
+ def test_build_rag_database_accepts_premade_chunks(tmp_path, monkeypatch):
970
+ from talkpipe.pipelines import vector_databases as vdb
971
+
972
+ monkeypatch.setattr(vdb, "LLMEmbed", _fake_llm_embed(drop_indices=(1,)))
973
+ db_path = str(tmp_path / "db")
974
+ chunks = [
975
+ {
976
+ "id": f"c{n}",
977
+ "content": f"text {n}",
978
+ "shingle_text": f"text {n}",
979
+ "source": f"/docs/{n % 2}.txt",
980
+ "title": f"{n % 2}.txt",
981
+ }
982
+ for n in range(3)
983
+ ]
984
+
985
+ result = vdb.build_rag_database(
986
+ None,
987
+ path=db_path,
988
+ embedding_model="fake-model",
989
+ embedding_source="fake-source",
990
+ doc_id_field="id",
991
+ chunks=chunks,
992
+ )
993
+
994
+ assert result.chunks_indexed == 2
995
+ assert result.chunks_skipped == 1
996
+ assert result.files_indexed == 1
997
+ store = LanceDBDocumentStore(path=db_path, table_name="docs", vector_dim=3)
998
+ assert store.count() == 2
999
+ assert store.get_document("c2") is not None
1000
+
1001
+
1002
+ def test_build_rag_database_requires_exactly_one_input(tmp_path, rag_corpus):
1003
+ from talkpipe.pipelines import vector_databases as vdb
1004
+
1005
+ with pytest.raises(ValueError, match="exactly one"):
1006
+ vdb.build_rag_database(None, path=str(tmp_path / "db"))
1007
+ with pytest.raises(ValueError, match="exactly one"):
1008
+ vdb.build_rag_database(rag_corpus, path=str(tmp_path / "db"), chunks=[])
1009
+
1010
+
969
1011
  def test_make_vector_database_passes_on_token_overflow(monkeypatch, tmp_path):
970
1012
  from talkpipe.pipelines import vector_databases as vdb
971
1013
 
@@ -529,6 +529,20 @@ def test_configure_logging_files_only(tmp_path):
529
529
  assert "files-only debug message" not in contents
530
530
 
531
531
 
532
+ def test_configure_logging_prints_each_record_once(capsys):
533
+ """``configure_logger("name:LEVEL")`` gives the named logger its own
534
+ console handler; the record used to propagate to the root handler that
535
+ ``basicConfig`` installed as well, so every line appeared twice."""
536
+ try:
537
+ talkpipe.util.config.configure_logger("talkpipe.test.once:INFO")
538
+ logger = logging.getLogger("talkpipe.test.once")
539
+ logger.info("printed exactly once")
540
+ captured = capsys.readouterr()
541
+ assert captured.err.count("printed exactly once") == 1
542
+ finally:
543
+ logging.getLogger("talkpipe.test.once").propagate = True
544
+
545
+
532
546
  def test_talkpipe_logger_has_null_handler():
533
547
  import logging
534
548