groundworkers 0.6.0__tar.gz → 0.7.1__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 (313) hide show
  1. groundworkers-0.7.1/.github/workflows/ci.yml +92 -0
  2. {groundworkers-0.6.0 → groundworkers-0.7.1}/.gitignore +2 -1
  3. {groundworkers-0.6.0 → groundworkers-0.7.1}/PKG-INFO +10 -9
  4. {groundworkers-0.6.0 → groundworkers-0.7.1}/README.md +1 -0
  5. {groundworkers-0.6.0 → groundworkers-0.7.1}/config/groundworkers.example.toml +6 -6
  6. groundworkers-0.7.1/docs/adapters/cdm.md +51 -0
  7. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/adapters/omop_emb.md +4 -4
  8. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/development/integration.md +5 -2
  9. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/development/plugins.md +21 -5
  10. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/index.md +1 -0
  11. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/embedding.md +10 -5
  12. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/usage/configuration.md +14 -5
  13. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/usage/setup_journey.md +4 -4
  14. groundworkers-0.7.1/docs/usage/testing.md +45 -0
  15. groundworkers-0.7.1/docs/usage/upgrading-from-0.6.md +31 -0
  16. {groundworkers-0.6.0 → groundworkers-0.7.1}/pyproject.toml +11 -8
  17. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/adapters/cdm.py +26 -5
  18. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/adapters/omop_emb.py +55 -28
  19. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/adapters/omop_graph.py +47 -21
  20. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/app.py +14 -9
  21. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/configuration.py +4 -26
  22. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/configuration_provider.py +122 -39
  23. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/databases.py +380 -294
  24. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_artifacts.py +7 -4
  25. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_coverage.py +4 -19
  26. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_population.py +32 -14
  27. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_registry.py +6 -6
  28. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_setup.py +6 -12
  29. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/graph_maintenance.py +3 -1
  30. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/models.py +11 -8
  31. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/performance_maintenance.py +45 -23
  32. groundworkers-0.7.1/src/groundworkers/base/domain_names.py +125 -0
  33. groundworkers-0.7.1/src/groundworkers/base/errors.py +144 -0
  34. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/base/sql.py +0 -25
  35. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/bootstrap.py +35 -19
  36. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/config.py +8 -34
  37. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/plugins.py +3 -1
  38. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/server.py +10 -2
  39. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/graph.py +24 -12
  40. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/assisted.py +5 -1
  41. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/vocab.py +22 -12
  42. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/transports/rest/api.py +5 -0
  43. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/pages/setup.py +6 -6
  44. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/overview.py +4 -3
  45. groundworkers-0.7.1/tests/conftest.py +114 -0
  46. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/integration/test_omop_emb_adapter.py +6 -4
  47. groundworkers-0.7.1/tests/integration/test_omop_emb_contract.py +147 -0
  48. groundworkers-0.7.1/tests/integration/test_omop_graph_adapter.py +356 -0
  49. groundworkers-0.7.1/tests/integration/test_omop_postgres_runtime.py +209 -0
  50. groundworkers-0.7.1/tests/support/embedding_contract_fixture.py +55 -0
  51. groundworkers-0.7.1/tests/support/omop.py +15 -0
  52. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/support/seed_postgres_fixture.py +31 -2
  53. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/support/stack_config.py +22 -14
  54. groundworkers-0.7.1/tests/support/wheel_smoke.py +93 -0
  55. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/test_bootstrap_config.py +96 -18
  56. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/test_rest_api.py +48 -0
  57. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/test_server_registry.py +3 -3
  58. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_configuration_provider.py +89 -12
  59. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_domain_names.py +37 -4
  60. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_migration_boundaries.py +14 -1
  61. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_normalized_index.py +102 -8
  62. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_omop_emb_adapter.py +20 -1
  63. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_omop_emb_setup_config.py +3 -3
  64. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_omop_graph_adapter.py +127 -18
  65. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_phase3_overview.py +1 -1
  66. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_plugin_configuration.py +5 -6
  67. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_plugins.py +49 -2
  68. groundworkers-0.7.1/tests/unit/test_required_integration_preflight.py +80 -0
  69. groundworkers-0.7.1/tests/unit/test_required_test_gate.py +16 -0
  70. groundworkers-0.7.1/tests/unit/test_schema_resolution.py +146 -0
  71. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_artifacts_and_coverage.py +5 -1
  72. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_configuration.py +2 -6
  73. groundworkers-0.7.1/tests/unit/test_setup_databases.py +508 -0
  74. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_embeddings.py +7 -7
  75. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_provider_conformance.py +3 -3
  76. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_runtime.py +1 -7
  77. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_truth.py +1 -1
  78. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_write_flows.py +7 -7
  79. groundworkers-0.7.1/tests/unit/test_source_planning_assisted_classifier.py +200 -0
  80. groundworkers-0.7.1/tests/unit/test_source_planning_document_formats.py +200 -0
  81. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_tools.py +36 -0
  82. groundworkers-0.7.1/tests/unit/test_split_classified_edges.py +96 -0
  83. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_tui_app.py +60 -11
  84. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_tui_state.py +4 -6
  85. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_vector_store_setup.py +101 -10
  86. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_vocab_service.py +14 -1
  87. {groundworkers-0.6.0 → groundworkers-0.7.1}/uv.lock +30 -29
  88. groundworkers-0.6.0/.github/workflows/ci.yml +0 -52
  89. groundworkers-0.6.0/docs/adapters/cdm.md +0 -53
  90. groundworkers-0.6.0/docs/usage/testing.md +0 -34
  91. groundworkers-0.6.0/src/groundworkers/base/domain_names.py +0 -78
  92. groundworkers-0.6.0/src/groundworkers/base/errors.py +0 -87
  93. groundworkers-0.6.0/tests/conftest.py +0 -33
  94. groundworkers-0.6.0/tests/integration/test_omop_graph_adapter.py +0 -435
  95. groundworkers-0.6.0/tests/unit/test_schema_resolution.py +0 -251
  96. groundworkers-0.6.0/tests/unit/test_setup_databases.py +0 -469
  97. {groundworkers-0.6.0 → groundworkers-0.7.1}/.githooks/pre-commit +0 -0
  98. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/CONTRIBUTING.md +0 -0
  99. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  100. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  101. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  102. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/ISSUE_TEMPLATE/not_working.yml +0 -0
  103. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  104. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/release-drafter.yml +0 -0
  105. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/workflows/docs.yml +0 -0
  106. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/workflows/merge.yml +0 -0
  107. {groundworkers-0.6.0 → groundworkers-0.7.1}/.github/workflows/publish.yml +0 -0
  108. {groundworkers-0.6.0 → groundworkers-0.7.1}/.python-version +0 -0
  109. {groundworkers-0.6.0 → groundworkers-0.7.1}/CHANGELOG.md +0 -0
  110. {groundworkers-0.6.0 → groundworkers-0.7.1}/Makefile +0 -0
  111. {groundworkers-0.6.0 → groundworkers-0.7.1}/config/docker-compose.yaml +0 -0
  112. {groundworkers-0.6.0 → groundworkers-0.7.1}/config/groundworkers_db.env +0 -0
  113. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/adapters/omop_graph.md +0 -0
  114. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/architecture.md +0 -0
  115. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/concepts.md +0 -0
  116. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/development/extending.md +0 -0
  117. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/from-scratch.md +0 -0
  118. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/js/mermaid-init.js +0 -0
  119. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/reference/ref_adapters.md +0 -0
  120. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/reference/ref_base.md +0 -0
  121. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/reference/ref_config.md +0 -0
  122. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/reference/ref_services.md +0 -0
  123. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/reference/ref_tools.md +0 -0
  124. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/domain.md +0 -0
  125. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/graph.md +0 -0
  126. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/grounding.md +0 -0
  127. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/mapping.md +0 -0
  128. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/semantic_projection.md +0 -0
  129. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/source_planning.md +0 -0
  130. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/text.md +0 -0
  131. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/services/vocab.md +0 -0
  132. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/01_create_config.png +0 -0
  133. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/02_empty_config.png +0 -0
  134. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/03_config_wizard.png +0 -0
  135. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/04_test_cnx.png +0 -0
  136. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/04_warnings.png +0 -0
  137. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/05_graph_setup.png +0 -0
  138. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/06_load_predicates.png +0 -0
  139. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/07_vector_store.png +0 -0
  140. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/08_register_embedding.png +0 -0
  141. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/static/10_setup_complete.png +0 -0
  142. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/concept.md +0 -0
  143. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/domain.md +0 -0
  144. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/knowledge.md +0 -0
  145. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/mapping.md +0 -0
  146. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/overview.md +0 -0
  147. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/resolver.md +0 -0
  148. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/search.md +0 -0
  149. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/semantic_projection.md +0 -0
  150. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/source_planning.md +0 -0
  151. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/system.md +0 -0
  152. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/tools/text.md +0 -0
  153. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/usage/installation.md +0 -0
  154. {groundworkers-0.6.0 → groundworkers-0.7.1}/docs/usage/integrations.md +0 -0
  155. {groundworkers-0.6.0 → groundworkers-0.7.1}/mkdocs.yaml +0 -0
  156. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/__init__.py +0 -0
  157. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/_env.py +0 -0
  158. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/adapters/__init__.py +0 -0
  159. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/adapters/llm.py +0 -0
  160. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/__init__.py +0 -0
  161. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/__init__.py +0 -0
  162. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_capability.py +0 -0
  163. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/embedding_reconciliation.py +0 -0
  164. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/integration.py +0 -0
  165. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/maintenance_runs.py +0 -0
  166. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/model_inventory.py +0 -0
  167. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/plugin_configuration.py +0 -0
  168. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/application/setup/runtime_setup.py +0 -0
  169. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/base/__init__.py +0 -0
  170. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/base/concept_payload.py +0 -0
  171. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/base/results.py +0 -0
  172. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/base/server.py +0 -0
  173. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/config/README +0 -0
  174. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/config/predicate_classification.csv +0 -0
  175. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/config/predicate_mapping.csv +0 -0
  176. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/criteria-gate-yesno/guidance.md +0 -0
  177. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/criteria-gate-yesno/manifest.yaml +0 -0
  178. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/diagnosis-role-modifier/guidance.md +0 -0
  179. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/diagnosis-role-modifier/manifest.yaml +0 -0
  180. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/domain-routing/guidance.md +0 -0
  181. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/domain-routing/manifest.yaml +0 -0
  182. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/domain-routing/rules.yaml +0 -0
  183. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/guidance.md +0 -0
  184. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/manifest.yaml +0 -0
  185. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/rules.yaml +0 -0
  186. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/history-of-event/guidance.md +0 -0
  187. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/history-of-event/manifest.yaml +0 -0
  188. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/standard-concept-preference/guidance.md +0 -0
  189. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/standard-concept-preference/manifest.yaml +0 -0
  190. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/knowledge/packs/core/standard-concept-preference/rules.yaml +0 -0
  191. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/__init__.py +0 -0
  192. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/domain.py +0 -0
  193. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/grounding.py +0 -0
  194. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/knowledge/__init__.py +0 -0
  195. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/knowledge/catalogue.py +0 -0
  196. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/knowledge/models.py +0 -0
  197. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/mapping.py +0 -0
  198. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/semantic_projection/__init__.py +0 -0
  199. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/semantic_projection/definitions.py +0 -0
  200. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/semantic_projection/models.py +0 -0
  201. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/semantic_projection/service.py +0 -0
  202. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/__init__.py +0 -0
  203. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/canonical_headers.py +0 -0
  204. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/classifier.py +0 -0
  205. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposer.py +0 -0
  206. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/__init__.py +0 -0
  207. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/csv_.py +0 -0
  208. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/ddl_.py +0 -0
  209. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/docx_.py +0 -0
  210. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/json_.py +0 -0
  211. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/pdf_.py +0 -0
  212. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/xlsx_.py +0 -0
  213. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/decomposers/xml_.py +0 -0
  214. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/detector.py +0 -0
  215. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/models.py +0 -0
  216. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/normalisation.py +0 -0
  217. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/provenance.py +0 -0
  218. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/router.py +0 -0
  219. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/serialisation.py +0 -0
  220. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/service.py +0 -0
  221. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/source_profiles/__init__.py +0 -0
  222. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/source_profiles/base.py +0 -0
  223. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/source_profiles/redcap.py +0 -0
  224. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/source_profiles/registry.py +0 -0
  225. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/source_planning/warnings.py +0 -0
  226. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/text/__init__.py +0 -0
  227. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/text/models.py +0 -0
  228. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/text/prompts.py +0 -0
  229. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/services/text/service.py +0 -0
  230. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/__init__.py +0 -0
  231. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/concept_tools.py +0 -0
  232. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/domain_tools.py +0 -0
  233. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/embedding_tools.py +0 -0
  234. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/knowledge_tools.py +0 -0
  235. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/mapping_tools.py +0 -0
  236. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/resolver_tools.py +0 -0
  237. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/search_tools.py +0 -0
  238. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/semantic_projection_tools.py +0 -0
  239. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/source_planning_tools.py +0 -0
  240. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/system_tools.py +0 -0
  241. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tools/text_tools.py +0 -0
  242. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/transports/__init__.py +0 -0
  243. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/transports/rest/__init__.py +0 -0
  244. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/transports/rest/models.py +0 -0
  245. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/__init__.py +0 -0
  246. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/app.py +0 -0
  247. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/pages/__init__.py +0 -0
  248. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/pages/base.py +0 -0
  249. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/pages/plugin_config.py +0 -0
  250. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/pages/plugin_setup.py +0 -0
  251. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/__init__.py +0 -0
  252. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/base.py +0 -0
  253. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/chat.py +0 -0
  254. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/configuration.py +0 -0
  255. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/database.py +0 -0
  256. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/embeddings.py +0 -0
  257. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/graph.py +0 -0
  258. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/llm_provider.py +0 -0
  259. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/performance.py +0 -0
  260. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/presenters/runs.py +0 -0
  261. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/routes.py +0 -0
  262. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/state.py +0 -0
  263. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/__init__.py +0 -0
  264. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/config_location.py +0 -0
  265. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/embedding_store.py +0 -0
  266. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/embeddings.py +0 -0
  267. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/graph_maintenance.py +0 -0
  268. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/performance_maintenance.py +0 -0
  269. {groundworkers-0.6.0 → groundworkers-0.7.1}/src/groundworkers/tui/wizards/plugin_setup.py +0 -0
  270. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/__init__.py +0 -0
  271. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/integration/__init__.py +0 -0
  272. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/support/__init__.py +0 -0
  273. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/support/postgres_ci_config.toml +0 -0
  274. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/__init__.py +0 -0
  275. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_concept_payload.py +0 -0
  276. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_concept_tools.py +0 -0
  277. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_config_location_wizard.py +0 -0
  278. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_domain_tools.py +0 -0
  279. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_embedding_population_scope.py +0 -0
  280. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_embedding_reconciliation.py +0 -0
  281. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_embedding_registry_step.py +0 -0
  282. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_embedding_tools.py +0 -0
  283. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_env_bootstrap.py +0 -0
  284. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_error_boundary.py +0 -0
  285. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_graph_maintenance.py +0 -0
  286. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_graph_maintenance_wizard.py +0 -0
  287. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_graph_service.py +0 -0
  288. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_graph_status.py +0 -0
  289. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_grounding_constraints.py +0 -0
  290. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_grounding_service.py +0 -0
  291. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_knowledge_catalogue.py +0 -0
  292. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_llm_adapter.py +0 -0
  293. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_maintenance_runs_phase2.py +0 -0
  294. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_mapping_context.py +0 -0
  295. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_mapping_service.py +0 -0
  296. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_mapping_tools.py +0 -0
  297. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_performance.py +0 -0
  298. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_performance_maintenance_wizard.py +0 -0
  299. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_provider_fields.py +0 -0
  300. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_semantic_projection_service.py +0 -0
  301. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_semantic_projection_tools.py +0 -0
  302. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_setup_configuration_section.py +0 -0
  303. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_classifier.py +0 -0
  304. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_decomposer.py +0 -0
  305. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_detector.py +0 -0
  306. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_models.py +0 -0
  307. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_normalisation.py +0 -0
  308. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_router.py +0 -0
  309. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_source_planning_service.py +0 -0
  310. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_stack_config_fixtures.py +0 -0
  311. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_system_tools.py +0 -0
  312. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_text_service.py +0 -0
  313. {groundworkers-0.6.0 → groundworkers-0.7.1}/tests/unit/test_text_tools.py +0 -0
