Skip to content

TypeScript / JavaScript SDK

The XeroML TypeScript/JavaScript SDK is split into focused packages so you only install what you need:

PackagePurpose
@xeroml/tracingCore tracing functions (startActiveObservation, observe, propagateAttributes)
@xeroml/otelXeroMLSpanProcessor for OpenTelemetry SDK setup
@xeroml/clientPrompt management, datasets, scores, data access
@xeroml/openaiOpenAI SDK integration
@xeroml/langchainLangChain CallbackHandler

Installation

Terminal window
# Core tracing (required for any instrumentation)
npm install @xeroml/tracing @xeroml/otel @opentelemetry/sdk-node
# Client for prompts, datasets, scores
npm install @xeroml/client
# Optional integrations
npm install @xeroml/openai # OpenAI
npm install @xeroml/langchain # LangChain

Quick Setup

  1. Set environment variables:

    Terminal window
    XEROML_SECRET_KEY="sk-xm-..."
    XEROML_PUBLIC_KEY="pk-xm-..."
    XEROML_BASE_URL="https://cloud.xeroml.com"
  2. 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();
  3. 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;
    }
    );
  4. 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 OpenAI
import 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

instrumentation.ts
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();
}
}

Platform Requirements

Resources