Note
Imports: @mv37/rollout (client + helpers), @mv37/rollout/edge, @mv37/rollout/optimization, @mv37/rollout/ai-sdk, and the disabled-by-default @mv37/rollout/browser. Requires Node 20+.
Rollout client
new Rollout(options?: RolloutOptions) — see configuration for every option. Methods:
// tracing — callback form runs and flushes; plain form returns the objecttrace<T>(name: string, fn: (trace: Trace) => T | Promise<T>, options?: TraceOptions): Promise<T>trace(name: string, options?: TraceOptions): Tracespan<T>(spanType: string, fn: (span: Span) => T | Promise<T>, options?: SpanOptions): Promise<T>span(spanType: string, options?: SpanOptions): Span// boundaries — wrap a function so each call is traced / recordedagent(name, fn, options?: TraceOptions & { captureInput?; captureOutput? }): (...args) => Promisetool(name, fn, options?: { recordInput?; recordOutput?; attributes? }): (...args) => PromisewrapTools(tools, options?): typeof toolswrap(obj): never // not implemented yet — throws// records (attach to the active or a referenced trace)message(options: { role; content; contentType?; toolCallId?; isInternal?; traceId?; externalTraceId?; attributes? })identifyUser(userId, options?: { traits?; accountId?; accountTraits?; traceId?; externalTraceId? })feedback(name, value, options?: { traceId?; externalTraceId?; attributes? })signal(name, value, options?: { traceId?; externalTraceId?; attributes? })captureEvent(eventType, options?: CaptureEventOptions)// lifecycleflush(): Promise<void>shutdown(): Promise<void>check(): Promise<CheckResult>Heads up
wrap() exists but throws — generic provider wrapping is not implemented in TypeScript yet. Use manual spans for the OpenAI SDK or wrapAISDK for the Vercel AI SDK.
Trace
Yielded by client.trace(...). Carries traceId, externalTraceId?, name, attributes, and context.
span<T>(spanType, fn, options?: SpanOptions): Promise<T>tool(name, options?: { toolCallId?; arguments?; retryCount?; attributes? }): ToolCallmessage(options: { role; content; contentType?; toolCallId?; isInternal?; attributes? })feedback(name, value)signal(name, value)identifyUser(userId, options?: { traits?; accountId?; accountTraits? })Span
Yielded by trace.span(...) / client.span(...). Carries spanType, spanId, parentSpanId?, and model.
recordInput(value: unknown)recordOutput(value: unknown)setUsage(usage: UsageInfo)end(output?: unknown, options?: { usage?: UsageInfo; status?: string; error?: unknown })SpanOptions: name?, spanId?, attributes?, model?, provider?, modelVersion?, reasoningMode?, temperature?, stream?.
ToolCall
Returned by trace.tool(...) for the manual paired form. Record the result, then it emits the tool.result on exit:
recordOutput(value: unknown): voidenter(): voidexit(error?: unknown)Module-level helpers
After init(), these route through the global client. Same signatures as the client methods of the same name:
| Export | Notes |
|---|---|
| init(options?): Rollout | Create and register the global client. |
| getClient(): Rollout | Return the global client. |
| trace / span | Callback and plain-object overloads, as on the client. |
| agent / tool / wrapTools / wrap | Boundary helpers (wrap throws). |
| message / identifyUser / feedback / signal / captureEvent | Record helpers. |
| flush / shutdown / check | Lifecycle helpers. |
Context
currentTrace<T = unknown>(): T | undefinedcurrentSpan<T = unknown>(): T | undefinedwithTraceContext<T>(context: TraceLike | undefined, fn: () => T): T // edge entry pointEdge entry point
@mv37/rollout/edge exports a Rollout subclass for request-scoped runtimes, plus Trace, Span, currentTrace, currentSpan, and withTraceContext. See Edge & browser.
Optimization
@mv37/rollout/optimization:
defineOptimizationTarget(target: OptimizationTarget): OptimizationTargetcreateOptimizationHandler(targets: OptimizationTarget[]): (request: Request) => Promise<Response>OPTIMIZATION_PROTOCOL_VERSION: 1interface OptimizationTarget { id: string; name?: string; description?: string; kind?: string; // defaults to "prompt" baseline: string; // required — the CLI registers it with Rollout run: (task: OptimizationTask, candidate: OptimizationCandidate) => OptimizationResult | string | Promise<OptimizationResult | string>;}interface OptimizationTask { id?; name?; instruction?; input?; expectedOutputSchema?; split?; metadata?;}interface OptimizationCandidate { kind?: string; text: string; }interface OptimizationResult { output: unknown; traceId?; latencyMs?; costUsd?; metadata?; }Walkthrough in Define a target — TypeScript.
AI-SDK integration
@mv37/rollout/ai-sdk:
wrapAISDK<T>(ai: T, options: { client: Rollout; context?: AISDKContextOptions }): TeventMetadata(options?: AISDKContextOptions): RolloutAIMetadataeventMetadataFromChatRequest(options: { request: unknown; userId?; sessionId?; conversationId?; externalTraceId?; agentName?; attributes?;}): RolloutAIMetadatainterface AISDKContextOptions { agentName?; userId?; sessionId?; conversationId?; externalTraceId?; attributes?;}Walkthrough in Vercel AI SDK.
Key types
| Type | Shape |
|---|---|
| UsageInfo | input_tokens?, output_tokens?, cached_tokens?, reasoning_tokens?, total_tokens?, cost_usd?, … |
| CheckResult | ok, accepted, rejected, errors, message |
| EventBatchResponse | accepted, rejected, retryable, errors[] |
| Scrubber / BeforeSend | (event) => event / (event) => event | null — scrubber runs first. |
| EventAttributes | Record<string, unknown> — free-form attributes on any record. |
The full Python equivalents live under Python API; shared environment variables are in Environment variables.