Runtime Events and Scopes
Worker code cannot manipulate host scope objects
directly. The SDK exposes an
authenticated PluginRuntime proxy whose operations preserve the invocation’s captured
scope context while the RelayHostRuntime service performs the real work.
Runtime Operation Map
Every host request carries the activation ID, token, and relevant scope context. A worker must not expose, log, or persist the activation token or codec capability IDs. Those values identify a live local capability and expire with the activation or invocation.
Control a Registration from a Background Task
Worker gates are host-resident. Relay does not call the worker while it resolves a middleware chain or publishes an event. A worker timer or health monitor can therefore register a constant-reason gate, retain its activation-owned handle, and deregister it later.
The following worker flows discover the observability plugin’s OpenTelemetry subscriber and disable it for one timer interval:
Python
Rust
The worker can remove only gates owned by its activation. Relay removes any
remaining owned gates during ordinary activation teardown. A worker can also
call PluginContext.register_conditional_middleware_guardrail during
registration to declare an initial host-resident gate; use PluginRuntime for
timer-controlled changes after activation.
Refer to Conditional Middleware Guardrails for global-only behavior, effective-name discovery, all-matching-gate semantics, and the distinction between activation-owned and runtime-discovered gates.
Declare an Initial Gate
Use the component context when the validated configuration requires the gate for the complete worker activation. The following examples install the same host-resident constant reason:
Python
Rust
Relay validates initial gate names, kinds, targets, and duplicate names before it commits the worker registrations. Failed registration returns no initial gates. Ordinary teardown removes every gate that remains owned by the worker activation.
Use typed mark options when an exported mark needs
a data schema or log severity. Use
emit_metric for Relay metric measurements. runtime_diagnostics returns the bounded,
ordered host-level { code, message, count } snapshot. It does not identify the plugin
that recorded a diagnostic.
Emit Typed Telemetry and Read Diagnostics
Choose your worker language to add schema and severity metadata to a mark and inspect runtime diagnostics:
Python
Rust
An older host can return UNIMPLEMENTED for runtime_diagnostics. The SDK reports that
as an unsupported runtime-diagnostics error. Relay validates the data schema and
severity at the host boundary. It validates metric measurements after sanitization, so
it rejects an invalid group as a whole.
Execute the Complete Cleanup Sequence
Choose your worker language to review the complete cleanup sequence:
Python
Rust
The Python helper pushes a child scope, emits the ordinary mark inside it, and closes the
scope by its returned handle. It then binds an isolated stack only for work that should
have independent parentage. The finally block drops the stack even if isolated mark
emission fails or the callback is cancelled.
Both implementations pop the handle exactly once. Successful work supplies scope output; failed work supplies failure metadata and then propagates the original callback error.
Clean Up Under Failure
The examples use a structured cleanup sequence: capture the previous binding, create an
isolated stack only when configured, bind it, push a scope, run plugin work, pop the scope
with success or error metadata, restore the previous binding, and drop the isolated
stack. Python uses try/finally; Rust uses explicit result handling and awaits cleanup
before returning.
Shutdown can race with these operations. The worker stops accepting new invocations, cancels active callbacks, and continues only the bounded cleanup that the SDK can still authenticate. An unreachable host can reject final cleanup, so the worker also releases its local handles and terminates rather than retrying forever.
Verify Parentage and Restoration
Use the following procedure to verify scope parentage, restoration, and failure cleanup:
- Invoke middleware inside a managed LLM scope and emit a mark through the runtime proxy. Confirm the mark’s parent is the invocation scope.
- Push and pop a child custom scope and verify its start and end event ordering.
- Create and bind an isolated stack, emit another mark, and confirm it belongs to the isolated root rather than the application call.
- Raise an error after the push and confirm the pop, prior binding restoration, and stack drop still occur.
- Cancel the callback during runtime work and repeat the same cleanup assertions.
Success means marks and scopes have intentional parentage, invocation tokens stay private, no stack remains owned after failure or cancellation, and subsequent worker callbacks receive their own unmodified scope snapshots.