Skip to Content
RiusInteroperabilityAttribute registryKeys other producers write

Keys other producers write

Keys from other instrumentations that the Rius SDKs emit or the Rius normalizers read. No upstream OpenTelemetry registry defines them, so this registry describes them as their producers write them, with the decision the normalizers take on each usage key. Their spellings under gen_ai.* are not defined here, because only OpenTelemetry may define that namespace; the full usage-key table, those included, is out/docs/usage-keys.md .

Generated from rius-semconv  1.5.0, the Rius attribute registry, and updated on each of its releases.

OpenInference attributes the Rius SDKs emit

KeyStabilityTypeDecisionDescriptionExamples
input.valueDevelopmentstringemittedThe input of an agent, tool, retriever or chain step, as text or JSON.{"args":["Weather in Paris?"],"kwargs":{}}; What is the weather in Paris?
openinference.span.kindDevelopmentstringemittedThe OpenInference span kind, which is the Rius span taxonomy.LLM; AGENT
output.valueDevelopmentstringemittedThe output of an agent, tool, retriever or chain step, as text or JSON.sunny, 22C; {"temperature_c":22}

openinference.span.kind has these values:

ValueDescriptionStability
AGENTan agent invocation or runDevelopment
LLMa model call (generations use this)Development
TOOLa tool executionDevelopment
RETRIEVERa retrieval / search stepDevelopment
EMBEDDINGan embedding computationDevelopment
RERANKERa reranking step, e.g. reordering retrieved documents by relevanceDevelopment
CHAINa generic processing step (the default)Development

Attributes OpenInference writes that the Rius normalizers read

KeyStabilityTypeDecisionDescriptionExamples
llm.cost.totalDevelopmentdoubleignoredUsage figure written by OpenInference, left on the span: nothing reads it as usage. [1]
llm.invocation_parametersDevelopmentanyreadThe request parameters an OpenInference instrumentor recorded, as one JSON object. [2]{"model": "gpt-4o-mini", "max_tokens": 64, "temperature": 0.2}
llm.token_count.completionDevelopmentintmapped to gen_ai.usage.output_tokens (python, typescript, sink)Usage count written by OpenInference; the python, typescript and sink normalizers map it to gen_ai.usage.output_tokens.
llm.token_count.completion_details.audioDevelopmentintignoredUsage figure written by OpenInference, left on the span: nothing reads it as usage. [3]
llm.token_count.completion_details.reasoningDevelopmentintmapped to gen_ai.usage.reasoning.output_tokens (python, typescript, sink)Usage count written by OpenInference; the python, typescript and sink normalizers map it to gen_ai.usage.reasoning.output_tokens.
llm.token_count.promptDevelopmentintmapped to gen_ai.usage.input_tokens (python, typescript, sink)Usage count written by OpenInference; the python, typescript and sink normalizers map it to gen_ai.usage.input_tokens. [4]
llm.token_count.prompt_details.audioDevelopmentintignoredUsage figure written by OpenInference, left on the span: nothing reads it as usage. [5]
llm.token_count.prompt_details.cache_readDevelopmentintmapped to gen_ai.usage.cache_read.input_tokens (python, typescript, sink)Usage count written by OpenInference; the python, typescript and sink normalizers map it to gen_ai.usage.cache_read.input_tokens.
llm.token_count.prompt_details.cache_writeDevelopmentintmapped to gen_ai.usage.cache_write.input_tokens (python, typescript, sink)Usage count written by OpenInference; the python, typescript and sink normalizers map it to gen_ai.usage.cache_write.input_tokens.
llm.token_count.totalDevelopmentintignoredUsage figure written by OpenInference, left on the span: nothing reads it as usage. [6]
metadata.ai.response.avgOutputTokensPerSecondDevelopmentdoublenot usageKey written by OpenInference that names tokens or cost but is not a usage count. [7]

Attributes OpenLLMetry writes that the Rius normalizers read

KeyStabilityTypeDecisionDescriptionExamples
llm.usage.reasoning_tokensDevelopmentintmapped to gen_ai.usage.reasoning.output_tokens (sink)Usage count written by OpenLLMetry; the sink normalizer maps it to gen_ai.usage.reasoning.output_tokens. [8]
llm.usage.total_tokensDevelopmentintignoredUsage figure written by OpenLLMetry, left on the span: nothing reads it as usage. [9]

Attributes pydantic-ai writes that the Rius normalizers read

KeyStabilityTypeDecisionDescriptionExamples
operation.costDevelopmentdoubleignoredUsage figure written by pydantic-ai, left on the span: nothing reads it as usage. [10]
pydantic_ai.cache.<key>Developmentanynot usageKey written by pydantic-ai that names tokens or cost but is not a usage count. [11]

Attributes the Vercel AI SDK writes that the Rius normalizers read

