TypeScript / JavaScript SDK
The XeroML TypeScript/JavaScript SDK is split into focused packages so you only install what you need:
| Package | Purpose |
|---|---|
@xeroml/tracing | Core tracing functions (startActiveObservation, observe, propagateAttributes) |
@xeroml/otel | XeroMLSpanProcessor for OpenTelemetry SDK setup |
@xeroml/client | Prompt management, datasets, scores, data access |
@xeroml/openai | OpenAI SDK integration |
@xeroml/langchain | LangChain CallbackHandler |
Installation
# Core tracing (required for any instrumentation)npm install @xeroml/tracing @xeroml/otel @opentelemetry/sdk-node
# Client for prompts, datasets, scoresnpm install @xeroml/client
# Optional integrationsnpm install @xeroml/openai # OpenAInpm install @xeroml/langchain # LangChainQuick Setup
-
Set environment variables:
Terminal window XEROML_SECRET_KEY="sk-xm-..."XEROML_PUBLIC_KEY="pk-xm-..."XEROML_BASE_URL="https://cloud.xeroml.com" -
Initialize OpenTelemetry (must run before any instrumented code):
import { NodeSDK } from "@opentelemetry/sdk-node";import { XeroMLSpanProcessor } from "@xeroml/otel";const sdk = new NodeSDK({spanProcessors: [new XeroMLSpanProcessor()],});sdk.start(); -
Instrument your code:
import { startActiveObservation } from "@xeroml/tracing";const result = await startActiveObservation({ name: "my-pipeline", type: "span" },async (obs) => {const output = await callLLM(input);obs.update({ output });return output;}); -
Flush before exit:
import { flushXeroML } from "@xeroml/tracing";await flushXeroML();
Instrumentation Methods
startActiveObservation
Creates a span and sets it as the active context. Child observations created within the callback are automatically nested:
import { startActiveObservation } from "@xeroml/tracing";
const result = await startActiveObservation( { name: "rag-pipeline", type: "span", input: { query } }, async (obs) => { const docs = await retrieve(query); const answer = await generate(query, docs); obs.update({ output: answer }); return answer; });observe Wrapper
Wraps a function with automatic input/output capture:
import { observe } from "@xeroml/tracing";
const processQuery = observe( { name: "process-query", type: "span" }, async (query: string): Promise<string> => { return await callLLM(query); });
const result = await processQuery("What is XeroML?");propagateAttributes
Attach user IDs, session IDs, tags, and other context to all observations in a scope:
import { propagateAttributes } from "@xeroml/tracing";
await propagateAttributes( { userId: "user-123", sessionId: "session-abc", tags: ["feature:chat"], environment: "production", }, async () => { await handleRequest(userMessage); });Prompt Management
import { XeroMLClient } from "@xeroml/client";
const xeroml = new XeroMLClient();
const prompt = await xeroml.getPrompt("my-prompt", { label: "production" });const compiled = prompt.compile({ userName: "Alice", topic: "finance" });
// Use with OpenAIimport OpenAI from "@xeroml/openai";
const openai = new OpenAI();const response = await openai.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: compiled }],});Scoring
import { XeroMLClient } from "@xeroml/client";
const xeroml = new XeroMLClient();
await xeroml.score({ traceId: "trace_abc123", name: "accuracy", value: 0.92, dataType: "NUMERIC",});Next.js / Edge Runtime
export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") { const { NodeSDK } = await import("@opentelemetry/sdk-node"); const { XeroMLSpanProcessor } = await import("@xeroml/otel");
const sdk = new NodeSDK({ spanProcessors: [new XeroMLSpanProcessor()], }); sdk.start(); }}