@@ -0,0 +1,92 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ branches: [main]
5
+ types: [opened, synchronize, reopened, labeled, unlabeled]
6
+ jobs:
7
+ label-gate:
8
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/label-gate.yml@main
9
+ build-test:
10
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test.yml@main
11
+ build-test-postgres:
12
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-postgres.yml@main
13
+ with:
14
+ ty-src: src
15
+ postgres-image: pgvector/pgvector:pg18
16
+ postgres-db: test_db
17
+ postgres-user: postgres
18
+ postgres-password: postgres
19
+ setup-commands: |
20
+ mkdir -p "$RUNNER_TEMP/omop"
21
+ cp tests/support/postgres_ci_config.toml "$RUNNER_TEMP/omop/config.toml"
22
+ export OA_CONFIG_PATH="$RUNNER_TEMP/omop/config.toml"
23
+ export GROUNDWORKERS_CONFIG_PATH="$RUNNER_TEMP/omop/config.toml"
24
+ export GROUNDWORKERS_REQUIRE_INTEGRATION=1
25
+ export GROUNDWORKERS_TEST_DATABASE_URL="postgresql+psycopg://postgres:postgres@localhost:5432/test_db"
26
+ echo "OA_CONFIG_PATH=$RUNNER_TEMP/omop/config.toml" >> "$GITHUB_ENV"
27
+ echo "GROUNDWORKERS_CONFIG_PATH=$RUNNER_TEMP/omop/config.toml" >> "$GITHUB_ENV"
28
+ echo "GROUNDWORKERS_REQUIRE_INTEGRATION=1" >> "$GITHUB_ENV"
29
+ echo "GROUNDWORKERS_TEST_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/test_db" >> "$GITHUB_ENV"
30
+ uv run omop-config connections add pg_test \
31
+ --dialect postgresql+psycopg \
32
+ --host localhost \
33
+ --port 5432 \
34
+ --user postgres \
35
+ --password postgres \
36
+ --database-name test_db \
37
+ --test-only false
38
+ uv run omop-config databases add cdm test_cdm_db --connection pg_test --cdm-schema gw_primary --vocab-schema gw_vocab
39
+ uv run omop-config databases add generic test_vector_db --connection pg_test --schema-name embeddings
40
+ uv run omop-config vector-stores add test_embeddings \
41
+ --backend-type pgvector \
42
+ --database test_vector_db
43
+ uv run omop-config configure groundworkers \
44
+ --cdm-db test_cdm_db \
45
+ --vector-store-name test_embeddings
46
+ uv run python -m tests.support.seed_postgres_fixture
47
+ test-evidence:
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+ - uses: actions/setup-python@v5
52
+ with:
53
+ python-version: "3.12"
54
+ - uses: astral-sh/setup-uv@v6
55
+ - name: Run hermetic suite with coverage and skip reasons
56
+ run: |
57
+ uv sync --frozen --all-extras --dev
58
+ export GROUNDWORKERS_REQUIRE_FORMAT_TESTS=1
59
+ echo "GROUNDWORKERS_REQUIRE_FORMAT_TESTS=1" >> "$GITHUB_ENV"
60
+ COVERAGE_FILE="$RUNNER_TEMP/groundworkers.coverage" uv run pytest -q -ra \
61
+ --cov=groundworkers --cov-branch \
62
+ --cov-report=xml:"$RUNNER_TEMP/coverage.xml" \
63
+ --junitxml="$RUNNER_TEMP/pytest.xml"
64
+ - uses: actions/upload-artifact@v4
65
+ if: always()
66
+ with:
67
+ name: groundworkers-test-evidence
68
+ path: |
69
+ ${{ runner.temp }}/coverage.xml
70
+ ${{ runner.temp }}/pytest.xml
71
+ if-no-files-found: warn
72
+ wheel-smoke:
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - uses: actions/setup-python@v5
77
+ with:
78
+ python-version: "3.12"
79
+ - uses: astral-sh/setup-uv@v6
80
+ - name: Build and smoke-test base and optional wheel installs
81
+ run: |
82
+ uv build --wheel
83
+ wheel="$(find dist -maxdepth 1 -name '*.whl' -print -quit)"
84
+ wheel="$(pwd)/$wheel"
85
+ uv venv "$RUNNER_TEMP/gw-wheel-base" --python 3.12
86
+ uv pip install --python "$RUNNER_TEMP/gw-wheel-base/bin/python" "$wheel"
87
+ mkdir -p "$RUNNER_TEMP/gw-wheel-run"
88
+ cd "$RUNNER_TEMP/gw-wheel-run"
89
+ "$RUNNER_TEMP/gw-wheel-base/bin/python" "$GITHUB_WORKSPACE/tests/support/wheel_smoke.py" base
90
+ uv venv "$RUNNER_TEMP/gw-wheel-extras" --python 3.12
91
+ uv pip install --python "$RUNNER_TEMP/gw-wheel-extras/bin/python" "$wheel[all_source,tui]" httpx
92
+ "$RUNNER_TEMP/gw-wheel-extras/bin/python" "$GITHUB_WORKSPACE/tests/support/wheel_smoke.py" extras
@@ -19,4 +19,5 @@ settings.json
19
19
  site/
