Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions docs/build-plugins/plugin-configuration-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,57 @@ generic plugin document and component-local `config` objects use canonical

</Note>

## Shortest Path Example

Use this minimal `plugins.toml` when you want the CLI gateway to start with one
plugin-managed observability exporter and no extra layering:

```toml
version = 1

[[components]]
kind = "observability"
enabled = true

[components.config]
version = 1

[components.config.atof]
enabled = true
output_directory = "logs"
filename = "events.jsonl"
mode = "append"
```

For the most deterministic verification path, place `plugins.toml` next to the
gateway `config.toml` you want this run to use, then launch the wrapper with
that explicit config root. For example:

```bash
nemo-relay --config path/to/config.toml run -- codex
```

This keeps plugin discovery scoped to the colocated `plugins.toml` instead of
relying on implicit project, user, or system plugin files. The plugin file is
the configuration being demonstrated here; `--config` only tells the gateway
which config root to use for this run. If you prefer implicit discovery, place
the file at `./.nemo-relay/plugins.toml` or another discovered location and
ensure no higher-precedence plugin file overrides the exporter you want to
verify. See [CLI Basic Usage](/nemo-relay-cli/basic-usage) for the wrapper
command shapes.

## What Success Looks Like

The shortest-path setup is working when:

- `nemo-relay` starts without plugin validation or activation errors.
- The observability component activates the ATOF exporter configured in this
file.
- An instrumented gateway run writes ATOF JSONL output to `logs/events.jsonl`.

After that path works, expand the config with additional components, policies,
or higher-precedence files as needed.

## File Shape

`plugins.toml` uses the canonical plugin document shape:
Expand Down
21 changes: 19 additions & 2 deletions docs/getting-started/quick-start/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ If you still need the shared runtime vocabulary for scopes, middleware, events,
or plugins, refer to the [Agent Runtime Primer](/getting-started/agent-runtime-primer)
or [Concepts](/about-nemo-relay/concepts) first.

## Examples by Integration Layer

Use this map when you know what Relay boundary you want to verify, but you do
not yet know which guide owns the working path.

| Layer | Use When | Start Here | Success Check |
|---|---|---|---|
| CLI and gateway | A coding-agent harness owns invocation and provider routing | [CLI Basic Usage](/nemo-relay-cli/basic-usage) | The wrapped agent runs with Relay active and emits hook output, plus gateway-routed LLM lifecycle output when provider routing is active. |
| Persistent host-plugin installs | You want the maintained install path for Codex or Claude Code instead of the transparent wrapper | [Plugin Installation](/nemo-relay-cli/plugin-installation) | `nemo-relay doctor --plugin <host>` confirms the installed host plugin is registered and ready. |
| Direct Python or Node.js application APIs | Your application owns the tool or LLM callback | [Python Quick Start](/getting-started/quick-start/python) or [Node.js Quick Start](/getting-started/quick-start/nodejs) | The sample prints event lines plus tool and LLM results. |
| Direct Rust application APIs | Your Rust application owns the tool or LLM callback | [Rust Quick Start](/getting-started/quick-start/rust) | The sample prints scope, tool, LLM, and mark lifecycle output. |
| Plugin-managed runtime setup | You need process-level exporter or plugin behavior from `plugins.toml` | [Plugin Configuration Files](/build-plugins/plugin-configuration-files) | The selected plugin path activates and writes the expected output or behavior. |
| Managed middleware | You want policy, redaction, routing, or execution wrapping around managed calls | [Add Middleware](/instrument-applications/advanced-guide) | One allowed request succeeds, one rejected request stops before execution, and observed payloads match the policy. |
| Framework integrations | A framework such as LangChain, LangGraph, or Deep Agents owns callbacks or scheduling | [Supported Integrations](/supported-integrations/about) | The integration guide's verify step confirms the expected framework-owned output. |
| OpenClaw plugin path | OpenClaw owns plugin setup and Relay observes the OpenClaw-managed boundary | [OpenClaw](/supported-integrations/openclaw-plugin) | The OpenClaw guide's verify step confirms plugin setup and runtime output. |
| Manual or CI workflows | You need explicit config files, deterministic commands, or non-interactive automation | [CLI Basic Usage](/nemo-relay-cli/basic-usage) and [Plugin Configuration Files](/build-plugins/plugin-configuration-files) | The explicit command uses the intended config files without interactive setup. |

## Local Coding-Agent Runs

Use the NVIDIA NeMo Relay CLI when you want to observe a local Codex, Claude
Expand Down Expand Up @@ -114,8 +131,8 @@ Smallest Node.js workflow that emits scope, tool, and LLM events.
href="/getting-started/quick-start/rust"
>

