Writing a Transformer Plugin¶
In a nutshell
This page is the tutorial for building your own transformer plugin: how to inherit from the right base class, register the entry point, package it, and test it. Looking for a plugin to use instead of writing one? Go to Transformer Plugins.
Creating a Plugin¶
-
Inherit from the base class for your transformer type. All seven live in
ovos_plugin_manager.templates.transformers:Base class Stage Entry-point group UtteranceTransformertext, before intent matching opm.transformer.textMetadataTransformermessage context, before intent matching opm.transformer.metadataIntentTransformerafter a match, before the handler runs opm.transformer.intentDialogTransformerspoken text, before TTS opm.transformer.dialogTTSTransformersynthesized audio, after TTS opm.transformer.ttsAudioTransformercaptured audio, before STT opm.transformer.audioTypedSlotsTransformertyped-slot spans, before the first matcher opm.transformer.typed_slotsEvery one of them takes
__init__(self, name, priority=50, config=None), andnameis a required positional argument. Pass your plugin's name as the default, because that name is also the key the base class reads your settings under inmycroft.conf:from ovos_plugin_manager.templates.transformers import UtteranceTransformer class MyCustomTransformer(UtteranceTransformer): def __init__(self, name="my-custom-transformer", priority=50, config=None): super().__init__(name, priority, config) def transform(self, utterances, context=None): return [u.lower() for u in utterances], {} -
Implement the
transformmethod (or specific audio hooks). It returns a tuple of(utterances, context)— return{}for the context if you add none. -
Register the entry point in your
pyproject.toml, using the group for your transformer type (here, an utterance transformer):
The optional config-discovery entry point
Like TTS and STT plugins, a transformer can register a second entry point that exposes
sample configurations for UI discovery. PluginConfigTypes defines one for every
transformer type: append .config to the group, so opm.transformer.text.config,
opm.transformer.audio.config, and so on.
[project.entry-points."opm.transformer.text.config"]
my-transformer.config = "my_package.module:MY_CONFIGS"
The entry-point name needs the .config suffix too, and the target must be a plain
dict — see Plugin Manager: Expose language
configurations. This is
optional; add it once the plugin has settings worth advertising.
Package and publish¶
-
Pin the dependency version. Put a floor and a ceiling on
ovos-plugin-managerinpyproject.toml, for exampleovos-plugin-manager>=0.5.0,<1.0.0, so a future breaking release does not silently pull in. -
Install for local development. Run
pip install -e .from the plugin's own repository. See OVOS Plugin Manager: Install and verify for the check that confirms the plugin is discoverable. -
Publish to PyPI. The Plugin Arena's benchmark sweep installs competitors from PyPI, so a transformer plugin needs a PyPI release before it can be entered. See Plugin Arena: Getting Your Plugin Ranked and TTS Plugins: Package and publish for the shared steps.
Test your plugin locally¶
Instantiate the class directly and call transform() on it:
from my_transformer_package import MyCustomTransformer
transformer = MyCustomTransformer()
utterances, context = transformer.transform(["HELLO WORLD"])
assert utterances == ["hello world"]
The constructor above works only because the example gives name a default. Without one,
MyCustomTransformer() raises TypeError: __init__() missing 1 required positional
argument: 'name' — the base class does not supply it.
Turn that into a pytest test that checks both return values:
from my_transformer_package import MyCustomTransformer
def test_transform_lowercases_utterances():
transformer = MyCustomTransformer()
utterances, context = transformer.transform(["HELLO WORLD"], context={})
assert utterances == ["hello world"]
assert isinstance(context, dict)
To exercise the plugin inside a full OVOS install, pip install -e . it into the same virtual
environment or container ovos-core runs in, then add its name under the matching section of
mycroft.conf (for example "utterance_transformers": {"my-custom-transformer": {}}) and
restart OVOS.
Read next: Transformer Plugins Related: Utterance Transformers · Plugin Manager · Plugin Arena