Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 76 additions & 13 deletions docs/about-nemo-relay/concepts/plugins.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Plugins let NeMo Relay install reusable runtime behavior from configuration
instead of requiring every application or framework integration to register the
same middleware and subscribers by hand.

They are the main packaging layer for reusable runtime components.
Plugins package reusable runtime components.

## Plugin Configuration Model

The canonical plugin document has three main areas:
A plugin configuration document has three main areas:

- `version`
- `components`
Expand All @@ -32,17 +32,29 @@ The version identifies the configuration format expected by the plugin system.

### Components

Components describe the individual runtime pieces to activate. Each component
declares what it is and which config it should use.
Components identify the runtime behavior to activate. Each component declares
its kind and configuration.

### Policy

Policy controls how strictly the plugin system interprets unknown fields,
unsupported values, or compatibility issues.

Two similarly named files serve different purposes:

| File | Owner | Purpose |
| --- | --- | --- |
| `plugins.toml` | Relay operator or application | Configures built-in components and records references to discoverable plugins. Relay discovers and layers this file. |
| `relay-plugin.toml` | Discoverable plugin author | Describes one packaged native library or worker, including compatibility, capabilities, loading, and integrity. Relay reads it through a reference in `plugins.toml`. |

Refer to [Plugin Configuration Files](/configure-plugins/plugin-configuration-files)
for runtime configuration and
[Discoverable Plugins](/build-plugins/dynamic-plugins/about) for the package
manifest.

## Component Lifecycle

Plugins follow a small lifecycle rather than registering everything blindly.
Relay validates plugin configuration before it activates any component.

### Validation

Expand All @@ -59,11 +71,21 @@ behavior.
Reporting provides structured diagnostics about what activated successfully and
what did not.

### Failure Boundary
### Deactivation and Cleanup

Relay tracks registrations created during plugin initialization. Clearing active
plugin configuration removes those registrations and runs component cleanup.
Dynamic plugin teardown also stops managed workers and releases native
activations after their callbacks are no longer registered. Applications should
clear plugin configuration during graceful shutdown and test teardown. Refer to
Comment thread
afourniernv marked this conversation as resolved.
[Register Plugin Behavior](/build-plugins/language-binding/register-behavior)
for the binding lifecycle.

### Setup Failures

Plugin validation and initialization are setup boundaries. If configuration is
invalid, a component kind is unavailable, or initialization fails, callers should
treat the plugin setup as failed before relying on the new runtime behavior.
Plugin validation and initialization happen during setup. If configuration is
invalid, a component kind is unavailable, or initialization fails, callers
should treat setup as failed before relying on the new runtime behavior.
Activation reports are the public way to inspect what validated or activated.

Runtime behavior after activation still belongs to the installed component. For
Expand Down Expand Up @@ -120,8 +142,8 @@ flowchart TB

## Plugin Context

The plugin context is the runtime surface that a component uses to register its
behavior. This is where plugins connect configuration to real runtime state.
The plugin context is the API that a component uses to register its behavior.
It connects plugin configuration to the active runtime.

## What Plugins Can Register

Expand All @@ -138,7 +160,9 @@ them.
## Ownership and Scope

Plugin initialization is process-level. It is intended for runtime components
that should activate once for the running process rather than once per request.
that should remain active across requests in one process. It is not permanent:
clearing or replacing the active plugin configuration removes plugin-owned
runtime behavior.

Scope-local behavior still matters after plugin installation, but the plugin
system itself is a global activation layer.
Expand All @@ -147,6 +171,17 @@ Plugins install runtime behavior; they do not create a separate execution
model. Scopes still own parentage and cleanup, middleware still owns execution
ordering, and events still own the canonical runtime record.

## Plugin Delivery Models

All plugin components use the same validation and activation model. They differ
in how their component kind becomes available to the host:

| Delivery model | How it becomes available | Use when |
| --- | --- | --- |
| Built-in | The Relay host registers a linked first-party component automatically. | The component ships as part of that host. |
| Host-registered | An embedding application links a component crate and registers its kind before validation. | An embedding application decides which component crates to link. |
| Discoverable | The CLI loads a manifest-backed native library or worker at startup. | A separately packaged extension should be installed without rebuilding Relay. |

## Built-In Plugin Components

The core runtime registers the `observability`, `nemo_guardrails`, and
Expand Down Expand Up @@ -220,6 +255,16 @@ The core crate ships a built-in `pricing` component. It loads catalog sources
that response codecs can use to annotate managed LLM responses with cost
estimates. Configure catalog sources through [Model Pricing](/configure-plugins/model-pricing).

### Switchyard (Experimental)

The experimental `switchyard` component asks a separately running Switchyard
Decision API to select a configured model backend. It is excluded from default
CLI builds and is registered only when the CLI is built with the optional
`switchyard` feature. Direct Rust, Python, and Node.js hosts do not register it
automatically. Refer to
[Switchyard (Experimental)](/configure-plugins/switchyard/about) for the pinned
compatibility and deployment requirements.

For `plugins.toml` discovery, precedence, merge, and gateway editing rules,
refer to [Plugin Configuration Files](/configure-plugins/plugin-configuration-files).

Expand All @@ -238,7 +283,25 @@ evidence before enabling or running a dynamic plugin. During startup, Relay
loads the enabled adapter and then validates the synthesized component. Refer
to [Configure Discoverable Plugins](/configure-plugins/discoverable-plugins)
for the operator workflow and [Discoverable Plugins](/build-plugins/dynamic-plugins/about)
for the authoring model.
for the authoring workflow.

The operator lifecycle is explicit:

1. `nemo-relay plugins add <manifest>` records the manifest and prepares managed
worker resources when required.
2. `nemo-relay plugins inspect <plugin-id>` reads the stored registration and
resolved manifest without changing desired state.
3. `nemo-relay plugins validate <plugin-id>` checks compatibility, schema,
policy, and trust evidence.
4. `nemo-relay plugins enable <plugin-id>` changes desired state; the plugin
loads during the next host startup.
5. `nemo-relay plugins disable <plugin-id>` keeps the registration but prevents
it from loading on the next startup.
6. `nemo-relay plugins remove <plugin-id>` deletes the registration and any
Relay-managed worker environment after the running host has stopped.

These commands manage future host activation. Teardown of an already running
host remains part of that host's owned plugin cleanup.

## Practical Guidance

Expand Down