TalkPipe 0.14.2__tar.gz → 1.0.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.
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/update-entry-points/scripts/update_entry_points.py +35 -5
- talkpipe-1.0.0/.gitea/default_merge_message/MERGE_TEMPLATE.md +1 -0
- talkpipe-1.0.0/.gitea/default_merge_message/SQUASH_TEMPLATE.md +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/CICD.md +33 -15
- talkpipe-1.0.0/.github/workflows/ci-cd.yml +375 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.gitignore +3 -0
- talkpipe-1.0.0/.pre-commit-config.yaml +20 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.safety-policy.yml +6 -2
- {talkpipe-0.14.2 → talkpipe-1.0.0}/AGENTS.md +2 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/CHANGELOG.md +387 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/Dockerfile +13 -4
- {talkpipe-0.14.2/src/talkpipe.egg-info → talkpipe-1.0.0}/PKG-INFO +100 -33
- talkpipe-0.14.2/PKG-INFO → talkpipe-1.0.0/README.md +69 -69
- talkpipe-1.0.0/RELEASING.md +55 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/README.md +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/README.md +5 -5
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/chatterlang-server.md +13 -2
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/chatterlang-workbench.md +20 -4
- talkpipe-1.0.0/docs/api-reference/lazy-loading.md +85 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/configuration.md +57 -17
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/protocol.md +3 -1
- talkpipe-1.0.0/docs/architecture/security.md +186 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/contributing/developer-handbook.md +98 -1
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/guides/container-images.md +5 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/guides/model-and-source-configuration.md +2 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/quickstart.md +2 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/step_3_extras.py +14 -10
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/step_1_extras.py +19 -18
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/step_2_extras.py +49 -42
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/step_3_extras.py +30 -33
- talkpipe-1.0.0/pyproject.toml +354 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/pytest.ini +2 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/scripts/extract_documentation_examples.py +1 -1
- talkpipe-1.0.0/src/talkpipe/__init__.py +60 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/chatterlang_generate_entry_points.py +120 -116
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/chatterlang_reference_browser.py +135 -96
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/chatterlang_reference_generator.py +125 -79
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/chatterlang_script.py +52 -19
- talkpipe-1.0.0/src/talkpipe/app/chatterlang_serve.py +1054 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/chatterlang_workbench.py +339 -158
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/doc_examples.py +94 -16
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/makevectordatabase.py +115 -30
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/precache_model2vec.py +5 -1
- talkpipe-1.0.0/src/talkpipe/app/server_common.py +148 -0
- talkpipe-1.0.0/src/talkpipe/app/serverag.py +270 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/common.js +54 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/index.css +238 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/index.js +87 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/stream.css +473 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/stream.js +215 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/vendor/LICENSES.txt +257 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/vendor/marked.min.js +69 -0
- talkpipe-1.0.0/src/talkpipe/app/static/serve/vendor/purify.min.js +3 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/index.html +28 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/talkpipe_plugin_manager.py +28 -16
- talkpipe-1.0.0/src/talkpipe/app/templates/chatterlang_serve/index.html +53 -0
- talkpipe-1.0.0/src/talkpipe/app/templates/chatterlang_serve/stream.html +47 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/corpus.py +60 -21
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/reference_api.py +215 -105
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/suggest.py +286 -139
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/suggest_api.py +29 -21
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/workspace.py +43 -27
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/workspace_api.py +32 -25
- talkpipe-1.0.0/src/talkpipe/chatterlang/__init__.py +4 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/chatterlang/compiler.py +276 -141
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/chatterlang/parsers.py +194 -130
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/chatterlang/registry.py +262 -200
- talkpipe-1.0.0/src/talkpipe/data/__init__.py +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/email.py +262 -151
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/extraction.py +180 -119
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/html.py +156 -88
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/image.py +16 -11
- talkpipe-1.0.0/src/talkpipe/data/mongo.py +334 -0
- talkpipe-1.0.0/src/talkpipe/data/rss.py +173 -0
- talkpipe-1.0.0/src/talkpipe/data/text/__init__.py +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/text/chunking_units.py +50 -22
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/text/cleaning.py +5 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/text/englishnormalize.py +12 -7
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/data/text/operations.py +34 -16
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/__init__.py +2 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/chat.py +165 -82
- talkpipe-1.0.0/src/talkpipe/llm/config.py +61 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/content.py +9 -8
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/embedding.py +63 -37
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/embedding_adapters.py +38 -27
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/embedding_adapters_model2vec.py +4 -4
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/embedding_adapters_openai.py +11 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/model2vec_embeddings.py +15 -14
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/multimodal.py +10 -7
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapter_base.py +65 -32
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapter_memory.py +99 -19
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapters.py +3 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapters_anthropic.py +51 -20
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapters_eliza.py +70 -34
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapters_ollama.py +40 -20
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/prompt_adapters_openai.py +42 -22
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/vision.py +42 -19
- talkpipe-1.0.0/src/talkpipe/operations/__init__.py +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/operations/filtering.py +37 -23
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/operations/matrices.py +35 -22
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/operations/thread_ops.py +75 -33
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/operations/transforms.py +67 -24
- talkpipe-1.0.0/src/talkpipe/pipe/__init__.py +3 -0
- talkpipe-1.0.0/src/talkpipe/pipe/basic.py +130 -0
- talkpipe-1.0.0/src/talkpipe/pipe/collect.py +43 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/pipe/core.py +396 -245
- talkpipe-1.0.0/src/talkpipe/pipe/debug.py +214 -0
- talkpipe-1.0.0/src/talkpipe/pipe/fields.py +467 -0
- talkpipe-1.0.0/src/talkpipe/pipe/filters.py +263 -0
- talkpipe-1.0.0/src/talkpipe/pipe/flow.py +162 -0
- talkpipe-1.0.0/src/talkpipe/pipe/fork.py +203 -0
- talkpipe-1.0.0/src/talkpipe/pipe/hashing.py +152 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/pipe/io.py +177 -98
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/pipe/math.py +61 -30
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/pipe/metadata.py +33 -23
- talkpipe-1.0.0/src/talkpipe/pipe/shell.py +31 -0
- talkpipe-1.0.0/src/talkpipe/pipelines/__init__.py +1 -0
- talkpipe-1.0.0/src/talkpipe/pipelines/basic_rag.py +605 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/pipelines/vector_databases.py +175 -113
- talkpipe-1.0.0/src/talkpipe/py.typed +0 -0
- talkpipe-1.0.0/src/talkpipe/search/__init__.py +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/search/abstract.py +40 -20
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/search/lancedb.py +199 -105
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/search/whoosh.py +173 -97
- talkpipe-1.0.0/src/talkpipe/util/__init__.py +1 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/collections.py +140 -119
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/config.py +168 -84
- talkpipe-1.0.0/src/talkpipe/util/constants.py +84 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/data_manipulation.py +192 -80
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/doc_extraction.py +118 -98
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/iterators.py +29 -21
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/os.py +120 -65
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/util/plugin_loader.py +42 -36
- talkpipe-0.14.2/README.md → talkpipe-1.0.0/src/talkpipe.egg-info/PKG-INFO +136 -9
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe.egg-info/SOURCES.txt +42 -8
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe.egg-info/entry_points.txt +32 -31
- talkpipe-1.0.0/src/talkpipe.egg-info/requires.txt +51 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe.egg-info/scm_file_list.json +308 -272
- talkpipe-1.0.0/src/talkpipe.egg-info/scm_version.json +8 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/conftest.py +72 -39
- talkpipe-1.0.0/tests/embedding_adapter_contract_suite.py +53 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/prompt_adapter_contract_suite.py +12 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_chatterlang_generate_entry_points.py +46 -36
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_chatterlang_reference_browser.py +173 -135
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_chatterlang_reference_generator.py +120 -116
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_chatterlang_script.py +47 -37
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_chatterlang_serve.py +524 -368
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_makevectordatabase.py +1 -1
- talkpipe-1.0.0/tests/talkpipe/app/test_precache_model2vec.py +69 -0
- talkpipe-1.0.0/tests/talkpipe/app/test_serve_static.py +44 -0
- talkpipe-1.0.0/tests/talkpipe/app/test_server_common.py +112 -0
- talkpipe-1.0.0/tests/talkpipe/app/test_server_hardening.py +247 -0
- talkpipe-1.0.0/tests/talkpipe/app/test_serverag.py +272 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_talkpipe_plugin_manager.py +89 -82
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_corpus.py +17 -14
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_load_module.py +1 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_reference_api.py +86 -19
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_suggest.py +201 -84
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_workspace.py +23 -8
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/chatterlang/test_chatterlang_workbench.py +88 -14
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/chatterlang/test_compiler.py +178 -83
- talkpipe-1.0.0/tests/talkpipe/chatterlang/test_entry_point_drift.py +69 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/chatterlang/test_entry_points.py +4 -4
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/chatterlang/test_parsers.py +172 -104
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/chatterlang/test_registry.py +147 -75
- talkpipe-1.0.0/tests/talkpipe/data/test_email.py +441 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_extraction.py +89 -32
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_html.py +169 -105
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_html_exceptions.py +69 -54
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_image.py +6 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_mogomock.py +163 -132
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_mongo.py +89 -97
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test_mongo_integration.py +96 -80
- talkpipe-1.0.0/tests/talkpipe/data/test_mongo_timeouts.py +89 -0
- talkpipe-1.0.0/tests/talkpipe/data/test_rss.py +88 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/text/test_chunking_units.py +60 -14
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/text/test_cleaning.py +4 -2
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/text/test_operations.py +104 -99
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_chat.py +153 -48
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_content.py +4 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_embedding.py +15 -9
- talkpipe-1.0.0/tests/talkpipe/llm/test_embedding_adapters_contract.py +179 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_embedding_batch.py +31 -30
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_embedding_model2vec.py +12 -10
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_embedding_token_overflow.py +9 -3
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_multimodal.py +1 -1
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_anthropic.py +15 -7
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_base.py +81 -1
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_eliza.py +10 -5
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_memory.py +40 -13
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_ollama.py +41 -20
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_prompt_adapters_openai.py +10 -5
- talkpipe-1.0.0/tests/talkpipe/llm/test_timeouts.py +158 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_vision_adapters.py +10 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/operations/test_filtering.py +39 -4
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/operations/test_matrices.py +24 -21
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/operations/test_threading.py +79 -40
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/operations/test_transforms.py +44 -29
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipe/test_basic.py +238 -105
- talkpipe-1.0.0/tests/talkpipe/pipe/test_basic_split.py +119 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipe/test_core.py +35 -17
- talkpipe-1.0.0/tests/talkpipe/pipe/test_fork.py +122 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipe/test_io.py +213 -186
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipe/test_math.py +13 -6
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipe/test_metadata.py +35 -35
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipelines/test_basic_rag.py +327 -169
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/pipelines/test_vector_databases.py +194 -91
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/search/test_abstract.py +9 -27
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/search/test_lancedb.py +359 -142
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/search/test_lancedb_cache.py +29 -24
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/search/test_whoosh.py +220 -98
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/test_documentation_examples.py +61 -43
- talkpipe-1.0.0/tests/talkpipe/test_heavy_imports_are_lazy.py +31 -0
- talkpipe-1.0.0/tests/talkpipe/test_py_typed.py +7 -0
- talkpipe-1.0.0/tests/talkpipe/test_version.py +13 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_collections.py +166 -142
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_config.py +75 -63
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_data_manipulation.py +28 -33
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_doc_extraction.py +53 -49
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_iterators.py +4 -4
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_os.py +5 -5
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_plugin_loader.py +112 -111
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/util/test_util.py +228 -68
- talkpipe-1.0.0/tests/test_config_keys_documented.py +62 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/test_doc_examples.py +59 -12
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/test_security_vulnerabilities.py +126 -109
- talkpipe-1.0.0/tests/test_tutorial_scripts.py +64 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/testutils.py +32 -23
- {talkpipe-0.14.2 → talkpipe-1.0.0}/uv.lock +409 -358
- talkpipe-0.14.2/.bandit +0 -19
- talkpipe-0.14.2/.github/workflows/ci-cd.yml +0 -223
- talkpipe-0.14.2/bin/config-analyzer.py +0 -158
- talkpipe-0.14.2/bin/config_bash +0 -11
- talkpipe-0.14.2/docs/api-reference/lazy-loading.md +0 -577
- talkpipe-0.14.2/pyproject.toml +0 -230
- talkpipe-0.14.2/setup.py +0 -27
- talkpipe-0.14.2/src/talkpipe/__init__.py +0 -20
- talkpipe-0.14.2/src/talkpipe/app/chatterlang_serve.py +0 -2040
- talkpipe-0.14.2/src/talkpipe/app/serverag.py +0 -175
- talkpipe-0.14.2/src/talkpipe/app/static/.gitignore +0 -2
- talkpipe-0.14.2/src/talkpipe/app/static/unit-docs.html +0 -1
- talkpipe-0.14.2/src/talkpipe/app/static/unit-docs.txt +0 -1
- talkpipe-0.14.2/src/talkpipe/chatterlang/__init__.py +0 -2
- talkpipe-0.14.2/src/talkpipe/data/__init__.py +0 -1
- talkpipe-0.14.2/src/talkpipe/data/mongo.py +0 -281
- talkpipe-0.14.2/src/talkpipe/data/rss.py +0 -156
- talkpipe-0.14.2/src/talkpipe/llm/config.py +0 -41
- talkpipe-0.14.2/src/talkpipe/operations/__init__.py +0 -1
- talkpipe-0.14.2/src/talkpipe/pipe/__init__.py +0 -1
- talkpipe-0.14.2/src/talkpipe/pipe/basic.py +0 -1005
- talkpipe-0.14.2/src/talkpipe/pipe/fork.py +0 -129
- talkpipe-0.14.2/src/talkpipe/pipelines/__init__.py +0 -1
- talkpipe-0.14.2/src/talkpipe/pipelines/basic_rag.py +0 -398
- talkpipe-0.14.2/src/talkpipe/util/__init__.py +0 -1
- talkpipe-0.14.2/src/talkpipe/util/constants.py +0 -20
- talkpipe-0.14.2/src/talkpipe.egg-info/requires.txt +0 -51
- talkpipe-0.14.2/src/talkpipe.egg-info/scm_version.json +0 -8
- talkpipe-0.14.2/test-workflow.yml +0 -20
- talkpipe-0.14.2/tests/talkpipe/data/test_email.py +0 -265
- talkpipe-0.14.2/tests/talkpipe/data/test_rss.py +0 -43
- talkpipe-0.14.2/tests/talkpipe/pipe/test_fork.py +0 -67
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/changelog-update/SKILL.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/doc-example-formatting/SKILL.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/run-documentation-examples/SKILL.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/run-documentation-examples/scripts/run_documentation_examples.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/test-driven-development/SKILL.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/update-entry-points/SKILL.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.dockerignore +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/ISSUE_TEMPLATE/release-checklist.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/SECURITY.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/copilot-instructions.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/dependabot.yml +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/prompts/add-segment.prompt.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/prompts/changelog.prompt.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/prompts/doc-examples.prompt.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/prompts/tdd.prompt.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.github/prompts/update-entry-points.prompt.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.safety-project.ini +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.vscode/settings.json +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/.vscode/tasks.json +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/COPYRIGHT +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/LICENSE +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/.gitignore +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/LLMChat.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/LLMEvaluateWebPage.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/TalkPipe.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/TalkPipe.xcf +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/chatterlang-script.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/talkpipe-plugin-manager.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/api-reference/talkpipe-ref.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/chatterlang.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/documentation-formatting.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/extending-talkpipe.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/metadata-stream.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/pipe-api.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/architecture/streaming.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/guides/makevectordatabase-and-serverag.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/guides/model2vec-embeddings.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/make_structure_diagram.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/structure.tex +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/talkpipe_architecture.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/talkpipe_architecture.tex +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/talkpipe_diagram.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/.gitignore +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_1_CreateSyntheticData.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_2_IndexStories.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/Step_3_SearchStories.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/stories.json +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_1-Document_Indexing/story_search_ui.yml +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_1_CreateVectorDatabase.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_2_SearchByExample.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/Step_3_SpecializedRag.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_2-Search_by_Example_and_RAG/story_by_example_ui.yml +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_1_ExecutiveSummaryGeneration.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_2_DetailedAnalysisReportGeneration.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.bat +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/Step_3_MultiFormatReportGeneration.sh +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/file_structure.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/multi_format_ui.yml +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/tutorials/Tutorial_3_Report_Writing/report_topic_ui.yml +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/docs/workbench_demo.mp4 +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/.gitignore +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/build.mjs +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/package-lock.json +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/package.json +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/frontend/src/cm.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/setup.cfg +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/__init__.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/favicon.ico +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/talkpipe_logo.png +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/app.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/editor.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/styles.css +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/suggest.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/vendor/LICENSES.txt +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/vendor/codemirror.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/static/workbench/workspace.js +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench/__init__.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/README.md +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_1_createsyntheticdata.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_2_indexstories.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_1-document_indexing__step_3_searchstories.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_1_createvectordatabase.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_2_searchbyexample.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_2-search_by_example_and_rag__step_3_specializedrag.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_1_executivesummarygeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_2_detailedanalysisreportgeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/app/workbench_data/seed_scripts/tutorial_3_report_writing__step_3_multiformatreportgeneration.script +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe/llm/embedding_errors.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe.egg-info/dependency_links.txt +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/src/talkpipe.egg-info/top_level.txt +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/app/test_workbench_static.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/sample_feed.pkl +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/test.docx +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/data/text/test_englishnormalize.py +0 -0
- {talkpipe-0.14.2 → talkpipe-1.0.0}/tests/talkpipe/llm/test_vision.py +0 -0
{talkpipe-0.14.2 → talkpipe-1.0.0}/.cursor/skills/update-entry-points/scripts/update_entry_points.py
RENAMED
|
@@ -18,7 +18,7 @@ from pathlib import Path
|
|
|
18
18
|
_project_root = Path(__file__).resolve().parent.parent.parent.parent.parent
|
|
19
19
|
sys.path.insert(0, str(_project_root / "src"))
|
|
20
20
|
|
|
21
|
-
from talkpipe.app.chatterlang_generate_entry_points import (
|
|
21
|
+
from talkpipe.app.chatterlang_generate_entry_points import ( # noqa: E402
|
|
22
22
|
generate_toml_section,
|
|
23
23
|
scan_directory,
|
|
24
24
|
)
|
|
@@ -35,6 +35,22 @@ def _find_entry_points_start(content: str) -> int:
|
|
|
35
35
|
return -1
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def _find_entry_points_end(content: str, start: int) -> int:
|
|
39
|
+
"""Return the index just past the last talkpipe entry-point table.
|
|
40
|
+
|
|
41
|
+
The generated block covers the ``talkpipe.sources`` and ``talkpipe.segments``
|
|
42
|
+
tables only; whatever follows (``[tool.*]`` and so on) is preserved.
|
|
43
|
+
"""
|
|
44
|
+
pos = start
|
|
45
|
+
while True:
|
|
46
|
+
match = re.compile(r"^\[[^\]]+\]", re.MULTILINE).search(content, pos)
|
|
47
|
+
if match is None:
|
|
48
|
+
return len(content)
|
|
49
|
+
if not re.match(r'\[project\.entry-points\.["\']talkpipe\.', match.group(0)):
|
|
50
|
+
return match.start()
|
|
51
|
+
pos = match.end()
|
|
52
|
+
|
|
53
|
+
|
|
38
54
|
def update_pyproject(
|
|
39
55
|
pyproject_path: Path,
|
|
40
56
|
source_dir: Path,
|
|
@@ -59,20 +75,30 @@ def update_pyproject(
|
|
|
59
75
|
new_toml = generate_toml_section(results["sources"], results["segments"])
|
|
60
76
|
|
|
61
77
|
if not new_toml.strip():
|
|
62
|
-
print(
|
|
78
|
+
print(
|
|
79
|
+
"Warning: No entry points generated. Check that sources use @register_source/@register_segment.",
|
|
80
|
+
file=sys.stderr,
|
|
81
|
+
)
|
|
63
82
|
return False
|
|
64
83
|
|
|
65
84
|
content = pyproject_path.read_text(encoding="utf-8")
|
|
66
85
|
start = _find_entry_points_start(content)
|
|
67
86
|
|
|
68
87
|
if start < 0:
|
|
69
|
-
print(
|
|
88
|
+
print(
|
|
89
|
+
'Error: Could not find [project.entry-points."talkpipe.sources"] in pyproject.toml',
|
|
90
|
+
file=sys.stderr,
|
|
91
|
+
)
|
|
70
92
|
return False
|
|
71
93
|
|
|
94
|
+
end = _find_entry_points_end(content, start)
|
|
72
95
|
prefix = content[:start]
|
|
96
|
+
suffix = content[end:]
|
|
73
97
|
# Ensure generated section ends with newline; strip trailing blanks from prefix
|
|
74
98
|
new_section = new_toml.rstrip() + "\n"
|
|
75
99
|
new_content = prefix.rstrip() + "\n\n" + new_section
|
|
100
|
+
if suffix.strip():
|
|
101
|
+
new_content += "\n" + suffix.lstrip("\n")
|
|
76
102
|
|
|
77
103
|
if dry_run:
|
|
78
104
|
print("Generated entry points (dry-run, no file written):")
|
|
@@ -87,9 +113,13 @@ def update_pyproject(
|
|
|
87
113
|
|
|
88
114
|
if new_content != content:
|
|
89
115
|
pyproject_path.write_text(new_content, encoding="utf-8")
|
|
90
|
-
print(
|
|
116
|
+
print(
|
|
117
|
+
f"Updated {pyproject_path} with {len(results['sources'])} sources and {len(results['segments'])} segments."
|
|
118
|
+
)
|
|
91
119
|
else:
|
|
92
|
-
print(
|
|
120
|
+
print(
|
|
121
|
+
"No changes needed; pyproject.toml already matches generated entry points."
|
|
122
|
+
)
|
|
93
123
|
|
|
94
124
|
return True
|
|
95
125
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Merge branch '${HeadBranch}': ${PullRequestTitle}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
${PullRequestTitle}
|
|
@@ -8,16 +8,26 @@ This directory contains the GitHub Actions workflows and configuration for the T
|
|
|
8
8
|
|
|
9
9
|
#### `ci-cd.yml` - Main CI/CD Pipeline
|
|
10
10
|
Comprehensive pipeline that runs on:
|
|
11
|
-
- Pushes to `main` and `
|
|
12
|
-
- Pull requests
|
|
11
|
+
- Pushes to `main` and topic branches (`bugfix/**`, `feature/**`, `chore/**`)
|
|
12
|
+
- Pull requests targeting `main`
|
|
13
13
|
- GitHub releases
|
|
14
14
|
|
|
15
15
|
**Pipeline Jobs:**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
|
|
17
|
+
Host-neutral jobs run identically on GitHub Actions and on any other
|
|
18
|
+
Actions-compatible runner; jobs that need github.com are guarded with
|
|
19
|
+
`if: github.server_url == 'https://github.com'`.
|
|
20
|
+
|
|
21
|
+
| Job | Runs | What it does |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `test` | everywhere, matrix 3.11 / 3.12 / 3.13 | `pytest --cov=src`; the `[tool.coverage.report] fail_under` floor in `pyproject.toml` fails the job if coverage drops below it. Coverage is uploaded to Codecov from the 3.11 leg. |
|
|
24
|
+
| `lint` | everywhere, 3.11 | `ruff check`, `ruff format --check`, `mypy` — all gating, no advisory mode — plus an entry-point drift check (regenerates the `talkpipe.sources`/`talkpipe.segments` tables from the `@register_*` decorators and fails on any diff to `pyproject.toml`). |
|
|
25
|
+
| `package` | everywhere, 3.11 | Builds the sdist and wheel, `twine check`s them, installs the wheel into a clean venv, imports the package, runs `chatterlang_script --help`, and loads every declared entry point. Catches packaging breakage before release time. |
|
|
26
|
+
| `lockfile-check` | everywhere | `uv lock --check` — the committed `uv.lock` must match `pyproject.toml`. Installs nothing; CI installs with pip on purpose. |
|
|
27
|
+
| `security-scan` | everywhere; needs `test`, `lint` | Bandit (`-c pyproject.toml`, the `[tool.bandit]` table) and Safety. Uses the commercial database when `SAFETY_API_KEY` is set and falls back to the free `safety check` database when it is not (secrets are not passed to pull-request runs); both fail the build on a known vulnerability. |
|
|
28
|
+
| `build-container` | github.com only | Docker image build and Trivy scan on every run; pushes to ghcr.io **on releases only** (`latest` for stable releases, `experimental` for pre-releases); multi-architecture (linux/amd64, linux/arm64) on release only. |
|
|
29
|
+
| `codeql-analysis` | github.com only | GitHub's semantic code analysis. |
|
|
30
|
+
| `publish-package` | on a published release; needs `test`, `lint`, `package`, `security-scan` | `python -m build`, `twine check`, upload to PyPI. Does not depend on the container job, so publishing is not blocked where that job is skipped. |
|
|
21
31
|
|
|
22
32
|
### Configuration Files
|
|
23
33
|
|
|
@@ -26,7 +36,7 @@ Comprehensive pipeline that runs on:
|
|
|
26
36
|
|
|
27
37
|
### Root Level Security Files
|
|
28
38
|
|
|
29
|
-
-
|
|
39
|
+
- **`[tool.bandit]` in `pyproject.toml`** - Configuration for Bandit static security analysis
|
|
30
40
|
- **`.dockerignore`** - Optimized Docker build context exclusions
|
|
31
41
|
|
|
32
42
|
## Security Scanning
|
|
@@ -48,7 +58,7 @@ Docker images are built and pushed to GitHub Container Registry. On **release**,
|
|
|
48
58
|
Images are available at:
|
|
49
59
|
```
|
|
50
60
|
ghcr.io/sandialabs/talkpipe:latest
|
|
51
|
-
ghcr.io/sandialabs/talkpipe
|
|
61
|
+
ghcr.io/sandialabs/talkpipe:experimental
|
|
52
62
|
ghcr.io/sandialabs/talkpipe:<version>
|
|
53
63
|
```
|
|
54
64
|
|
|
@@ -90,11 +100,20 @@ To enable full functionality, set these secrets in your GitHub repository settin
|
|
|
90
100
|
Before pushing, you can test components locally:
|
|
91
101
|
|
|
92
102
|
```bash
|
|
93
|
-
# Run tests with coverage (matches CI)
|
|
94
|
-
pytest --cov=src --cov-report=xml --cov-report=html
|
|
103
|
+
# Run tests with coverage (matches CI; fails below the fail_under floor)
|
|
104
|
+
pytest --cov=src --cov-report=term --cov-report=xml --cov-report=html
|
|
105
|
+
|
|
106
|
+
# Lint / format / types (matches CI)
|
|
107
|
+
ruff check . && ruff format --check . && mypy
|
|
108
|
+
|
|
109
|
+
# Entry-point drift check (matches CI)
|
|
110
|
+
python .cursor/skills/update-entry-points/scripts/update_entry_points.py && git diff --exit-code -- pyproject.toml
|
|
111
|
+
|
|
112
|
+
# Packaging smoke test (matches CI)
|
|
113
|
+
python -m build && twine check dist/*
|
|
95
114
|
|
|
96
115
|
# Run security scans
|
|
97
|
-
bandit -r src/
|
|
116
|
+
bandit -c pyproject.toml -r src/
|
|
98
117
|
export SAFETY_API_KEY=your-key # optional; links results to Safety Platform
|
|
99
118
|
safety scan
|
|
100
119
|
|
|
@@ -110,10 +129,9 @@ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
|
|
110
129
|
|
|
111
130
|
| Event | Trigger | Jobs Run |
|
|
112
131
|
|-------|---------|----------|
|
|
113
|
-
| Push to main
|
|
132
|
+
| Push to main | Automatic | All jobs |
|
|
114
133
|
| Pull Request | Automatic | All except publish |
|
|
115
134
|
| Release published | Automatic | All jobs + PyPI publish |
|
|
116
|
-
| Manual trigger | `workflow_dispatch` | All jobs |
|
|
117
135
|
|
|
118
136
|
## Monitoring
|
|
119
137
|
|
|
@@ -144,6 +162,6 @@ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
|
|
144
162
|
4. **Security Scans Fail**:
|
|
145
163
|
- Review Bandit/Safety reports
|
|
146
164
|
- Update vulnerable dependencies
|
|
147
|
-
- Add exclusions to
|
|
165
|
+
- Add exclusions to `[tool.bandit]` in `pyproject.toml` if needed
|
|
148
166
|
|
|
149
167
|
For additional help, check the Actions tab logs or create an issue in the repository.
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
name: CI/CD Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, 'bugfix/**', 'feature/**', "chore/**" ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, 'bugfix/**', 'feature/**', "chore/**" ]
|
|
8
|
+
release:
|
|
9
|
+
types: [ published ]
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
REGISTRY: ghcr.io
|
|
13
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
28
|
+
uses: actions/setup-python@v7
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
|
|
32
|
+
- name: Cache pip dependencies
|
|
33
|
+
uses: actions/cache@v6
|
|
34
|
+
with:
|
|
35
|
+
path: ~/.cache/pip
|
|
36
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
|
|
37
|
+
restore-keys: |
|
|
38
|
+
${{ runner.os }}-pip-
|
|
39
|
+
|
|
40
|
+
- name: Install dependencies
|
|
41
|
+
run: |
|
|
42
|
+
# Install into a project venv rather than the interpreter itself. On a
|
|
43
|
+
# self-hosted runner /opt/hostedtoolcache is a volume shared by every
|
|
44
|
+
# job, so installing there leaks packages between repos.
|
|
45
|
+
python -m venv .venv
|
|
46
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
47
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
48
|
+
.venv/bin/pip install -e ".[dev,all]"
|
|
49
|
+
|
|
50
|
+
- name: Run tests with coverage
|
|
51
|
+
run: |
|
|
52
|
+
# --cov-report=term makes the [tool.coverage.report] fail_under floor
|
|
53
|
+
# in pyproject.toml fail this step; xml/html are for Codecov and
|
|
54
|
+
# local inspection.
|
|
55
|
+
pytest --cov=src --cov-report=term --cov-report=xml --cov-report=html
|
|
56
|
+
|
|
57
|
+
- name: Upload coverage to Codecov
|
|
58
|
+
if: matrix.python-version == '3.11'
|
|
59
|
+
uses: codecov/codecov-action@v7
|
|
60
|
+
with:
|
|
61
|
+
files: ./coverage.xml
|
|
62
|
+
flags: unittests
|
|
63
|
+
|
|
64
|
+
lint:
|
|
65
|
+
# Ruff (lint + format) and mypy gate the build; there is no advisory
|
|
66
|
+
# pass and nothing here may swallow a failure. Local equivalent:
|
|
67
|
+
# `pre-commit run --all-files`, or the three commands below.
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v7
|
|
72
|
+
|
|
73
|
+
- name: Set up Python
|
|
74
|
+
uses: actions/setup-python@v7
|
|
75
|
+
with:
|
|
76
|
+
python-version: '3.11'
|
|
77
|
+
|
|
78
|
+
- name: Install dependencies
|
|
79
|
+
run: |
|
|
80
|
+
# see the note on the test job's install step
|
|
81
|
+
python -m venv .venv
|
|
82
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
83
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
84
|
+
.venv/bin/pip install -e ".[dev,all]"
|
|
85
|
+
|
|
86
|
+
- name: Ruff lint
|
|
87
|
+
run: ruff check --output-format=github .
|
|
88
|
+
|
|
89
|
+
- name: Ruff format check
|
|
90
|
+
run: ruff format --check --diff .
|
|
91
|
+
|
|
92
|
+
- name: mypy
|
|
93
|
+
run: mypy
|
|
94
|
+
|
|
95
|
+
- name: Entry points match the registered sources and segments
|
|
96
|
+
run: |
|
|
97
|
+
# Regenerate the talkpipe.sources / talkpipe.segments tables from the
|
|
98
|
+
# @register_* decorators; any diff means a component was added or
|
|
99
|
+
# renamed without updating pyproject.toml (it would be invisible to
|
|
100
|
+
# name lookup until its module happened to be imported).
|
|
101
|
+
python .cursor/skills/update-entry-points/scripts/update_entry_points.py
|
|
102
|
+
git diff --exit-code -- pyproject.toml
|
|
103
|
+
|
|
104
|
+
package:
|
|
105
|
+
# Build the sdist and wheel the way a release would, then install the
|
|
106
|
+
# wheel into a clean venv and import/run it. Without this a broken
|
|
107
|
+
# wheel is only discovered by publish-package, at release time.
|
|
108
|
+
# Host-neutral: runs unchanged on any Actions-compatible runner.
|
|
109
|
+
runs-on: ubuntu-latest
|
|
110
|
+
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/checkout@v7
|
|
113
|
+
with:
|
|
114
|
+
fetch-depth: 0 # setuptools_scm derives the version from tags
|
|
115
|
+
|
|
116
|
+
- name: Set up Python
|
|
117
|
+
uses: actions/setup-python@v7
|
|
118
|
+
with:
|
|
119
|
+
python-version: '3.11'
|
|
120
|
+
|
|
121
|
+
- name: Build sdist and wheel
|
|
122
|
+
run: |
|
|
123
|
+
# see the note on the test job's install step
|
|
124
|
+
python -m venv .venv
|
|
125
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
126
|
+
.venv/bin/python -m pip install --upgrade pip
|
|
127
|
+
.venv/bin/pip install build twine
|
|
128
|
+
.venv/bin/python -m build
|
|
129
|
+
.venv/bin/twine check dist/*
|
|
130
|
+
|
|
131
|
+
- name: Install the wheel into a clean venv and smoke-test it
|
|
132
|
+
run: |
|
|
133
|
+
python -m venv .smoke
|
|
134
|
+
.smoke/bin/python -m pip install --upgrade pip
|
|
135
|
+
.smoke/bin/pip install dist/*.whl
|
|
136
|
+
# Import the package plus the two subpackages that ship without
|
|
137
|
+
# __init__.py history, and prove the version metadata resolves.
|
|
138
|
+
.smoke/bin/python -c "import talkpipe, talkpipe.search.lancedb, talkpipe.data.text.cleaning; print(talkpipe.__version__)"
|
|
139
|
+
.smoke/bin/chatterlang_script --help
|
|
140
|
+
# Every declared entry point must resolve in the installed wheel.
|
|
141
|
+
.smoke/bin/python - <<'PY'
|
|
142
|
+
from importlib.metadata import entry_points
|
|
143
|
+
bad = []
|
|
144
|
+
for group in ("talkpipe.sources", "talkpipe.segments"):
|
|
145
|
+
for ep in entry_points(group=group):
|
|
146
|
+
try:
|
|
147
|
+
ep.load()
|
|
148
|
+
except Exception as exc: # noqa: BLE001
|
|
149
|
+
bad.append(f"{group}:{ep.name} -> {exc!r}")
|
|
150
|
+
if bad:
|
|
151
|
+
raise SystemExit("unresolvable entry points:\n" + "\n".join(bad))
|
|
152
|
+
print("all entry points resolve")
|
|
153
|
+
PY
|
|
154
|
+
|
|
155
|
+
lockfile-check:
|
|
156
|
+
# uv.lock is a development convenience only -- CI installs with pip on
|
|
157
|
+
# purpose (see README, "Development environment"). This job installs
|
|
158
|
+
# nothing from the lock; it only fails when uv.lock has drifted out of
|
|
159
|
+
# sync with pyproject.toml, so the committed lock cannot go stale
|
|
160
|
+
# unnoticed.
|
|
161
|
+
runs-on: ubuntu-latest
|
|
162
|
+
|
|
163
|
+
steps:
|
|
164
|
+
- uses: actions/checkout@v7
|
|
165
|
+
|
|
166
|
+
- name: Install uv
|
|
167
|
+
uses: astral-sh/setup-uv@v7
|
|
168
|
+
|
|
169
|
+
- name: Check uv.lock is in sync with pyproject.toml
|
|
170
|
+
run: uv lock --check
|
|
171
|
+
|
|
172
|
+
security-scan:
|
|
173
|
+
runs-on: ubuntu-latest
|
|
174
|
+
needs: [test, lint]
|
|
175
|
+
env:
|
|
176
|
+
SAFETY_API_KEY: ${{ secrets.SAFETY_API_KEY }}
|
|
177
|
+
|
|
178
|
+
steps:
|
|
179
|
+
- uses: actions/checkout@v7
|
|
180
|
+
with:
|
|
181
|
+
fetch-depth: 0
|
|
182
|
+
|
|
183
|
+
- name: Set up Python
|
|
184
|
+
uses: actions/setup-python@v7
|
|
185
|
+
with:
|
|
186
|
+
python-version: '3.11'
|
|
187
|
+
|
|
188
|
+
- name: Install dependencies for security scan
|
|
189
|
+
run: |
|
|
190
|
+
# see the note on the test job's install step
|
|
191
|
+
python -m venv .venv
|
|
192
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
193
|
+
# `python -m venv` seeds the venv with whatever pip and setuptools the
|
|
194
|
+
# interpreter bundles, and safety scans the whole venv, so upgrade
|
|
195
|
+
# both: a stale bundled setuptools fails the scan on an advisory
|
|
196
|
+
# unrelated to anything this project declares or installs.
|
|
197
|
+
.venv/bin/python -m pip install --upgrade pip setuptools
|
|
198
|
+
.venv/bin/pip install -e ".[dev,all]"
|
|
199
|
+
.venv/bin/pip install bandit safety
|
|
200
|
+
|
|
201
|
+
- name: Run Bandit security scan
|
|
202
|
+
run: |
|
|
203
|
+
bandit -c pyproject.toml -r src/ -f json -o bandit-report.json
|
|
204
|
+
bandit -c pyproject.toml -r src/ -f txt
|
|
205
|
+
|
|
206
|
+
- name: Run Safety dependency scan
|
|
207
|
+
run: |
|
|
208
|
+
if [ -n "${SAFETY_API_KEY:-}" ]; then
|
|
209
|
+
# Authenticated: the commercial database, gated by .safety-policy.yml.
|
|
210
|
+
safety scan --save-as json safety-report.json
|
|
211
|
+
safety scan
|
|
212
|
+
else
|
|
213
|
+
# Repository secrets are not passed to pull-request runs, so the key
|
|
214
|
+
# is absent there and `safety scan` would only ask us to log in.
|
|
215
|
+
# Fall back to the free database rather than failing for lack of auth
|
|
216
|
+
# or, worse, passing without scanning anything. This still fails the
|
|
217
|
+
# build on a known vulnerability -- the database is just staler than
|
|
218
|
+
# the authenticated scan that gates pushes to main.
|
|
219
|
+
echo "SAFETY_API_KEY unavailable; falling back to 'safety check' (free database)."
|
|
220
|
+
# `check` is the legacy command and the only one that runs without an
|
|
221
|
+
# account. It rejects .safety-policy.yml because that file is v3.0 and
|
|
222
|
+
# only `scan` parses v3, so run it from a directory holding no policy
|
|
223
|
+
# file; it scans the installed environment either way.
|
|
224
|
+
report="$PWD/safety-report.json"
|
|
225
|
+
workdir="$(mktemp -d)"
|
|
226
|
+
(cd "$workdir" && safety check --save-json "$report")
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
- name: Upload security scan results
|
|
230
|
+
uses: actions/upload-artifact@v7
|
|
231
|
+
# upload-artifact v4+ refuses to run when the server isn't github.com
|
|
232
|
+
if: always() && github.server_url == 'https://github.com'
|
|
233
|
+
with:
|
|
234
|
+
name: security-reports
|
|
235
|
+
path: |
|
|
236
|
+
bandit-report.json
|
|
237
|
+
safety-report.json
|
|
238
|
+
|
|
239
|
+
build-container:
|
|
240
|
+
runs-on: ubuntu-latest
|
|
241
|
+
needs: [test, lint, security-scan]
|
|
242
|
+
# pushes to ghcr.io with a GitHub token; only available on github.com
|
|
243
|
+
if: github.server_url == 'https://github.com'
|
|
244
|
+
permissions:
|
|
245
|
+
contents: read
|
|
246
|
+
packages: write
|
|
247
|
+
security-events: write
|
|
248
|
+
|
|
249
|
+
steps:
|
|
250
|
+
- name: Checkout repository
|
|
251
|
+
uses: actions/checkout@v7
|
|
252
|
+
|
|
253
|
+
- name: Log in to Container Registry
|
|
254
|
+
uses: docker/login-action@v4
|
|
255
|
+
with:
|
|
256
|
+
registry: ${{ env.REGISTRY }}
|
|
257
|
+
username: ${{ github.actor }}
|
|
258
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
259
|
+
|
|
260
|
+
- name: Set up QEMU
|
|
261
|
+
if: github.event_name == 'release'
|
|
262
|
+
uses: docker/setup-qemu-action@v4
|
|
263
|
+
|
|
264
|
+
- name: Set up Docker Buildx
|
|
265
|
+
uses: docker/setup-buildx-action@v4
|
|
266
|
+
|
|
267
|
+
- name: Extract metadata
|
|
268
|
+
id: meta
|
|
269
|
+
uses: docker/metadata-action@v6
|
|
270
|
+
with:
|
|
271
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
272
|
+
tags: |
|
|
273
|
+
type=ref,event=branch
|
|
274
|
+
type=ref,event=pr
|
|
275
|
+
type=semver,pattern={{version}}
|
|
276
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
277
|
+
type=sha
|
|
278
|
+
type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
|
|
279
|
+
type=raw,value=experimental,enable=${{ github.event_name == 'release' && github.event.release.prerelease }}
|
|
280
|
+
|
|
281
|
+
- name: Build and push Docker image
|
|
282
|
+
uses: docker/build-push-action@v7
|
|
283
|
+
with:
|
|
284
|
+
context: .
|
|
285
|
+
platforms: ${{ github.event_name == 'release' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
|
|
286
|
+
# only releases publish images; other runs build (and Trivy-scan)
|
|
287
|
+
# without pushing, so `load` puts the image in the local daemon
|
|
288
|
+
push: ${{ github.event_name == 'release' }}
|
|
289
|
+
load: ${{ github.event_name != 'release' }}
|
|
290
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
291
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
292
|
+
cache-from: type=gha
|
|
293
|
+
cache-to: type=gha,mode=max
|
|
294
|
+
|
|
295
|
+
- name: Extract first tag for Trivy
|
|
296
|
+
id: first-tag
|
|
297
|
+
run: echo "tag=$(echo '${{ steps.meta.outputs.tags }}' | head -n1)" >> $GITHUB_OUTPUT
|
|
298
|
+
|
|
299
|
+
- name: Run container security scan with Trivy
|
|
300
|
+
uses: aquasecurity/trivy-action@master
|
|
301
|
+
with:
|
|
302
|
+
image-ref: ${{ steps.first-tag.outputs.tag }}
|
|
303
|
+
format: 'sarif'
|
|
304
|
+
output: 'trivy-results.sarif'
|
|
305
|
+
|
|
306
|
+
- name: Upload Trivy scan results to GitHub Security tab
|
|
307
|
+
uses: github/codeql-action/upload-sarif@v4
|
|
308
|
+
if: always()
|
|
309
|
+
with:
|
|
310
|
+
sarif_file: 'trivy-results.sarif'
|
|
311
|
+
|
|
312
|
+
codeql-analysis:
|
|
313
|
+
name: CodeQL Analysis
|
|
314
|
+
runs-on: ubuntu-latest
|
|
315
|
+
# needs GitHub's code-scanning API, only available on github.com
|
|
316
|
+
if: github.server_url == 'https://github.com'
|
|
317
|
+
permissions:
|
|
318
|
+
actions: read
|
|
319
|
+
contents: read
|
|
320
|
+
security-events: write
|
|
321
|
+
|
|
322
|
+
strategy:
|
|
323
|
+
fail-fast: false
|
|
324
|
+
matrix:
|
|
325
|
+
language: [ 'python' ]
|
|
326
|
+
|
|
327
|
+
steps:
|
|
328
|
+
- name: Checkout repository
|
|
329
|
+
uses: actions/checkout@v7
|
|
330
|
+
|
|
331
|
+
- name: Initialize CodeQL
|
|
332
|
+
uses: github/codeql-action/init@v4
|
|
333
|
+
with:
|
|
334
|
+
languages: ${{ matrix.language }}
|
|
335
|
+
|
|
336
|
+
- name: Autobuild
|
|
337
|
+
uses: github/codeql-action/autobuild@v4
|
|
338
|
+
|
|
339
|
+
- name: Perform CodeQL Analysis
|
|
340
|
+
uses: github/codeql-action/analyze@v4
|
|
341
|
+
|
|
342
|
+
publish-package:
|
|
343
|
+
runs-on: ubuntu-latest
|
|
344
|
+
# build-container is GitHub-only; listing it here would leave publishing
|
|
345
|
+
# blocked behind a skipped job everywhere else. The container image is
|
|
346
|
+
# published independently by that job on github.com.
|
|
347
|
+
needs: [test, lint, package, security-scan]
|
|
348
|
+
if: github.event_name == 'release' && github.event.action == 'published'
|
|
349
|
+
|
|
350
|
+
steps:
|
|
351
|
+
- uses: actions/checkout@v7
|
|
352
|
+
with:
|
|
353
|
+
fetch-depth: 0
|
|
354
|
+
|
|
355
|
+
- name: Set up Python
|
|
356
|
+
uses: actions/setup-python@v7
|
|
357
|
+
with:
|
|
358
|
+
python-version: '3.11'
|
|
359
|
+
|
|
360
|
+
- name: Install build dependencies
|
|
361
|
+
run: |
|
|
362
|
+
python -m pip install --upgrade pip
|
|
363
|
+
pip install build twine
|
|
364
|
+
|
|
365
|
+
- name: Build package
|
|
366
|
+
run: python -m build
|
|
367
|
+
|
|
368
|
+
- name: Check package
|
|
369
|
+
run: twine check dist/*
|
|
370
|
+
|
|
371
|
+
- name: Publish to PyPI
|
|
372
|
+
env:
|
|
373
|
+
TWINE_USERNAME: __token__
|
|
374
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
375
|
+
run: twine upload dist/*
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Opt-in desktop hooks mirroring the CI lint job: `pre-commit install` once
|
|
2
|
+
# per clone; `pre-commit run --all-files` reproduces the gate locally.
|
|
3
|
+
repos:
|
|
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
|
|
6
|
+
hooks:
|
|
7
|
+
- id: ruff-check
|
|
8
|
+
args: [--fix, --show-fixes]
|
|
9
|
+
- id: ruff-format
|
|
10
|
+
- repo: local
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
name: mypy
|
|
14
|
+
# The project venv's mypy (so versions match uv.lock): install and
|
|
15
|
+
# run pre-commit from inside it -- `uv run pre-commit ...` or an
|
|
16
|
+
# activated .venv -- so `mypy` resolves on PATH.
|
|
17
|
+
entry: mypy
|
|
18
|
+
language: system
|
|
19
|
+
types: [python]
|
|
20
|
+
pass_filenames: false
|
|
@@ -13,8 +13,12 @@ report:
|
|
|
13
13
|
enabled: true
|
|
14
14
|
auto-ignore-in-report:
|
|
15
15
|
python:
|
|
16
|
-
|
|
17
|
-
unpinned
|
|
16
|
+
# Both are deliberately false: findings against the installed
|
|
17
|
+
# environment and against unpinned declared requirements must show up
|
|
18
|
+
# in the report and fail the scan. Do not flip these back to true to
|
|
19
|
+
# get a red build green -- fix the requirement instead.
|
|
20
|
+
environment-results: false
|
|
21
|
+
unpinned-requirements: false
|
|
18
22
|
cvss-severity: []
|
|
19
23
|
|
|
20
24
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
## Dev environment tips
|
|
2
2
|
- When running code or pytest, use the .venv environment in the root of the project. Activate it with `source .venv/bin/activate` (or `source .venv/Scripts/activate` on Windows).
|
|
3
3
|
- If the .venv environment doesn't exist and you need to run code or tests, abort and ask the user to create the environment.
|
|
4
|
+
- Local development resolves against the committed `uv.lock` (`uv sync --all-extras`); CI installs with pip and ignores the lock on purpose, so it resolves the way `pip install talkpipe` does. See "Development environment" in [README.md](README.md). The lock is a dev convenience, not a security control — fix a vulnerable dependency by raising its floor in [pyproject.toml](pyproject.toml), and re-run `uv lock` after any dependency change so `uv lock --check` stays green in CI.
|
|
4
5
|
|
|
5
6
|
## Important Commands
|
|
6
7
|
- `python -m build` — create a new release
|
|
7
8
|
- `pytest --cov=src` — run unit tests with coverage
|
|
9
|
+
- `ruff check .`, `ruff format --check .`, `mypy` — the code-quality gate. **CI fails on any finding from these three**; run them before pushing. `ruff check --fix . && ruff format .` fixes most lint/format findings; the rule set and mypy config live in `pyproject.toml`. `pre-commit install` (opt-in, per clone) runs the same checks on every commit.
|
|
8
10
|
- `python .cursor/skills/update-entry-points/scripts/update_entry_points.py` — generate entry points from decorators and update pyproject.toml (preferred over chatterlang_generate_entry_points when updating pyproject.toml)
|
|
9
11
|
- `pytest tests/test_doc_examples.py -v` — run all doc examples as tests (requires full_network for LLM examples; skip with `-m "not requires_ollama"` when Ollama unavailable)
|
|
10
12
|
- `run_doc_examples` — extract and run all doc examples (alternative to pytest; requires full_network for LLM examples)
|