Skip to content

Observability

ThinkLang has optional OpenTelemetry integration. When @opentelemetry/api is installed, all core operations automatically emit spans.

Setup

bash
npm install @opentelemetry/api @opentelemetry/sdk-node

No code changes needed. ThinkLang detects @opentelemetry/api at runtime and wraps operations in spans.

Spans

OperationSpan NameAttributes
think()thinklang.thinkthinklang.model, thinklang.input_tokens, thinklang.output_tokens, thinklang.duration_ms
infer()thinklang.inferSame
reason()thinklang.reasonSame
agent()thinklang.agentSame
batch()thinklang.batchthinklang.batch_size, thinklang.batch_success, thinklang.batch_errors, thinklang.duration_ms

Example

typescript
import { NodeSDK } from "@opentelemetry/sdk-node";
import { ConsoleSpanExporter } from "@opentelemetry/sdk-trace-node";
import { think, zodSchema } from "thinklang";
import { z } from "zod";

// Initialize OTel
const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter() });
sdk.start();

// ThinkLang operations now emit spans automatically
const Sentiment = z.object({ label: z.string(), score: z.number() });
const result = await think({
  prompt: "Analyze sentiment",
  ...zodSchema(Sentiment),
});

await sdk.shutdown();

Programmatic API

You can also add custom attributes to the active span:

typescript
import { withSpan, addSpanAttributes } from "thinklang";

await withSpan("my.custom.span", { "my.attr": "value" }, async () => {
  // your code here
  addSpanAttributes({ "my.result": "success" });
  return result;
});

No-Op Behavior

When @opentelemetry/api is not installed, all telemetry functions are no-ops with zero overhead. You don't need to add conditional checks.