Rust Quick Start#

This quick start shows the smallest Rust workflow that emits scope and mark events.

Choose an Install Path#

Pick the installation path that matches whether you are using a published package or a local checkout.

Install from a Package Manager#

Use the published crates when you are consuming a release:

cargo add nemo-relay@0.3.0
cargo add nemo-relay-adaptive@0.3.0
cargo add serde_json

Install the published NeMo Relay CLI separately when you need coding-agent hook and LLM gateway observability:

cargo install nemo-relay-cli@0.3.0

Install from the Repository#

Use a path dependency when your application is consuming a local checkout:

[dependencies]
nemo-relay = { path = "../NeMo-Relay/crates/core" }
nemo-relay-adaptive = { path = "../NeMo-Relay/crates/adaptive" }
serde_json = "1"
  • nemo-relay is the core Rust runtime surface.

  • nemo-relay-adaptive is the companion crate for adaptive runtime primitives and Redis-backed learning components.

  • nemo-relay-cli is a binary crate. Use cargo install nemo-relay-cli@0.3.0 when you need the NeMo Relay CLI.

Push a Scope and Emit a Mark#

The example below creates a scope and records a mark event from Rust.

use nemo_relay::api::scope::{
    self, EmitMarkEventParams, PopScopeParams, PushScopeParams, ScopeAttributes, ScopeType,
};
use nemo_relay::api::subscriber::{deregister_subscriber, register_subscriber};
use serde_json::json;
use std::sync::Arc;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    register_subscriber(
        "quickstart-printer",
        Arc::new(|event| {
            println!("{} {}", event.kind(), event.name());
        }),
    )?;

    let handle = scope::push_scope(
        PushScopeParams::builder()
            .name("demo-agent")
            .scope_type(ScopeType::Agent)
            .attributes(ScopeAttributes::empty())
            .data(json!({"binding": "rust"}))
            .build(),
    )?;

    scope::event(
        EmitMarkEventParams::builder()
            .name("initialized")
            .parent(&handle)
            .data(json!({"ok": true}))
            .build(),
    )?;
    scope::pop_scope(PopScopeParams::builder().handle_uuid(&handle.uuid).build())?;
    let _ = deregister_subscriber("quickstart-printer")?;
    Ok(())
}

What Success Looks Like#

The script should exit cleanly and print lifecycle lines from the subscriber. You should see one line for the scope start event, one for the initialized mark, and one for the scope end event.

That tells you two things:

  • The scope API ran successfully.

  • Emitted events were observable through the subscriber system.

What to Learn Next#

Use these links to continue from the quick start into the core runtime concepts.