How does Rius read OpenTelemetry GenAI conversation id attributes?
Rius reads gen_ai.conversation.id, the OpenTelemetry GenAI session key, as the session whenever a span has no session.id, so conversations group without extra setup. Spans that follow the GenAI conventions need no renaming. The traces of one conversation are grouped together as a session in the console.
How it works
The OpenTelemetry GenAI conventions name the conversation key gen_ai.conversation.id. Rius picks the session for each span in this order:
session.id, if the span has it.gen_ai.conversation.id, ifsession.idis absent.- The span’s trace id, if neither is set. The trace is then its own session.
A few details matter when you send this attribute:
- Read per span. Rius checks each span for the key, not only the root span. Set it on every span of the trace, because a span without it falls back to its trace id.
- Stored as you send it. Rius does not move
gen_ai.conversation.idonto another key. It stays under its own name, so search and filter ongen_ai.conversation.idin trace inspection. It is a nativegen_ai.*key, and native keys always win over normalization. - Same session meaning. The value groups the traces of one conversation or agent run, just as
session.iddoes.session.idis the key OpenInference uses for sessions, and Rius also reads it as sent.
The span attribute reference lists the session, user and resource attributes Rius reads, and the supported-conventions table that shows what each attribute family gets.
Set it up
-
Send traces over OTLP/HTTP to the Rius ingest endpoint with your API key as a bearer token. Any OpenTelemetry SDK or collector works. The interoperability overview links the setup page for each sender.
POST https://ingest.eu.console.rius-glassflow.com/v1/traces Authorization: Bearer <your API key> Content-Type: application/x-protobuf -
Set
gen_ai.conversation.idon every span that belongs to the conversation, using one value for the whole conversation. The value is your own, for example:gen_ai.conversation.id = "support-chat-1042" -
If your instrumentation already follows the OpenTelemetry GenAI conventions, check that it writes this attribute on child spans too, such as model calls and tool calls. Rius does not copy it from the root span down to its children.
-
Prefer an opaque value, such as a generated id, over text that identifies a person.
-
If you use the Rius SDKs instead, you do not need to set the key yourself. The Python SDK stamps
session.idwithrius.session, and the TypeScript SDK does it withwithSession. To set one session id for a whole process, useRIUS_SESSION_ID. The Trace LLM calls with OpenTelemetry guide compares the SDK path with sending raw OpenTelemetry.
What you get
- Conversations grouped as sessions. Traces that share a
gen_ai.conversation.idappear together as one session, with nosession.idneeded. - No conversion step. A sender that follows the GenAI conventions works as is, and your attribute is kept under its original name for search and filters.
- Same analytics as any other sender. Taxonomy, model, tokens, cost and time to first token come from the other
gen_ai.*attributes on the spans, as described in the attribute reference. Cost is computed by Rius from the model and token counts, so you never send a cost value. - A safe default. If a span carries neither key, it is grouped by its trace id and nothing is rejected.
When something else fits
If you control the instrumentation and want one key that works across senders, set session.id on every span. It takes priority over gen_ai.conversation.id, and OpenInference senders already use it. If you want the session stamped for you, use the Rius SDK scopes. For the full list of attribute families Rius reads, see the attribute reference.