How do I move my sessions from Helicone to Rius?
Rius maps a Helicone session to session.id, which you set with rius.session in Python or withSession in TypeScript instead of Helicone-Session-Id headers. Every span started inside the scope, including the auto-instrumented model call, carries the session id. The session path becomes the nesting of your spans, and there is no separate session name field. This is one part of the Migrate to Rius path.
How it works
Helicone sets session fields in request headers on each call. Rius sets them in your code, around the work, and stamps them on every span in scope.
- Helicone-Session-Id becomes a session scope.
rius.session(id)stampssession.idon every span inside it. Traces that share asession.idare grouped as one session. - Helicone-Session-Path becomes span nesting. A span started inside another span is its child, so the tree comes from how your code calls, not from a path string. For
/ticket/answer, start aticketspan and ananswerspan inside it. - Helicone-Session-Name has no counterpart field. Name the span that wraps the work, for example
support_ticket, or set an attribute on it. - Helicone-User-Id becomes
rius.user(id)(withUserin TypeScript), which stampsuser.id. It is separate from the session and feeds the Users page. - A process-wide session can be set with the
RIUS_SESSION_IDenvironment variable, for a whole process that is one session.
With no session.id, a trace is its own session. Set it on every span you control, root included, to keep related traces together. If you used the async logger’s set_properties (withProperties in TypeScript), replace it with these scopes and with span attributes.
Set it up
-
Install the SDK with the integration for your provider and start it once at startup. The Migrate from Helicone guide covers the full setup for the proxy, AI Gateway and async logger paths.
pip install "glassflow-rius[openai]" openai export RIUS_API_KEY="ri_..."import rius rius.init(service_name="my-agent") # reads RIUS_API_KEY -
Find the calls that send
Helicone-Session-*headers. If you compare both tools side by side, keep these headers until cutover, then remove them:# Before: Helicone session headers on each request response = openai_client.chat.completions.create( model="gpt-4o-mini", messages=messages, extra_headers={ "Helicone-Session-Id": session_id, "Helicone-Session-Path": "/ticket/answer", "Helicone-Session-Name": "Support ticket", }, ) -
Wrap the work in a session scope and a parent span instead:
# After: a Rius session scope and a parent span with rius.session(session_id): with rius.start_as_current_span("support_ticket"): response = openai_client.chat.completions.create( model="gpt-4o-mini", messages=messages, ) -
In TypeScript, use
withSessionandstartAsCurrentSpan:import { withSession, startAsCurrentSpan } from '@glassflow-ai/rius' await withSession(sessionId, () => startAsCurrentSpan('support_ticket', async () => { const response = await openai.chat.completions.create({ model: 'gpt-4o-mini', messages, }) }), ) -
Rebuild the session path by nesting spans, and put the old session name on the wrapping span or as an attribute.
-
If you also sent
Helicone-User-Id, wrap the request inrius.user(request.user_id)so each span carriesuser.id. -
Run one session end to end and check that the session shows on the trace. Once you have compared both tools, remove the
Helicone-*headers and the Helicone base URL. If you rely on the Helicone gateway, leave its base URL in place. The Rius integrations patch the client library in your process, so calls are traced either way. If you used the async logger, remove it instead of running both in one process, because both register the process-wide OpenTelemetry tracer provider and only one registration is kept.
What you get
- Related traces grouped by one
session.id, with the full tree of model, tool and agent steps under each trace, not only the LLM requests. - Session scopes that apply to every span inside them, so you set the id once per piece of work instead of once per request.
- Per-user views on the Users page when you also set the user, with each user’s traces, failures and cost.
- Cost computed by Rius from the model and token counts, so you send no cost value. Costs are list-price estimates in US dollars.
- Side-by-side checking on the same traffic while the Helicone base URL stays in place.
When something else fits
- Your existing sessions stay in Helicone. Rius has no import from Helicone and starts from the first span you send it.
- If you depend on caching, rate limits, retries, fallbacks, prompt management, scores or datasets, keep those in Helicone or another tool. Rius does not offer them, and it traces your calls either way.