Skip to main content

maintain-dynamic-plugins

Change NeMo Relay dynamic plugin loaders, manifests, native ABI, gRPC worker protocol, or Python worker SDK. Do not use for ordinary built-in plugin configuration.

Source facts

Repository
NVIDIA/NeMo-Relay
Last source activity
November 4, 2026 at 17:41
Detected SKILL.md language
English
Stars
240
Forks
109

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
maintain-dynamic-plugins
description
Change NeMo Relay dynamic plugin loaders, manifests, native ABI, gRPC worker protocol, or Python worker SDK. Do not use for ordinary built-in plugin configuration.
license
Apache-2.0
# Maintain Dynamic Plugins Use this skill for `plugin.kind = "rust_dynamic"`, `plugin.kind = "worker"`, `nemo-relay-plugin`, `nemo-relay-worker`, `nemo-relay-worker-proto`, `nemo-relay-types`, and the Python `nemo-relay-plugin` package. ## Rules - Keep the stable boundary explicit: native plugins cross a C ABI; worker plugins cross `nvidia.nemo.relay.worker.v1` (contract `1.0.0`). - Do not pass Rust runtime types, trait objects, futures, or allocator-owned strings across the native dynamic-library boundary. - Typed native middleware futures run on the SDK-owned Tokio executor. Keep subscribers synchronous and preserve raw synchronous ABI registrations. - Define closed worker transport structures in protobuf when generated clients must enforce their fields. Keep open application payloads lossless by using `JsonValue` or `JsonObject` rather than `google.protobuf.Value`. - Keep `relay-plugin.toml` dynamic records separate from generic runtime components. Enabled records can create internal component specs. Disabled records remain available for inspection but do not load. - Require migrated worker plugins to regenerate their bindings, rebuild, and declare a `compat.relay` range covering the new contract. Recommend `>=1.0.0,<2.0` for the current worker SDK. - Treat `compat.relay` as the plugin author's compatibility assertion, not proof that an artifact was rebuilt. Do not add a legacy raw-result adapter. - The worker protocol is `nvidia.nemo.relay.worker.v1`, contract version `1.0.0`. The native host uses ABI v8 and accepts v7 callback layouts. Guard append-only extensions with `struct_size`. Keep existing fields at their original offsets. A breaking native JSON contract needs a new `native_api` value. A breaking C layout needs a new ABI version. A breaking worker contract needs a new protocol identity. - Do not add tests under `src`; Rust tests belong in crate `tests/` trees and Python SDK tests belong under `python/tests`. - Native and worker plugins are trusted extensions. Document that native plugins are in-process and unsandboxed; worker plugins provide process isolation but not a security sandbox. ## Checklist - [ ] Manifest validation covers kind, compatibility, load contract, integrity, capability mismatch, and disabled-plugin behavior. - [ ] Native loader keeps libraries alive until registered callbacks are cleared and deregisters plugin kinds before unload. - [ ] Worker activation covers process launch, token auth, handshake, validation, declarative registration, proxy rollback, cancellation, and shutdown. - [ ] Rust and Python SDKs expose every supported registration surface. - [ ] Runtime helpers cover marks, scopes, continuations, and isolated scope stacks. - [ ] `plugins list`, `plugins inspect`, and `plugins validate` report lifecycle and compatibility status without leaking secret config. - [ ] Top-level `doctor` reports resolved dynamic plugin and host configuration status. - [ ] When detailed dynamic plugin guides exist, they keep Rust native, Python worker, and `nvidia.nemo.relay.worker.v1` protocol details on separate pages. - [ ] `justfile`, Codecov, and CI package/test workflows include new plugin crates and packages. ## Validation Choose checks by the changed layer: - Manifest or shared types: test the owning Rust crate. - Native loader or ABI: prepare plugin fixtures and run the focused native plugin integration test. - Worker protocol or host: test the worker crates and regenerate or test the Python worker SDK only when its protocol surface changes. - Shared runtime behavior: run the Rust suite and only binding suites whose observable plugin behavior changes. - Documentation or packaging: run their targeted checks only when changed. Canonical surface suites prepare plugin fixtures. Before a raw focused native or worker integration test, run `just build-test-plugin-fixtures`; never compile fixtures inside an individual test case. ## References - `crates/plugin-host/src/dynamic/` - `crates/plugin` - `crates/worker` - `crates/worker-proto` - `crates/types` - `python/plugin` - `examples/rust-native-plugin` - `docs/build-plugins` - `examples/python-grpc-worker-plugin`
View on GitHub