20
20
  _knowledge/
21
21
  data/
22
- .env
22
+ .env
23
+ *.db
@@ -1,16 +1,16 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: groundworkers
3
- Version: 0.6.0
3
+ Version: 0.7.1
4
4
  Summary: Groundworkers MCP server — read-only agentive access to OMOP vocabularies, concept graphs, and embeddings.
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: fastapi<1.0,>=0.110
7
7
  Requires-Dist: mcp[cli]<2,>=1
8
8
  Requires-Dist: numpy<3,>=1.26
9
- Requires-Dist: oa-configurator<2,>=1.3.0
10
- Requires-Dist: omop-alchemy<2,>=1.1
11
- Requires-Dist: omop-emb<3,>=2.1
12
- Requires-Dist: omop-graph<3,>=2.1
13
- Requires-Dist: omop-llm<2,>=1
9
+ Requires-Dist: oa-configurator<3,>=2.0.0
10
+ Requires-Dist: omop-alchemy<3,>=2.0.0
11
+ Requires-Dist: omop-emb<4,>=3.0.0
12
+ Requires-Dist: omop-graph<4,>=3.0.0
13
+ Requires-Dist: omop-llm<2,>=1.0.2
14
14
  Requires-Dist: omop-semantics<1,>=0.6
15
15
  Requires-Dist: psutil<8,>=5.9
