TalkPipe 0.9.3__tar.gz → 0.9.4__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 (192) hide show
  1. {talkpipe-0.9.3 → talkpipe-0.9.4}/.github/workflows/ci-cd.yml +4 -4
  2. {talkpipe-0.9.3 → talkpipe-0.9.4}/CHANGELOG.md +38 -0
  3. {talkpipe-0.9.3 → talkpipe-0.9.4}/CLAUDE.md +2 -0
  4. {talkpipe-0.9.3 → talkpipe-0.9.4}/PKG-INFO +1 -1
  5. talkpipe-0.9.4/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.bat +2 -0
  6. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.script +10 -7
  7. talkpipe-0.9.4/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.sh +2 -0
  8. talkpipe-0.9.4/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.bat +2 -0
  9. talkpipe-0.9.4/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.bat +2 -0
  10. talkpipe-0.9.4/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.bat +2 -0
  11. talkpipe-0.9.4/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.bat +2 -0
  12. talkpipe-0.9.4/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.bat +2 -0
  13. talkpipe-0.9.4/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.bat +2 -0
  14. talkpipe-0.9.4/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.bat +2 -0
  15. talkpipe-0.9.4/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.bat +2 -0
  16. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/chatterlang_serve.py +26 -22
  17. talkpipe-0.9.4/src/talkpipe/app/static/unit-docs.html +1 -0
  18. talkpipe-0.9.4/src/talkpipe/app/static/unit-docs.txt +1 -0
  19. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/chatterlang/compiler.py +12 -2
  20. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/chatterlang/parsers.py +5 -4
  21. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/extraction.py +15 -13
  22. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/chat.py +6 -1
  23. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/config.py +0 -2
  24. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/embedding_adapters.py +9 -3
  25. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/prompt_adapters.py +22 -5
  26. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/operations/matrices.py +2 -0
  27. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/basic.py +13 -38
  28. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/io.py +84 -11
  29. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/config.py +30 -20
  30. talkpipe-0.9.4/src/talkpipe/util/constants.py +3 -0
  31. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/data_manipulation.py +2 -5
  32. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/PKG-INFO +1 -1
  33. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/SOURCES.txt +11 -0
  34. talkpipe-0.9.4/stories.json +50 -0
  35. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/app/test_chatterlang_script.py +33 -4
  36. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/app/test_chatterlang_serve.py +59 -16
  37. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/chatterlang/test_compiler.py +16 -0
  38. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/chatterlang/test_parsers.py +7 -1
  39. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/llm/test_chat.py +23 -0
  40. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/pipe/test_io.py +109 -3
  41. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_util.py +18 -13
  42. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/test_security_vulnerabilities.py +5 -5
  43. talkpipe-0.9.3/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.sh +0 -2
  44. talkpipe-0.9.3/src/talkpipe/app/static/unit-docs.html +0 -1
  45. talkpipe-0.9.3/src/talkpipe/app/static/unit-docs.txt +0 -1
  46. {talkpipe-0.9.3 → talkpipe-0.9.4}/.bandit +0 -0
  47. {talkpipe-0.9.3 → talkpipe-0.9.4}/.dockerignore +0 -0
  48. {talkpipe-0.9.3 → talkpipe-0.9.4}/.github/CICD.md +0 -0
  49. {talkpipe-0.9.3 → talkpipe-0.9.4}/.github/ISSUE_TEMPLATE/release-checklist.md +0 -0
  50. {talkpipe-0.9.3 → talkpipe-0.9.4}/.github/SECURITY.md +0 -0
  51. {talkpipe-0.9.3 → talkpipe-0.9.4}/.github/dependabot.yml +0 -0
  52. {talkpipe-0.9.3 → talkpipe-0.9.4}/.gitignore +0 -0
  53. {talkpipe-0.9.3 → talkpipe-0.9.4}/.safety-project.ini +0 -0
  54. {talkpipe-0.9.3 → talkpipe-0.9.4}/.vscode/settings.json +0 -0
  55. {talkpipe-0.9.3 → talkpipe-0.9.4}/.vscode/tasks.json +0 -0
  56. {talkpipe-0.9.3 → talkpipe-0.9.4}/COPYRIGHT +0 -0
  57. {talkpipe-0.9.3 → talkpipe-0.9.4}/Dockerfile +0 -0
  58. {talkpipe-0.9.3 → talkpipe-0.9.4}/LICENSE +0 -0
  59. {talkpipe-0.9.3 → talkpipe-0.9.4}/README.md +0 -0
  60. {talkpipe-0.9.3 → talkpipe-0.9.4}/bin/config-analyzer.py +0 -0
  61. {talkpipe-0.9.3 → talkpipe-0.9.4}/bin/config_bash +0 -0
  62. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/.gitignore +0 -0
  63. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/LLMChat.png +0 -0
  64. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/LLMEvaluateWebPage.png +0 -0
  65. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/README.md +0 -0
  66. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/TalkPipe.png +0 -0
  67. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/TalkPipe.xcf +0 -0
  68. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/README.md +0 -0
  69. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/chatterlang-script.md +0 -0
  70. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/chatterlang-server.md +0 -0
  71. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/chatterlang-workbench.md +0 -0
  72. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/talkpipe-plugin-manager.md +0 -0
  73. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/api-reference/talkpipe-ref.md +0 -0
  74. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/README.md +0 -0
  75. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/chatterlang.md +0 -0
  76. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/configuration.md +0 -0
  77. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/extending-talkpipe.md +0 -0
  78. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/pipe-api.md +0 -0
  79. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/architecture/streaming.md +0 -0
  80. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/make_structure_diagram.sh +0 -0
  81. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/quickstart.md +0 -0
  82. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/structure.tex +0 -0
  83. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/talkpipe_diagram.png +0 -0
  84. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/.gitignore +0 -0
  85. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/README.md +0 -0
  86. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/README.md +0 -0
  87. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.script +0 -0
  88. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.sh +0 -0
  89. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.script +0 -0
  90. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.sh +0 -0
  91. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/stories.json +0 -0
  92. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_1-Document_Indexing/story_search_ui.yml +0 -0
  93. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/README.md +0 -0
  94. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.script +0 -0
  95. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.sh +0 -0
  96. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.script +0 -0
  97. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.sh +0 -0
  98. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.script +0 -0
  99. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.sh +0 -0
  100. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/step_3_extras.py +0 -0
  101. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/story_by_example_ui.yml +0 -0
  102. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/README.md +0 -0
  103. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.script +0 -0
  104. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.sh +0 -0
  105. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.script +0 -0
  106. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.sh +0 -0
  107. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.script +0 -0
  108. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.sh +0 -0
  109. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/file_structure.md +0 -0
  110. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/multi_format_ui.yml +0 -0
  111. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/report_topic_ui.yml +0 -0
  112. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/step3_extras.py +0 -0
  113. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/step_1_extras.py +0 -0
  114. {talkpipe-0.9.3 → talkpipe-0.9.4}/docs/tutorials/Tutorial_3_Report_Writing/step_2_extras.py +0 -0
  115. {talkpipe-0.9.3 → talkpipe-0.9.4}/pyproject.toml +0 -0
  116. {talkpipe-0.9.3 → talkpipe-0.9.4}/pytest.ini +0 -0
  117. {talkpipe-0.9.3 → talkpipe-0.9.4}/setup.cfg +0 -0
  118. {talkpipe-0.9.3 → talkpipe-0.9.4}/setup.py +0 -0
  119. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/__init__.py +0 -0
  120. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/__init__.py +0 -0
  121. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/chatterlang_reference_browser.py +0 -0
  122. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/chatterlang_reference_generator.py +0 -0
  123. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/chatterlang_script.py +0 -0
  124. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/chatterlang_workbench.py +0 -0
  125. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/static/.gitignore +0 -0
  126. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/static/favicon.ico +0 -0
  127. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/app/talkpipe_plugin_manager.py +0 -0
  128. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/chatterlang/__init__.py +0 -0
  129. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/chatterlang/registry.py +0 -0
  130. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/__init__.py +0 -0
  131. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/email.py +0 -0
  132. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/html.py +0 -0
  133. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/mongo.py +0 -0
  134. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/data/rss.py +0 -0
  135. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/__init__.py +0 -0
  136. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/llm/embedding.py +0 -0
  137. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/operations/__init__.py +0 -0
  138. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/operations/filtering.py +0 -0
  139. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/operations/thread_ops.py +0 -0
  140. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/operations/transforms.py +0 -0
  141. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/__init__.py +0 -0
  142. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/core.py +0 -0
  143. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/fork.py +0 -0
  144. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/pipe/math.py +0 -0
  145. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/search/abstract.py +0 -0
  146. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/search/lancedb.py +0 -0
  147. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/search/simplevectordb.py +0 -0
  148. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/search/whoosh.py +0 -0
  149. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/__init__.py +0 -0
  150. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/collections.py +0 -0
  151. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/doc_extraction.py +0 -0
  152. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/os.py +0 -0
  153. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe/util/plugin_loader.py +0 -0
  154. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/dependency_links.txt +0 -0
  155. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/entry_points.txt +0 -0
  156. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/requires.txt +0 -0
  157. {talkpipe-0.9.3 → talkpipe-0.9.4}/src/talkpipe.egg-info/top_level.txt +0 -0
  158. {talkpipe-0.9.3 → talkpipe-0.9.4}/test-workflow.yml +0 -0
  159. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/conftest.py +0 -0
  160. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/app/test_chatterlang_reference_browser.py +0 -0
  161. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/app/test_chatterlang_reference_generator.py +0 -0
  162. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/app/test_talkpipe_plugin_manager.py +0 -0
  163. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/chatterlang/test_chatterlang_workbench.py +0 -0
  164. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/sample_feed.pkl +0 -0
  165. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test.docx +0 -0
  166. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_email.py +0 -0
  167. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_extraction.py +0 -0
  168. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_html.py +0 -0
  169. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_html_exceptions.py +0 -0
  170. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_mogomock.py +0 -0
  171. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_mongo.py +0 -0
  172. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_mongo_integration.py +0 -0
  173. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/data/test_rss.py +0 -0
  174. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/llm/test_embedding.py +0 -0
  175. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/operations/test_filtering.py +0 -0
  176. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/operations/test_matrices.py +0 -0
  177. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/operations/test_threading.py +0 -0
  178. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/operations/test_transforms.py +0 -0
  179. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/pipe/test_basic.py +0 -0
  180. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/pipe/test_core.py +0 -0
  181. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/pipe/test_fork.py +0 -0
  182. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/pipe/test_math.py +0 -0
  183. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/search/test_lancedb.py +0 -0
  184. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/search/test_simplevectordb.py +0 -0
  185. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/search/test_whoosh.py +0 -0
  186. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/test_documentation_examples.py +0 -0
  187. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_collections.py +0 -0
  188. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_config.py +0 -0
  189. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_data_manipulation.py +0 -0
  190. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_doc_extraction.py +0 -0
  191. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/talkpipe/util/test_plugin_loader.py +0 -0
  192. {talkpipe-0.9.3 → talkpipe-0.9.4}/tests/testutils.py +0 -0