Smallest Rust workflow for direct runtime ownership, starting from scope events
and mark-based checkpoints.
Smallest Rust workflow for direct runtime ownership that emits scope, tool, and
LLM events.
</Card>

</CardGroup>
3 changes: 3 additions & 0 deletions docs/getting-started/quick-start/nodejs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ This path is for local source development when you need to build the binding fro
## Run One Scope, One Tool Call, and One LLM Call

The example below runs one minimal instrumented workflow through the binding.
Save it as `quickstart.js` in the same project where you installed
`nemo-relay-node`, then run `node quickstart.js`.

```js
const {
Expand Down Expand Up @@ -85,6 +87,7 @@ async function main() {
});

flushSubscribers();
await new Promise((resolve) => setImmediate(resolve));
deregisterSubscriber("quickstart-printer");
}

Expand Down
3 changes: 3 additions & 0 deletions docs/getting-started/quick-start/python.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ This records the local source in the application's `pyproject.toml` through
## Run One Scope, One Tool Call, and One LLM Call

The example below runs one minimal instrumented workflow through the binding.
Save it as `quickstart.py` in the same Python project where you installed
`nemo-relay`, then run `uv run python quickstart.py`. If you are not using
`uv`, run it with the same Python environment where you installed the package.

```python
import asyncio
Expand Down
81 changes: 66 additions & 15 deletions docs/getting-started/quick-start/rust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ position: 3
{/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0 */}

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

## Choose an Install Path

Expand All @@ -19,8 +19,8 @@ Use the published crates when you are consuming a release:

```bash
cargo add nemo-relay@0.5.0
cargo add nemo-relay-adaptive@0.5.0
cargo add serde_json
cargo add tokio --features macros,rt-multi-thread
```

Install the published NeMo Relay CLI separately when you need coding-agent hook
Expand All @@ -37,28 +37,38 @@ Use a path dependency when your application is consuming a local checkout:
```toml
[dependencies]
nemo-relay = { path = "../NeMo-Relay/crates/core" }
nemo-relay-adaptive = { path = "../NeMo-Relay/crates/adaptive" }
serde_json = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

- `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.5.0` when
you need the NeMo Relay CLI.
- `tokio` provides the async runtime used by the managed tool and LLM helpers in
this quick start.
- `nemo-relay-adaptive` is a companion crate for adaptive runtime primitives and
Redis-backed learning components when you need adaptive behavior later, but it
is not required for this minimal direct-runtime example.
- `nemo-relay-cli` is a binary crate. Use `cargo install nemo-relay-cli@0.5.0`
when you need the NeMo Relay CLI.

## Push a Scope and Emit a Mark
## Run One Scope, One Tool Call, and One LLM Call

The example below creates a scope and records a mark event from Rust.
The example below creates a scope, records an initialization mark, runs one
managed tool call, and runs one managed LLM call through the public Rust APIs.
Place it in `src/main.rs` in the same Cargo project where you added the
dependencies above, then run `cargo run`.

```rust
use nemo_relay::api::llm::{llm_call_execute, LlmCallExecuteParams, LlmRequest};
use nemo_relay::api::scope::{
self, EmitMarkEventParams, PopScopeParams, PushScopeParams, ScopeAttributes, ScopeType,
};
use nemo_relay::api::subscriber::{deregister_subscriber, flush_subscribers, register_subscriber};
use nemo_relay::api::tool::{tool_call_execute, ToolCallExecuteParams};
use serde_json::json;
use std::sync::Arc;

