Integrations
Rius integrates with the client libraries, agent frameworks, and protocols
agents are built on: model calls arrive as generations with tokens and
cost, and run structure arrives from the framework’s own spans or a thin
layer of observe wrappers. Each integration’s page
covers setup, what lands in the trace, and the blind spots.
Support matrix
| Integration | Type | Model calls captured by | Python | TypeScript |
|---|---|---|---|---|
| OpenAI | Client library | the openai instrumentation | ✓ | ✓ |
| Anthropic | Client library | the anthropic instrumentation | ✓ | ✓ |
| LangChain | Framework | its callbacks, hooked by the langchain instrumentation | ✓ | ✓ |
| LlamaIndex | Framework | the llama-index instrumentation | ✓ | N/A |
| LiteLLM | Router | the litellm instrumentation | ✓ | N/A |
| MCP | Protocol | instrumentation bundled in the SDK | ✓ | ✓ |
| Vercel AI SDK | Framework | its OpenTelemetry telemetry | N/A | ✓ |
| OpenAI Agents SDK | Agent framework | the openai instrumentation underneath | ✓ | N/A |
| Pydantic AI | Agent framework | its native OpenTelemetry spans | ✓ | N/A |
| CrewAI | Agent framework | the openai instrumentation (litellm when LiteLLM is installed) | ✓ | N/A |
| AutoGen | Agent framework | its native OpenTelemetry spans plus the openai instrumentation | ✓ | N/A |
| Claude Agent SDK | Agent framework | manual tracing: an observe root plus a generation filled from the run result | ✓ | N/A |
“N/A” means no integration in that language today; trace those calls with manual generations. Install commands and package names live on each integration’s page.
Installing
Python
Each integration is an optional extra, and extras can be combined:
pip install "glassflow-rius[openai]"
pip install "glassflow-rius[anthropic,langchain]"
pip install "glassflow-rius[instruments]" # all of themEach extra installs the instrumentation for a library, never the library
itself. glassflow-rius[anthropic] expects anthropic to be in your
environment already, which it is in any project that calls Anthropic: Rius
deliberately takes no dependency on provider SDKs, so it never pins or
upgrades the versions your code runs against. An extra installed without its
library makes init() log a DependencyConflict from OpenTelemetry and
leaves that integration off, which is the one failure worth recognizing
here; see
Troubleshooting.
mcp needs no extra at all. Its instrumentation ships inside the SDK rather
than as a separate package, so there is nothing for an extra to add: it turns
itself on whenever the mcp package is importable, which it is in any agent
that calls MCP tools.
The client-library integrations are powered by OpenInference , the open source (Apache-2.0) instrumentation project from Arize AI; the SDK bundles its instrumentors and wires them into the Rius pipeline. The MCP integration is built into the SDK itself.
Enabling
With a default (global) init(), every installed integration is enabled
automatically:
Python
rius.init() # everything installed
rius.init(instruments=["openai"]) # only OpenAI
rius.init(instruments=[]) # noneDetails worth knowing:
- Requesting an integration whose package is not installed logs a warning
and continues; a broken instrumentor never blocks
init(). - If a library is already instrumented by other OpenTelemetry code (not by this SDK), it is left alone.
- Scoped clients (
set_global=False) do not auto-instrument, because instrumentors patch libraries process-wide; passinstruments=[...]explicitly to opt in.
In TypeScript the loud and quiet cases are deliberately split: a package you
did not install stays silent, while a package that is installed but fails to
load logs a warning naming the integration and the underlying error. Either
way init() continues, and the remaining integrations still attach.
What the SDK normalizes
Each bundled instrumentor writes its own attribute dialect, mostly
OpenInference’s llm.* keys. Since 1.0.0 both SDKs rewrite those spans onto
the same OpenTelemetry GenAI keys a manual generation
carries, inside your process and before the
privacy controls run:
- Taxonomy. Every span carries both
openinference.span.kindandgen_ai.operation.name, whichever one the instrumentor set. - The model call.
gen_ai.provider.name,gen_ai.request.model, the request parameters the SDK recognizes (asgen_ai.request.*, plusrius.request.tool_choice),gen_ai.response.finish_reasons(the provider’s own values, not rewritten), andgen_ai.response.id. - Usage. Input and output tokens, cache reads and writes, and reasoning
tokens, under the
gen_ai.usage.*keys. - Messages. The flattened
llm.input_messages.*andllm.output_messages.*keys are reassembled intogen_ai.input.messagesandgen_ai.output.messages, including Anthropic’s multi-part contents. An Anthropic system prompt arrives as the leading system message. - Tools.
gen_ai.tool.nameon tool spans, and the request’s tool list asgen_ai.tool.definitions. - Errors.
error.type, taken from the recorded exception. In TypeScript, provider SDK errors are named by class and package, such asanthropic.NotFoundError, the same spelling Python reports. - Streaming. The instrumentor’s own first-token event, where it records
one, becomes
gen_ai.first_tokenwith the time to first chunk. - Embeddings. The embedding model becomes
gen_ai.request.model, and embedding vectors are dropped rather than exported.
A mapped source key is removed once its value has moved, so each fact is stored once. A key the instrumentation already writes in the canonical spelling is never overwritten, and a key with no canonical equivalent passes through unchanged.
Known limitations
-
Nested model spans are counted twice. Trace and workspace totals add up tokens and cost over every span that carries them, so when two layers both record the same model call, its usage is counted twice:
- LangChain together with a client instrumentation such as
openai: the LangChain LLM span and the client span underneath it both carry the call’s tokens. - LiteLLM together with the
openaiinstrumentation: LiteLLM calls OpenAI-compatible providers through theopenaiclient library, so both instrumentors record the call. - The Vercel AI SDK on
ai7: theinvoke_agentspan for agenerateTextorstreamTextcall carries the usage of the whole call, and eachchatstep span under it carries its own.
In Python, enable one layer with
init(instruments=[...]), for exampleinstruments=["langchain"]. The Vercel case has no switch today. - LangChain together with a client instrumentation such as
-
No time to first token on auto-instrumented Anthropic streams, or on TypeScript OpenAI streams. Of the client instrumentations, only the Python
openaione records a first-token event. Where TTFT matters for those calls, trace them as a manual generation. -
TypeScript OpenAI streams carry no token usage, so they get no cost. See OpenAI.