KeyStabilityTypeDecisionDescriptionExamples
ai.response.avgOutputTokensPerSecondDevelopmentdoublenot usageKey written by the Vercel AI SDK that names tokens or cost but is not a usage count. [12]
ai.response.usageDevelopmentstringignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [13]
ai.settings.maxOutputTokensDevelopmentintnot usageKey written by the Vercel AI SDK that names tokens or cost but is not a usage count. [14]
ai.usage.cachedInputTokensDevelopmentintmapped to gen_ai.usage.cache_read.input_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.cache_read.input_tokens. [15]
ai.usage.completionTokensDevelopmentintignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [16]
ai.usage.inputTokenDetails.cacheReadTokensDevelopmentintmapped to gen_ai.usage.cache_read.input_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.cache_read.input_tokens.
ai.usage.inputTokenDetails.cacheWriteTokensDevelopmentintmapped to gen_ai.usage.cache_write.input_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.cache_write.input_tokens.
ai.usage.inputTokenDetails.noCacheTokensDevelopmentintignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [17]
ai.usage.inputTokensDevelopmentintmapped to gen_ai.usage.input_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.input_tokens. [18]
ai.usage.outputTokenDetails.reasoningTokensDevelopmentintmapped to gen_ai.usage.reasoning.output_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.reasoning.output_tokens.
ai.usage.outputTokenDetails.textTokensDevelopmentintignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [19]
ai.usage.outputTokensDevelopmentintmapped to gen_ai.usage.output_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.output_tokens.
ai.usage.promptTokensDevelopmentintignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [20]
ai.usage.reasoningTokensDevelopmentintmapped to gen_ai.usage.reasoning.output_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.reasoning.output_tokens. [21]
ai.usage.tokensDevelopmentintmapped to gen_ai.usage.input_tokens (typescript, sink)Usage count written by the Vercel AI SDK; the typescript and sink normalizers map it to gen_ai.usage.input_tokens. [22]
ai.usage.totalTokensDevelopmentintignoredUsage figure written by the Vercel AI SDK, left on the span: nothing reads it as usage. [23]

Notes

[1] llm.cost.total: Cost stays off the wire on purpose: the backend prices from the token counts with its own table, so a producer’s figure is never trusted.

[2] llm.invocation_parameters: The request-parameters bag OpenInference instrumentors emit.

[3] llm.token_count.completion_details.audio: No canonical key; modality splits are not priced separately.

[4] llm.token_count.prompt: Copied, never summed with the cache counts: every bundled instrumentor already reports it inclusive of them.

[5] llm.token_count.prompt_details.audio: No canonical key; modality splits are not priced separately.

[6] llm.token_count.total: The conventions define no total: they record input and output and leave the sum to the reader. The sink reads it for validation only.

[7] metadata.ai.response.avgOutputTokensPerSecond: @arizeai/openinference-vercel’s metadata.* mirror of ai.response.avgOutputTokensPerSecond. No recording carries it: the TypeScript SDK no longer runs that transform. An app can still run the package’s span processor itself on a provider the SDK bridges onto, and its spans then carry the mirror, so the entry stays.

[8] llm.usage.reasoning_tokens: OpenLLMetry’s reasoning count in older releases.

[9] llm.usage.total_tokens: OpenLLMetry’s and Laminar’s total, as gen_ai.usage.total_tokens.

[10] operation.cost: pydantic-ai’s own price for the call. Cost stays off the wire on purpose, as with llm.cost.total.

[11] pydantic_ai.cache.<key>: pydantic-ai’s prompt-cache health diagnostics (the cached prefix a conversation established, hit ratio, misses), not provider usage.

[12] ai.response.avgOutputTokensPerSecond: A throughput figure, not a count.

[13] ai.response.usage: @ai-sdk/otel’s speech and transcription spans, with its usage option: the provider’s usage object whole, as a JSON string, in whatever units the provider bills (tokens, seconds, characters). The integration also writes its numeric leaves on the same span as gen_ai.usage.<key>, which is what is read (input_tokens, output_tokens) or decided above, so parsing this would count the same usage twice.

[14] ai.settings.maxOutputTokens: A request parameter, mapped to gen_ai.request.max_tokens (which the AI SDK also writes itself on a model call).

[15] ai.usage.cachedInputTokens: v5’s cache-read count, still written beside the detailed spelling by v6. Without it cached input was priced as uncached.

[16] ai.usage.completionTokens: v5’s output count on generateText and generateObject; as ai.usage.promptTokens.

[17] ai.usage.inputTokenDetails.noCacheTokens: The uncached remainder of ai.usage.inputTokens. The conventions record the inclusive input count and the cached part; this is their difference.

[18] ai.usage.inputTokens: Inclusive of the cached tokens, as the canonical key is.

[19] ai.usage.outputTokenDetails.textTokens: The non-reasoning remainder of ai.usage.outputTokens; the conventions record the inclusive output count and the reasoning part.

[20] ai.usage.promptTokens: v5’s input count on generateText and generateObject, left unread on purpose. On a model call the AI SDK writes the same value to gen_ai.usage.input_tokens itself. On the generateText wrapper v5 takes it from the LAST step’s response, not the run’s total (v5’s streams and v6 report the total under ai.usage.inputTokens), so mapping it to rius.aggregated_usage.* would put a short total under a key that promises the whole run.

[21] ai.usage.reasoningTokens: v5’s reasoning count, still written beside the detailed spelling by v6.

[22] ai.usage.tokens: An embedding call’s input count (ai.embed, ai.embedMany and their doEmbed).

[23] ai.usage.totalTokens: A total; the conventions define none.

Last updated on