fn main() -> Result<(), Box<dyn std::error::Error>> {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
register_subscriber(
"quickstart-printer",
Arc::new(|event| {
Expand All @@ -82,6 +92,41 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.data(json!({"ok": true}))
.build(),
)?;

let tool_result = tool_call_execute(
ToolCallExecuteParams::builder()
.name("search")
.args(json!({"query": "hello"}))
.func(Arc::new(|args| Box::pin(async move {
Ok(json!({"echo": args["query"]}))
})))
.parent(handle.clone())
.build(),
)
.await?;

let llm_result = llm_call_execute(
LlmCallExecuteParams::builder()
.name("demo-provider")
.request(LlmRequest {
headers: Default::default(),
content: json!({"messages": [{"role": "user", "content": "hi"}]}),
})
.func(Arc::new(|request| Box::pin(async move {
Ok(json!({
"messages": request.content["messages"],
"ok": true
}))
})))
.parent(handle.clone())
.model_name("demo-model")
.build(),
)
.await?;

println!("{tool_result}");
println!("{llm_result}");

scope::pop_scope(PopScopeParams::builder().handle_uuid(&handle.uuid).build())?;
flush_subscribers()?;
let _ = deregister_subscriber("quickstart-printer")?;
Expand All @@ -91,15 +136,21 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

## 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.
You should see:

- Event lines for the root scope, managed tool span, managed LLM span, and
mark lifecycle
- `{"echo":"hello"}` from the tool call
- A final object containing `ok: true` and the echoed message payload from the
LLM callback

Native subscriber delivery is asynchronous, so flush before checking subscriber
output. If you only see the returned JSON values and no event lines, the
business callbacks ran but you did not verify instrumentation.

That tells you two things:

- The scope API ran successfully.
- The direct Rust runtime APIs ran successfully.
- Emitted events were observable through the subscriber system.

## What to Learn Next
Expand Down
25 changes: 22 additions & 3 deletions docs/observability-plugin/about.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ Use the Observability plugin when you need to inspect NeMo Relay lifecycle event
in process or export agent activity to tracing, trajectory, or analysis
systems from one plugin configuration document.

## Shortest Path

Start with one plugin-managed exporter before layering in additional formats or
manual subscribers. A common first path is:

1. Instrument one scope, tool call, or LLM call in your application.
2. Enable the Observability plugin with only one exporter, such as ATOF JSONL.
3. Run one request through the instrumented path.
4. Confirm the emitted output before adding more exporters or sanitization rules.

Observability in NeMo Relay starts with events. Scopes, marks, managed tool
calls, managed LLM calls, middleware, and manual lifecycle APIs emit the
canonical Agent Trajectory Observability Format (ATOF) event stream.
Expand Down Expand Up @@ -85,9 +95,18 @@ Choose the exporter based on the downstream system:
Start with in-process event inspection before exporting externally. Add sanitize
guardrails before exporters receive sensitive payloads.

For trace incidents involving missing traces, wrong scope attachment, export
failures, duplicate events, or sensitive telemetry, use the
[Trace Incident Runbook](/resources/troubleshooting/trace-incident-runbook).
## What Success Looks Like

Your first exporter path is wired correctly when:

- The instrumented request still completes successfully.
- The chosen exporter receives scope data for that request, plus tool or LLM
lifecycle data when the request exercises those paths.
- The exported output shows the same NeMo Relay scope hierarchy you expect from the runtime contract.

If that basic check fails, use the
[Trace Incident Runbook](/resources/troubleshooting/trace-incident-runbook)
before adding more exporters or extra config layers.

## Correlating Trajectories And Traces

Expand Down
12 changes: 11 additions & 1 deletion docs/supported-integrations/deepagents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ agent = create_deep_agent(
**add_nemo_relay_integration(
model="nvidia:nvidia/nemotron-3-nano-30b-a3b",
tools=[],
skills=["/skills/research/"],
name="main-agent",
)
)
Expand All @@ -87,6 +86,17 @@ final_message = result["messages"][-1]
print(f"Final response: {final_message.content}")
```

Add `skills=[...]` or subagent configuration after this minimal path is working
if you want to capture Deep Agents skill or subagent marks too.

## Verify the Integration

The integration is wired correctly when:

- The Deep Agents run completes and prints a final response.
- The `deepagents-request` scope contains the top-level agent execution.
- Skill, subagent, and human-in-the-loop marks appear when those features are exercised.

## Observability

The integration composes the existing NeMo Relay LangChain and LangGraph hooks,
Expand Down
8 changes: 8 additions & 0 deletions docs/supported-integrations/langchain.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ final_message = result["messages"][-1]
print(f"Final response: {final_message.content}")
```

## Verify the Integration

The integration is wired correctly when:

- The agent run completes and prints a final response.
- The `langchain-request` scope contains the managed model call.
- Tool activity appears under the same request when the agent decides to use `get_weather`.

## Observability

Refer to [Observability](/observability-plugin/about) for details on exporting NeMo Relay observability data to third-party systems.
8 changes: 8 additions & 0 deletions docs/supported-integrations/langgraph.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ pip install "nemo-relay[langgraph,langchain-nvidia]"

</Tabs>

## Verify the Integration

The integration is wired correctly when:

- `graph.invoke(...)` returns the incremented state from the example.
- The `langgraph-request` scope contains the LangGraph run.
- Nested LangChain agents inherit the same callback config when you pass the LangGraph `config` through.

## Observability

Refer to [Observability](/observability-plugin/about) for details on exporting NeMo Relay observability data to third-party systems.
Loading