16
16
  Requires-Dist: psycopg[binary]<4,>=3.1
@@ -43,13 +43,13 @@ Requires-Dist: python-docx>=1.0; extra == 'docx'
43
43
  Provides-Extra: embedding-artifacts
44
44
  Requires-Dist: h5py<4,>=3.10; extra == 'embedding-artifacts'
45
45
  Provides-Extra: embedding-faiss
46
- Requires-Dist: omop-emb[faiss-cpu]<3,>=2.1; extra == 'embedding-faiss'
46
+ Requires-Dist: omop-emb[faiss-cpu]<4,>=3.0.0; extra == 'embedding-faiss'
47
47
  Provides-Extra: embedding-pgvector
48
- Requires-Dist: omop-emb[pgvector]<3,>=2.1; extra == 'embedding-pgvector'
48
+ Requires-Dist: omop-emb[pgvector]<4,>=3.0.0; extra == 'embedding-pgvector'
49
49
  Provides-Extra: pdf
50
50
  Requires-Dist: pdfplumber>=0.10; extra == 'pdf'
51
51
  Provides-Extra: tui
52
- Requires-Dist: groundskeeping<1,>=0.8.1; extra == 'tui'
52
+ Requires-Dist: groundskeeping<1,>=0.9.1; extra == 'tui'
53
53
  Requires-Dist: rich<15,>=13; extra == 'tui'
54
54
  Requires-Dist: textual>=0.60; extra == 'tui'
55
55
  Provides-Extra: xlsx
@@ -77,6 +77,7 @@ Start with the [documentation home](docs/index.md), or choose a path directly:
77
77
  - [Initial local setup](docs/from-scratch.md) walks through a fresh CDM-backed deployment.
78
78
  - [Integrations](docs/usage/integrations.md) shows MCP, REST, and Python calls.
79
79
  - [Configuration](docs/usage/configuration.md) explains shared-stack references and optional capabilities.
80
+ - [Upgrading from 0.6](docs/usage/upgrading-from-0.6.md) lists the 0.7 configuration and runtime changes.
80
81
  - [Tools overview](docs/tools/overview.md) maps jobs to the discoverable MCP surface.
81
82
 
82
83
  ## Quick start
@@ -19,6 +19,7 @@ Start with the [documentation home](docs/index.md), or choose a path directly:
19
19
  - [Initial local setup](docs/from-scratch.md) walks through a fresh CDM-backed deployment.
20
20
  - [Integrations](docs/usage/integrations.md) shows MCP, REST, and Python calls.
21
21
  - [Configuration](docs/usage/configuration.md) explains shared-stack references and optional capabilities.
22
+ - [Upgrading from 0.6](docs/usage/upgrading-from-0.6.md) lists the 0.7 configuration and runtime changes.
22
23
  - [Tools overview](docs/tools/overview.md) maps jobs to the discoverable MCP surface.
23
24
 
24
25
  ## Quick start
@@ -1,4 +1,4 @@
1
- # groundworkers example config — oa-configurator 1.x StackConfig format
1
+ # groundworkers example config — oa-configurator 2.0 StackConfig format
2
2
  #
3
3
  # Copy to a path selected by the setup console and fill in your values.
4
4
  # Full reference: https://oa-configurator.readthedocs.io (or run omop-config --help)
@@ -33,19 +33,19 @@ database_name = "cava"
33
33
  # Databases — logical roles over those connections
34
34
  # ---------------------------------------------------------------------------
35
35
 
36
- # kind = "cdm" bundles the CDM, vocabulary, and results roles. vocab_connection
37
- # and vocab_schema fall back to the primary connection and schema when unset.
36
+ # kind = "cdm" bundles the CDM, vocabulary, and results roles. The role schema
37
+ # fields fall back to the primary schema when unset. Omit these fields for SQLite.
38
38
  [databases.cdm_db]
39
39
  kind = "cdm"
40
40
  connection = "cdm_main"
41
- schema_name = "public"
41
+ cdm_schema = "public"
42
42
  vocab_schema = "public"
43
43
 
44
- # The embedding store's database. kind = "generic": no CDM role-splitting.
44
+ # The embedding store's database. Keep its schema distinct from the CDM schema.
45
45
  [databases.emb_db]
46
46
  kind = "generic"
47
47
  connection = "cdm_main"
48
- schema_name = "public"
48
+ schema_name = "groundworkers"
49
49
 
50
50
  # ---------------------------------------------------------------------------
51
51
  # Providers and models — endpoints, then the named models served through them
@@ -0,0 +1,51 @@
1
+ # CDM Adapter
2
+
3
+ `CDMAdapter` holds the primary engine, vocabulary engine, and routed session factory for a resolved CDM database. It is the shared connection layer used by `VocabService` and `OmopGraphAdapter`.
4
+
5
+ ## What it is
6
+
7
+ `CDMAdapter` is a thin connection-management object. It does not issue queries itself. Its purpose is to:
8
+
9
+ - hold the primary and vocabulary `sqlalchemy.Engine` objects
10
+ - expose a routed session factory for callers that query role-tagged OMOP tables
11
+ - be constructed once per CDM database in `build_application()` and shared across the components that need it
12
+
13
+ ## Who uses it
14
+
15
+ | Component | How |
16
+ |---|---|
17
+ | `VocabService` | Takes a `CDMAdapter` as its only constructor argument. Uses the session factory to open per-call sessions for vocabulary table queries. |
18
+ | `OmopGraphAdapter` | Uses the routed session factory so vocabulary and primary-role graph tables reach their configured databases. |
19
+
20
+ The adapter is created once per CDM database at application startup and wired through `build_application()`. It is not per-request.
21
+
22
+ ## Construction
23
+
24
+ `CDMAdapter` is config-agnostic. It accepts an engine and optional routed factory, while `build_application()` creates them through `omop_alchemy.config.create_cdm_engines()` and `omop_alchemy.cross_database.cdm_sessionmaker()`:
25
+
26
+ - the adapter remains testable by passing a SQLite engine directly
27
+ - changing the connection source means changing `build_application()` only;`CDMAdapter` and every service that uses it are untouched
28
+
29
+ ## Usage from `build_application()`
30
+
31
+ ```python
32
+ from groundworkers.app import build_application
33
+ from groundworkers.bootstrap import build_app_config
34
+
35
+ config = build_app_config()
36
+ app = build_application(config)
37
+
38
+ # CDMAdapter is available at:
39
+ app.adapters.cdm
40
+ ```
41
+
42
+ `VocabService` is wired automatically:
43
+ ```python
44
+ app.services.vocab # backed by app.adapters.cdm
45
+ ```
46
+
47
+ ## Lifecycle
48
+
49
+ `build_app_config()` creates role engines through `create_cdm_engines(..., register_claims=False)`. Startup fails fast when either database role is unreachable and prints the scrubbed reason with a database recovery hint. `CDMAdapter.is_available()` also performs a lightweight Core query (`SELECT 1`).
50
+
51
+ `close()` disposes both role engines. Call it explicitly in teardown (for example in a test fixture `yield`/`finally` block) when you need to ensure connections are returned promptly. Process-level startup and shutdown wiring belongs in the application or transport layer, not in the adapter itself.
@@ -10,15 +10,15 @@ The adapter is responsible for:
10
10
  - optional on-the-fly query encoding through an embedding client
