For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
  • About NVIDIA NeMo Relay
    • Overview
    • Architecture
    • Ecosystem
    • Concepts
    • Release Notes
  • Getting Started
    • Agent Runtime Primer
    • Prerequisites
    • Installation
    • Configuration / Setup
    • Quick Start
  • NVIDIA NeMo Relay CLI
    • About
    • Basic Usage
    • Claude Code
    • Codex
    • Cursor
    • Hermes Agent
  • Supported Integrations
    • About
    • OpenClaw Plugin Guide
    • LangChain Integration Guide
    • LangGraph Integration Guide
    • Deep Agents Integration Guide
  • Instrument Applications
    • About
    • Adding Scopes and Marks
    • Instrument a Tool Call
    • Instrument an LLM Call
    • Add Middleware
    • Code Examples
  • Observability Plugin
    • About
    • Configuration
    • Agent Trajectory Interchange Format (ATIF)
    • Agent Trajectory Observability Format (ATOF)
    • OpenTelemetry
    • OpenInference
  • Adaptive Plugin
    • About
    • Configuration
    • Adaptive Cache Governor (ACG)
    • Adaptive Hints
  • NeMo Guardrails Plugin
    • About
    • Configuration
  • Integrate into Frameworks
    • About
    • Adding Scopes
    • Wrap Tool Calls
    • Wrap LLM Calls
    • Handle Non-Serializable Data
    • Using Codecs
    • Provider Codecs
    • Provider Response Codecs
    • Code Examples
  • Build Plugins
    • About
    • Define a Plugin
    • Validate Plugin Configuration
    • Plugin Configuration Files
    • Register Plugin Behavior
    • Design Plugin Configuration
    • NeMo Guardrails Example Plugin
    • Code Examples
  • Contribute
    • About
    • Development Setup
    • Workflow and Reviews
    • Testing and Documentation
  • Reference
    • APIs
    • Performance
  • Resources
    • Support and FAQs
    • Glossary
    • Troubleshooting Guide
    • Community
    • Legal
NVIDIANVIDIA
Developer-friendly docs for your API
Privacy Policy | Your Privacy Choices | Terms of Service | Accessibility | Corporate Policies | Product Security | Contact

Copyright © 2026, NVIDIA Corporation.

LogoLogo
On this page
  • plugins.toml Example
  • Fields
  • Remote storage
  • S3-compatible storage
  • Multiple destinations
  • Connection fields
  • Secret credential fields
  • Expected Output
  • Plugin Configuration
  • Manual API
  • Common Validation Failures
Observability Plugin

Agent Trajectory Interchange Format (ATIF)

||View as Markdown|
Previous

Observability Configuration

Next

Agent Trajectory Observability Format (ATOF)

Use the atif section when you want one Agent Trajectory Interchange Format (ATIF) trajectory artifact per top-level agent run.

The plugin-managed ATIF dispatcher watches for direct child scopes with category agent, creates a scope-local exporter for each one, and writes the trajectory when that agent scope ends. Nested agent scopes remain in the parent trajectory.

plugins.toml Example

1version = 1
2
3[[components]]
4kind = "observability"
5enabled = true
6
7[components.config]
8version = 1
9
10[components.config.atif]
11enabled = true
12agent_name = "Planner"
13agent_version = "1.0.0"
14model_name = "unknown"
15output_directory = "logs"
16filename_template = "trajectory-{session_id}.json"

This configuration writes a trajectory file such as logs/trajectory-<scope-uuid>.json for each top-level agent scope.

Fields

FieldDefaultNotes
enabledfalseMust be true to write trajectories.
agent_nameNeMo RelayAgent metadata written into the trajectory.
agent_versionNeMo Relay crate versionAgent version metadata.
model_nameunknownDefault model metadata when no call-level model is present.
tool_definitionsOmittedOptional ATIF tool metadata.
extraOmittedOptional ATIF agent metadata.
output_directoryCurrent working directoryDirectory containing trajectory files. Ignored when storage is non-empty.
filename_templatenemo-relay-atif-{session_id}.jsonMust contain {session_id}.
storageOmittedOptional list of remote storage destinations. When non-empty, trajectories are uploaded to every configured backend instead of being written locally. See Remote storage.

Remote storage

For sandboxed runtimes such as NemoClaw / Omnistation / OpenShell, where local trace files are not durable across sessions, configure storage to ship completed trajectories directly to object storage. When storage is non-empty the local file write is replaced by uploads to every configured backend; output_directory is ignored.

Each storage entry is tagged with a type discriminator so additional backends can be added without breaking existing configs. Today, S3-compatible object storage is supported.

S3-compatible storage

1[components.config.atif]
2enabled = true
3filename_template = "trajectory-{session_id}.json"
4
5[[components.config.atif.storage]]
6type = "s3"
7bucket = "nemo-relay-traces"
8key_prefix = "openshell/"

Multiple destinations

Add additional [[components.config.atif.storage]] tables to fan out the same trajectory to every destination — for example, an in-cluster MinIO target and a remote AWS target:

