Skip to Content

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

  1. Install the SDK with the OpenAI extra and the framework, then call rius.init and wrap your entrypoint and tools with observe. The OpenAI Agents SDK integration has the full setup.

    pip install "glassflow-rius[openai]" openai-agents
  2. Wrap each turn in rius.session(), passing the id of the conversation. Here handle_ticket is the observe-wrapped entrypoint that calls Runner.run_sync, and conversation_id is your own variable.

    import rius with rius.session(conversation_id): handle_ticket(ticket) # every span of the turn carries session.id
  3. Reuse the same conversation_id for 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.

  4. If you want to log the id or pass it along, let Rius mint it:

    with rius.session() as session_id: handle_ticket(ticket)
  5. For a CLI run or batch job that handles exactly one session per process, you can skip the scope. Set init(session_id=...) or the RIUS_SESSION_ID environment variable once at startup. An active rius.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 AGENT span, 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=...) or RIUS_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.

Still stuck? Get help

Last updated on