feat(python): initialize plugins from TOML - #684
Draft
bbednarski9 wants to merge 7 commits into
Draft
Conversation
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
License DiffCompared against Lockfile license changesLockfile License ChangesRustAdded
Removed
Updated/Changed
NodeAdded
Removed
Updated/Changed
PythonAdded
Removed
Updated/Changed
Status output |
2 tasks
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
Signed-off-by: Bryan Bednarski <bbednarski@nvidia.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds an owned Python initialization path for ordinary
plugins.tomlfiles, including lifecycle-enabled dynamic plugins, without requiring an embedded host to parse[[plugins.dynamic]]or construct activation specs itself.This is the first PR in a two-PR stack. It introduces the binding-neutral resolver and activation foundation and exposes it in Python. A stacked follow-up will migrate the CLI runtime owner to the same activation plan while preserving the CLI control plane and bootstrap behavior.
Details
nemo-relay-plugin-host-configworkspace crate. It shares Relay's user/project/system source selection, component merge rules, dynamic host policy, lifecycle state, trust checks, managed-environment attestation, and immutable activation snapshots with embedded hosts.nemo_relay.plugin.initialize_from_plugins_toml(...)and the ownedPluginFileActivationasync lifetime. The API supports default discovery or a selectedplugins.toml, a highest-precedence static overlay, inactive no-input handles, owned static-only handles, deterministic/idempotent close, async context management, and best-effort finalization.[[plugins.dynamic]]as declarations only. Each declaration is validated and reconciled against the same source file's sibling.dynamic-plugins.json; only live records withspec.enabled == trueenter the activation plan. Initialization never installs packages, creates environments, changes enablement, or editsplugins.toml.config_ref; duplicate IDs and ambiguous live source moves fail closed.PluginHostActivationPlanthat carries resolved static config, ordered dynamic specs, redacted diagnostics, andArc-owned snapshot resources into Relay's cancellation-resistant mutation executor.libpython<major>.<minor>.dylibselected by the attestation-verifiedpyvenv.cfg; the copied runtime library is then covered by the immutable snapshot digest and protection.initialize(),initialize_with_dynamic_plugins(), explicit activation specs, generic clear APIs, and non-Python bindings unchanged.Security model: calling the new initializer is explicit consent to load lifecycle-enabled trusted native libraries or worker processes from the selected configuration scope. Enabled Python workers must already have a valid Relay-managed environment and attestation; this API is not an installer or control plane. Diagnostics include source paths and plugin IDs but do not include component values or credentials.
Validation completed locally:
cargo test -p nemo-relay-plugin-host-configcargo test -p nemo-relay-cli plugins::lifecycle::tests(79 lifecycle/control-plane tests)cargo test -p nemo-relay --features worker-grpc --test native_plugin_integration --test worker_plugin_integrationjust test-rustjust test-python-pluginjust test-python-plugin-e2eunder the CI-pinned uv CPython 3.11.14 runtime (managed gRPC worker add, enable, activation, middleware execution, and teardown)just test-pythonjust test-gojust test-nodecargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningsjust package-rustjust package-pythonjust package-python-sdist(verified the shared crate is present in the sdist)just docsjust docs-linkcheckuv run pre-commit run --all-filesBreaking changes: none. This is an additive Python API and a document-hidden Rust host contract. Node, FFI, and Go retain their existing explicit-spec APIs.
Where should the reviewer start?
Start with
crates/plugin-host-config/src/activation.rsandcrates/plugin-host-config/src/resolver.rsfor the file-backed contract, then reviewcrates/core/src/plugin/dynamic/host.rsfor atomic ownership and teardown. The Python surface is wired incrates/python/src/py_plugin.rsandpython/nemo_relay/plugin.py.The most important design invariant is that the same immutable snapshot verified immediately before load remains owned by the native or worker runtime through the last in-flight callback. Lifecycle reconciliation is durable configuration state, not part of the runtime activation transaction.
Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)