@@ -148,7 +148,7 @@ jobs:
148
148
  output: 'trivy-results.sarif'
149
149
 
150
150
  - name: Upload Trivy scan results to GitHub Security tab
151
- uses: github/codeql-action/upload-sarif@v3
151
+ uses: github/codeql-action/upload-sarif@v4
152
152
  if: always()
153
153
  with:
154
154
  sarif_file: 'trivy-results.sarif'
@@ -171,15 +171,15 @@ jobs:
171
171
  uses: actions/checkout@v5
172
172
 
173
173
  - name: Initialize CodeQL
174
- uses: github/codeql-action/init@v3
174
+ uses: github/codeql-action/init@v4
175
175
  with:
176
176
  languages: ${{ matrix.language }}
177
177
 
178
178
  - name: Autobuild
179
- uses: github/codeql-action/autobuild@v3
179
+ uses: github/codeql-action/autobuild@v4
180
180
 
181
181
  - name: Perform CodeQL Analysis
182
- uses: github/codeql-action/analyze@v3
182
+ uses: github/codeql-action/analyze@v4
183
183
 
184
184
  publish-package:
185
185
  runs-on: ubuntu-latest
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.4
4
+ ### Improvements
5
+ - Changes several logging statements to make the consistent with the rest of the code
6
+ - Refactored **lambda** to use AbstractFieldSegment for consistency
7
+ - Removed fail_on_error parameter in **lambda** and **lambdaFilter**. This is an API breaking change.
8
+ The segments will now always fail on an error and there is no option to silently fail.
9
+ - Changed chatterlang_serve so that it raises and exception an exits if given a script that can't be
10
+ compiled. The previous behavior was that it would issue a log message and fall back to the default
11
+ script.
12
+ - Added unit test for parse_unknown_args and expanded it to support boolean flag parameters
13
+ - Marked UMAP as deprecated. It will be removed in 1.0. It requires additional dependencies that no
14
+ other core modules need.
15
+ - Updated the ollama embedding and chat connector so that it uses the OLLAMA_SERVER_URL configuration
16
+ variable as the host where ollama is installed. So OLLAMA_SERVER_URL can be set in the TOML configuration
17
+ file or TALKPIPE_OLLAMA_SERVER_URL can be set as an environment variable.
18
+ - Implemented better compile errors for when sources or segments are not found. It had been a key error.
19
+ It will now be a compile error.
20
+ - Added batch files for the tutorials so it is easier to run them on Windows
21
+ - Enhanced **prompt** source to catch downstream pipeline errors and continue prompting instead of
22
+ crashing. When a user enters invalid input that causes an exception in downstream segments, the error
23
+ is displayed with a full traceback, and the prompt continues accepting input. This makes interactive
24
+ pipelines more robust and user-friendly. The error-resilient behavior is enabled by default but can
25
+ be disabled by setting `error_resilient=False`.
26
+ - Updated **chatterlang_serve** to support API key configuration via the configuration system. When
27
+ `--api-key` is not specified on the command line, it will check for `API_KEY` in the configuration,
28
+ which automatically checks the `TALKPIPE_API_KEY` environment variable. This makes it easier to
29
+ deploy chatterlang_serve in Docker and CI/CD environments without exposing API keys in command history.
30
+ - Added support for single-quoted strings in ChatterLang scripts. Single quotes work identically to
31
+ double quotes, including support for escaping quotes by doubling them (`''` → `'`). This provides
32
+ more flexibility when writing scripts, especially when the string content contains double quotes.
33
+ - Enhanced **echo** source with an `n` parameter to repeat the output data multiple times. For example,
34
+ `echo[data='a,b', n=3]` will emit: a, b, a, b, a, b. This is useful for testing pipelines and
35
+ generating repeated test data.
36
+ - Improved **chatterlang_serve** startup output to clearly distinguish between the user interface URL
37
+ and the API endpoint URL. The server now displays a formatted message showing both URLs with clear
38
+ labels when it starts.
39
+ - Updated tutorial 1, step 1 to show more feedback to the user so it doesn't just seem to be hanging
40
+
3
41
  ## 0.9.3