11
11
  - exposing backend availability and registered model metadata
12
12
 
13
- The adapter does **not** resolve stack config itself. `build_application(...)` constructs it from the already-resolved `omop-emb` package config and any required engines.
13
+ The adapter does **not** resolve stack config itself. `build_application(...)` constructs it from Groundworkers' `[tools.groundworkers]` `embedding_model_name` and `vector_store_name` references.
14
14
 
15
15
  ## Backends
16
16
 
17
17
  `groundworkers` supports the same primary storage backends it wires from `omop-emb`:
18
18
 
19
- | Backend | omop-emb config |
19
+ | Backend | Groundworkers stack config |
20
20
  |---|---|
21
- | `sqlitevec` | `backend = "sqlitevec"` plus `sqlite_path` |
21
+ | `sqlitevec` | a `[vector_stores.*]` entry with `backend_type = "sqlitevec"` and a database reference |
22
22
  | `pgvector` | a `[vector_stores.*]` entry with `backend_type = "pgvector"` and a `database` reference |
23
23
 
24
24
  FAISS remains a sidecar acceleration layer rather than a standalone primary backend.
@@ -34,7 +34,7 @@ No live model API is required.
34
34
 
35
35
  ### Text search mode
36
36
 
37
- Requires an embedding client configured through `omop-emb` package settings.
37
+ Requires `embedding_model_name` and `vector_store_name`, plus a configured embedding provider/model.
38
38
 
39
39
  - `embedding_search` encodes a text query on the fly
40
40
  - `embedding_search_batch` encodes and searches multiple text queries with one provider/index batch, returning rows aligned to input order
@@ -18,7 +18,8 @@ app = build_application(config)
18
18
  |---|---|
19
19
  | `groundworkers` | `GroundworkersConfig` |
20
20
  | `cdm_database` | `ResolvedCDMDatabase` |
21
- | `cdm_engine`, `vocabulary_engine` | `sqlalchemy.Engine` |
21
+ | `cdm_engine`, `cdm_vocab_engine` | `sqlalchemy.Engine` |
22
+ | `cdm_session_factory` | Routed SQLAlchemy session factory for primary, vocabulary, and results roles |
22
23
  | `embedding_model` | `ResolvedModel \| None` |
23
24
  | `vector_store` | `ResolvedVectorStore \| None` |
24
25
 
@@ -42,6 +43,8 @@ services.source_planning
42
43
 
43
44
  A CDM-only configuration is fully supported. Graph availability follows the resolved CDM database — there is no separate section to enable.
44
45
 
46
+ The engines are created by `omop_alchemy.config.create_cdm_engines(..., register_claims=False)`, and `cdm_session_factory` comes from `omop_alchemy.cross_database.cdm_sessionmaker`. Use the session factory for queries that may touch more than one OMOP role. On PostgreSQL, engine creation checks role schema claims eagerly, so the configured databases must be reachable while `build_app_config()` runs.
47
+
45
48
  ## Grounding free text
46
49
 
47
50
  ```python
@@ -127,6 +130,6 @@ operation = (
127
130
  controller = ConfigWizardController(cdm_setup_workflow(operation), service)
128
131
  ```
129
132
 
130
- The same shape covers `MODEL_SETUP_TARGET` / `model_setup_workflow` and `LLM_SETUP_TARGET` / `llm_setup_workflow`. The provider decides create-versus-update from the current file, owns revision checking and redaction, and returns `conflicted` rather than clobbering another writer. `model_discoverer` is the injected seam for live model inventory; supply your own to avoid network calls in tests.
133
+ The same shape covers `MODEL_SETUP_TARGET` / `model_setup_workflow`, `LLM_SETUP_TARGET` / `llm_setup_workflow`, and `VECTOR_STORE_SETUP_TARGET` / `vector_store_setup_workflow`. The provider decides create-versus-update from the current file, owns revision checking and redaction, and returns `conflicted` rather than clobbering another writer. `model_discoverer` is the injected seam for live model inventory; supply your own to avoid network calls in tests.
131
134
 
132
135
  This requires the `tui` extra for Groundskeeping, but not Textual — the provider and controller are host-agnostic.
@@ -59,7 +59,7 @@ For example, a plugin recommending comparator cohorts might reason like this.
59
59
 
60
60
  | Use case | What you need | How you get it |
61
61
  |---|---|---|
62
- | Look up existing OMOP concepts | Read access to the CDM vocabulary connection Groundworkers already opened | `context.cdm_engine` / `context.resolver` |
62
+ | Look up existing OMOP concepts | Read access through Groundworkers' routed vocabulary session | `context.cdm_session_factory` / `context.resolver` |
63
63
  | Rank or filter by similarity to concepts Groundworkers already embedded | The concept embeddings Groundworkers already populated, via omop-emb | `context.vector_store` + `context.embedding_backend_factory` |
64
64
  | Ask an LLM to help decide something | The chat model Groundworkers already configured, via omop-llm | `context.chat_backend_factory` |
65
65
 
@@ -76,12 +76,14 @@ The concept-embedding row and the free-text-embedding row look similar but are n
76
76
 
77
77
  ### Assumptions this table is making
78
78
 
79
- - **Vocabulary only, so far.** Every example above reads OMOP *vocabulary* i.e. operations over concepts, concept relationships, concept embeddings, or the host's shared grounding cascade. Nothing about `context.cdm_engine` restricts a plugin to vocabulary tables specifically, however. These tables are available over the same CDM connection groundworkers itself uses, and a plugin *could* query clinical/person-level tables (`condition_occurrence`, `drug_exposure`, etc.) through it just as easily, subject to whatever environmental and procedural access controls actually govern that data.
79
+ - **Vocabulary only, so far.** Every example above reads OMOP vocabulary: concepts, concept relationships, concept embeddings, or the host's shared grounding cascade. `context.cdm_session_factory` routes vocabulary and primary roles, including on split-vocabulary deployments. Clinical/person-level queries need a database role explicitly configured for them.
80
80
  - **Shared mapping access.** `PluginContext.mapping_context` is an optional,read-only capability façade over the host's mapping and grounding policy. Use its operations when a plugin needs candidate bundles, text grounding, or concept context. `concept_shared_standard_ancestor(concept_ids, max_depth=5)` returns the unique nearest shared standard ancestor when one exists; raise `max_depth` to widen the hierarchy search. The underlying vocabulary, graph, and service objects are deliberately not exposed. Do not construct a second `omop-graph` or vocabulary adapter from `context.cdm_engine`. The field is `None` only when the host did not compose services for the plugin context.
81
81
 
82
82
  ## Build and register a new plugin
83
83
 
