nvidia-nemo/labs-oo-agents · Archived

nooa-capturing-traces

Capture execution traces from NOOA. Use when instrumenting an agent run, writing traces to JSONL files, sending traces to the viewer or an OTLP/Langfuse/Phoenix backend, controlling which methods are traced, or when traces are mysteriously missing.

First seen Aug 13, 2026

Installation

$ npx skills add nvidia-nemo/labs-oo-agents --skill nooa-capturing-traces

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from nvidia-nemo/labs-oo-agents · top by installs.

npx skills add nvidia-nemo/labs-oo-agents

Browse all from nvidia-nemo/labs-oo-agents

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1.5K
License LICENSE
Default branch main
Open issues 44
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Compatibilitynooa package; the [tracing] extra (opentelemetry + openinference) for exporters

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,493 B
  • docs SUMMARY.md 277 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Capturing Traces

NOOA traces every agent method call, LLM call, code execution, and tool invocation as OpenTelemetry spans using OpenInference semantic conventions. Traces are grouped by session.id and nested by call hierarchy.

Automatic tracing (zero config)

Every Agent.init() auto-attempts tracing once per process: it probes the trace viewer at http://localhost:5001 (or $OTLP_ENDPOINT) and, if reachable, streams spans to it. Nothing to import, nothing to call:

nooa start-dev            # terminal 1: viewer + OTLP receiver on :5001
uv run python my_agent.py    # terminal 2: traces appear automatically

If the viewer is not reachable, tracing is silently disabled. There is NO automatic fallback to files. The only exception: if you explicitly set OTLP_ENDPOINT and it's unreachable, a warning is printed to stderr. If you need traces without a viewer, use explicit file export (below).

Explicit tracing

from nooa.tracing import enable_tracing, exporters, flush_traces

# Write JSONL files — one file per session: {trace_dir}/{session_id}.jsonl
enable_tracing(exporters=[exporters.jsonl("./traces")])

# ... run the agent ...
flush_traces()   # force-flush pending spans (e.g. before process exit)

Signature: enabletracing(exporters=None, *, experiment=None, extraresourceattrs=None) -> None (source: src/nooa/tracing/init.py). It is idempotent for no-arg calls; calling again with explicit exporters replaces the previous exporters. experiment tags every span's resource with an experiment name (defaults to $TRACEEXPERIMENT), which the viewer uses to group eval runs.

Exporter factories (nooa.tracing.exporters)

Factory Destination Notes
exporters.jsonl(trace_dir=None) {tracedir}/{sessionid}.jsonl dir from arg → $TRACE_DIR./traces/
exporters.journal(endpoint=None) viewer (delta journal) the default used by auto-tracing; most efficient for the viewer
exporters.local_otlp(endpoint=None) OTLP JSON over HTTP lightweight urllib POST to $OTLP_ENDPOINT
exporters.otlp(endpoint, headers=None) real OTLP/HTTP collector needs opentelemetry-exporter-otlp-proto-http
exporters.langfuse(host=None, ...) Langfuse reads LANGFUSEHOST/PUBLICKEY/SECRET_KEY
exporters.console() stdout quick debugging

Multiple destinations at once:

enable_tracing(exporters=[
    exporters.jsonl("./traces"),
    exporters.journal(),          # viewer too, if running
])

Session IDs

Spans are grouped by session.id. Set it explicitly when you need a stable, known ID (e.g. eval harnesses):

from nooa.tracing import set_session, get_session
set_session("my-run-001")   # call before running the agent

What gets traced

All agent methods are traced by default — public, private (_x), and async dunders. Generation methods, plain-Python orchestrators, and deterministic helpers all produce spans. Opt out per-method:

from nooa import no_trace

class MyAgent(Agent, llm=llm):
    @no_trace
    async def utility(self):
        """Runs (and generates) normally, but produces no span."""
        ...

(Older docs claiming "private methods are not traced" are outdated — trust this table.)

Span name Kind Meaning
method.{name} AGENT an agent method call; carries args as input.value, docstring, signature
generation CHAIN one strategy execution (an LLM "thinking" episode)
litellm.acompletion LLM the actual LLM call (from openinference-litellm), nested under generation; carries llm.inputmessages/llm.outputmessages/llm.model_name
code_execution TOOL one CodeAct execute_python cell
method_call.{name} TOOL LLM-generated code calling a method on self
tool_execution.{tool} TOOL external tool invocation

Parent-child nesting follows the call hierarchy: orchestrator → generation methods → generations → LLM calls / code executions.

Trace file format

Files are OTLP JSON Lines: each line is one {"resourceSpans": [...]} object. This is the interchange format for the whole toolchain — the viewer imports it (nooa import-traces ./traces) and the trace explorer reads it directly (trace-explorer ./traces/<session_id>.jsonl).

Environment variables

Variable Meaning Default
OTLP_ENDPOINT where auto-tracing / local_otlp / journal send spans http://localhost:5001/v1/traces
OTLPPROBETIMEOUT viewer reachability probe timeout (seconds) 2.0
TRACE_DIR default dir for exporters.jsonl() ./traces
TRACE_EXPERIMENT default experiment resource attribute unset

Pitfalls

  • Do NOT use legacy OpenInference instrumentation imports or enabletracing(tracedir=...) — both appear in older docs/comments but do not exist. Tracing lives in nooa.tracing; tracedir is an argument of exporters.jsonl(), and enabletracing() returns None.
  • Auto-tracing is attempted once per process. If the viewer wasn't running when the first Agent was constructed, later agents won't retry — call enable_tracing(...) explicitly or restart with the viewer up.
  • For short scripts, call flush_traces() before exit; batch exporters flush on a ~1s schedule and a fast exit can drop the tail of a trace.
  • Logic that runs outside agent methods (module-level preprocessing, main() helpers) is invisible in traces. Keep interesting logic inside agent methods so failures leave trace evidence.

Verifying capture works

from nooa.tracing import enable_tracing, exporters, flush_traces
enable_tracing(exporters=[exporters.jsonl("./traces")])
agent = MyAgent()
await agent.run("test")
flush_traces()
# ls ./traces/*.jsonl  → one file per session; inspect with trace-explorer

Related skills

  • nooa-trace-viewer — run the web viewer and browse captured traces.
  • nooa-trace-explorer — programmatic/CLI trace analysis and root-cause debugging.