Skip to main content
The SDK gives you three ways to open a trace. All three produce the same thing — a trace with nested spans — so pick whichever fits the shape of your code. Within a trace, the t.llm / t.tool / t.span helpers record the steps.

Mode 1 — callback-scoped (the default path)

Wrap a run in glassray.trace(name, meta?, fn). The callback receives a trace handle t; the return value becomes the trace’s output, and a throw is recorded as an error (the trace still sends).
The optional meta object takes { customer?, sessionId?, flow?, traceId?, environment? } — see Metadata for what each field does. environment is accepted for backward compatibility but ignored since 0.1.3 (the ingest key selects the project).

Mode 2 — wrap once, trace every call

For an agent with a single entry function, wrap it once and every invocation becomes a trace:
Arguments are captured as the trace’s input and the return value as its output (best-effort, subject to the privacy controls).

Mode 3 — manual lifecycle

When a run doesn’t fit inside one callback — batch pipelines, event-driven steps — drive the handles yourself:
Span setters: s.setInput(x), s.setOutput(y), s.setUsage({ inputTokens, outputTokens }), s.setError(err), s.end(). The trace sends when t.end() is called.

Recording steps

Inside any trace, three helpers cover the step kinds Glassray understands:
Each helper runs your function, captures its return value as the span’s output, records timing, and marks the span errored if it throws (the exception passes through untouched). Nesting follows call structure. Spans opened inside another helper’s callback become its children; parallel t.tool() calls (Promise.all) become siblings. Spans still open when the root settles are auto-closed and flagged, so a forgotten end() can’t wedge a trace.

Usage capture

For t.llm, token usage is extracted automatically from the two common response shapes — Anthropic (usage.input_tokens / output_tokens) and OpenAI (usage.prompt_tokens / completion_tokens). For anything else, set it explicitly:

Errors

A throw anywhere — in the root callback or any helper — is recorded on the corresponding span and rethrown unchanged. You never need to try/catch for Glassray’s benefit. To record an error without throwing, use s.setError(err) in manual mode.

Escape hatches

Automatic capture reads arguments and return values. When those aren’t the interesting payload, set trace or span I/O explicitly — explicit setters always win:

Sessions

Group multi-turn conversations by passing the same sessionId on each turn’s trace:

Deterministic trace IDs

To correlate a trace with an external system (a ticket ID, a request ID) before any span exists, derive the trace ID from a seed — the same seed always yields the same ID:
Sending nothing? Check glassray.stats() and the troubleshooting checklist. Worried about what’s inside the payloads? Privacy & redaction covers what leaves the process.