Build and Package

View as Markdown

The repository example builds a cdylib against the current 0.9.0 SDK and packages it with a strict schema. Run every command in this procedure from examples/rust-native-plugin unless a step says otherwise.

Build the Library

The example crate exposes both cdylib and rlib. Relay loads the cdylib; the rlib lets the example integration tests call validation helpers without loading an unsafe dynamic boundary. The dependencies use the current 0.9.0 public SDK rather than a Git revision or an older package line. The path = "../../crates/plugin" override exists only because this checked example builds inside the NeMo Relay repository. A standalone plugin depends on the published nemo-relay-plugin = "0.9.0" package without path.

The checked example uses the following package and dependency configuration:

1[package]
2name = "nemo-relay-rust-native-plugin-example"
3version = "0.1.0"
4edition = "2024"
5publish = false
6
7[lib]
8crate-type = ["cdylib", "rlib"]
9
10[dependencies]
11futures = "0.3"
12nemo-relay-plugin = { version = "0.9.0", path = "../../crates/plugin" }
13serde = { version = "1", features = ["derive"] }
14serde_json = "1"
15tokio = { version = "1", features = ["io-util", "macros", "time"] }

Build and materialize the platform-specific library as follows:

  1. Run the example tests and build the debug library.

    $cargo test
    $cargo build
  2. Copy relay-plugin.toml to relay-plugin.local.toml. Replace <platform-library-file> in source.artifact and load.library with the file Cargo produced: libnemo_relay_rust_native_plugin_example.dylib on macOS, libnemo_relay_rust_native_plugin_example.so on Linux, or nemo_relay_rust_native_plugin_example.dll on Windows.

  3. Calculate the artifact SHA-256 from the example directory. Use shasum -a 256 target/debug/<platform-library-file> on macOS, sha256sum target/debug/<platform-library-file> on Linux, or Get-FileHash -Algorithm SHA256 target/debug/<platform-library-file> in PowerShell. Put the lowercase result after the existing sha256: prefix.

At this point, success means the tests pass, the library exists at both manifest paths, and the digest describes those exact bytes.

Understand the Manifest

The checked manifest template declares the plugin identity, version contracts, schema, library path, and exported symbol:

1manifest_version = 1
2
3[plugin]
4id = "examples.rust_native_policy"
5kind = "rust_dynamic"
6
7[compat]
8relay = ">=0.9.0,<1.0"
9native_api = "1"
10
11[defaults]
12enabled = false
13
14[capabilities]
15items = ["plugin_native", "config_schema"]
16
17[config_schema]
18path = "config.schema.json"
19
20[source]
21artifact = "target/debug/<platform-library-file>"
22
23[integrity]
24sha256 = "sha256:<artifact-sha256>"
25
26[load]
27library = "target/debug/<platform-library-file>"
28symbol = "nemo_relay_register_plugin"

The source.artifact and load.library paths must identify the same library. Replace <artifact-sha256> with the lowercase digest of those bytes. The exported descriptor’s plugin kind must exactly match plugin.id. The schema includes the SDK-owned executor.worker_threads property because this example registers typed async middleware and allows a component override. additionalProperties: false prevents an operator typo from silently becoming inactive configuration.

The native-only schema fragment below gives the SDK executor override a strict positive integer. executor_config_for_component performs the corresponding runtime validation, so direct activation and package validation agree.

1{
2 "executor": {
3 "description": "Overrides the SDK-owned Tokio executor for this component.",
4 "type": "object",
5 "additionalProperties": false,
6 "properties": {
7 "worker_threads": {
8 "type": "integer",
9 "minimum": 1,
10 "default": 2
11 }
12 }
13 }
14}

Validate and Activate

Use the following procedure to validate the package, activate it, and remove it safely:

  1. From the repository root, validate the local manifest before adding it.

    $nemo-relay plugins validate ./examples/rust-native-plugin/relay-plugin.local.toml
  2. Register and enable the package in the user configuration.

    $nemo-relay plugins add --user ./examples/rust-native-plugin/relay-plugin.local.toml
    $nemo-relay plugins enable examples.rust_native_policy
  3. Add the shared scenario configuration under the dynamic record, including executor.worker_threads = 2. Start Relay with the package enabled, inspect the activation report, and execute the documented tool and LLM calls.

  4. Change requests.mode to an unsupported value and validate again. Then restore the valid value, add an unknown property, and verify that static package validation rejects the schema violation. During component validation, confirm that the plugin’s diagnostic also reports the field rather than ignoring it.

  5. Disable and remove the package after clearing the active component.

    $nemo-relay plugins disable examples.rust_native_policy
    $nemo-relay plugins remove examples.rust_native_policy

Success means manifest and schema validation fail before loading altered or invalid artifacts, a valid component produces an active runtime report, representative calls show the configured behavior, and removal occurs only after the host reports that the component registrations have been cleared.