4
42
  ### Improvements
5
43
  - Updated tutorials to use lancedb.
@@ -16,6 +16,8 @@ ChatterLang is an external DSL and is defined under talkpipe/chatterlang
16
16
  Other packages in the project other than util include implementations of pipe sources and segments
17
17
  Util contains various generally usable utility functions, expecially for basic data manipulation and configuration.
18
18
  talkpipe/README.md contains a longer overview
19
+ After making a change, update CHANGELOG.md
20
+ When making a change, write a unit test that fails without the change, verify that the unit test fails, make the change and then verity that the unit test now passes. Notify the user if it is not reasonable to write the unit test.
19
21
 
20
22
  ## Important Commands
21
23
  python -m build for creating a new release
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: talkpipe
3
- Version: 0.9.3
3
+ Version: 0.9.4
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>
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_script --script Step_1_CreateSyntheticData.script
@@ -17,10 +17,13 @@
17
17
  # 6. The output is redirected to a file named "stories.json".
18
18
  ###################################################################################
19
19
 
20
- LOOP 50 TIMES {
21
- INPUT FROM "Write a fictitious five sentence story about technology development in an imaginary country."
22
- | llmPrompt[source="ollama", model="llama3.2", multi_turn=False]
23
- | toDict[field_list="_:content"]
24
- | llmPrompt[source="ollama", model="llama3.2", system_prompt="Write exactly one title for this story in plain text with no markdown", field="content", set_as="title", multi_turn=False]
25
- | dumpsJsonl | print;
26
- }
20
+
21
+ INPUT FROM "Generating 50 synthetic stories into stories.json" | print;
22
+ INPUT FROM echo[data="Write a fictitious five sentence story about technology development in an imaginary country.", n=50]
23
+ | llmPrompt[source="ollama", model="llama3.2", multi_turn=False]
24
+ | toDict[field_list="_:content"]
25
+ | llmPrompt[source="ollama", model="llama3.2", system_prompt="Write exactly one title for this story in plain text with no markdown", field="content", set_as="title", multi_turn=False]
26
+ | progressTicks[tick_count=1, eol_count=10, print_count=true]
27
+ | dumpsJsonl
28
+ | writeString[fname="stories.json"];
29
+
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ chatterlang_script --script Step_1_CreateSyntheticData.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_script --script Step_2_IndexStories.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config story_search_ui.yml --title "Story Search" --display-property query --script Step_3_SearchStories.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_script --script Step_1_CreateVectorDatabase.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config story_by_example_ui.yml --display-property example --script Step_2_SearchByExample.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config story_by_example_ui.yml --load-module step_3_extras.py --display-property example --script Step_3_SpecializedRag.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config report_topic_ui.yml --load-module step_1_extras.py --display-property topic --script Step_1_ExecutiveSummaryGeneration.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config report_topic_ui.yml --load-module step_2_extras.py --display-property topic --script Step_2_DetailedAnalysisReportGeneration.script
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ chatterlang_serve --form-config multi_format_ui.yml --load-module step3_extras.py --display-property topic --script Step_3_MultiFormatReportGeneration.script
@@ -51,16 +51,10 @@ class UserSession:
51
51
 
