Skip to content

Conversation

@mart-r
Copy link
Collaborator

@mart-r mart-r commented Dec 21, 2025

Improved Plugin System: Model Awareness and Better Error Handling

Overview

This PR enhances the plugin system to make models aware of what plugins they use, improves error handling when required plugins are missing, and provides better visibility into plugin dependencies through model cards.

Key Features

1. Plugin Registration and Tracking

  • Plugin Registry: Created a centralized registry (PluginRegistry) that tracks all loaded plugins and their metadata (name, version, author, URL)
  • Component Tracking: Each plugin now registers which components (core and addons) it provides
  • Automatic Discovery: Plugins can be discovered via module path fallback when explicit registration isn't available
    • This can happen if the registration of a component happens outside the scope of the loading of the plugin by the core lib

2. Model Card Enhancements

  • Pipeline Description: Model cards now include detailed pipeline information showing all components and their providers
  • Required Plugins: Model cards list all required plugins with their metadata (author, URL)
  • Clear Dependencies: Users can see exactly what plugins are needed to load and use a model pack

3. Improved Error Handling

  • MissingPluginError: New exception type for when required plugins are missing
  • Informative Messages: Clear error messages listing missing plugins and what they provide
  • Early Detection: Plugin availability is checked before attempting to load the model

4. Backward Compatibility

  • Default Provider: Components without explicit plugin association default to "medcat"
  • Fallback Mechanisms: Works with plugins that don't use the new registration system
  • Legacy Support: Maintains compatibility with existing models and plugins

Example: Missing Plugin Error

When a user tries to load a model pack without the required plugins installed, they now get a clear error message:

>>> cat = CAT.load_model_pack("../../cogstack-ops/medcat-gliner/temp/2023_w_gliner_234dda1597f635e3.zip")
Missing required plugins for this model pack. Attempting to load anyway, but it may fail. Missing: ['medcat_gliner']
Traceback (most recent call last):
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/cat.py", line 857, in load_model_pack
    cat = deserialise(model_pack_path, model_load_path=model_pack_path,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/storage/serialisers.py", line 369, in deserialise
    return ser.deserialise_all(
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/storage/serialisers.py", line 210, in deserialise_all
    part = self.deserialise_all(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/storage/serialisers.py", line 210, in deserialise_all
    part = self.deserialise_all(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/storage/serialisers.py", line 210, in deserialise_all
    part = self.deserialise_all(
           ^^^^^^^^^^^^^^^^^^^^^
  [Previous line repeated 2 more times]
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/storage/serialisers.py", line 189, in deserialise_all
    module = import_module(module_path)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/martratas/.pyenv/versions/3.12.10/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'medcat_gliner'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/martratas/Documents/CogStack/.MedCAT.nosync/monorepo-nlp/medcat-v2/medcat/cat.py", line 874, in load_model_pack
    raise MissingPluginError(missing_plugins) from e
medcat.utils.exceptions.MissingPluginError: The following required plugins are missing:
  - Plugin: medcat_gliner
    Provides components: ner:gliner_ner
    Author: Mart Ratas <mart.ratas@kcl.ac.uk>
    URL: Homepage, https://github.com/CogStack/medcat-ops/tree/main/medcat-gliner

Please install the missing plugins to load this model pack.

Model card example

{
  "Model ID": "234dda1597f635e3",
  "Last Modified On": "2025-11-07T12:57:03.405689",
  "History (from least to most recent)": [
    "234dda1597f635e3"
  ],
  "Description": "This is a UK KCH medcat model. Created on the 20220913. It contains mappings to ICD10 and OPCS4. Enjoy!",
  "Source Ontology": [
    "20220803_SNOMED_UK_clinical_ext",
    "20220831_SNOMED_UK_drug_ext",
    "Enriched via UMLS v2022AA English terms only"
  ],
  "Location": "N/A",
  "Pipeline Description": {
    "core": {
      "tagging": {
        "name": "tag-and-skip-tagger",
        "provider": "medcat"
      },
      "token_normalizing": {
        "name": "token_normalizer",
        "provider": "medcat"
      },
      "ner": {
        "name": "gliner_ner",
        "provider": "medcat_gliner"
      },
      "linking": {
        "name": "medcat2_linker",
        "provider": "medcat"
      }
    },
    "addons": []
  },
  "Required Plugins": [
    {
      "name": "medcat_gliner",
      "provides": [
        [
          "ner",
          "gliner_ner"
        ]
      ],
      "author": "Mart Ratas <mart.ratas@kcl.ac.uk>",
      "url": "Homepage, https://github.com/CogStack/medcat-ops/tree/main/medcat-gliner"
    }
  ],
  "MetaCAT models": [],
  "Basic CDB Stats": {
    "Number of concepts": 760283,
    "Number of names": 3080847,
    "Number of concepts that received training": 38460,
    "Number of seen training examples in total": 153875883,
    "Average training examples per concept": 4000.932995319813,
    "Unsupervised training history": [],
    "Supervised training history": []
  },
  "Performance": {},
  "Important Parameters (Partial view, all available in cat.config)": {
    "config.ponents.ner.min_name_len": {
      "value": 2,
      "description": "Minimum detection length (found terms/mentions shorter than this will not be detected)."
    },
    "config.ponents.ner.upper_case_limit_len": {
      "value": 2,
      "description": "All detected terms shorter than this value have to be uppercase, otherwise they will be ignored."
    },
    "config.ponents.linking.similarity_threshold": {
      "value": 0.3,
      "description": "If the confidence of the model is lower than this a detection will be ignore."
    },
    "config.ponents.linking.filters.cuis": {
      "value": 0,
      "description": "Length of the CUIs filter to be included in outputs. If this is not 0 (i.e. not empty) its best to check what is included before using the model"
    },
    "config.general.spell_check": {
      "value": true,
      "description": "Is spell checking enabled."
    },
    "config.general.spell_check_len_limit": {
      "value": 4,
      "description": "Words shorter than this will not be spell checked."
    }
  },
  "MedCAT Version": "2.2.0.dev0"
}

@tomolopolis
Copy link
Member

Task linked: CU-869bhm1zy Improve plugin system

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants