Python Worker
The examples/python-grpc-worker-plugin package uses the 0.8.0
nemo-relay-plugin SDK and the shared documentation configuration. Its worker registers
all 16 surfaces, accepts
synchronous and asynchronous callback forms where the
Python SDK permits them, and relies on the SDK for protobuf stubs, the authenticated
server, and cooperative task cancellation.
Test the Package
Run the package’s atomic tests before creating a managed environment:
-
Enter the example directory and run its self-contained test project.
Every test creates its own worker instance and mock host context, and any one test can be selected by node ID without running the rest of the suite. The tests separate configuration, JSON Schema, source digest, wheel packaging, registration metadata, sanitizers, policies, request outcomes, continuations, streams, and runtime cleanup. A digest mismatch is a packaging failure, not an activation warning.
Define the Installable Python Package
Relay creates the managed environment from the package root named by the
manifest. A
minimal pyproject.toml therefore needs a standard build backend, a package, and the
0.8 worker SDK dependency:
The module entrypoint is an async function, not a server factory or a prebound port. Relay supplies the authenticated endpoint and activation credentials when it starts the managed command.
Configure the Snapshot Location
Relay copies the worker runtime closure into an isolated activation snapshot before
starting the worker. Set NEMO_RELAY_PLUGIN_SNAPSHOT_DIR in the environment that starts
Relay to use a directory of your choice; Relay creates it when it does not exist. Choose a
location outside every directory copied into a snapshot, including active plugin packages and
external entrypoint directories:
Relay calls validation before registration, but register still rejects invalid direct
use instead of assuming every possible host followed the expected sequence.
The corresponding manifest tells Relay to install this directory and import main from
the installed module. Calculate the <worker-source-sha256> placeholder from the current
worker.py; changing that file requires a new digest.
The manifest uses relay = ">=0.8.0,<1.0" because Relay 0.8 changes the grpc-v1
tool-result boundary. ToolNext.call()
returns ToolExecutionResult, whose result
contains the application payload and whose optional annotation remains adjacent opaque
metadata. The protocol identifier stays grpc-v1, but workers built against earlier
generated bindings cannot decode the current structural result messages.
Install and Activate the Package
Use the following procedure to install the package into Relay’s managed environment and start the worker:
-
From
examples/python-grpc-worker-plugin, create a clean temporary Relay state and add the manifest.plugins addcreates an isolated managed environment and installssource.manifest_rootwith pip. SetNEMO_RELAY_PYTHONonly for this add operation when Relay must use a non-default base interpreter. Standard pip index, proxy, certificate, and wheelhouse variables control dependency resolution. -
Enable the component and start Relay.
The activation report should identify
examples.python_grpc_worker, and the worker handshake should advertise all 16 supported surfaces.
Verify Behavior and Clean Up
Use the following procedure to verify each callback family and clean up the managed environment:
-
Exercise one allowed and one blocked tool, one allowed and one blocked model, a unary LLM continuation, and a multi-chunk stream. Confirm configured headers, sanitized event fields, preserved annotations, pending marks, and lazy chunk transformation.
-
Cancel a long-running async callback and abandon a worker stream. Confirm the SDK task receives cancellation and the worker’s
finallycleanup runs. A synchronous callback cannot be preempted, so the example keeps synchronous work bounded. -
Emit a mark, use a nested scope, create and bind an isolated stack, then force a failure. Confirm the prior scope context is restored and the stack is dropped.
-
Stop Relay with
Ctrl+C, then remove the plugin and delete the temporary state from the shell whererelay_tmpandrelay_configremain defined.
plugins remove deletes the Relay-managed environment. Copying a Python worker manifest
into plugins.toml is not an equivalent installation path because no attested environment
would exist. Success means the managed environment is created and later removed, every
feature group has an observable call-path result, cancellation cleanup runs, and no
worker process remains after shutdown.