Plugins

Plugin registry exports.

@domain plugins @see [[knowledge/architecture/plugins]]

Plugin registry with entry-point discovery.

@domain plugins @see [[knowledge/architecture/plugins]] @tested-by [[tests/plugins/test_registry.py]]

mllm_shap.plugins.registry.PluginFactory

Callable building a plugin from a PluginContext.

alias of Callable[[PluginContext], object]

class mllm_shap.plugins.registry.PluginRegistry[source]

Bases: object

Register and resolve pipeline plugins by group and name.

copy() → PluginRegistry[source]

Return a registry with the same factories, independent of this one.

register(group: PluginGroup | str, name: str, factory: Callable[[PluginContext], object], replace: bool = False) → None[source]

Register a plugin factory under group and name.

Raises:

PluginConflictError – If name is already registered in group and replace is false.

resolve(group: PluginGroup | str, name: str, context: PluginContext) → object[source]

Build the plugin registered under group and name.

The factory receives context with options set to explanation.plugin_options["<group>/<name>"] or, failing that, explanation.plugin_options["<name>"] (empty when both are absent), validated against the plugin’s options model when it declares one.

Raises:
  • PluginNotFoundError – If nothing is registered under that name.

  • ConfigError – If the options hold an unknown key or a wrong type, or the plugin has options under both keys.

resolve_factory(group: PluginGroup | str, name: str) → Callable[[PluginContext], object][source]

Return the factory registered under group and name.

Raises:

PluginNotFoundError – If nothing is registered under that name.

resolve_type(group: PluginGroup | str, name: str) → type[source]

Return a plugin class registered under group and name.

names(group: PluginGroup | str) → tuple[str, ...][source]

Return sorted plugin names registered for group.

load_entry_points(group: PluginGroup | str) → None[source]

Discover and register plugins from a packaging entry-point group.

Names that are already registered (for example the built-in plugins registered by register_builtin_plugins()) are skipped without importing their entry point.

Raises:

PluginLoadError – If an entry point cannot be imported.

Context handed to every plugin factory.

@domain plugins @see [[knowledge/architecture/plugins]]

class mllm_shap.plugins.context.PluginContext(config: ExplainConfig, options: Mapping[str, object]=<factory>, registry: PluginRegistry = <factory>)[source]

Bases: object

Inputs a plugin factory receives when the registry builds a plugin.

Plugin classes take the context as their first constructor argument (Plugin(context)) and read the settings they need from it.

config: ExplainConfig

Validated explain configuration of the run.

options: Mapping[str, object]

Validated options for this plugin from explanation.plugin_options.

Looked up under <group>/<name> first, then under the bare plugin name.

registry: PluginRegistry

Registry that built the plugin, for plugins that resolve other plugins.

option(key: str, default: T) → T[source]

Return options[key], or default when the key is absent.

Integers are accepted where the default is a float.

Raises:

ConfigError – If the option value has a different type than default.

Lookup and validation of explanation.plugin_options.

@domain plugins @see [[knowledge/architecture/plugins]]

mllm_shap.plugins.options.group_key(group: PluginGroup | str) → str[source]

Return the short group name used in qualified option keys (value_fns).

mllm_shap.plugins.options.select_plugin_options(plugin_options: Mapping[str, Mapping[str, object]], group: PluginGroup | str, name: str) → Mapping[str, object][source]

Return the options stored under <group>/<name> or the bare <name>.

Raises:

ConfigError – If both keys are present.

mllm_shap.plugins.options.validate_plugin_options(factory: PluginFactory, group: PluginGroup | str, name: str, options: Mapping[str, object]) → Mapping[str, object][source]

Check options against the factory’s declared options model.

Factories that declare no PluginOptions model get options back unchanged.

Raises:

ConfigError – Naming the group, plugin and key of an unknown option or of a value with the wrong type.

mllm_shap.plugins.options.run_plugins(config: ExplainConfig) → dict[str, str][source]

Return the plugin name the run selects in each group, keyed by short group.

mllm_shap.plugins.options.check_plugin_options(config: ExplainConfig, registry: PluginRegistry) → None[source]

Check every explanation.plugin_options entry before a run starts.

A key is <group>/<name> (for example absence_policies/pad) or a bare plugin name. It must name a plugin the run uses, or a registered renderer; a bare name must match one group only. Options of plugins that declare an options model are validated against it.

Raises:

ConfigError – If a key names no plugin of the run, an unknown group or more than one plugin, or holds an unknown option.

Plugin group identifiers for entry-point loading.

@domain plugins @see [[knowledge/architecture/plugins]] @tested-by [[tests/plugins/test_groups.py]]

class mllm_shap.plugins.groups.PluginGroup(*values)[source]

Bases: StrEnum

Entry-point groups registered in packaging metadata.

ESTIMATORS = 'mllm_shap.estimators'

Coalition-sampling estimator plugins.

