How do I group the traces of one conversation into a session with AutoGen?
Rius groups the traces of one AutoGen conversation into a session when you wrap each run in rius.session() and pass your conversation id. Every span started inside the block carries that id as session.id, including the spans AutoGen emits itself. Each turn stays its own trace, and the session ties the turns together. AutoGen tracing in Rius is Python only.
How it works
- A trace is one run of your entrypoint. Each turn of a chat is its own trace, and a session is the id you assign to tie those traces together.
rius.session(conversation_id)stampssession.idon every span started inside the block. That covers yourobserveroot span, thecreate_agentandinvoke_agentspans AutoGen emits, theChatCompletiongeneration and theexecute_toolspans.- The scope rides OpenTelemetry context, so it follows
asyncwork. You can open it around anawaitof your async entrypoint. Scopes nest, and the innermost wins. - Open the scope outside the
observe-wrapped entrypoint, not inside it, so the root span carries the id as well. - You choose the id. Reuse a conversation id or ticket id you already have, or call
rius.session()with no argument to mint a fresh UUID. The block yields the id, so you can log it or hand it to the next turn. - Do not wrap AutoGen tool functions with
observe. The framework runs tools in a detached context, so the wrapper’s span splits off as its own single-span trace, outside your session. Theexecute_toolspans AutoGen emits already cover tools.
The AutoGen integration page covers the framework spans and the OpenAI generations. Tracing your code covers session scopes in full.
Set it up
- Install the SDK with the OpenAI integration and AutoGen, then call
rius.init()once at startup. The AutoGen integration page has the full agent setup and thehandle_ticketentrypoint used below.
pip install "glassflow-rius[openai]" "autogen-agentchat" "autogen-ext[openai]"-
Keep your entrypoint wrapped in
observewith the AGENT kind, as on that page. This gives one trace per turn. -
Open a session scope around each call to that entrypoint, passing the same id for every turn of the conversation.
conversation_idandhandle_conversationare your own names.
import rius
async def handle_conversation(conversation_id: str, tickets: list[str]) -> None:
for ticket in tickets:
with rius.session(conversation_id):
await handle_ticket(ticket)-
If one process serves exactly one conversation, such as a CLI run or a batch job, set the id once instead. Use
init(session_id=...)in Python or theRIUS_SESSION_IDenvironment variable. 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. -
Run two turns of the same conversation, then open the traces in the console. Both should carry the same
session.id.
What you get
- One session per conversation. The turns are separate traces, each with its AGENT root span, the framework’s
invoke_agentandexecute_toolspans, and theChatCompletiongeneration with model, tokens and cost. - A session that stays whole across deploys and replicas. The grouping rides on the traces, not on the process serving them, so a conversation that moves between replicas is still one session.
- A way to check your setup. 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.idand those sessions are not meaningful groupings. - An id that matches one you already have, so you can find a conversation in Rius from your own logs. The concepts page defines sessions and how they relate to traces and instances.
For how sessions fit into watching an agent over time, see Monitor AI agents in production.
When something else fits
- If a process handles exactly one conversation, a process-wide
session_idorRIUS_SESSION_IDsaves you from scoping every call. - If you also want to follow one person across conversations, add a user scope with
rius.user()alongside the session. The user id then ties together all of that person’s sessions.