NVIDIA-NeMo / NVIDIA-NeMo/Switchyard

Emit physical provider and classifier attempt lifecycles through Relay

Open
#299 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
3.2k
Forks
291
Avg merge
1d 8h
Merged PRs (30d)
182

Description

Problem

The NeMo Relay plugin exposes one logical LLM call plus high-level Switchyard marks and metrics. Those records show that routing happened, which model calls ran, how long routing took, and whether the selected model fell back. They do not create nested timed spans for the work Switchyard performs inside that call.

A routed request can include:

Relay LLM call
  Switchyard algorithm
    classifier or judge call
      candidate model call
        HTTP attempt and retry
    answer candidate
      fallback candidate

Today Relay exports the outer LLM span and the Switchyard summary marks. In a trace viewer, the internal routing work appears as flat records rather than a timed hierarchy. This makes it hard to see where routing time was spent or which retry or fallback caused a delay.

ATIF should continue to describe the normal agent trajectory without these internal calls. This issue is about the OpenTelemetry trace.

Existing instrumentation

Switchyard already emits these spans while running inside the plugin:

  • libsy.run for the algorithm run
  • libsy.llm_call for classifier and judge requests
  • libsy.client_call for model candidates and fallbacks
  • libsy.upstream_attempt for HTTP attempts and retries

Together they cover most of the internal timeline, although they are not yet one complete hierarchy. Relay does not receive these spans through its plugin runtime, so its OpenTelemetry exporter cannot include them. The plugin currently reports summaries through Relay marks and metrics instead.

#604 and #612 improve those summaries but do not solve the missing span hierarchy.

Boundary to settle

There are two reasonable approaches:

  1. Switchyard exports its existing spans directly to the same collector, using the trace context Relay provides.
  2. Relay adds a native plugin API for explicitly parented child spans and remains responsible for exporting them.

Relay currently provides marks, metrics, and stack-based scopes. It does not provide an explicit child-span surface suited to overlapping work or spans that remain open while a response stream is consumed.

The second approach keeps one observability pipeline, but the boundary should be agreed with Relay maintainers before adding another lifecycle implementation to the plugin.

Desired outcome

  • Keep the outer Relay LLM span.
  • Show Switchyard routing work beneath it in the same trace.
  • Distinguish classifier or judge calls from answer calls.
  • Show model candidates, fallbacks, HTTP attempts, and retries with their own timing and outcome.
  • Close streaming spans exactly once on completion, error, or cancellation.
  • Preserve the existing routing marks and metrics.
  • Avoid duplicate span export.
  • Keep request content and unsafe provider error text out of span fields.
  • Add tests for parent-child relationships, ordering, and balanced span lifecycles.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing libsy.run, libsy.llm_call, libsy.client_call, and libsy.upstream_attempt instrumentation, along with Relay's current marks, metrics, and stack-based scopes. Review PRs #604 and #612, then settle the export boundary with Relay maintainers. Done means one trace contains the nested routing, candidate, fallback, HTTP, retry, and streaming lifecycles without duplicate export or unsafe span fields.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
observability-sre
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.