How do I group the traces of one conversation into a session with the OpenAI Agents SDK?
Rius groups the traces of one conversation into a session when you wrap each OpenAI Agents SDK run in rius.session() with your conversation id. Every span started inside the block carries that id as session.id, so each turn stays its own trace and the session ties the turns together. The OpenAI Agents SDK integration is Python, so you use the Python SDK.
How it works
A trace is one run, which for a chat is one turn. A session is the id you assign to correlate several traces, as described in Concepts. You mint the id, or reuse one you already have such as a conversation id or ticket id, and the SDK stamps it as the session.id attribute on every span started in scope.
For the OpenAI Agents SDK, the scope goes around the entrypoint you wrap with observe, the function that calls Runner.run_sync. Because the scope opens before that function starts, the root AGENT span carries the id, and so do the spans for each model call and each tool call. The OpenAI Agents SDK integration captures those calls.
Scopes ride OpenTelemetry context, not a global:
- They nest, and the innermost one wins.
- They unwind with the block, even when an error is raised.
- They follow async work the same way the active span does.
With rius.session() and no argument, Rius mints a fresh UUID for the scope. The block yields the id, so you can log it or pass it to the next turn.
Set it up
-
Install the SDK with the OpenAI extra and the framework, then call
rius.initand wrap your entrypoint and tools withobserve. The OpenAI Agents SDK integration has the full setup.pip install "glassflow-rius[openai]" openai-agents -
Wrap each turn in
rius.session(), passing the id of the conversation. Herehandle_ticketis theobserve-wrapped entrypoint that callsRunner.run_sync, andconversation_idis your own variable.import rius with rius.session(conversation_id): handle_ticket(ticket) # every span of the turn carries session.id -
Reuse the same
conversation_idfor every turn of that conversation. Turn one and turn five then land in the same session, even if a deploy happens or a different replica serves them. -
If you want to log the id or pass it along, let Rius mint it:
with rius.session() as session_id: handle_ticket(ticket) -
For a CLI run or batch job that handles exactly one session per process, you can skip the scope. Set
init(session_id=...)or theRIUS_SESSION_IDenvironment variable once at startup. An activerius.session()scope overrides that default. Do not use a process-wide default in a server that handles many users, because every user’s traces would merge into one session. Scope each request instead.
The Tracing your code page covers sessions, users and the other scopes in full.
What you get
- Each turn of a conversation is its own trace, and all the turns that share an id read as one session in the console.
- The session id sits on every span of the turn, including the root
AGENTspan, the model calls and the tool calls, so you can follow the conversation from the session down to a single span. - The id is independent of the process serving it. A conversation that outlives a deploy or moves between replicas stays one session.
- A trace with no session id is grouped as its own single-trace session. If an agent’s session count equals its trace count, nothing is setting
session.id, and those sessions are not meaningful groupings. Check that the scope wraps the call. - Your conversation or ticket id doubles as the session id, so you can match a session in Rius to a record in your own system.
For the wider picture of watching agents once they are grouped, see Monitor AI agents in production.
When something else fits
- If one process serves exactly one session, the process-wide default (
init(session_id=...)orRIUS_SESSION_ID) is simpler than scoping each call. - If you want to follow a person across conversations rather than group one chat, use
rius.user(...)alongside the session scope. The two combine freely. - If you leave out the session id, Rius still shows every trace, each as its own session.