ESTIMANDS = 'mllm_shap.estimands'

Coalition payoff aggregation plugins.

VALUE_FNS = 'mllm_shap.value_fns'

Utility scoring plugins for coalition outputs.

NORMALIZERS = 'mllm_shap.normalizers'

Post-aggregation presentation normalizer plugins.

BACKENDS = 'mllm_shap.backends'

Model inference backend plugins.

PARTITIONS = 'mllm_shap.partitions'

Player-partitioning plugins for conversation snapshots.

ABSENCE_POLICIES = 'mllm_shap.absence_policies'

Absence-policy plugins for rendering masked snapshots.

RENDERERS = 'mllm_shap.renderers'

Attribution visualization renderer plugins.

Built-in plugin registration and the default registry.

@domain plugins @see [[knowledge/architecture/plugins]] @tested-by [[tests/plugins/test_builtin.py]]

mllm_shap.plugins.builtin.BUILTIN_PLUGINS: dict[PluginGroup, dict[str, Callable[[PluginContext], object]]] = {PluginGroup.ABSENCE_POLICIES: {'delete': <class 'mllm_shap.masking.policies.DeletePolicy'>, 'neutral': <class 'mllm_shap.masking.policies.NeutralPolicy'>, 'pad': <class 'mllm_shap.masking.policies.PadPolicy'>}, PluginGroup.BACKENDS: {'api': <class 'mllm_shap.backends.api.backend.ApiBackend'>, 'lmstudio': <class 'mllm_shap.backends.lmstudio.backend.LmStudioBackend'>, 'mock': <class 'mllm_shap.backends.mock.backend.MockBackend'>, 'mock_audio': <class 'mllm_shap.backends.mock.audio.MockAudioBackend'>, 'transformers': <class 'mllm_shap.backends.transformers.text.TransformersTextBackend'>}, PluginGroup.ESTIMANDS: {'banzhaf': <class 'mllm_shap.estimation.estimands.banzhaf.BanzhafAggregator'>, 'shapley': <class 'mllm_shap.estimation.estimands.shapley.ShapleyAggregator'>}, PluginGroup.ESTIMATORS: {'complementary': <class 'mllm_shap.estimation.complementary.ComplementaryEstimator'>, 'exact': <class 'mllm_shap.estimation.exact.ExactEstimator'>, 'loo': <class 'mllm_shap.estimation.loo.LeaveOneOutEstimator'>, 'mc': <class 'mllm_shap.estimation.monte_carlo.MonteCarloEstimator'>, 'neyman_cc': <class 'mllm_shap.estimation.neyman.NeymanEstimator'>}, PluginGroup.NORMALIZERS: {'abs_sum': <class 'mllm_shap.estimation.normalizers.AbsSumNormalizer'>, 'identity': <class 'mllm_shap.estimation.normalizers.IdentityNormalizer'>, 'min_max': <class 'mllm_shap.estimation.normalizers.MinMaxNormalizer'>, 'power_shift': <class 'mllm_shap.estimation.normalizers.PowerShiftNormalizer'>}, PluginGroup.PARTITIONS: {'messages': <class 'mllm_shap.masking.partitions.MessagePartitioner'>, 'sgpa_segments': <class 'mllm_shap.alignment.partitions.SgpaSegmentPartitioner'>, 'tokens': <class 'mllm_shap.masking.partitions.TokenPartitioner'>}, PluginGroup.RENDERERS: {'token_bar': <class 'mllm_shap.viz.token_bar.TokenBarRenderer'>, 'token_text': <class 'mllm_shap.viz.token_text.TokenTextRenderer'>}, PluginGroup.VALUE_FNS: {'embedding_cosine': <class 'mllm_shap.value.embedding.CosineEmbeddingValue'>, 'embedding_euclidean': <class 'mllm_shap.value.embedding.EuclideanEmbeddingValue'>, 'logprob': <class 'mllm_shap.value.logprob.LogprobValue'>, 'reference_wer': <class 'mllm_shap.value.wer.ReferenceWerValue'>, 'tfidf_cosine': <class 'mllm_shap.value.tfidf.TfIdfCosineValue'>}}

Built-in plugin factories per group; mirrors the pyproject.toml entry points.

mllm_shap.plugins.builtin.register_builtin_plugins(registry: PluginRegistry) → None[source]

Register every built-in plugin of all eight groups in registry.

mllm_shap.plugins.builtin.default_registry() → PluginRegistry[source]

Return a registry with the built-in plugins and third-party entry points.

Entry points that reuse a built-in name are skipped.

Raises:

PluginLoadError – If a third-party entry point cannot be imported.

Backend plugin construction helpers.

@domain plugins @see [[knowledge/architecture/plugins]] @tested-by [[tests/plugins/test_backends.py]]

mllm_shap.plugins.backends.instantiate_backend(context: PluginContext) → GenerativeBackend[source]

Build the backend named by context.config.backend.kind.