84
- `build()` receives `PluginContext`. The context provides the resolved CDM database and engine, vector store, shared lazy model backend factories, the optional read-only `mapping_context`, and a deliberately narrow resolver for independent named OA resources. Return `None` when a prerequisite is unavailable. Groundworkers then keeps serving its core capabilities and reports why the plugin was not activated.
84
+ `build()` receives `PluginContext`. The context provides the resolved CDM database and primary engine, routed `cdm_session_factory`, vocabulary engine, vector store, shared lazy model backend factories, the optional read-only `mapping_context`, and a deliberately narrow resolver for independent named OA resources. Return `None` when a prerequisite is unavailable. Groundworkers then keeps serving its core capabilities and reports why the plugin was not activated.
85
+
86
+ Use `context.cdm_session_factory` for role-tagged OMOP queries. `context.cdm_engine` remains available for primary-role access. On split-vocabulary stacks, plugins must use the routed factory; an Engine-based OmopGraphAdapter or DomainNameResolver cannot route vocabulary queries and will fail with upgrade guidance.
85
87
 
86
88
  `register()` adds MCP tools, prompts, or resources against the state returned by `build()`. The shared MCP registration wrapper supplies the same safe error translation used by core tools. Code-defined prompts can continue to derive their arguments from the callable signature. A plugin publishing data-defined prompts can pass explicit string metadata with `PromptArgument`; this keeps dynamic pack fields out of Python closure signatures:
87
89
 
@@ -158,7 +160,8 @@ Schemas requiring live discovery or a conditional flow (and therefore not fittin
158
160
  ```python
159
161
  from typing import Annotated, ClassVar
160
162
 
161
- from oa_configurator import PackageConfigBase, Sensitive
163
+ from oa_configurator import PackageConfigBase
164
+ from oa_configurator.refs import Sensitive, Secret
162
165
  from pydantic import Field
163
166
 
164
167
 
@@ -167,10 +170,23 @@ class ExampleConfig(PackageConfigBase):
167
170
  api_token: Annotated[str | None, Sensitive()] = Field(default=None)
168
171
  ```
169
172
 
170
- The `oa_configurator.Secret` alias is equivalent to `Annotated[str | None, Sensitive()]`. Prefer a `RefTo` field when a plugin can reuse an existing database, model, provider, or vector-store entry. The plugin then stores only the logical reference name; sensitivity remains declared on the referenced schema, such as `ConnectionConfig.password` or `ProviderConfig.api_key`, and the generic recursive configuration workflow preserves those declarations.
173
+ The `Secret` alias is equivalent to `Annotated[str | None, Sensitive()]`. Prefer a `RefTo` field when a plugin can reuse an existing database, model, provider, or vector-store entry. The plugin then stores only the logical reference name; sensitivity remains declared on the referenced schema, such as `ConnectionConfig.password` or `ProviderConfig.api_key`, and the generic recursive configuration workflow preserves those declarations.
171
174
 
172
175
  This protects display and logging surfaces; it does not encrypt persisted configuration. Plugin documentation must describe the storage expectations for any secret it introduces.
173
176
 
177
+ ## Upgrading plugins to Groundworkers 0.7
178
+
179
+ 1. Require `oa-configurator>=2,<3` and `groundworkers>=0.7,<0.8` in the plugin package.
180
+ 2. Import `Sensitive` and `Secret` from `oa_configurator.refs`, and load files with `load_stack_config(path)`.
181
+ 3. Create CDM role engines with `omop_alchemy.config.create_cdm_engines(resolved, register_claims=False)` for read-only plugin access; use `context.cdm_session_factory` when Groundworkers provides the database.
182
+ 4. Remove schema fields from SQLite database entries. For PostgreSQL CDM entries, use `cdm_schema`; vector-store database entries continue to use `schema_name`.
183
+ 5. Keep accepting `context.cdm_engine` for integrations that need the primary SQLAlchemy engine. The routed factory handles vocabulary, primary, and results roles for ORM queries.
184
+ 6. Treat `context.embedding_backend_factory()` as a read-only omop-emb 3.0 `EmbeddingStoreReader`. It is shared with Groundworkers tools and status; reader methods no longer accept `metric_type`, and model enumeration is `get_registered_models()`. Do not use it to register models, create tables, or write vectors. Use a plugin-owned store and explicit setup operation for plugin data.
185
+ 7. Pass `context.cdm_session_factory` when constructing `OmopGraphAdapter`; Engine mode only works for colocated databases. `context.cdm_engine` is the primary-role engine and cannot query vocabulary on a split deployment.
186
+ 8. Use the current public error codes: `LEGACY_REGISTRY`, `MISPLACED_REGISTRY`, `MISSING_STORAGE_TABLE`, `MODEL_REGISTRATION_CONFLICT`, and `READ_ONLY_STORE`.
187
+ 9. Update `describe()` consumers for the `llm_model`, `stack`, `groundworkers`, and `app_name` keys and `cdm_schema` / `vocab_schema` names. The old `base.sql` schema/engine helpers have been removed; use oa-configurator's `physical_schema_of`, `qualified`, `supports_schemas`, and `schema_for_role` APIs.
188
+ 10. Update direct `AppConfig` construction for the required `stack`, `groundworkers`, `cdm_database`, `cdm_engine`, `cdm_vocab_engine`, `cdm_session_factory`, `embedding_model`, `llm_model`, `vector_store`, and `knowledge_root` fields; prefer `build_app_config()` in plugins and tests.
189
+
174
190
  ## Setup steps
175
191
 
176
192
  Plugin data preparation belongs in registered setup steps. A plugin may expose a `setup_steps` tuple of `PluginSetupStep` instances. Each step declares a stable key, operator copy, typed arguments, and a `build_plan(values, config_path)` callable that returns a `MaintenancePlan`.
@@ -69,6 +69,7 @@ The output includes the active tools, prompts, resources, plugins, redacted conf
69
69
  - [Initial local setup](from-scratch.md) for a fresh local deployment
70
70
  - [Integrations](usage/integrations.md) for MCP, REST, and direct Python usage
71
71
  - [Configuration](usage/configuration.md) for the shared-stack config model and runtime combinations
72
+ - [Upgrading from 0.6](usage/upgrading-from-0.6.md) for the 0.7 configuration and plugin changes
72
73
  - [Tools overview](tools/overview.md) for the discoverable MCP surface
73
74
 
74
75
  ## Relationship to groundcrew
@@ -1,6 +1,6 @@
1
1
  # Embedding Tools
2
2
 
3
- Five tools expose the embedding index. All require `omop_emb` to be enabled in the config.
3
+ Five tools expose the embedding index. They require `embedding_model_name` and `vector_store_name` in `[tools.groundworkers]`.
4
4
 
5
5
  ## `embedding_index_status`
6
6
 
@@ -23,12 +23,16 @@ Returns the status of the embedding backend and all registered models. Takes no
23
23
  }
24
24
  ```
25
25
 
26
- When the backend is unavailable or no models are registered, `"available"` is `false` and `"models"` is an empty array. This tool never returns an error dict — it degrades gracefully.
26
+ When the backend is unavailable or no models are registered, `"available"` is `false` and `"models"` is an empty array. This tool never returns an error dict — it degrades gracefully. A legacy registry, misplaced registry, or missing model table is reported in `detail` with a specific explanation.
27
+
28
+ Groundworkers opens the store through omop-emb's read-only reader for status and query tools. A pre-3.0 store reports `LEGACY_REGISTRY`. The migration script is tracked in oa-configurator issue #40; once it ships, Groundworkers will show omop-emb's migration command. Groundworkers does not migrate the store.
27
29
 
28
30
  ## `embedding_neighbours`
29
31
 
30
32
  Returns the nearest embedding-space neighbours for one OMOP concept by looking up its existing vector in the index.
31
33
 
34
+ By default `standard_only` and `active_only` are both `true`, matching the partial HNSW index predicate. Set either to `false` to widen the result set.
35
+
32
36
  ```json
