AI / LLM Observability

Anthropic SDK

The Anthropic SDK integration provides a drop-in replacement for the official @anthropic-ai/sdk package. Use the same API you already know with automatic observability built-in.

Installation

bash
bun add @databuddy/ai @anthropic-ai/sdk

Quick Start

Replace your Anthropic import with the Databuddy version:

tsx
// Before
// import Anthropic from "@anthropic-ai/sdk";

// After
import { Anthropic } from "@databuddy/ai/anthropic";

const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: {
  apiKey: process.env.DATABUDDY_API_KEY
}
});

const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }]
});

Configuration

Constructor Options

The Anthropic class accepts all standard Anthropic options plus databuddy configuration:

tsx
import { Anthropic } from "@databuddy/ai/anthropic";

const client = new Anthropic({
// Standard Anthropic options
apiKey: process.env.ANTHROPIC_API_KEY,
baseURL: "https://api.anthropic.com",

// Databuddy options
databuddy: {
  // Required: API key for authentication
  apiKey: process.env.DATABUDDY_API_KEY,
  
  // Optional: Custom API endpoint
  apiUrl: "https://basket.databuddy.cc/llm",
  
  // Optional: Compute token costs (default: true)
  computeCosts: true,
  
  // Optional: Don't capture message content (default: false)
  privacyMode: false,
  
  // Optional: Success callback
  onSuccess: (call) => console.log("Call completed:", call.traceId),
  
  // Optional: Error callback
  onError: (call) => console.error("Call failed:", call.error)
}
});

Databuddy Options Reference

OptionTypeDefaultDescription
apiKeystringDATABUDDY_API_KEY env varRequired. API key for authentication
apiUrlstringhttps://api.databuddy.cc/llmAPI endpoint (or DATABUDDY_API_URL env var)
transportTransportHTTP transportCustom transport function
computeCostsbooleantrueCompute token costs using TokenLens
privacyModebooleanfalseDon't capture input/output content
onSuccess(call) => void-Callback on successful calls
onError(call) => void-Callback on failed calls

Basic Usage

Messages

tsx
import { Anthropic } from "@databuddy/ai/anthropic";

const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: {
  apiKey: process.env.DATABUDDY_API_KEY
}
});

const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: "You are a helpful assistant.",
messages: [
  { role: "user", content: "What is the capital of France?" }
]
});

console.log(response.content[0].text);

Streaming

tsx
const stream = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a poem" }],
stream: true
});

for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
  process.stdout.write(event.delta.text);
}
}

// Usage is tracked when stream completes

Per-Call Options

Override Databuddy options for specific calls:

tsx
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Process sensitive data..." }],

// Per-call Databuddy options
databuddy: {
  // Custom trace ID
  traceId: "conversation-123",
  
  // Enable privacy mode for this call
  privacyMode: true,
  
  // Disable cost computation
  computeCosts: false,
  
  // Custom callbacks
  onSuccess: (call) => console.log("Done:", call.durationMs),
  onError: (call) => console.error("Failed:", call.error)
}
});

Per-Call Options Reference

OptionTypeDescription
traceIdstringCustom trace ID to link related calls
transportTransportOverride transport for this call
computeCostsbooleanOverride cost computation
privacyModebooleanOverride privacy mode
onSuccess(call) => voidOverride success callback
onError(call) => voidOverride error callback

Tool Use

Tools are automatically tracked:

tsx
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "What's the weather in London?" }],
tools: [
  {
    name: "get_weather",
    description: "Get current weather for a city",
    input_schema: {
      type: "object",
      properties: {
        city: { type: "string" }
      },
      required: ["city"]
    }
  }
]
});

// Tracked data includes:
// tools: {
//   callCount: 1,
//   calledTools: ["get_weather"],
//   availableTools: ["get_weather"]
// }

Error Tracking

Errors are automatically captured:

tsx
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: {
  apiKey: process.env.DATABUDDY_API_KEY,
  onError: (call) => {
    console.error("AI call failed:", {
      model: call.model,
      error: call.error?.message,
      httpStatus: call.httpStatus,
      durationMs: call.durationMs
    });
  }
}
});

try {
await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "..." }]
});
} catch (error) {
// Error is logged automatically, plus your onError callback runs
}

Privacy Mode

Enable privacy mode to track usage without capturing message content:

tsx
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: {
  apiKey: process.env.DATABUDDY_API_KEY,
  privacyMode: true  // Don't capture prompts/responses
}
});

// Only usage, costs, and metadata are tracked
// input: [] and output: [] in the logged data

Trace IDs

Link related calls with trace IDs:

tsx
import { Anthropic, createTraceId } from "@databuddy/ai/anthropic";

const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: { apiKey: process.env.DATABUDDY_API_KEY }
});

// Generate a trace ID for a conversation
const traceId = createTraceId();

// First message
const result1 = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "What is 2+2?" }],
databuddy: { traceId }
});

// Follow-up with same trace ID
const result2 = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [
  { role: "user", content: "What is 2+2?" },
  { role: "assistant", content: result1.content[0].text },
  { role: "user", content: "And what is that times 3?" }
],
databuddy: { traceId }
});

Custom Transport

Use a custom transport for logging to other destinations:

tsx
import { Anthropic, httpTransport, type AnthropicLLMCall } from "@databuddy/ai/anthropic";

// Custom transport that logs locally and sends to API
const customTransport = async (call: AnthropicLLMCall) => {
console.log("AI call:", {
  model: call.model,
  tokens: call.usage.totalTokens,
  cost: call.cost.totalCostUSD
});

// Also send to Databuddy
await httpTransport("https://api.databuddy.cc/llm", "your-api-key")(call);
};

const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
databuddy: {
  transport: customTransport
}
});

What Gets Tracked

Each call captures:

json
{
"timestamp": "2024-01-15T10:30:00.000Z",
"traceId": "01234567-89ab-cdef-0123-456789abcdef",
"type": "generate",
"model": "claude-sonnet-4-20250514",
"provider": "anthropic",
"finishReason": "end_turn",
"input": [
  { "role": "system", "content": [{ "type": "text", "text": "You are helpful." }] },
  { "role": "user", "content": [{ "type": "text", "text": "Hello!" }] }
],
"output": [
  { "role": "assistant", "content": [{ "type": "text", "text": "Hi there!" }] }
],
"usage": {
  "inputTokens": 15,
  "outputTokens": 45,
  "totalTokens": 60,
  "cacheCreationInputTokens": 0,
  "cacheReadInputTokens": 0
},
"cost": {
  "inputCostUSD": 0.000045,
  "outputCostUSD": 0.000675,
  "totalCostUSD": 0.00072
},
"tools": {
  "callCount": 0,
  "resultCount": 0,
  "calledTools": [],
  "availableTools": []
},
"durationMs": 920,
"httpStatus": 200
}

Supported Models

ModelDescription
claude-sonnet-4-20250514Latest Sonnet model
claude-opus-4-20250514Latest Opus model
claude-3-5-sonnet-20241022Claude 3.5 Sonnet
claude-3-5-haiku-20241022Claude 3.5 Haiku
claude-3-opus-20240229Claude 3 Opus
claude-3-sonnet-20240229Claude 3 Sonnet
claude-3-haiku-20240307Claude 3 Haiku

TypeScript Types

tsx
import {
Anthropic,
createTraceId,
httpTransport,
type AnthropicCallOptions,
type AnthropicLLMCall,
type AnthropicTrackerOptions,
type AnthropicTransport
} from "@databuddy/ai/anthropic";

How is this guide?