> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/guardrails/llms.txt.
> For full documentation content, see https://docs.nvidia.com/nemo/guardrails/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/guardrails/_mcp/server.

# nemoguardrails.tracing.constants

OpenTelemetry constants, semantic conventions, and engine-agnostic
GenAI client-side metric instruments for NeMo Guardrails.

The OTEL GenAI client-side metric helpers (`LLMInstruments`,
`record_token_usage`, `llm_operation_duration`,
`record_time_to_first_chunk`, `record_time_per_output_chunk`) live
here next to the metric-name and attribute constants they emit.  They
are engine-agnostic — any caller that issues an LLM call can use them
to satisfy the OTEL GenAI semantic conventions.

## Module Contents

### Classes

| Name                                                                             | Description                                                             |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [`CommonAttributes`](#nemoguardrails-tracing-constants-CommonAttributes)         | Common OpenTelemetry attributes used across spans.                      |
| [`EventNames`](#nemoguardrails-tracing-constants-EventNames)                     | Standard event names for OpenTelemetry GenAI semantic conventions.      |
| [`GenAIAttributes`](#nemoguardrails-tracing-constants-GenAIAttributes)           | GenAI semantic convention attributes following the draft specification. |
| [`GuardrailsAttributes`](#nemoguardrails-tracing-constants-GuardrailsAttributes) | NeMo Guardrails-specific attributes for spans.                          |
| [`GuardrailsEventNames`](#nemoguardrails-tracing-constants-GuardrailsEventNames) | NeMo Guardrails-specific event names (not OTel GenAI conventions).      |
| [`GuardrailsEventTypes`](#nemoguardrails-tracing-constants-GuardrailsEventTypes) | NeMo Guardrails internal event type constants.                          |
| [`LLMInstruments`](#nemoguardrails-tracing-constants-LLMInstruments)             | LLM-call-scope OTEL instruments for downstream model calls.             |
| [`MetricNames`](#nemoguardrails-tracing-constants-MetricNames)                   | OTEL metric names emitted by the IORails engine.                        |
| [`OperationNames`](#nemoguardrails-tracing-constants-OperationNames)             | Standard operation names for GenAI semantic conventions.                |
| [`OtelContentCapture`](#nemoguardrails-tracing-constants-OtelContentCapture)     | OTEL environment-variable names and tokens for content-capture gating.  |
| [`SpanKind`](#nemoguardrails-tracing-constants-SpanKind)                         | String constants for span kinds.                                        |
| [`SpanNamePatterns`](#nemoguardrails-tracing-constants-SpanNamePatterns)         | Patterns used for identifying span types from span names.               |
| [`SpanNames`](#nemoguardrails-tracing-constants-SpanNames)                       | Standard span names following OpenTelemetry GenAI semantic conventions. |
| [`SpanTypes`](#nemoguardrails-tracing-constants-SpanTypes)                       | Internal span type identifiers used in span mapping.                    |
| [`SystemConstants`](#nemoguardrails-tracing-constants-SystemConstants)           | System-level constants for NeMo Guardrails.                             |
| [`TokenType`](#nemoguardrails-tracing-constants-TokenType)                       | Allowed values for the `gen_ai.token.type` metric label.                |

### Functions

| Name                                                                                             | Description                                                         |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| [`_ensure_llm_instruments`](#nemoguardrails-tracing-constants-_ensure_llm_instruments)           | Lazily create the LLM-call-scope instruments and return them as     |
| [`_llm_call_attributes`](#nemoguardrails-tracing-constants-_llm_call_attributes)                 | Return the standard OTEL GenAI label set shared by every            |
| [`llm_operation_duration`](#nemoguardrails-tracing-constants-llm_operation_duration)             | Context manager that records the wrapped block's wall-clock         |
| [`record_time_per_output_chunk`](#nemoguardrails-tracing-constants-record_time_per_output_chunk) | Emit a `gen_ai.client.operation.time_per_output_chunk` observation. |
| [`record_time_to_first_chunk`](#nemoguardrails-tracing-constants-record_time_to_first_chunk)     | Emit a `gen_ai.client.operation.time_to_first_chunk` observation.   |
| [`record_token_usage`](#nemoguardrails-tracing-constants-record_token_usage)                     | Emit two `gen_ai.client.token.usage` observations (one input,       |

### Data

[`_LLM_DURATION_BUCKETS`](#nemoguardrails-tracing-constants-_LLM_DURATION_BUCKETS)

[`_LLM_TOKEN_BUCKETS`](#nemoguardrails-tracing-constants-_LLM_TOKEN_BUCKETS)

[`_llm_instruments`](#nemoguardrails-tracing-constants-_llm_instruments)

### API

```python
class nemoguardrails.tracing.constants.CommonAttributes()
```

Common OpenTelemetry attributes used across spans.

```python
class nemoguardrails.tracing.constants.EventNames()
```

Standard event names for OpenTelemetry GenAI semantic conventions.

Based on official spec at:
[https://github.com/open-telemetry/semantic-conventions/blob/main/model/gen-ai/events.yaml](https://github.com/open-telemetry/semantic-conventions/blob/main/model/gen-ai/events.yaml)

```python
class nemoguardrails.tracing.constants.GenAIAttributes()
```

GenAI semantic convention attributes following the draft specification.

Note: These are based on the experimental OpenTelemetry GenAI semantic conventions
since they are not yet available in the stable semantic conventions package.

See: [https://opentelemetry.io/docs/specs/semconv/gen-ai/](https://opentelemetry.io/docs/specs/semconv/gen-ai/)

```python
class nemoguardrails.tracing.constants.GuardrailsAttributes()
```

NeMo Guardrails-specific attributes for spans.

```python
class nemoguardrails.tracing.constants.GuardrailsEventNames()
```

NeMo Guardrails-specific event names (not OTel GenAI conventions).

These events represent internal guardrails state changes, not LLM API calls.
They use a guardrails-specific namespace to avoid confusion with OTel GenAI semantic conventions.

```python
class nemoguardrails.tracing.constants.GuardrailsEventTypes()
```

NeMo Guardrails internal event type constants.

These are the type values from internal guardrails events.

```python
class nemoguardrails.tracing.constants.LLMInstruments(
    token_usage: opentelemetry.metrics.Histogram,
    operation_duration: opentelemetry.metrics.Histogram,
    time_to_first_chunk: opentelemetry.metrics.Histogram,
    time_per_output_chunk: opentelemetry.metrics.Histogram
)
```

Dataclass

LLM-call-scope OTEL instruments for downstream model calls.

These metrics fire once per LLM call (not once per IORails request)
and follow the OTEL GenAI semantic conventions exactly — the field
names mirror the metric names with the `gen_ai.client.` prefix
stripped, and both are Histograms (per spec).

* `token_usage` — `gen_ai.client.token.usage` Histogram, unit
  `&#123;token&#125;`.  Records input and output tokens as separate
  observations distinguished by the required `gen_ai.token.type`
  label (`input` or `output`).
* `operation_duration` — `gen_ai.client.operation.duration`
  Histogram, unit `s`.  Records the wall-clock time of each
  LLM call from request issue to response completion.
* `time_to_first_chunk` — `gen_ai.client.operation.time_to_first_chunk`
  Histogram, unit `s`.  Streaming-only.  Time from request
  issue to the first content-bearing chunk yielded.
* `time_per_output_chunk` — `gen_ai.client.operation.time_per_output_chunk`
  Histogram, unit `s`.  Streaming-only.  Inter-chunk gap; one
  observation per content-bearing chunk after the first.

```python
class nemoguardrails.tracing.constants.MetricNames()
```

OTEL metric names emitted by the IORails engine.

These names are part of the library's public API — customers point
dashboards and alerts at them.  Tests deliberately assert on the raw
strings rather than these constants so the assertions verify the wire
contract instead of re-referencing the same symbol the production code
uses.

```python
class nemoguardrails.tracing.constants.OperationNames()
```

Standard operation names for GenAI semantic conventions.

Note: This only defines standard LLM operations. Custom actions and tasks
should be passed through as-is since they are dynamic and user-defined.

```python
class nemoguardrails.tracing.constants.OtelContentCapture()
```

OTEL environment-variable names and tokens for content-capture gating.

Two independent OTEL-standard env vars control content capture:

* `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` — fallback
  enable switch when `config.tracing.enable_content_capture` is
  unset/False.  Truthy values (`"true"`, `"1"`) turn capture on.
* `OTEL_SEMCONV_STABILITY_OPT_IN` — comma-separated stability
  opt-in list.  When `"gen_ai_latest_experimental"` is present,
  content is emitted as new-form span attributes
  (`gen_ai.input.messages` etc.); otherwise as legacy span events
  (`gen_ai.user.message` etc.).

```python
class nemoguardrails.tracing.constants.SpanKind()
```

String constants for span kinds.

```python
class nemoguardrails.tracing.constants.SpanNamePatterns()
```

Patterns used for identifying span types from span names.

```python
class nemoguardrails.tracing.constants.SpanNames()
```

Standard span names following OpenTelemetry GenAI semantic conventions.

Based on: [https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/)

IMPORTANT: Span names must be low cardinality to avoid performance issues.
Variable/high cardinality data (like specific rail types, model names, etc.)
should go in attributes instead of the span name.

```python
class nemoguardrails.tracing.constants.SpanTypes()
```

Internal span type identifiers used in span mapping.

These are internal identifiers used to categorize spans before mapping
to actual span names. They represent the type of operation being traced.

Note: 'llm\_call' maps to various GenAI semantic convention span types
like inference (gen\_ai.inference.client), embeddings, etc.

```python
class nemoguardrails.tracing.constants.SystemConstants()
```

System-level constants for NeMo Guardrails.

```python
class nemoguardrails.tracing.constants.TokenType()
```

Allowed values for the `gen_ai.token.type` metric label.

Per OTEL GenAI semconv, only `input` and `output` are valid.
Reasoning and cached tokens are exposed as span attributes
(`gen_ai.usage.reasoning.output_tokens` etc.), not as additional
`token.type` values on the `gen_ai.client.token.usage` metric.

```python
nemoguardrails.tracing.constants._ensure_llm_instruments() -> typing.Optional[nemoguardrails.tracing.constants.LLMInstruments]
```

Lazily create the LLM-call-scope instruments and return them as
an :class:`LLMInstruments`.  Returns `None` when the OTEL API is
not installed.

Bucket boundaries on every histogram are exact matches to the OTEL
GenAI semantic-conventions spec recommendations:
[https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/)
See :data:`_LLM_DURATION_BUCKETS` and :data:`_LLM_TOKEN_BUCKETS`
above.

```python
nemoguardrails.tracing.constants._llm_call_attributes(
    model_name: str,
    provider_name: str,
    operation_name: str
) -> dict
```

Return the standard OTEL GenAI label set shared by every
`gen_ai.client.*` Histogram emission.

These three are the lowest-cardinality labels the spec mandates as
Required (`operation.name`, `provider.name`) or Conditionally
Required (`request.model`).  Per-metric labels (`token.type`,
`error.type`) are added by individual emission helpers.

```python
nemoguardrails.tracing.constants.llm_operation_duration(
    model_name: str,
    provider_name: str,
    operation_name: str
) -> typing.Generator[None, None, None]
```

Context manager that records the wrapped block's wall-clock
duration into `gen_ai.client.operation.duration`.

On exception, adds the `error.type` label (per spec, conditionally
required on the duration metric only — token usage carries no
error.type even on failed calls) and re-raises.  No-op when the
OTEL API is unavailable.

```python
nemoguardrails.tracing.constants.record_time_per_output_chunk(
    model_name: str,
    provider_name: str,
    operation_name: str,
    duration_s: float
) -> None
```

Emit a `gen_ai.client.operation.time_per_output_chunk` observation.

Records the inter-chunk interval for one content-bearing chunk
after the first.  Each chunk produces one observation; aggregates
show p50/p95/p99 for chunk-arrival pacing across the stream.

Caller is responsible for skipping the first chunk (covered by
`record_time_to_first_chunk` instead) and for skipping
non-content frames (terminal usage chunk, role-only frames) that
would skew the distribution.

No-op when the OTEL API is unavailable.

```python
nemoguardrails.tracing.constants.record_time_to_first_chunk(
    model_name: str,
    provider_name: str,
    operation_name: str,
    duration_s: float
) -> None
```

Emit a `gen_ai.client.operation.time_to_first_chunk` observation.

Records the elapsed seconds from request issue to the first
content-bearing chunk yielded by the streaming response.  Caller
is responsible for the timing — this helper just records the value
onto the histogram with the standard label set.

Per OTEL semconv, "first chunk" is the first chunk carrying actual
output (content or reasoning delta) — not the role-only or other
cosmetic SSE frames that don't carry data.

No-op when the OTEL API is unavailable.

```python
nemoguardrails.tracing.constants.record_token_usage(
    model_name: str,
    provider_name: str,
    operation_name: str,
    usage: typing.Optional[nemoguardrails.types.UsageInfo]
) -> None
```

Emit two `gen_ai.client.token.usage` observations (one input,
one output) for a completed LLM call.

Per spec only `input` and `output` are valid
`gen_ai.token.type` values — reasoning and cached tokens are
span-only attributes, not metric labels.

No-op when `usage` is `None` (the upstream provider didn't
return a `usage` field — common for streaming when
`stream_options.include_usage` is suppressed) or the OTEL API is
unavailable.  Skipping emission rather than recording zeros keeps
the histogram honest: "no observation" is distinct from "0 tokens".

```python
nemoguardrails.tracing.constants._LLM_DURATION_BUCKETS = [0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96...
```

```python
nemoguardrails.tracing.constants._LLM_TOKEN_BUCKETS = [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216...
```

```python
nemoguardrails.tracing.constants._llm_instruments: Optional[LLMInstruments] = None
```