33
37
  {"concept_id": 4119419, "limit": 10, "model_name": "qwen3-embedding:0.6b"}
34
38
  ```
@@ -66,9 +70,10 @@ Encodes a text query on the fly and returns the nearest concepts by vector simil
66
70
 
67
71
  All parameters except `query` are optional.
68
72
 
69
- !!! warning "Requires `api_base` configuration"
73
+ !!! warning "Requires a configured embedding model"
70
74
  `embedding_search` must encode the query string using a live embedding model.
71
- This requires `omop_emb.api_base` (and `api_key`) to be configured. Without it
75
+ Configure `embedding_model_name` in `[tools.groundworkers]` and give its
76
+ `[models.*]` entry a provider in `[providers.*]`. Without a live model client,
72
77
  the tool returns `BACKEND_UNAVAIL`.
73
78
 
74
79
  ## `embedding_search_batch`
@@ -110,4 +115,4 @@ Encodes a text string into one query embedding vector.
110
115
  }
111
116
  ```
112
117
 
113
- Like `embedding_search`, this requires `omop_emb.api_base` and `omop_emb.api_key` to be configured.
118
+ Like `embedding_search`, this requires a configured `embedding_model_name` and a live provider client.
@@ -64,7 +64,7 @@ database_name = "omop"
64
64
  [databases.cdm_db]
65
65
  kind = "cdm"
66
66
  connection = "cdm_main"
67
- schema_name = "public"
67
+ cdm_schema = "public"
68
68
  vocab_schema = "public"
69
69
 
70
70
  [providers.local_ollama]
@@ -86,6 +86,11 @@ structured_output = true
86
86
  backend_type = "pgvector"
87
87
  database = "vector_db"
88
88
 
89
+ [databases.vector_db]
90
+ kind = "generic"
91
+ connection = "cdm_main"
92
+ schema_name = "groundworkers"
93
+
89
94
  [tools.groundworkers]
90
95
  cdm_db = "cdm_db"
91
96
  embedding_model_name = "embedding_model"
@@ -169,7 +174,7 @@ REST is selected explicitly with `--transport rest`; it is not started alongside
169
174
  | `rest_port` | `int` | `8080` |
170
175
  | `rest_base_path` | `str` | `/v1` |
171
176
 
172
- `base_path` is validated to begin with `/`.
177
+ `rest_base_path` is validated to begin with `/`.
173
178
 
174
179
  ### `llm_model_name` and chat
175
180
 
@@ -201,9 +206,9 @@ Groundworkers-owned grounding policy. omop-graph's traversal limits are per-call
201
206
  | `grounding_min_fulltext_overlap` | `float` | `0.0` |
202
207
  | `grounding_max_depth` | `int` (1-10) | `5` |
203
208
 
204
- `min_fulltext_overlap` must be between `0.0` and `1.0`. It is the minimum proportion of query tokens that must appear in a matched concept name for a full-text hit to be accepted; below the threshold grounding falls through to the next tier.
209
+ `grounding_min_fulltext_overlap` must be between `0.0` and `1.0`. It is the minimum proportion of query tokens that must appear in a matched concept name for a full-text hit to be accepted; below the threshold grounding falls through to the next tier.
205
210
 
206
- `max_depth` bounds the hierarchy distance between a grounding candidate and a required parent concept, or the identity-hop count when grounding runs without `parent_ids`.
211
+ `grounding_max_depth` bounds the hierarchy distance between a grounding candidate and a required parent concept, or the identity-hop count when grounding runs without `parent_ids`.
207
212
 
208
213
  ### Concept flag contract
209
214
 
@@ -289,6 +294,10 @@ Both references are required. With only one configured, status reports an action
289
294
 
290
295
  The store must be populated before the embedding tier can return anything. Population is explicit (see the Embeddings setup section) and never starts at query time. The server holds the graph read-only (`write=False`), so Groundworkers encodes query text for the embedding tier but never writes vectors.
291
296
 
297
+ Groundworkers opens vector stores with omop-emb's read-only reader for MCP tools, status, coverage, and setup diagnostics. Explicit store initialization uses omop-emb's writer. A database supports one vector store per model: reuse the existing store or choose another database when registering a model that is already present. On PostgreSQL, the wizard stores vectors in the dedicated `groundworkers` schema. omop-emb also creates `omop_emb_registry`, and oa-configurator may create `oa_configurator_provenance`. SQLite uses its database file without a schema.
298
+
299
+ If the store predates omop-emb 3.0, Groundworkers reports `LEGACY_REGISTRY`. The migration script is tracked in oa-configurator issue #40; once it ships, Groundworkers will show omop-emb's migration command. Groundworkers does not migrate legacy stores.
300
+
292
301
  ### With `groundworkers.llm_model_name` configured
293
302
 
294
303
  You additionally get:
@@ -342,4 +351,4 @@ mapping = app.services.mapping
342
351
 
343
352
  Service attributes are `None` only when their prerequisites are not available in the resolved runtime.
344
353
 
345
- `config.describe()` returns a redacted summary keyed by `database`, `model`, and `vector_store`. Passwords and API keys are masked; safe URLs never carry credentials.
354
+ `config.describe()` returns a redacted summary keyed by `database`, `model`, `llm_model`, `vector_store`, `stack`, `groundworkers`, and `app_name`. CDM schema keys are `cdm_schema` and `vocab_schema`; generic/vector-store databases continue to use `schema_name`. Passwords and API keys are masked; safe URLs never carry credentials.
@@ -5,11 +5,11 @@ The setup console is organized by the capability being configured:
5
5
  1. **Overview** — CDM readiness, optional capabilities, and integration output;
6
6
  2. **Database** — physical connections and logical CDM database entries;
7
7
  3. **Graph** — CDM-backed search and graph preparation;
8
- 4. **Chat Model** — provider and model entries for LLM-backed features;
9
- 5. **Embeddings** — vector-store setup, coverage, and population;
10
- 6. **Performance** — graph, trigram, and embedding-index readiness;
8
+ 4. **Performance** — graph, trigram, and embedding-index readiness;
9
+ 5. **LLM provider** — provider and model entries for language features;
10
+ 6. **Embeddings** — vector-store setup, coverage, and population;
11
11
  7. **Chat** — checks for the selected chat model;
12
- 8. **View Configuration** — redacted stack configuration; and
12
+ 8. **Configuration** — redacted stack configuration; and
13
13
  9. **Runs** — progress and history for durable maintenance work.
14
14
 
15
15
  For a minimal local setup, use **Overview → Configure CDM → Test connections**. Optional capabilities can be configured later. Configuration changes show the redacted entries that will be written before they are applied.