52
52
  def compile_script(self, script_content: str):
53
53
  """Compile a Chatterlang script for this session"""
54
- try:
55
- from talkpipe.chatterlang import compile as chatterlang_compile
56
-
57
- # Compile script - configuration values are accessible via $key syntax
58
- self.compiled_script = chatterlang_compile(script_content)
59
- self.compiled_script = self.compiled_script.as_function(single_in=True, single_out=False)
60
- logger.info(f"Session {self.session_id}: Script compiled successfully")
61
- except Exception as e:
62
- logger.error(f"Session {self.session_id}: Error compiling script: {e}")
63
- self.compiled_script = None
54
+ # Compile script - configuration values are accessible via $key syntax
55
+ self.compiled_script = compile(script_content)
56
+ self.compiled_script = self.compiled_script.as_function(single_in=True, single_out=False)
57
+ logger.info(f"Session {self.session_id}: Script compiled successfully")
64
58
 
65
59
  def add_to_history(self, entry: dict):
66
60
  """Add entry to session history"""
@@ -1652,16 +1646,21 @@ class ChatterlangServer:
1652
1646
 
1653
1647
  def start(self, background: bool = False):
1654
1648
  """Start the FastAPI server"""
1655
- logger.info(f"Starting JSON Data Receiver on http://{self.host}:{self.port}")
1656
- logger.info(f"Main interface: http://{self.host}:{self.port}/")
1657
- logger.info(f"Streaming interface: http://{self.host}:{self.port}/stream")
1658
- logger.info(f"API documentation: http://{self.host}:{self.port}/docs")
1649
+ print(f"\n{'='*60}")
1650
+ print(f"ChatterLang Server Started")
1651
+ print(f"{'='*60}")
1652
+ print(f"User Interface: http://{self.host}:{self.port}/stream")
1653
+ print(f"API Endpoint: http://{self.host}:{self.port}/process")
1654
+ print(f"API Documentation: http://{self.host}:{self.port}/docs")
1659
1655
  if self.require_auth:
1660
- logger.info(f"Port {self.port}: API key authentication: ENABLED")
1661
-
1662
- processor_name = self.processor_function.__name__
1656
+ print(f"Authentication: ENABLED (API key required)")
1657
+ print(f"{'='*60}\n")
1658
+
1659
+ # Also log for debugging purposes
1660
+ logger.info(f"Starting JSON Data Receiver on http://{self.host}:{self.port}")
1661
+ processor_name = self.processor_function.__name__
1663
1662
  logger.info(f"Port {self.port}: Using processor function: {processor_name}")
1664
-
1663
+
1665
1664
  if background:
1666
1665
  self.server_thread = threading.Thread(
1667
1666
  target=lambda: uvicorn.run(self.app, host=self.host, port=self.port),
@@ -1794,19 +1793,24 @@ def go():
1794
1793
  help='Property of the input json to display in the stream interface as user input.')
