TypeScript reference
Generated from the @glassflow-ai/rius 1.0.0 type declarations,
covering the TypeScript SDK’s public API surface. Wording fixes happen upstream
in the SDK repository, never here.
Most code starts with init(), then observe() or the
startSpan / startGeneration helpers.
RiusClient is the handle init() returns; the rest are the
option shapes those take.
getTracer()
function getTracer(): Tracer;The SDK tracer. Scope name is wire-visible; do not parameterize it.
Returns
Tracer
init()
function init(options?): RiusClient;Initialize the SDK: build a tracer pipeline that exports OTLP traces and enable every bundled auto-instrumentation whose package is installed.
Call it once, as early as possible in your process. A second call while a
client is active logs a warning and returns the existing client unchanged;
shutdown() releases the slot. init() is synchronous; await
RiusClient.ready if instrumentation must be attached before your
first span.
The SDK installs no exit hook for SPANS: short-lived processes must call
RiusClient.flush before exiting or spans still in the batch queue
are lost. (The heartbeat does register a beforeExit listener, only to
send its final stopped ping; it flushes nothing.)
Parameters
| Parameter | Type |
|---|---|
options? | InitOptions |
Returns
observe()
function observe<F>(fn, options?): (...args) => Promise<Awaited<ReturnType<F>>>;Wrap a function so each call becomes a span. The returned function takes
the same parameters and always returns a Promise of the original’s result
(a synchronous function becomes asynchronous), so call sites need an
await but no other change.
A wrapper rather than a decorator on purpose: TypeScript decorators apply only to class members, and most agent code is plain functions.
Type Parameters
| Type Parameter |
|---|
F extends (…args) => unknown |
Parameters
| Parameter | Type |
|---|---|
fn | F |
options? | ObserveOptions |
Returns
(...args): Promise<Awaited<ReturnType<F>>>;Parameters
| Parameter | Type |
|---|---|
…args | Parameters<F> |
Returns
Promise<Awaited<ReturnType<F>>>
registerWorkspace()
function registerWorkspace(alias, apiKey): void;Add (or rotate the key of) a workspace destination on the global client.
Requires init({ workspaces }) to have opted into routing (an empty
object opts in with no static routes). Spans started inside
withWorkspace(alias, ...) are then exported with apiKey.
Parameters
| Parameter | Type |
|---|---|
alias | string |
apiKey | string |
Returns
void
startAsCurrentGeneration()
Call Signature
function startAsCurrentGeneration<T>(name, fn): Promise<T>;Run fn with a generation span active. Auto-ends, records exceptions.
Both the name and options are optional and the callback stays last, so
startAsCurrentGeneration({ model: "gpt-4o" }, fn) names the span
chat gpt-4o for you.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
name | string |
fn | GenerationBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentGeneration<T>(
name,
options,
fn): Promise<T>;Run fn with a generation span active. Auto-ends, records exceptions.
Both the name and options are optional and the callback stays last, so
startAsCurrentGeneration({ model: "gpt-4o" }, fn) names the span
chat gpt-4o for you.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
name | string |
options | GenerationOptions |
fn | GenerationBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentGeneration<T>(options, fn): Promise<T>;Run fn with a generation span active. Auto-ends, records exceptions.
Both the name and options are optional and the callback stays last, so
startAsCurrentGeneration({ model: "gpt-4o" }, fn) names the span
chat gpt-4o for you.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
options | GenerationOptions |
fn | GenerationBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentGeneration<T>(fn): Promise<T>;Run fn with a generation span active. Auto-ends, records exceptions.
Both the name and options are optional and the callback stays last, so
startAsCurrentGeneration({ model: "gpt-4o" }, fn) names the span
chat gpt-4o for you.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
fn | GenerationBody<T> |
Returns
Promise<T>
startAsCurrentSpan()
Call Signature
function startAsCurrentSpan<T>(name, fn): Promise<T>;Run fn with a new span active, so spans created inside it nest under this
one across async boundaries. Auto-ends, records exceptions, rethrows.
Both the name and options are optional, and the callback always comes
last: startAsCurrentSpan(name, fn), startAsCurrentSpan(options, fn) and
startAsCurrentSpan(fn) all work, as does the full three-argument form.
Omitting the name asks for the conventions’ {operation} {target} name;
see startSpan.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
name | string |
fn | SpanBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentSpan<T>(
name,
options,
fn): Promise<T>;Run fn with a new span active, so spans created inside it nest under this
one across async boundaries. Auto-ends, records exceptions, rethrows.
Both the name and options are optional, and the callback always comes
last: startAsCurrentSpan(name, fn), startAsCurrentSpan(options, fn) and
startAsCurrentSpan(fn) all work, as does the full three-argument form.
Omitting the name asks for the conventions’ {operation} {target} name;
see startSpan.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
name | string |
options | SpanOptions |
fn | SpanBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentSpan<T>(options, fn): Promise<T>;Run fn with a new span active, so spans created inside it nest under this
one across async boundaries. Auto-ends, records exceptions, rethrows.
Both the name and options are optional, and the callback always comes
last: startAsCurrentSpan(name, fn), startAsCurrentSpan(options, fn) and
startAsCurrentSpan(fn) all work, as does the full three-argument form.
Omitting the name asks for the conventions’ {operation} {target} name;
see startSpan.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
options | SpanOptions |
fn | SpanBody<T> |
Returns
Promise<T>
Call Signature
function startAsCurrentSpan<T>(fn): Promise<T>;Run fn with a new span active, so spans created inside it nest under this
one across async boundaries. Auto-ends, records exceptions, rethrows.
Both the name and options are optional, and the callback always comes
last: startAsCurrentSpan(name, fn), startAsCurrentSpan(options, fn) and
startAsCurrentSpan(fn) all work, as does the full three-argument form.
Omitting the name asks for the conventions’ {operation} {target} name;
see startSpan.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
fn | SpanBody<T> |
Returns
Promise<T>
startGeneration()
Call Signature
function startGeneration(name, options?): Generation;Create a generation span and return a handle. You MUST call end().
The name is optional; omitted, the span is named {operation} {model}.
Parameters
| Parameter | Type |
|---|---|
name | string |
options? | GenerationOptions |
Returns
Call Signature
function startGeneration(options?): Generation;Create a generation span and return a handle. You MUST call end().
The name is optional; omitted, the span is named {operation} {model}.
Parameters
| Parameter | Type |
|---|---|
options? | GenerationOptions |
Returns
startSpan()
Call Signature
function startSpan(name, options?): Observation;Create a span and return a handle. You MUST call end() (or use using).
The span is parented to whatever is current but does NOT become current.
Because it never becomes current, an AGENT span created here opens no
agent scope: a TOOL span started while it is open falls back to the
configured agent name for gen_ai.agent.name rather than naming this one.
Use startAsCurrentSpan (or observe) where that matters.
The name is optional: omit it and the span is named the way the GenAI
conventions say to, {operation} {target} — execute_tool get_weather,
invoke_agent planner, retrieval docs-index — from the attributes it is
being created with. A name you pass always wins.
Parameters
| Parameter | Type |
|---|---|
name | string |
options? | SpanOptions |
Returns
Call Signature
function startSpan(options?): Observation;Create a span and return a handle. You MUST call end() (or use using).
The span is parented to whatever is current but does NOT become current.
Because it never becomes current, an AGENT span created here opens no
agent scope: a TOOL span started while it is open falls back to the
configured agent name for gen_ai.agent.name rather than naming this one.
Use startAsCurrentSpan (or observe) where that matters.
The name is optional: omit it and the span is named the way the GenAI
conventions say to, {operation} {target} — execute_tool get_weather,
invoke_agent planner, retrieval docs-index — from the attributes it is
being created with. A name you pass always wins.
Parameters
| Parameter | Type |
|---|---|
options? | SpanOptions |
Returns
withSession()
Call Signature
function withSession<T>(fn): T;Scope every span started inside fn to one session id.
Pass the application’s own id (a conversation id, a job id) to correlate
with it; omit it to mint a fresh UUID for the scope. Either way the scope’s
id is passed to the callback, so it can be logged or handed to the next
turn. Nested scopes override outer ones, and an active scope overrides the
init({ sessionId }) default.
There is deliberately no process-wide auto-generation: without an id the backend groups each trace as its own session, which stays true in a server handling many users, while an auto-minted global id would merge every user into one. A generated id is only ever scoped to an explicit callback, where “this is one session” is the caller’s own claim.
await withSession(conversationId, async () => {
await handleTurn(message) // every span of the turn carries session.id
})Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
fn | (sessionId) => T |
Returns
T
Call Signature
function withSession<T>(sessionId, fn): T;Scope every span started inside fn to one session id.
Pass the application’s own id (a conversation id, a job id) to correlate
with it; omit it to mint a fresh UUID for the scope. Either way the scope’s
id is passed to the callback, so it can be logged or handed to the next
turn. Nested scopes override outer ones, and an active scope overrides the
init({ sessionId }) default.
There is deliberately no process-wide auto-generation: without an id the backend groups each trace as its own session, which stays true in a server handling many users, while an auto-minted global id would merge every user into one. A generated id is only ever scoped to an explicit callback, where “this is one session” is the caller’s own claim.
await withSession(conversationId, async () => {
await handleTurn(message) // every span of the turn carries session.id
})Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
sessionId | string |
fn | (sessionId) => T |
Returns
T
withUser()
function withUser<T>(userId, fn): T;Scope every span started inside fn to one end user.
Pass the application’s own identifier for the person the request serves.
Prefer an opaque id over an email: it is stored on every span and shown
in the console. When only sensitive identifiers exist, hash them first
(OTel’s user.hash / enduser.pseudo.id guidance). Nested scopes
override outer ones. The id is passed to the callback so it can be logged
alongside the work.
await withUser(request.userId, async () => {
await handle(request) // every span of the request carries user.id
})Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
userId | string |
fn | (userId) => T |
Returns
T
withWorkspace()
function withWorkspace<T>(alias, fn): T;Scope every span started inside fn to one workspace destination.
alias names a workspace registered via init({ workspaces }) or
registerWorkspace(); the scope’s spans are exported with that
workspace’s API key. Scopes nest and follow async continuations the way
all OTel context does, but a trace must stay inside one workspace: enter
the scope at a request boundary, before the root span starts.
await withWorkspace("acme", async () => {
await handle(request) // every span of the request lands in acme's workspace
})Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
alias | string |
fn | (alias) => T |
Returns
T
Generation
An LLM call. Content uses gen_ai message keys, never input.value.
Extends
Constructors
Constructor
new Generation(span, provider?): Generation;The provider passed at creation; drives the Anthropic input-token summing
in setUsage. A bare new Generation(span) has none and never sums.
Parameters
| Parameter | Type |
|---|---|
span | Span |
provider? | string |
Returns
Overrides
Methods
[dispose]()
dispose: void;Lets callers write using obs = startSpan(...). Sugar over end().
Returns
void
Inherited from
end()
end(): void;Ends the span after recording the context sizes; idempotent like the base.
Returns
void
Overrides
recordException()
recordException(error): this;Record an error on the span, set ERROR status and error.type. This is
exactly what the startAsCurrent* helpers do on a thrown error, exposed
so the manual start* path does not have to reach through .span to
match it.
error.type is Conditionally Required by the GenAI conventions on every
span that ends in an error, and every helper’s throw path funnels through
here, so this is the one place that sets it. The error’s name or class
(see errorType), never the message: it must stay low-cardinality and free
of echoed content.
Accepts unknown because that is what a catch binding is; a non-Error
throwable is wrapped so recordException still gets a real Error.
Parameters
| Parameter | Type |
|---|---|
error | unknown |
Returns
this
Inherited from
recordFirstToken()
recordFirstToken(): this;Mark the arrival of the first streamed token. Records the
gen_ai.first_token event (the timestamp the backend derives TTFT from)
and, per the GenAI conventions, the derived
gen_ai.response.time_to_first_chunk (seconds since span creation) plus
gen_ai.request.stream = true: a first chunk arriving is what tells the
SDK the request streamed. Idempotent: only the first call records, so a
streaming loop can call this unconditionally on every chunk without
inflating the span. A no-op after the span has ended.
Returns
this
setAttribute()
setAttribute(key, value): this;Set an arbitrary attribute. Primitives and homogeneous primitive arrays
are passed through as the OTel values they are; objects are JSON-encoded
and bounded; undefined and null set nothing, since “no value” is not
an empty string.
Parameters
| Parameter | Type |
|---|---|
key | string |
value | unknown |
Returns
this
Inherited from
setFinishReasons()
setFinishReasons(reasons): this;Why generation stopped (gen_ai.response.finish_reasons), e.g. "stop",
"length", "tool_calls". The convention is a list; a single reason is
wrapped so callers do not have to.
Parameters
| Parameter | Type |
|---|---|
reasons | string | string[] |
Returns
this
setInput()
setInput(value): this;Record the request messages (gen_ai.input.messages), normalised to the
GenAI {role, parts} shape like the Python SDK does: bare strings, OpenAI
dicts (including tool_calls and tool responses) and multimodal content
lists are all accepted. Bare strings default to the user role.
Parameters
| Parameter | Type |
|---|---|
value | unknown |
Returns
this
Overrides
setModel()
setModel(model): this;Parameters
| Parameter | Type |
|---|---|
model | string |
Returns
this
setOutput()
setOutput(value): this;Record the response messages (gen_ai.output.messages); bare strings default to assistant.
Parameters
| Parameter | Type |
|---|---|
value | unknown |
Returns
this
Overrides
setResponseId()
setResponseId(id): this;The provider’s identifier for this completion (gen_ai.response.id) —
OpenAI’s id, Anthropic’s id, and so on. A post-call setter and not a
creation option for the reason setModel is one: the value arrives WITH
the response, so no span can carry it at creation and no pending snapshot
can either. Recorded verbatim; it is an opaque provider string, and it is
not content, so it survives captureContent: false.
Parameters
| Parameter | Type |
|---|---|
id | string |
Returns
this
setRetrievedDocuments()
setRetrievedDocuments(documents): this;Record what a retrieval returned, as gen_ai.retrieval.documents.
The conventions define this as an array of objects, each with an optional
id and an optional score. Identifiers and relevance, never document
text, which is why it is not treated as content: it survives
captureContent: false the way token counts do. Put the retrieved text in
setOutput if you want it captured, and masking applies to it there.
Unlike dataSourceId and topK, which describe the request and are
passed at span creation, this is only knowable once the search has run, so
it never reaches a pending snapshot.
Parameters
| Parameter | Type |
|---|---|
documents | unknown |
Returns
this
Inherited from
Observation.setRetrievedDocuments
setToolDefinitions()
setToolDefinitions(tools): this;The request’s tool/function definitions (gen_ai.tool.definitions).
Serialized verbatim, in whatever shape the provider request used (OpenAI
nests each tool under function, Anthropic uses top-level
name/input_schema) — no normalization, so what is recorded is exactly
what the model was shown. Definitions are content, not identity: they are
masked/stripped under captureContent: false like messages are.
Parameters
| Parameter | Type |
|---|---|
tools | unknown[] |
Returns
this
setUsage()
setUsage(usage): this;Token usage (gen_ai.usage.*). Pass provider-reported values as-is;
never pre-add anything. Per the GenAI conventions, inputTokens is the
total including cached tokens (the cache counts are subsets of it).
Anthropic’s API reports input_tokens excluding the cache counts, and
the conventions require the instrumentation to do the summing, so when
the generation’s provider is "anthropic" the emitted total is
inputTokens plus both cache counts. Every other provider is recorded
verbatim.
Parameters
| Parameter | Type | Description |
|---|---|---|
usage | { cacheReadInputTokens?: number; cacheWriteInputTokens?: number; inputTokens?: number; outputTokens?: number; reasoningOutputTokens?: number; } | - |
usage.cacheReadInputTokens? | number | Input tokens served from a provider-managed prompt cache. |
usage.cacheWriteInputTokens? | number | Input tokens written to a provider-managed prompt cache (called “cache creation” by Anthropic). |
usage.inputTokens? | number | - |
usage.outputTokens? | number | - |
usage.reasoningOutputTokens? | number | Output tokens spent on reasoning / extended thinking. A subset of outputTokens, never in addition to it: providers already include reasoning tokens in the output total, so pass both as reported and do no arithmetic. |
Returns
this
Properties
| Property | Modifier | Type | Inherited from |
|---|---|---|---|
span | readonly | Span | Observation.span |
Observation
A handle over a span. Chainable setters; end() is idempotent.
Extended by
Constructors
Constructor
new Observation(span): Observation;Parameters
| Parameter | Type |
|---|---|
span | Span |
Returns
Methods
[dispose]()
dispose: void;Lets callers write using obs = startSpan(...). Sugar over end().
Returns
void
end()
end(): void;Returns
void
recordException()
recordException(error): this;Record an error on the span, set ERROR status and error.type. This is
exactly what the startAsCurrent* helpers do on a thrown error, exposed
so the manual start* path does not have to reach through .span to
match it.
error.type is Conditionally Required by the GenAI conventions on every
span that ends in an error, and every helper’s throw path funnels through
here, so this is the one place that sets it. The error’s name or class
(see errorType), never the message: it must stay low-cardinality and free
of echoed content.
Accepts unknown because that is what a catch binding is; a non-Error
throwable is wrapped so recordException still gets a real Error.
Parameters
| Parameter | Type |
|---|---|
error | unknown |
Returns
this
setAttribute()
setAttribute(key, value): this;Set an arbitrary attribute. Primitives and homogeneous primitive arrays
are passed through as the OTel values they are; objects are JSON-encoded
and bounded; undefined and null set nothing, since “no value” is not
an empty string.
Parameters
| Parameter | Type |
|---|---|
key | string |
value | unknown |
Returns
this
setInput()
setInput(value): this;Parameters
| Parameter | Type |
|---|---|
value | unknown |
Returns
this
setOutput()
setOutput(value): this;Parameters
| Parameter | Type |
|---|---|
value | unknown |
Returns
this
setRetrievedDocuments()
setRetrievedDocuments(documents): this;Record what a retrieval returned, as gen_ai.retrieval.documents.
The conventions define this as an array of objects, each with an optional
id and an optional score. Identifiers and relevance, never document
text, which is why it is not treated as content: it survives
captureContent: false the way token counts do. Put the retrieved text in
setOutput if you want it captured, and masking applies to it there.
Unlike dataSourceId and topK, which describe the request and are
passed at span creation, this is only knowable once the search has run, so
it never reaches a pending snapshot.
Parameters
| Parameter | Type |
|---|---|
documents | unknown |
Returns
this
Properties
| Property | Modifier | Type |
|---|---|---|
span | readonly | Span |
RiusClient
Handle over a configured tracer pipeline, returned by init.
Exposes the lifecycle operations (flush, shutdown) and ready, which
resolves with the auto-instrumentations that attached.
Methods
flush()
flush(): Promise<boolean>;Drains the queue. Resolves false if the most recent export failed.
Returns
Promise<boolean>
shutdown()
shutdown(): Promise<void>;Drains and tears down the provider, then releases the global registration so a later init() can reconfigure the SDK.
The heartbeat’s final stopped: true ping is sent before the provider
shuts down, so the backend hears “stopped” while the trace pipeline can
still export it. Idempotent: sender.stop() no-ops on a second call, and
the beforeExit listener is removed here so repeated init/shutdown
cycles never leak listeners.
Returns
Promise<void>
Properties
| Property | Modifier | Type | Description |
|---|---|---|---|
ready | readonly | Promise<string[]> | Resolves with the names of the auto-instrumentations that attached. |
GenerationOptions
Options for startGeneration and startAsCurrentGeneration: the model identity and request parameters an LLM span carries.
Properties
| Property | Type | Description |
|---|---|---|
input? | unknown | - |
model? | string | - |
modelParameters? | Record<string, unknown> | Request parameters, for example { temperature: 0.2, max_tokens: 512 }, recorded at span creation so they ride pending snapshots. A parameter the GenAI conventions define, under its canonical name or a recognised provider spelling (OpenAI’s max_completion_tokens, Google’s maxOutputTokens, a camelCase topP), is recorded under its canonical gen_ai.request.* key and only that one. Everything else is recorded under rius.request.<key>, this SDK’s own namespace, with the key otherwise untouched. Values that are not scalars or homogeneous scalar arrays are JSON-encoded; null and undefined mean “not set” and are skipped. The model and reasoningLevel options win over a parameter that maps to the same key. |
operation? | string | Operation name (gen_ai.operation.name); default "chat". Set it for text_completion, embeddings or generate_content calls, as the Python SDK’s operation= allows. |
outputType? | string | The output modality requested of the model (gen_ai.output.type) — "text", "json", "image" or "speech" per the conventions, which make it Conditionally Required when the request asks for a specific output format. An option rather than a setter because it is a property of the REQUEST: known before the call, so it is set at span creation and reaches pending snapshots. The string is recorded verbatim, not validated against the four members: the enum is open, and a provider’s own spelling is still what the caller asked for. |
provider? | string | - |
reasoningLevel? | string | Requested reasoning/thinking effort level (gen_ai.request.reasoning.level), e.g. OpenAI’s reasoning.effort values. Provider-defined string, recorded verbatim. Passing reasoning_effort through modelParameters lands on the same key; this option wins when both are given. |
tools? | unknown[] | The request’s tool/function definitions, recorded immediately via Generation.setToolDefinitions — verbatim, any provider shape. |
userId? | string | End-user identity (user.id). Sugar for withUser: set on this span at creation and, for the scoped variant, on every span opened inside it. |
InitOptions
Options accepted by init, extending the shared configuration.
Extends
Properties
| Property | Type | Description | Inherited from |
|---|---|---|---|
agentName? | string | - | RiusOptions.agentName |
apiKey? | string | - | RiusOptions.apiKey |
bridgeForeignProvider? | boolean | What to do when another SDK already holds the OpenTelemetry global tracer provider at init() (RIUS_BRIDGE_FOREIGN_PROVIDER; off by default). Off, Rius keeps to its own provider: LLM spans started inside the other SDK’s spans arrive without their parent, flagged rius.parent.foreign, counted in the heartbeat, and the first one logs a warning. On, Rius also exports the other SDK’s spans (the parents), under Rius’s resource identity and subject to Rius’s sampling and content settings, and it never modifies what the other SDK exports. Either way the resource records the conflict as rius.sdk.global_provider. Off by default: exporting another SDK’s spans is consent the caller gives explicitly. | RiusOptions.bridgeForeignProvider |
captureContent? | boolean | - | RiusOptions.captureContent |
disabled? | boolean | - | RiusOptions.disabled |
endpoint? | string | - | RiusOptions.endpoint |
heartbeat? | boolean | - | RiusOptions.heartbeat |
heartbeatInterval? | number | Seconds between agent-lifetime heartbeat pings. | RiusOptions.heartbeatInterval |
heartbeatTransport? | HeartbeatTransport | Override the heartbeat HTTP transport. The test seam; prefer this to mocking fetch. | - |
mainAgentDescription? | string | A human-readable description of the agent this process is, stamped as rius.main_agent.description. This option, then RIUS_MAIN_AGENT_DESCRIPTION, then unset. | RiusOptions.mainAgentDescription |
mainAgentId? | string | A STABLE identifier for the agent this process is, stamped on the resource as rius.main_agent.id. A registry id or a hosted agent’s ARN, NOT a transient in-memory or process-local id: a uuid minted at startup identifies a run, not an agent, and would split one agent into a fresh bucket per restart. service.instance.id already answers “which process”. Absent by default and never defaulted. Resolution: this option, then RIUS_MAIN_AGENT_ID, then unset. | RiusOptions.mainAgentId |
mainAgentVersion? | string | The version of the AGENT DEFINITION this process runs — its prompt, tools and policy — stamped as rius.main_agent.version. Deliberately NOT serviceVersion, which is the version of the build hosting it: the two move independently, and neither is ever derived from the other. Resolution: this option, then RIUS_MAIN_AGENT_VERSION, then unset. The OTel environment is not consulted, unlike serviceVersion: no convention defines this key, so OTEL_RESOURCE_ATTRIBUTES cannot be carrying it. | RiusOptions.mainAgentVersion |
mask? | Mask | - | RiusOptions.mask |
partialSpans? | boolean | - | RiusOptions.partialSpans |
partialSpansDelay? | number | Seconds to debounce a pending-span snapshot after span start. | RiusOptions.partialSpansDelay |
sampleRate? | number | - | RiusOptions.sampleRate |
serviceName? | string | - | RiusOptions.serviceName |
serviceVersion? | string | The running build’s version, stamped on the resource as service.version. There is deliberately NO default: service.name already shows what a missing value costs, where the unknown_service placeholder merges every unconfigured process into one bucket. An absent version is a visibly absent version, so the resource simply omits the key. Resolution: this option, then RIUS_SERVICE_VERSION, then service.version inside OTEL_RESOURCE_ATTRIBUTES, then unset. | RiusOptions.serviceVersion |
sessionId? | string | Process-wide session id, stamped as session.id on every span. For one-run-per-process agents; a server handling many sessions scopes each one with withSession() instead, which overrides this default. | RiusOptions.sessionId |
spanExporter? | SpanExporter | Inject an exporter instead of OTLP. The test seam; prefer this to mocking. | - |
workspaceExporterFactory? | WorkspaceExporterFactory | Override how per-workspace exporters are built from an API key. The test seam, like spanExporter; defaults to the standard OTLP exporter against the configured endpoint. | - |
workspaces? | Record<string, string> | Enable multi-workspace routing: a map of alias to API key. Spans started inside withWorkspace(alias, fn) are exported with that workspace’s key; spans outside any scope use the default apiKey. Pass {} to opt in with no static routes and register destinations later via registerWorkspace(). One trace must stay inside one workspace. | - |
ObserveOptions
Options for observe.
Properties
| Property | Type | Description |
|---|---|---|
agentId? | string | The invoked agent’s identifier (gen_ai.agent.id). For a HOSTED agent resource such as a Bedrock agent ARN; an in-process agent leaves it unset. |
agentName? | string | The agent an AGENT-kind wrapper invokes, set as gen_ai.agent.name. Unset, it falls back to the agent name init() was given; it is never taken from the wrapped function’s name. Ignored on every other kind. It also scopes the call: TOOL spans opened while the wrapped function runs carry this name as the agent that EXECUTED them, which is what the same key means on an execute-tool span. |
agentVersion? | string | The invoked agent’s version (gen_ai.agent.version): the version of the agent definition, taken verbatim and never derived from the service version or from the version of the agent this process is. |
captureInput? | boolean | - |
captureOutput? | boolean | - |
dataSourceId? | string | The index, collection or knowledge base a RETRIEVER-kind wrapper searched, set as gen_ai.data_source.id. Ignored on every other kind. |
kind? | SpanKind | - |
name? | string | - |
toolCallId? | string | The id of the model tool-call a TOOL-kind wrapper answers, set as gen_ai.tool.call.id. Only the caller has it — a wrapper sees the arguments, never the assistant message that produced them — so it is passed or omitted, never derived. Ignored on every other kind. |
toolName? | string | The tool name a TOOL-kind wrapper carries as gen_ai.tool.name. Defaults to the span name, so a wrapped function whose name IS the tool name needs nothing; pass it when the two differ. |
toolType? | string | What kind of tool a TOOL-kind wrapper runs, set as gen_ai.tool.type ("function", "extension", "datastore"). Recorded verbatim and never inferred from the wrapped callable: the wrapper shape says nothing about where the tool actually executes. Ignored on every other kind. |
topK? | number | How many documents a RETRIEVER-kind wrapper asked for, set as gen_ai.retrieval.top_k. Ignored on every other kind. |
RiusOptions
Configuration shared by every client. Each option can also come from a
RIUS_* environment variable; explicit options win over the environment,
which wins over defaults.
Extended by
Properties
| Property | Type | Description |
|---|---|---|
agentName? | string | - |
apiKey? | string | - |
bridgeForeignProvider? | boolean | What to do when another SDK already holds the OpenTelemetry global tracer provider at init() (RIUS_BRIDGE_FOREIGN_PROVIDER; off by default). Off, Rius keeps to its own provider: LLM spans started inside the other SDK’s spans arrive without their parent, flagged rius.parent.foreign, counted in the heartbeat, and the first one logs a warning. On, Rius also exports the other SDK’s spans (the parents), under Rius’s resource identity and subject to Rius’s sampling and content settings, and it never modifies what the other SDK exports. Either way the resource records the conflict as rius.sdk.global_provider. Off by default: exporting another SDK’s spans is consent the caller gives explicitly. |
captureContent? | boolean | - |
disabled? | boolean | - |
endpoint? | string | - |
heartbeat? | boolean | - |
heartbeatInterval? | number | Seconds between agent-lifetime heartbeat pings. |
mainAgentDescription? | string | A human-readable description of the agent this process is, stamped as rius.main_agent.description. This option, then RIUS_MAIN_AGENT_DESCRIPTION, then unset. |
mainAgentId? | string | A STABLE identifier for the agent this process is, stamped on the resource as rius.main_agent.id. A registry id or a hosted agent’s ARN, NOT a transient in-memory or process-local id: a uuid minted at startup identifies a run, not an agent, and would split one agent into a fresh bucket per restart. service.instance.id already answers “which process”. Absent by default and never defaulted. Resolution: this option, then RIUS_MAIN_AGENT_ID, then unset. |
mainAgentVersion? | string | The version of the AGENT DEFINITION this process runs — its prompt, tools and policy — stamped as rius.main_agent.version. Deliberately NOT serviceVersion, which is the version of the build hosting it: the two move independently, and neither is ever derived from the other. Resolution: this option, then RIUS_MAIN_AGENT_VERSION, then unset. The OTel environment is not consulted, unlike serviceVersion: no convention defines this key, so OTEL_RESOURCE_ATTRIBUTES cannot be carrying it. |
mask? | Mask | - |
partialSpans? | boolean | - |
partialSpansDelay? | number | Seconds to debounce a pending-span snapshot after span start. |
sampleRate? | number | - |
serviceName? | string | - |
serviceVersion? | string | The running build’s version, stamped on the resource as service.version. There is deliberately NO default: service.name already shows what a missing value costs, where the unknown_service placeholder merges every unconfigured process into one bucket. An absent version is a visibly absent version, so the resource simply omits the key. Resolution: this option, then RIUS_SERVICE_VERSION, then service.version inside OTEL_RESOURCE_ATTRIBUTES, then unset. |
sessionId? | string | Process-wide session id, stamped as session.id on every span. For one-run-per-process agents; a server handling many sessions scopes each one with withSession() instead, which overrides this default. |
SpanOptions
Options for startSpan and startAsCurrentSpan.
Properties
| Property | Type | Description |
|---|---|---|
agentId? | string | The invoked agent’s identifier, set as gen_ai.agent.id. This key is for a HOSTED agent resource, such as a Bedrock agent ARN; the conventions advise against recording a transient in-memory instance id there, so an in-process agent leaves it unset. Ignored on every other kind. |
agentName? | string | The agent an AGENT span INVOKES, set as gen_ai.agent.name. That is what the key means on an invoke-agent span, where the conventions make it Conditionally Required; on an execute-tool span the same key means the agent DOING the call, which is why this is scoped to AGENT here. Unset, it falls back to the agent name init() was given. It is never taken from the span name, unlike the tool name: that fallback exists only because a tool’s name and its span name were historically one string, and a wrong agent name mislabels every span beneath it. Ignored on every other kind, where the key would read as “the agent that produced this span” — which is what the resource attribute of the same name says. On the scoped surface this name also becomes the enclosing agent scope, so TOOL spans opened inside the callback carry it as the agent that EXECUTED them. See startAsCurrentSpan. |
agentVersion? | string | The invoked agent’s version, set as gen_ai.agent.version: the version of the agent DEFINITION this span invoked — its prompt, tools and policy. Taken verbatim; the conventions’ own examples are 1.0.0 and 2025-05-01, so there is no one format to hold callers to. Never derived from service.version (the build running this process) nor from the main-agent version (the agent this process IS): a process at one version can invoke agents at several others. Ignored on every other kind, like the name and the id it accompanies. |
attributes? | Record<string, string> | Identity attributes to set at span CREATION rather than after it. Pending snapshots are built at start, so anything a caller would otherwise setAttribute first thing (a tool name, say) belongs here to reach them. Content never does: it is not known at start and would bypass masking’s assumptions about where content lives. |
dataSourceId? | string | The index, collection or knowledge base a RETRIEVER span searched, set as gen_ai.data_source.id. Ignored on every other kind: the key means the target of a retrieval, and putting it elsewhere would make the attribute mean something different depending on the span. Omitted when not passed, never guessed. |
input? | unknown | - |
kind? | SpanKind | - |
otelKind? | SpanKind | The OpenTelemetry SpanKind FIELD (INTERNAL, CLIENT, …), orthogonal to kind above, which is our taxonomy attribute. Conventions set it per operation, so by default it is derived from kind (see otelSpanKind); set this to override, as the MCP wrapper does for a remote tool call. |
toolCallId? | string | The id of the model’s tool-call message this TOOL span answers, set as gen_ai.tool.call.id. Caller-supplied and nothing else: the id belongs to the assistant turn that requested the call, which the SDK never sees, so there is nothing to derive it from and it is omitted rather than invented. Scoped to TOOL, like toolName: on any other kind the key would claim a tool call that is not there. |
toolName? | string | The tool name a TOOL span carries as gen_ai.tool.name. Defaults to the span name, which is what a caller who passes nothing meant back when the two were necessarily the same string. Pass it explicitly whenever the span name is not the bare tool name — and prefer passing it INSTEAD of a span name, which gets you the conventions’ execute_tool {tool} name for free. With neither, the span is named execute_tool and carries no tool name: nothing is invented. |
toolType? | string | What kind of tool this TOOL span ran, set as gen_ai.tool.type — the conventions’ examples are "function", "extension" and "datastore". Caller-supplied, recorded verbatim, never guessed from the callable: a wrapped function is not automatically a function tool, since the same wrapper is what an agent-side extension call goes through. Scoped to TOOL, like toolCallId. |
topK? | number | How many documents a RETRIEVER span asked for, set as gen_ai.retrieval.top_k. Ignored on every other kind. What came back is not an option here: it is unknown at span creation, so it is recorded afterwards with Observation.setRetrievedDocuments. |
userId? | string | End-user identity (user.id). Sugar for withUser: set on this span at creation and, for the scoped variant, on every span opened inside it. To attribute a whole request, including auto-instrumented spans, prefer withUser around the handler. |
GenerationBody()
type GenerationBody<T> = (generation) => Promise<T> | T;The body of a scoped generation.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
generation | Generation |
Returns
Promise<T> | T
Mask()
type Mask = (value, context?) => unknown;Redacts content attribute values at export. Receives the key when it accepts one.
Parameters
| Parameter | Type |
|---|---|
value | unknown |
context? | { key: string; } |
context.key? | string |
Returns
unknown
SpanBody()
type SpanBody<T> = (observation) => Promise<T> | T;The body of a scoped span.
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
observation | Observation |
Returns
Promise<T> | T
WorkspaceExporterFactory()
type WorkspaceExporterFactory = (apiKey) => SpanExporter;Workspaces: route spans from one process to per-customer destinations.
One client, one provider, one batch pipeline; the destination is a
context-scoped property. withWorkspace(alias, fn) sets an OTel context
key (exactly like withSession), WorkspaceSpanProcessor stamps it as a
transient attribute at span start, and RoutingSpanExporter partitions
each export batch by that attribute, strips it, and forwards every
partition to the exporter registered for its alias. Spans started outside
any scope go to the default destination.
Because the alias rides OTel context, everything started in scope routes
together: observe wrappers, generations, sessions, and spans created by
auto-instrumentation. That is the property a second client could never
give, which is why this SDK has no scoped-client mode at all.
Two rules the design enforces or warns about:
- The routing attribute never reaches the wire. The destination’s API key is what tells the backend which workspace a span belongs to; the alias is process-local configuration, so the exporter strips it before delegating.
- One trace, one workspace. The backend derives the workspace from the API key per request, so a trace split across scopes would come apart. Starting a span under a different alias than its parent’s logs a warning; switch workspaces at request boundaries, not inside a trace.
Parameters
| Parameter | Type |
|---|---|
apiKey | string |
Returns
SpanExporter
SpanKind
Observation kind. Values are OpenInference openinference.span.kind
values, the taxonomy the platform’s agent analytics group by.
Enumeration Members
| Enumeration Member | Value |
|---|---|
AGENT | "AGENT" |
CHAIN | "CHAIN" |
EMBEDDING | "EMBEDDING" |
LLM | "LLM" |
RETRIEVER | "RETRIEVER" |
TOOL | "TOOL" |
VERSION
const VERSION: "1.0.0" = "1.0.0";