@@ -0,0 +1,45 @@
1
+ # Testing
2
+
3
+ ## Test lanes
4
+
5
+ Groundworkers uses distinct lanes because an isolated unit run cannot prove the database, optional parser, plugin-entry-point, or built-wheel contracts.
6
+
7
+ | Lane | What it proves | CI behavior |
8
+ |---|---|---|
9
+ | Unit and service | Deterministic policy, adapter boundaries, source planning, transport behavior, and controlled provider responses | Runs without a live database or model service |
10
+ | Optional dependency | Real XLSX, DOCX, and PDF parsing plus missing-extra guidance | Required format tests must pass in the all-extras CI lane; missing-extra behavior is simulated |
11
+ | PostgreSQL integration | Seeded graph retrieval, real pgvector storage and reader behavior, model selection, filters, and embedding-tier grounding | Required: every required_integration case must be collected and pass |
12
+ | Wheel smoke | Base and optional-extra installations, package entry-point discovery, CLI startup, and successful MCP/REST planning operations | Builds once and runs outside the checkout |
13
+ | Optional live provider | Real configured model-provider connectivity | Opt-in developer smoke only; never substitutes for seeded embedding tests |
14
+
15
+ ## Running tests
16
+
17
+ ~~~bash
18
+ # Hermetic suite, including real optional-format parsers
19
+ uv run pytest -q -ra
20
+
21
+ # Unit tests only
22
+ uv run pytest tests/unit/
23
+
24
+ # Required PostgreSQL cases; provide a seeded test stack first
25
+ GROUNDWORKERS_CONFIG_PATH=/path/to/stack.toml \
26
+ GROUNDWORKERS_REQUIRE_INTEGRATION=1 \
27
+ GROUNDWORKERS_TEST_DATABASE_URL=postgresql+psycopg://... \
28
+ uv run pytest -m required_integration -q -ra
29
+
30
+ # Coverage for local review
31
+ COVERAGE_FILE=/tmp/groundworkers.coverage uv run pytest -q -ra \
32
+ --cov=groundworkers --cov-branch --cov-report=term-missing
33
+ ~~~
34
+
35
+ The required integration gate derives its cases from the `required_integration` marker, so every marked case is checked for collection and a passing result. Missing configuration, unavailable adapters, and absent seeded rows fail in that lane. The all-extras CI job applies the same execution check to `required_format` cases, so a missing parser cannot silently turn the format contract into a skip. Without the corresponding `GROUNDWORKERS_REQUIRE_*` flag, PostgreSQL and optional-format fixtures remain opt-in and skip with a reason.
36
+
37
+ ## Configuration and optional provider smoke
38
+
39
+ Set GROUNDWORKERS_CONFIG_PATH (or GROUNDWORKERS_CONFIG) to the explicit Groundworkers stack file for integration tests. OA_CONFIG_PATH selects the oa-configurator default stack, but does not by itself opt the graph integration tests into a required run. PostgreSQL CI sets both paths and seeds a compact fixture before pytest starts.
40
+
41
+ The external-provider smoke tests are separate from seeded deterministic embedding tests. To run them locally, set GROUNDWORKERS_RUN_EMBEDDING_INTEGRATION=1, GROUNDWORKERS_CONFIG_PATH, and GROUNDWORKERS_TEST_CONCEPT_ID; they require a configured provider and a concept with stored vectors.
42
+
43
+ ## Coverage and skip evidence
44
+
45
+ CI publishes coverage.xml and pytest.xml from the hermetic all-extras run. The JUnit report carries named skip reasons. PostgreSQL CI separately enforces the required test list, so optional local skips cannot satisfy that gate. Coverage percentages are review evidence, not a global pass threshold. Prioritize unexecuted behavior at database, provider, transport, and packaging boundaries.
@@ -0,0 +1,31 @@
1
+ # Upgrading from Groundworkers 0.6
2
+
3
+ Groundworkers 0.7 uses the oa-configurator 2.0 stack and supports a vocabulary database separate from the primary CDM database.
4
+
5
+ ## Configuration changes
6
+
7
+ - Rename the former database `schema_name` setting to `cdm_schema` for a CDM database. Use `vocab_schema` when vocabulary has a distinct schema. Generic databases, including vector-store databases, still use `schema_name`.
8
+ - SQLite has no schemas. Remove schema settings from SQLite database entries; setup ignores those fields and tells you when they are unavailable.
9
+ - A PostgreSQL vector store colocated with the CDM uses the dedicated `groundworkers` schema. Its database is a generic entry on the CDM connection:
10
+
11
+ ```toml
12
+ [databases.groundworkers_vectors]
13
+ kind = "generic"
14
+ connection = "cdm_main"
15
+ schema_name = "groundworkers"
16
+ ```
17
+
18
+ - Add databases with the 2.0 CLI syntax, for example:
19
+
20
+ ```bash
21
+ omop-config databases add cdm clinical --connection cdm_main --cdm-schema public
22
+ omop-config databases add generic vectors --connection cdm_main --schema-name groundworkers
23
+ ```
24
+
25
+ - Startup now fails fast if either the primary or vocabulary endpoint cannot be reached. The console prints the first scrubbed cause and a database recovery hint.
26
+ - A pre-3.0 embedding store reports `LEGACY_REGISTRY`. The migration script is tracked in oa-configurator issue #40; once it ships, Groundworkers will provide the omop-emb migration command.
27
+ - To split the vocabulary, set `vocab_connection` on the CDM database entry. Groundworkers 0.7 routes vocabulary reads to that connection, including setup diagnostics and graph searches.
28
+
29
+ ## Plugin changes
30
+
31
+ See [Upgrading plugins to Groundworkers 0.7](../development/plugins.md#upgrading-plugins-to-groundworkers-07) for the full API checklist. Plugins should require `groundworkers>=0.7,<0.8`, pass `cdm_session_factory` for OMOP graph/vocabulary access, and treat `embedding_backend_factory()` as a read-only `EmbeddingStoreReader`.
@@ -14,11 +14,11 @@ dependencies = [
14
14
  "psycopg[binary]>=3.1,<4",
15
15
  "python-dotenv>=1,<2",
16
16
  "psutil>=5.9,<8",
17
- "oa-configurator>=1.3.0,<2",
18
- "omop-alchemy>=1.1,<2",
19
- "omop-graph>=2.1,<3",
20
- "omop-emb>=2.1,<3",
21
- "omop-llm>=1,<2",
17
+ "oa-configurator>=2.0.0,<3",
18
+ "omop-alchemy>=2.0.0,<3",
19
+ "omop-graph>=3.0.0,<4",
20
+ "omop-emb>=3.0.0,<4",
21
+ "omop-llm>=1.0.2,<2",
22
22
  "omop-semantics>=0.6,<1",
23
23
  "uvicorn[standard]>=0.29,<1.0",
24
24
  ]
@@ -31,7 +31,7 @@ pdf = [
31
31
  "pdfplumber>=0.10",
32
32
  ]
33
33
  tui = [
34
- "groundskeeping>=0.8.1,<1",
34
+ "groundskeeping>=0.9.1,<1",
35
35
  "textual>=0.60",
36
36
  "rich>=13,<15",
37
37
  ]
@@ -48,10 +48,10 @@ all_source = [
48
48
  "python-docx>=1.0",
49
49
  ]
50
50
  embedding-pgvector = [
51
- "omop-emb[pgvector]>=2.1,<3",
51
+ "omop-emb[pgvector]>=3.0.0,<4",
52
52
  ]
53
53
  embedding-faiss = [
54
- "omop-emb[faiss-cpu]>=2.1,<3",
54
+ "omop-emb[faiss-cpu]>=3.0.0,<4",
55
55
  ]
56
56
  dev = [
57
57
  "httpx>=0.27,<1",
@@ -112,5 +112,8 @@ include = ["src"]
112
112
  testpaths = ["tests"]
113
113
  markers = [
114
114
  "integration: requires a live backend or database",
115
+ "required_integration: deterministic integration contract required by CI",
116
+ "required_format: optional document-format contract required in all-extras CI",
117
+ "optional_integration: environment-dependent integration smoke test",
115
118
  "requires_client: requires an embedding API client",
116
119
  ]