groundworkers 0.6.0__tar.gz → 0.7.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.
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/workflows/ci.yml +2 -8
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.gitignore +2 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/PKG-INFO +10 -9
- {groundworkers-0.6.0 → groundworkers-0.7.0}/README.md +1 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/config/groundworkers.example.toml +6 -6
- groundworkers-0.7.0/docs/adapters/cdm.md +51 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/adapters/omop_emb.md +4 -4
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/development/integration.md +5 -2
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/development/plugins.md +21 -5
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/index.md +1 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/embedding.md +10 -5
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/usage/configuration.md +14 -5
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/usage/setup_journey.md +4 -4
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/usage/testing.md +2 -2
- groundworkers-0.7.0/docs/usage/upgrading-from-0.6.md +31 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/pyproject.toml +8 -8
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/adapters/cdm.py +26 -5
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/adapters/omop_emb.py +55 -28
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/adapters/omop_graph.py +47 -21
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/app.py +14 -9
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/configuration.py +4 -26
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/configuration_provider.py +122 -39
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/databases.py +380 -294
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_artifacts.py +7 -4
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_coverage.py +4 -19
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_population.py +32 -14
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_registry.py +6 -6
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_setup.py +6 -12
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/graph_maintenance.py +3 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/models.py +11 -8
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/performance_maintenance.py +45 -23
- groundworkers-0.7.0/src/groundworkers/base/domain_names.py +125 -0
- groundworkers-0.7.0/src/groundworkers/base/errors.py +144 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/base/sql.py +0 -25
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/bootstrap.py +35 -19
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/config.py +8 -34
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/plugins.py +2 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/server.py +10 -2
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/graph.py +24 -12
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/vocab.py +22 -12
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/transports/rest/api.py +5 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/pages/setup.py +6 -6
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/overview.py +4 -3
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/integration/test_omop_graph_adapter.py +82 -87
- groundworkers-0.7.0/tests/support/omop.py +15 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/support/seed_postgres_fixture.py +5 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/support/stack_config.py +22 -14
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/test_bootstrap_config.py +96 -18
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/test_rest_api.py +15 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/test_server_registry.py +3 -3
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_configuration_provider.py +89 -12
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_domain_names.py +37 -4
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_migration_boundaries.py +14 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_normalized_index.py +102 -8
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_omop_emb_adapter.py +20 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_omop_emb_setup_config.py +3 -3
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_omop_graph_adapter.py +127 -18
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_phase3_overview.py +1 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_plugin_configuration.py +5 -6
- groundworkers-0.7.0/tests/unit/test_schema_resolution.py +146 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_artifacts_and_coverage.py +5 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_configuration.py +2 -6
- groundworkers-0.7.0/tests/unit/test_setup_databases.py +508 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_embeddings.py +7 -7
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_provider_conformance.py +3 -3
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_runtime.py +1 -7
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_truth.py +1 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_write_flows.py +7 -7
- groundworkers-0.7.0/tests/unit/test_split_classified_edges.py +96 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_tui_app.py +46 -9
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_tui_state.py +4 -6
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_vector_store_setup.py +101 -10
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_vocab_service.py +14 -1
- {groundworkers-0.6.0 → groundworkers-0.7.0}/uv.lock +30 -29
- groundworkers-0.6.0/docs/adapters/cdm.md +0 -53
- groundworkers-0.6.0/src/groundworkers/base/domain_names.py +0 -78
- groundworkers-0.6.0/src/groundworkers/base/errors.py +0 -87
- groundworkers-0.6.0/tests/unit/test_schema_resolution.py +0 -251
- groundworkers-0.6.0/tests/unit/test_setup_databases.py +0 -469
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.githooks/pre-commit +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/CONTRIBUTING.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/ISSUE_TEMPLATE/not_working.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/release-drafter.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/workflows/docs.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/workflows/merge.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.github/workflows/publish.yml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/.python-version +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/CHANGELOG.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/Makefile +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/config/docker-compose.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/config/groundworkers_db.env +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/adapters/omop_graph.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/architecture.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/concepts.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/development/extending.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/from-scratch.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/js/mermaid-init.js +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/reference/ref_adapters.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/reference/ref_base.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/reference/ref_config.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/reference/ref_services.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/reference/ref_tools.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/domain.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/graph.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/grounding.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/mapping.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/semantic_projection.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/source_planning.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/text.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/services/vocab.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/01_create_config.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/02_empty_config.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/03_config_wizard.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/04_test_cnx.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/04_warnings.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/05_graph_setup.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/06_load_predicates.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/07_vector_store.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/08_register_embedding.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/static/10_setup_complete.png +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/concept.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/domain.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/knowledge.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/mapping.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/overview.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/resolver.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/search.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/semantic_projection.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/source_planning.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/system.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/tools/text.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/usage/installation.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/docs/usage/integrations.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/mkdocs.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/_env.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/adapters/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/adapters/llm.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_capability.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/embedding_reconciliation.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/integration.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/maintenance_runs.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/model_inventory.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/plugin_configuration.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/application/setup/runtime_setup.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/base/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/base/concept_payload.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/base/results.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/base/server.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/config/README +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/config/predicate_classification.csv +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/config/predicate_mapping.csv +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/criteria-gate-yesno/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/criteria-gate-yesno/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/diagnosis-role-modifier/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/diagnosis-role-modifier/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/domain-routing/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/domain-routing/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/domain-routing/rules.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/drug-concept-granularity/rules.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/history-of-event/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/history-of-event/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/standard-concept-preference/guidance.md +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/standard-concept-preference/manifest.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/knowledge/packs/core/standard-concept-preference/rules.yaml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/domain.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/grounding.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/knowledge/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/knowledge/catalogue.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/knowledge/models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/mapping.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/semantic_projection/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/semantic_projection/definitions.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/semantic_projection/models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/semantic_projection/service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/assisted.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/canonical_headers.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/classifier.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposer.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/csv_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/ddl_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/docx_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/json_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/pdf_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/xlsx_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/decomposers/xml_.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/detector.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/normalisation.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/provenance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/router.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/serialisation.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/source_profiles/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/source_profiles/base.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/source_profiles/redcap.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/source_profiles/registry.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/source_planning/warnings.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/text/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/text/models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/text/prompts.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/services/text/service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/concept_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/domain_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/embedding_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/knowledge_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/mapping_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/resolver_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/search_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/semantic_projection_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/source_planning_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/system_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tools/text_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/transports/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/transports/rest/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/transports/rest/models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/app.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/pages/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/pages/base.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/pages/plugin_config.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/pages/plugin_setup.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/base.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/chat.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/configuration.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/database.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/embeddings.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/graph.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/llm_provider.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/performance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/presenters/runs.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/routes.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/state.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/config_location.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/embedding_store.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/embeddings.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/graph_maintenance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/performance_maintenance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/src/groundworkers/tui/wizards/plugin_setup.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/conftest.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/integration/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/integration/test_omop_emb_adapter.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/support/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/support/postgres_ci_config.toml +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/__init__.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_concept_payload.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_concept_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_config_location_wizard.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_domain_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_embedding_population_scope.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_embedding_reconciliation.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_embedding_registry_step.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_embedding_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_env_bootstrap.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_error_boundary.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_graph_maintenance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_graph_maintenance_wizard.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_graph_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_graph_status.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_grounding_constraints.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_grounding_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_knowledge_catalogue.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_llm_adapter.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_maintenance_runs_phase2.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_mapping_context.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_mapping_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_mapping_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_performance.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_performance_maintenance_wizard.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_plugins.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_provider_fields.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_semantic_projection_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_semantic_projection_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_setup_configuration_section.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_classifier.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_decomposer.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_detector.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_models.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_normalisation.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_router.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_source_planning_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_stack_config_fixtures.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_system_tools.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_text_service.py +0 -0
- {groundworkers-0.6.0 → groundworkers-0.7.0}/tests/unit/test_text_tools.py +0 -0
|
@@ -35,14 +35,8 @@ jobs:
|
|
|
35
35
|
--password postgres \
|
|
36
36
|
--database-name test_db \
|
|
37
37
|
--test-only false
|
|
38
|
-
uv run omop-config databases add test_cdm_db
|
|
39
|
-
|
|
40
|
-
--connection pg_test \
|
|
41
|
-
--schema-name public
|
|
42
|
-
uv run omop-config databases add test_vector_db \
|
|
43
|
-
--kind generic \
|
|
44
|
-
--connection pg_test \
|
|
45
|
-
--schema-name public
|
|
38
|
+
uv run omop-config databases add cdm test_cdm_db --connection pg_test --cdm-schema public
|
|
39
|
+
uv run omop-config databases add generic test_vector_db --connection pg_test --schema-name embeddings
|
|
46
40
|
uv run omop-config vector-stores add test_embeddings \
|
|
47
41
|
--backend-type pgvector \
|
|
48
42
|
--database test_vector_db
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: groundworkers
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
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
|
|
10
|
-
Requires-Dist: omop-alchemy<2
|
|
11
|
-
Requires-Dist: omop-emb<3
|
|
12
|
-
Requires-Dist: omop-graph<3
|
|
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
|
|
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
|
|
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.
|
|
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
|
+
# 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.
|
|
37
|
-
#
|
|
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
|
-
|
|
41
|
+
cdm_schema = "public"
|
|
42
42
|
vocab_schema = "public"
|
|
43
43
|
|
|
44
|
-
# The embedding store's database.
|
|
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 = "
|
|
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
|
|
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 |
|
|
19
|
+
| Backend | Groundworkers stack config |
|
|
20
20
|
|---|---|
|
|
21
|
-
| `sqlitevec` | `
|
|
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
|
|
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`, `
|
|
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 `
|
|
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
|
|
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
|
|
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
|
|
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 `
|
|
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.
|
|
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
|
|
73
|
+
!!! warning "Requires a configured embedding model"
|
|
70
74
|
`embedding_search` must encode the query string using a live embedding model.
|
|
71
|
-
|
|
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 `
|
|
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
|
-
|
|
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
|
-
`
|
|
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
|
-
`
|
|
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
|
-
`
|
|
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 `
|
|
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. **
|
|
9
|
-
5. **
|
|
10
|
-
6. **
|
|
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. **
|
|
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.
|
|
@@ -18,7 +18,7 @@ pytest tests/unit/test_concept_tools.py
|
|
|
18
18
|
Integration tests that query the OMOP database require a `.env` file at the repo root (or an environment-variable equivalent):
|
|
19
19
|
|
|
20
20
|
```dotenv
|
|
21
|
-
|
|
21
|
+
OA_CONFIG_PATH=/path/to/stack.toml
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Unit tests mock the adapter layer and run without a live database.
|
|
@@ -31,4 +31,4 @@ Unit tests mock the adapter layer and run without a live database.
|
|
|
31
31
|
| Resolver tools | `concept_ground`: empty query rejection, result ordering by score, match_kind on exact hits |
|
|
32
32
|
| Embedding tools | `embedding_index_status`, `embedding_neighbours`, `embedding_search`, `embedding_search_batch`, `embedding_encode`: correct responses, clamped limits, aligned batch rows, error propagation |
|
|
33
33
|
| Server registry | `create_server` with and without each adapter; system tools always present; adapter-conditional tool registration |
|
|
34
|
-
| Config validation |
|
|
34
|
+
| Config validation | oa-configurator stack validation, Groundworkers package fields, and extra field rejection |
|
|
@@ -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>=
|
|
18
|
-
"omop-alchemy>=
|
|
19
|
-
"omop-graph>=
|
|
20
|
-
"omop-emb>=
|
|
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.
|
|
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]>=
|
|
51
|
+
"omop-emb[pgvector]>=3.0.0,<4",
|
|
52
52
|
]
|
|
53
53
|
embedding-faiss = [
|
|
54
|
-
"omop-emb[faiss-cpu]>=
|
|
54
|
+
"omop-emb[faiss-cpu]>=3.0.0,<4",
|
|
55
55
|
]
|
|
56
56
|
dev = [
|
|
57
57
|
"httpx>=0.27,<1",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
from sqlalchemy import literal, select
|
|
4
6
|
from sqlalchemy.engine import Engine
|
|
5
|
-
from sqlalchemy.orm import sessionmaker
|
|
7
|
+
from sqlalchemy.orm import Session, sessionmaker
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class CDMAdapter:
|
|
@@ -16,15 +18,32 @@ class CDMAdapter:
|
|
|
16
18
|
Use session() for services that need a scoped session context manager.
|
|
17
19
|
"""
|
|
18
20
|
|
|
19
|
-
def __init__(
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
engine: Engine,
|
|
24
|
+
*,
|
|
25
|
+
vocab_engine: Engine | None = None,
|
|
26
|
+
session_factory: Callable[[], Session] | None = None,
|
|
27
|
+
) -> None:
|
|
20
28
|
self._engine = engine
|
|
21
|
-
self.
|
|
29
|
+
self._vocab_engine = vocab_engine or engine
|
|
30
|
+
self._session_factory = session_factory or sessionmaker(bind=engine)
|
|
22
31
|
|
|
23
32
|
@property
|
|
24
33
|
def engine(self) -> Engine:
|
|
25
34
|
"""The underlying SQLAlchemy engine."""
|
|
26
35
|
return self._engine
|
|
27
36
|
|
|
37
|
+
@property
|
|
38
|
+
def vocab_engine(self) -> Engine:
|
|
39
|
+
"""The engine routed to the OMOP vocabulary role."""
|
|
40
|
+
return self._vocab_engine
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def session_factory(self) -> Callable[[], Session]:
|
|
44
|
+
"""The session factory routed across the primary and vocabulary roles."""
|
|
45
|
+
return self._session_factory
|
|
46
|
+
|
|
28
47
|
def session(self):
|
|
29
48
|
"""Return a session context manager."""
|
|
30
49
|
return self._session_factory()
|
|
@@ -33,7 +52,7 @@ class CDMAdapter:
|
|
|
33
52
|
"""Return True if the CDM database is reachable (SELECT 1 probe)."""
|
|
34
53
|
try:
|
|
35
54
|
with self._engine.connect() as conn:
|
|
36
|
-
conn.execute(
|
|
55
|
+
conn.execute(select(literal(1)))
|
|
37
56
|
return True
|
|
38
57
|
except Exception:
|
|
39
58
|
return False
|
|
@@ -41,3 +60,5 @@ class CDMAdapter:
|
|
|
41
60
|
def close(self) -> None:
|
|
42
61
|
"""Dispose the engine and release the connection pool."""
|
|
43
62
|
self._engine.dispose()
|
|
63
|
+
if self._vocab_engine is not self._engine:
|
|
64
|
+
self._vocab_engine.dispose()
|