Installation and configuration
The Rius SDK for Python is published as glassflow-rius and imported as
rius; it requires Python 3.10 or newer. The TypeScript SDK is published as
@glassflow-ai/rius and requires Node 18 or newer.
Python
pip install glassflow-riusTo auto-instrument the LLM libraries you use, install their extras (see Integrations):
pip install "glassflow-rius[openai]" # one library
pip install "glassflow-rius[instruments]" # everythingAn extra installs the instrumentation for a library, never the library
itself: glassflow-rius[anthropic] brings in the Anthropic instrumentation
and expects anthropic to already be in your environment, which it is in
any project that calls Anthropic. Rius deliberately does not depend on
provider SDKs, so it never pins or upgrades the versions your code runs
against. If an extra is installed without its library, init() logs a
DependencyConflict from OpenTelemetry and that integration stays off; see
Troubleshooting.
MCP needs no extra: Rius instruments it directly rather than through a
separate package, so that integration turns itself on whenever mcp is
importable.
Initializing
Call init() once, as early as possible in your process:
Python
import rius
client = rius.init(
api_key="ri_...",
service_name="my-agent",
)Every argument is optional and can also come from an environment variable. Explicit arguments win over environment variables, which win over defaults.
Naming your agent
Set service_name (RIUS_SERVICE_NAME) explicitly. It is the
service.name resource attribute stamped on every span and how you find
your agent in trace filters, analytics, and cost breakdowns. It defaults
to unknown_service.
Optionally set agent_name (RIUS_AGENT_NAME) to control how instances
group in the Agents view. It defaults to
service_name; set it separately only when several services form one
logical agent.
Keep the name constant across replicas and deploys. Each process start is a fresh instance under the same name, so three replicas show as three instances of one agent. Keep version numbers out of the name; the SDK already reports its version per instance.
Renaming does not re-key history: stored spans keep the old service.name
and stay filterable under it, while the new name starts empty. In the
Agents view the old name’s instances report gone and linger until their
heartbeat records are garbage-collected. Treat the name as an identifier,
not a label.
Configuration reference
Python
| Argument | Environment variable | Default | What it does |
|---|---|---|---|
endpoint | RIUS_ENDPOINT | https://ingest.eu.console.rius-glassflow.com | Base OTLP endpoint. Traces post to {endpoint}/v1/traces. |
api_key | RIUS_API_KEY | None | Sent as Authorization: Bearer <key>. If you pass your own Authorization header via headers, it wins. None is valid for OTLP backends that need no auth. |
service_name | RIUS_SERVICE_NAME | unknown_service | The service.name resource attribute on every span. Set it; it is how you find your agent later. See Naming your agent. |
headers | none | {} | Extra headers for the exporter. |
disabled | RIUS_DISABLED | False | Kill switch. When true, no exporter is attached and spans are dropped in-process. |
sample_rate | RIUS_SAMPLE_RATE | 1.0 | Head sampling rate for root traces. See Sampling. |
capture_content | RIUS_CAPTURE_CONTENT | True | When false, prompt and response content is stripped at export; metadata still flows. See Privacy controls. |
mask | none | None | Redaction callable applied to content attributes at export. See Privacy controls. |
instruments | none | None | Which integrations to enable: None enables all installed, [] disables, ["openai"] restricts. See Integrations. |
span_exporter | none | None | Override the OTLP exporter (mostly for tests). |
heartbeat | RIUS_HEARTBEAT | True | The agent-lifetime heartbeat thread: pings {endpoint}/v1/heartbeat from init() until process exit, powering the Agents view. On by default since 0.10.0; set False (or RIUS_HEARTBEAT=false) to opt out. Delivery semantics in Reliability. |
heartbeat_interval | RIUS_HEARTBEAT_INTERVAL | 15 | Seconds between pings, clamped to 5-300. Staleness detection derives from it, so a slower interval also slows stale/gone detection. |
agent_name | RIUS_AGENT_NAME | service_name | The identity heartbeat instances group under in the Agents view. Set it when several services are one logical agent. See Naming your agent. |
heartbeat_transport | none | None | Override the heartbeat HTTP transport (mostly for tests, like span_exporter). |
partial_spans | RIUS_PARTIAL_SPANS | False | Export a content-free snapshot of every span at start, so in-flight and crashed work is visible. See Partial spans. |
partial_spans_delay | RIUS_PARTIAL_SPANS_DELAY | 0.0 | Seconds to hold a snapshot before sending it, clamped to 0-60. A span that finishes within the delay sends no snapshot at all. |
session_id | RIUS_SESSION_ID | None | Process-wide session.id for every span, for an agent that handles one session per process. A session scope overrides it; do not set it in a server handling many users. |
workspaces | none | None | Multi-workspace routing: a mapping of alias to API key. Spans inside rius.workspace(alias) export with that workspace’s key; {} opts in with routes added later via register_workspace(). See routing traces to the right workspace. |
workspace_exporter_factory | none | None | Override how per-workspace exporters are built from an API key (mostly for tests, like span_exporter). |
set_global | none | True | Register the provider as the global OpenTelemetry provider. |
Boolean environment variables accept 1, true, yes, or on in any case.
Out-of-range sample_rate values are clamped to [0.0, 1.0] with a warning.
Calling init() twice
The OpenTelemetry global provider is write-once, so a second global init()
while a client is active logs a warning and returns the existing client
unchanged. To reconfigure, call client.shutdown() first, which drains
pending spans and releases the slot. With heartbeats enabled, shutdown()
also sends the final stopped ping, which is how the platform tells a
clean exit from a crash (see
status semantics).
If your process needs an isolated pipeline next to an existing one, use a scoped client instead:
Python
client = rius.init(set_global=False, service_name="side-pipeline")
tracer = client.get_tracer()A scoped client does not claim the global slot, and it does not enable
auto-instrumentation unless you pass instruments=[...] explicitly, because
instrumentors patch libraries process-wide.
What every span carries
The SDK stamps these resource attributes on all spans it exports:
service.name, from your configurationtelemetry.distro.name: glassflow-riusandtelemetry.distro.version
Spans created by the SDK itself use the tracer scope name glassflow.
Next steps
- Tracing your code: tracing functions with
observe, spans, and generations. - Integrations: tracing OpenAI, Anthropic, LangChain, and friends without manual spans.
- Monitoring live agents: what the heartbeat powers, including the status semantics.