Rust Quick Start

View as Markdown

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:

1[dependencies]
2nemo-relay = { path = "../NeMo-Relay/crates/core" }
3nemo-relay-adaptive = { path = "../NeMo-Relay/crates/adaptive" }
4serde_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.

1use nemo_relay::api::scope::{
2 self, EmitMarkEventParams, PopScopeParams, PushScopeParams, ScopeAttributes, ScopeType,
3};
4use nemo_relay::api::subscriber::{deregister_subscriber, flush_subscribers, register_subscriber};
5use serde_json::json;
6use std::sync::Arc;
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 register_subscriber(
10 "quickstart-printer",
11 Arc::new(|event| {
12 println!("{} {}", event.kind(), event.name());
13 }),
14 )?;
15
16 let handle = scope::push_scope(
17 PushScopeParams::builder()
18 .name("demo-agent")
19 .scope_type(ScopeType::Agent)
20 .attributes(ScopeAttributes::empty())
21 .data(json!({"binding": "rust"}))
22 .build(),
23 )?;
24
25 scope::event(
26 EmitMarkEventParams::builder()
27 .name("initialized")
28 .parent(&handle)
29 .data(json!({"ok": true}))
30 .build(),
31 )?;
32 scope::pop_scope(PopScopeParams::builder().handle_uuid(&handle.uuid).build())?;
33 flush_subscribers()?;
34 let _ = deregister_subscriber("quickstart-printer")?;
35 Ok(())
36}

What Success Looks Like

The script should exit cleanly and print lifecycle lines from the subscriber. Native subscriber delivery is asynchronous, so examples flush before checking subscriber output. 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.