1[components.config.atif]
2enabled = true
3filename_template = "trajectory-{session_id}.json"
4
5[[components.config.atif.storage]]
6type = "s3"
7bucket = "nemo-relay-traces"
8key_prefix = "openshell/"
9
10[[components.config.atif.storage]]
11type = "s3"
12bucket = "team-archive"
13key_prefix = "openshell/"
14endpoint_url = "http://localhost:9000"
15allow_http = true

Connection fields

By default, credentials, region, and endpoint URL are read from the standard AWS environment variables. Any non-secret connection field can also be set directly in the config so a single file can describe a complete destination, which is what unblocks running multiple S3-compatible endpoints side by side (for example, an in-cluster MinIO target and a remote AWS target):

FieldDefaultNotes
bucketrequiredDestination bucket name.
key_prefix""Optional prefix applied to every object. A trailing / is added if missing.
access_key_idAWS_ACCESS_KEY_IDInline static access key ID.
regionAWS_REGIONBucket region.
endpoint_urlAWS_ENDPOINT_URLEndpoint override for S3-compatible storage.
allow_httpAWS_ALLOW_HTTPSet to true when targeting an HTTP endpoint.

Explicit fields take precedence; anything left unset falls back to the matching AWS_* environment variable.

Secret credential fields

Secret values stay out of checked-in config files. Each secret field carries a _var suffix and holds the name of an environment variable that contains the secret value. The name is validated at plugin initialization time:

FieldEnv Var FallbackNotes
secret_access_key_varAWS_SECRET_ACCESS_KEYName of the env var that holds the static secret key.
session_token_varAWS_SESSION_TOKENName of the env var that holds the optional STS session token.

Each trajectory is uploaded under {key_prefix}{rendered_filename}. The filename_template is rendered the same way it would be for local files, so a local→remote transition keeps object names stable. A trailing / is added to key_prefix when one is missing.

If an upload fails for a given destination, that destination is recorded as unhealthy and skipped on later trajectories. The other destinations continue to receive writes. All recorded sink failures are joined into the dispatcher’s last-error result on plugin teardown.

Expected Output

The exporter translates NeMo Relay lifecycle events into ATIF v1.7 trajectory data. LLM start and end events become model steps, tool events become tool calls and observations, and scope nesting contributes lineage metadata. Nested agent scopes are embedded in the parent file as subagent_trajectories and referenced from parent observation results with subagent_trajectory_ref.trajectory_id. The reference points to the embedded child trajectory by ID so consumers can validate the parent and child as one single-file ATIF v1.7 artifact.

The plugin writes each trajectory when the top-level agent scope closes. If the plugin is cleared while an agent is still open, teardown flushes the partial trajectory.

To correlate ATIF with OpenTelemetry or OpenInference traces from the same run, join on NeMo Relay UUIDs. The plugin-managed ATIF session_id is the top-level agent scope UUID. Each step’s extra.ancestry.function_id is the event UUID, and extra.ancestry.parent_id is the parent event UUID. Trace spans expose the same values as nemo_relay.uuid and nemo_relay.parent_uuid attributes.

Plugin Configuration

Use plugin configuration when the application should let NeMo Relay own the ATIF dispatcher lifecycle.

Python
Node.js
Rust
1from nemo_relay import plugin
2from nemo_relay.observability import AtifConfig, ComponentSpec, ObservabilityConfig
3
4config = plugin.PluginConfig(
5 components=[
6 ComponentSpec(
7 ObservabilityConfig(
8 atif=AtifConfig(
9 enabled=True,
10 agent_name="Planner",
11 agent_version="1.0.0",
12 model_name="unknown",
13 output_directory="logs",
14 filename_template="trajectory-{session_id}.json",
15 )
16 )
17 )
18 ]
19)
20
21report = plugin.validate(config)
22if any(diagnostic["level"] == "error" for diagnostic in report["diagnostics"]):
23 raise RuntimeError(report["diagnostics"])
24
25await plugin.initialize(config)
26try:
27 # Run instrumented application work here.
28 pass
29finally:
30 plugin.clear()

Manual API

Use the manual AtifExporter API when you need explicit collection boundaries or one exporter object per run.

Python
Node.js
Rust
1from nemo_relay import AtifExporter
2
3exporter = AtifExporter("session-1", "agent", "1.0.0", model_name="demo-model")
4exporter.register("atif-exporter")
5
6# Run instrumented application work here.
7
8trajectory = exporter.export()
9exporter.deregister("atif-exporter")
10exporter.clear()

Common Validation Failures

  • filename_template does not contain {session_id}.
  • The output directory is not writable at runtime.
  • Tool definitions or extra metadata are not JSON-compatible.
  • The application never opens a top-level agent scope, so no trajectory file is created.
  • storage[i].type is unknown or storage[i].bucket is empty for some entry.
  • storage is non-empty in a build that was compiled without the atif-storage feature, or on a target (such as WebAssembly) where remote storage is not supported.