1795
1794
 
1796
1795
  args, unknown_args = parser.parse_known_args()
1797
-
1796
+
1798
1797
  # Parse unknown arguments and add to configuration so they're accessible via $key syntax
1799
1798
  constants = parse_unknown_args(unknown_args)
1800
-
1799
+
1801
1800
  # Add command-line constants to the configuration
1802
1801
  if constants:
1803
1802
  add_config_values(constants, override=True)
1804
1803
  print(f"Added command-line values to configuration: {list(constants.keys())}")
1805
-
1804
+
1806
1805
  if args.load_module:
1807
1806
  for module_file in args.load_module:
1808
1807
  load_module_file(fname=module_file, fail_on_missing=False)
1809
1808
 
1809
+ # Get API key from command line, or fall back to configuration (which checks environment variable)
1810
+ api_key = args.api_key
1811
+ if api_key is None:
1812
+ api_key = get_config().get('API_KEY')
1813
+
1810
1814
  script_content = None
1811
1815
  if args.script:
1812
1816
  script_content = load_script(args.script)
@@ -1829,7 +1833,7 @@ def go():
1829
1833
  receiver = ChatterlangServer(
1830
1834
  host=args.host,
1831
1835
  port=args.port,
1832
- api_key=args.api_key,
1836
+ api_key=api_key,
1833
1837
  require_auth=args.require_auth,
1834
1838
  title=args.title,
1835
1839
  form_config=form_config,
@@ -0,0 +1 @@
1
+ Documentation generation failed: Command '['/tmp/build-env-6ktuidus/bin/python', 'src/talkpipe/app/chatterlang_reference_generator.py', 'src', 'src/talkpipe/app/static/unit-docs.html', 'src/talkpipe/app/static/unit-docs.txt']' returned non-zero exit status 1.
@@ -0,0 +1 @@
1
+ Documentation generation failed: Command '['/tmp/build-env-6ktuidus/bin/python', 'src/talkpipe/app/chatterlang_reference_generator.py', 'src', 'src/talkpipe/app/static/unit-docs.html', 'src/talkpipe/app/static/unit-docs.txt']' returned non-zero exit status 1.
@@ -16,6 +16,10 @@ from talkpipe.pipe import io
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
+ class CompileError(Exception):
20
+ """ Exception raised when a compilation error occurs in chatterlang """
21
+ pass
22
+
19
23
  @singledispatch
20
24
  def compile(script: ParsedScript, runtime: RuntimeComponent = None) -> Callable:
21
25
  """ Compile a parsed script into a callable function
@@ -58,7 +62,10 @@ def _(pipeline: ParsedPipeline, runtime: RuntimeComponent) -> Pipeline:
58
62
  ans = VariableSource(pipeline.input_node.source.name)
59
63
  logger.debug(f"Created variable source with name {pipeline.input_node.source.name}")
60
64
  else:
61
- ans = registry.input_registry.get(pipeline.input_node.source.name)(**_resolve_params(pipeline.input_node.params, runtime=runtime))
65
+ try:
66
+ ans = registry.input_registry.get(pipeline.input_node.source.name)(**_resolve_params(pipeline.input_node.params, runtime=runtime))
67
+ except KeyError:
68
+ raise CompileError(f"Source '{pipeline.input_node.source.name}' not found")
62
69
  logger.debug(f"Created registered input {pipeline.input_node.source.name}")
63
70
  ans.runtime = runtime
64
71
 
@@ -68,7 +75,10 @@ def _(pipeline: ParsedPipeline, runtime: RuntimeComponent) -> Pipeline:
68
75
  next_transform = VariableSetSegment(transform.name)
69
76
  logger.debug(f"Created variable set segment for {transform.name}")
70
77
  elif isinstance(transform, SegmentNode):
71
- next_transform = registry.segment_registry.get(transform.operation.name)(**_resolve_params(transform.params, runtime=runtime))
78
+ try:
79
+ next_transform = registry.segment_registry.get(transform.operation.name)(**_resolve_params(transform.params, runtime=runtime))
80
+ except KeyError:
81
+ raise CompileError(f"Segment '{transform.operation.name}' not found")
72
82
  logger.debug(f"Created segment {transform.operation.name}")
73
83
  elif isinstance(transform, ForkNode):
74
84
  next_transform = compile(transform, runtime)
@@ -133,11 +133,12 @@ identifier = regex(r'[a-zA-Z][a-zA-Z0-9_]*').map(lambda s: Identifier(name=s))
133
133
  variable = (string('@') >> identifier).map(lambda x: x).map(lambda x: VariableName(name=x.name))
134
134
  """A parser for variable names. Variables are used to store and retrieve data in the pipeline."""
135
135
  environmentVariable = (string('$') >> identifier).map(lambda x: get_config()[x.name])
136
- # quoted_string = regex(r'"[^"]*"').map(lambda s: s[1:-1])
137
- quoted_string = regex(r'"(?:[^"]|"")*"').map(
138
- lambda s: s[1:-1].replace('""', '"')
136
+ # quoted_string supports both double and single quotes with escaping
137
+ quoted_string = (
138
+ regex(r'"(?:[^"]|"")*"').map(lambda s: s[1:-1].replace('""', '"'))
139
+ | regex(r"'(?:[^']|'')*'").map(lambda s: s[1:-1].replace("''", "'"))
139
140
  )
140
- """A parser for quoted strings."""
141
+ """A parser for quoted strings. Supports both double quotes ("...") and single quotes ('...')."""
141
142
  number = regex(r'-?\d+(\.\d+)?').map(lambda s: int(s) if '.' not in s else float(s))
142
143
  """A parser for numbers. Returns both ints and floats."""
143
144
 
@@ -10,6 +10,8 @@ from pathlib import Path
10
10
  import glob
11
11
  import os
12
12
 
13
+ logger = logging.getLogger(__name__)
14
+
13
15
  @register_segment("readtxt")
14
16
  @field_segment()
15
17
  def readtxt(file_path: Annotated[str, "Path to the text file to read"]):
@@ -30,15 +32,15 @@ def readtxt(file_path: Annotated[str, "Path to the text file to read"]):
30
32
  p = Path(file_path)
31
33
 
32
34
  if not p.exists():
33
- logging.error(f"Path does not exist: {file_path}")
35
+ logger.error(f"Path does not exist: {file_path}")
34
36
  raise FileNotFoundError(f"Path does not exist: {file_path}")
35
37
 
36
38
  if p.is_file():
37
- logging.info(f"Reading text file: {p}")
39
+ logger.debug(f"Reading text file: {p}")
38
40
  with p.open("r") as file:
39
41
  return file.read()
40
42
  else:
41
- logging.error(f"Unsupported path type: {file_path}")
43
+ logger.error(f"Unsupported path type: {file_path}")
42
44
  raise FileNotFoundError(f"Unsupported path type: {file_path}")
43
45
 
44
46
  @register_segment("readdocx")
@@ -60,18 +62,18 @@ def readdocx(file_path: Annotated[str, "Path to the .docx file to read"]):
60
62
  p = Path(file_path)
61
63
 
62
64
  if not p.exists():
63
- logging.error(f"Path does not exist: {file_path}")
65
+ logger.error(f"Path does not exist: {file_path}")
64
66
  raise FileNotFoundError(f"Path does not exist: {file_path}")
65
67
 
66
68
  if p.is_file():
67
- logging.info(f"Reading docx file: {p}")
69
+ logger.info(f"Reading docx file: {p}")
68
70
  doc = Document(p)
69
71
  full_text = []
70
72
  for para in doc.paragraphs:
71
73
  full_text.append(para.text)
72
74
  return " ".join(full_text)
73
75
  else:
74
- logging.error(f"Unsupported path type: {file_path}")
76
+ logger.error(f"Unsupported path type: {file_path}")
75
77
  raise FileNotFoundError(f"Unsupported path type: {file_path}")
76
78
 
77
79
  @register_segment("listFiles")
@@ -93,8 +95,8 @@ def listFiles(patterns: Annotated[Iterable[str], "Iterable of file patterns or p
93
95
  path = Path(expanded_pattern)
94
96
  if path.is_dir() and not any(char in expanded_pattern for char in ['*', '?', '[']):
95
97
  expanded_pattern = os.path.join(expanded_pattern, '*')
96
-
97
- logging.info(f"Searching for files matching pattern: {expanded_pattern}")
98
+
99
+ logger.info(f"Searching for files matching pattern: {expanded_pattern}")
98
100
  matches = glob.glob(expanded_pattern, recursive=True)
99
101
 
100
102
  for match in sorted(matches):
@@ -105,7 +107,7 @@ def listFiles(patterns: Annotated[Iterable[str], "Iterable of file patterns or p
105
107
  else:
106
108
  yield path.name
107
109
  else:
108
- logging.debug(f"Skipping non-file: {match}")
110
+ logger.debug(f"Skipping non-file: {match}")
109
111
 
110
112
  @register_segment("readFile")
111
113
  class ReadFile(AbstractFieldSegment):
@@ -128,21 +130,21 @@ class ReadFile(AbstractFieldSegment):
128
130
 
129
131
  def __init__(self, field: str = None, set_as: str = None):
130
132
  super().__init__(field=field, set_as=set_as)
131
- logging.debug("Initializing FileExtractor")
133
+ logger.debug("Initializing FileExtractor")
132
134
  self._extractors = {}
133
135
  self.register_extractor("txt", readtxt())
134
136
  self.register_extractor("md", readtxt())
135
137
  self.register_extractor("docx", readdocx())
136
138
 
137
139
  def register_extractor(self, file_extension:str, extractor):
138
- logging.debug(f"Registering extractor for extension: {file_extension}")
140
+ logger.debug(f"Registering extractor for extension: {file_extension}")
139
141
  self._extractors[file_extension] = extractor
140
142
 
141
143
  def process_value(self, file_path:Union[str, PosixPath]):
142
144
  file_extension = file_path.split(".")[-1] if isinstance(file_path, str) else file_path.suffix[1:]
143
145
  if file_extension not in self._extractors:
144
- logging.error(f"Unsupported file extension: {file_extension}")
146
+ logger.error(f"Unsupported file extension: {file_extension}")
145
147
  raise Exception(f"File extension {file_extension} not supported")
146
- logging.debug(f"Extracting content from file: {file_path}")
148
+ logger.debug(f"Extracting content from file: {file_path}")
147
149
  return next(self._extractors[file_extension]([file_path]))
148
150
 
@@ -9,7 +9,7 @@ from abc import ABC, abstractmethod
9
9
  import logging
10
10
  from pydantic import BaseModel
11
11
 
12
- from talkpipe.llm.config import TALKPIPE_MODEL_NAME, TALKPIPE_SOURCE
12
+ from talkpipe.util.constants import TALKPIPE_MODEL_NAME, TALKPIPE_SOURCE
13
13
  from talkpipe.util.data_manipulation import extract_property
14
14
 
15
15
 
@@ -31,6 +31,11 @@ class LLMPrompt(AbstractSegment):
31
31
  and TALKPIPE_default_source). If those are not set, the values will be loaded
32
32
  from the configuration file (~/.talkpipe.toml). If none of those are set, an
33
33
  error will be raised.
34
+
35
+ Currently supported sources are "ollama," "openai," and "anthropic." If
36
+ you specify "ollama," you can optionally set the OLLAMA_SERVER_URL environment
37
+ variable or configuration value to point to a different server. By default,
38
+ ollama assumes localhost.
34
39
  """
35
40
 
36
41
  def __init__(
@@ -34,5 +34,3 @@ def getEmbeddingSources()->List[str]:
34
34
  return list(_embeddingAdapter.keys())
35
35
 
36
36
 
37
- TALKPIPE_MODEL_NAME = "default_model_name"
38
- TALKPIPE_SOURCE = "default_model_source"
@@ -1,6 +1,7 @@
1
1
  from typing import List
2
-
3
2
  import numpy as np
3
+ from talkpipe.util.config import get_config
4
+ from talkpipe.util.constants import OLLAMA_SERVER_URL
4
5
 
5
6
  class AbstractEmbeddingAdapter:
6
7
  """Abstract class for embedding text.
@@ -44,8 +45,9 @@ class AbstractEmbeddingAdapter:
44
45
  class OllamaEmbedderAdapter(AbstractEmbeddingAdapter):
45
46
  """Embedding adapter for Ollama"""
46
47
 
47
- def __init__(self, model: str):
48
+ def __init__(self, model: str, server_url: str = None):
48
49
  super().__init__(model, "ollama")
50
+ self._server_url = server_url
49
51
 
50
52
  def execute(self, text: str) -> List[float]:
51
53
  try:
@@ -55,7 +57,11 @@ class OllamaEmbedderAdapter(AbstractEmbeddingAdapter):
55
57
  "Ollama is not installed. Please install it with: pip install talkpipe[ollama]"
56
58
  )
57
59
 
58
- response = ollama.embed(
60
+ server_url = self._server_url
61
+ if not server_url:
62
+ server_url = get_config().get(OLLAMA_SERVER_URL, None)
63
+ client = ollama.Client(server_url) if server_url else ollama
64
+ response = client.embed(
59
65
  model=self.model_name,
60
66
  input=text
61
67
  )
@@ -1,8 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+ import logging
1
3
  import json
2
4
  from pydantic import BaseModel
3
- import logging
4
-
5
- from abc import ABC, abstractmethod
5
+ from talkpipe.util.config import get_config
6
+ from talkpipe.util.constants import OLLAMA_SERVER_URL
6
7
 
7
8
  logger = logging.getLogger(__name__)
8
9
 
@@ -73,13 +74,25 @@ class AbstractLLMPromptAdapter(ABC):
73
74
  class OllamaPromptAdapter(AbstractLLMPromptAdapter):
74
75
  """Prompt adapter for Ollama
75
76
 
77
+ Note: By default, ollama assumes localhost for the ollama server.
78
+ If your server is running elsewhere, you can set the OLLAMA_SERVER_URL
79
+ environment variable or in the configuration, or pass the server_url
80
+ parameter.
81
+
76
82
  """
77
83
 
78
- def __init__(self, model: str, system_prompt: str = "You are a helpful assistant.", multi_turn: bool = True, temperature: float = None, output_format: BaseModel = None):
84
+ def __init__(self,
85
+ model: str,
86
+ system_prompt: str = "You are a helpful assistant.",
87
+ multi_turn: bool = True,
88
+ temperature: float = None,
89
+ output_format: BaseModel = None,
90
+ server_url: str = None):
79
91
  super().__init__(model, "ollama", system_prompt, multi_turn, temperature, output_format)
80
92
  # Ollama uses 0.5 as default when temperature is not specified
81
93
  if self._temperature is None:
82
94
  self._temperature = 0.5
95
+ self._server_url = server_url
83
96
 
84
97
  def execute(self, prompt: str) -> str:
85
98
  """Execute the chat model.
@@ -97,7 +110,11 @@ class OllamaPromptAdapter(AbstractLLMPromptAdapter):
97
110
  self._messages.append({"role": "user", "content": prompt})
98
111
 
99
112
  logger.debug(f"Sending chat request to Ollama model {self._model_name}")
100
- response = ollama.chat(
113
+ server_url = self._server_url
114
+ if not server_url:
115
+ server_url = get_config().get(OLLAMA_SERVER_URL, None)
116
+ client = ollama.Client(server_url) if server_url else ollama
117
+ response = client.chat(
101
118
  self._model_name,
102
119
  messages=[self._system_message] + self._messages,
103
120
  format=self._output_format.model_json_schema() if self._output_format else None,
@@ -1,3 +1,4 @@
1
+ from deprecated import deprecated
1
2
  from typing import Optional, Annotated
2
3
  import numpy as np
3
4
  import umap
@@ -5,6 +6,7 @@ from sklearn.manifold import TSNE
5
6
  from talkpipe import register_segment, AbstractSegment
6
7
 
7
8
  @register_segment("reduceUMAP")
9
+ @deprecated(reason="This segment is deprecated and will be removed in version 1.0.")
8
10
  class ReduceUMAP(AbstractSegment):
9
11
  """Use UMAP to reduce dimensionality of provided matrix.
10
12
 
@@ -13,7 +13,7 @@ from talkpipe.util.data_manipulation import extract_property, extract_template_f
13
13
  from talkpipe.util.data_manipulation import compileLambda
14
14
  from talkpipe.util.os import run_command
15
15
  from talkpipe.util.data_manipulation import get_type_safely
16
- from talkpipe.pipe.core import AbstractSegment, source, segment, field_segment
16
+ from talkpipe.pipe.core import AbstractSegment, AbstractFieldSegment, source, segment, field_segment
17
17
  import talkpipe.chatterlang.registry as registry
18
18
  from talkpipe.util.data_manipulation import fill_template, dict_to_text, toDict
19
19
 
@@ -635,57 +635,34 @@ def fillTemplate(item,
635
635
  return fill_template(template, values)
636
636
 
637
637
  @registry.register_segment("lambda")
638
- class EvalExpression(AbstractSegment):
638
+ class EvalExpression(AbstractFieldSegment):
639
639
  """Evaluate a Python expression on each item in the input stream.
640
640
 
641
641
  This segment pre-compiles the expression during initialization for efficiency
642
642
  and then applies it to each item during transformation. Expressions are evaluated
643
643
  in a restricted environment for security.
644
644
 
645
- The item is available in expressions as 'item'. If the item is a dictionary,
646
- its fields can be accessed directly as variables in the expression.
647
-
645
+ The item is available in expressions as 'item'.
648
646
  """
649
647
 
650
648
  def __init__(self,
651
649
  expression: Annotated[str, "The Python expression to evaluate"],
652
650
  field: Annotated[Optional[str], "If provided, extract this field from each item before evaluating"] = "_",
653
- set_as: Annotated[Optional[str], "If provided, append the result to each item under this field name"] = None,
654
- fail_on_error: Annotated[bool, "If True, raises exceptions when evaluation fails. If False, logs errors and returns None"] = True):
651
+ set_as: Annotated[Optional[str], "If provided, append the result to each item under this field name"] = None):
655
652
  super().__init__()
656
653
  self.expression = expression
657
654
  self.field = field
658
655
  self.set_as = set_as
659
- self.fail_on_error = fail_on_error
660
656
 
661
657
  # Compile the expression into a lambda function
662
- self.lambda_function = compileLambda(expression, fail_on_error)
658
+ self.lambda_function = compileLambda(expression)
663
659
 
664
- def transform(self, input_iter: Iterable[Any]) -> Iterator[Any]:
665
- """Process each item from the input stream."""
666
- for item in input_iter:
667
- logger.debug(f"Processing input item: {item}")
668
-
669
- # Extract field value if specified
670
- if self.field is not None:
671
- value = extract_property(item, self.field)
672
- logger.debug(f"Extracted value from field {self.field}: {value}")
673
- else:
674
- value = item
675
- logger.debug(f"Using item directly: {value}")
676
-
677
- # Evaluate the expression on the value
678
- result = self.lambda_function(value)
679
- logger.debug(f"Evaluation result: {result}")
680
-
681
- # Handle the result according to set_as
682
- if self.set_as is not None and hasattr(item, '__setitem__'):
683
- logger.debug(f"Appending result to field {self.set_as}")
684
- item[self.set_as] = result
685
- yield item
686
- else:
687
- logger.debug("Yielding result directly")
688
- yield result
660
+ def process_value(self, value):
661
+ try:
662
+ return self.lambda_function(value)
663
+ except Exception as e:
664
+ logger.error(f"Error evaluating expression '{self.expression}' on value '{value}': {e}")
665
+ raise
689
666
 
690
667
  @registry.register_segment("lambdaFilter")
691
668
  class FilterExpression(AbstractSegment):
@@ -702,15 +679,13 @@ class FilterExpression(AbstractSegment):
702
679
 
703
680
  def __init__(self,
704
681
  expression: Annotated[str, "The Python expression to evaluate"],
705
- field: Annotated[Optional[str], "If provided, extract this field from each item before evaluating"] = "_",
706
- fail_on_error: Annotated[bool, "If True, raises exceptions when evaluation fails. If False, logs errors and returns None"] = True):
682
+ field: Annotated[Optional[str], "If provided, extract this field from each item before evaluating"] = "_"):
707
683
  super().__init__()
708
684
  self.expression = expression
709
685
  self.field = field
710
- self.fail_on_error = fail_on_error
711
686
 
712
687
  # Compile the expression into a lambda function
713
- self.lambda_function = compileLambda(expression, fail_on_error)
688
+ self.lambda_function = compileLambda(expression)
714
689
  logger.debug(f"Compiled filter expression: {self.expression}")
715
690
 
716
691
  def transform(self, input_iter: Iterable[Any]) -> Iterator[Any]: