nemo-flow 0.1.0

Core Rust SDK for NeMo Flow observability, scope management, and runtime instrumentation.
Documentation
nemo-flow-0.1.0 has been yanked.

nemo-flow

nemo-flow is the core Rust SDK for NeMo Flow, a portable execution runtime for agent systems. Use it when a Rust application, framework adapter, or service needs one consistent way to scope, control, and observe tool and LLM calls.

Rust is the source of truth for NeMo Flow runtime behavior. The Python and Node.js bindings mirror the semantics exposed by this crate.

Why Use It?

  • 🧭 Own Rust execution context: Hierarchical scopes preserve parent-child relationships across tools, LLM calls, middleware, subscribers, and events.
  • 🛡️ Put policy around real calls: Guardrails and intercepts can block work, sanitize observability payloads, rewrite requests, or wrap execution.
  • 📡 Emit one lifecycle stream: Subscribers can consume canonical runtime events in-process or export them to ATIF, OpenTelemetry, and OpenInference.
  • 🧩 Integrate without changing orchestration: Wrap framework and provider callbacks while leaving scheduling, retries, memory, and result handling in the owning application.

What You Get

  • Managed tool and LLM execution: Run call boundaries through consistent lifecycle helpers and middleware ordering.
  • Scope-local runtime behavior: Attach middleware and subscribers to the scope that owns them and clean them up when that scope closes.
  • Plugin primitives: Register reusable runtime behavior configured from one shared plugin system.
  • Codec and typed helpers: Normalize provider requests and responses for framework integrations.
  • Binding source of truth: Use the runtime semantics mirrored by the Python and Node.js bindings.

Installation

Install the published crate in a Rust application:

cargo add nemo-flow serde_json

To add adaptive runtime behavior, install the companion crate too:

cargo add nemo-flow-adaptive

When consuming a local checkout, use path dependencies:

[dependencies]
nemo-flow = { path = "../NeMo-Flow/crates/core" }
nemo-flow-adaptive = { path = "../NeMo-Flow/crates/adaptive" }
serde_json = "1"

Getting Started

The smallest useful workflow is to create a scope, emit a mark event, and close the scope:

use nemo_flow::api::scope::{
    self, EmitMarkEventParams, PopScopeParams, PushScopeParams, ScopeAttributes, ScopeType,
};
use serde_json::json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    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())?;
    Ok(())
}

Documentation

NeMo Flow Documentation: https://nvidia.github.io/NeMo-Flow