# @mutagent/sdk

```
  ███╗   ███╗██╗   ██╗████████╗ █████╗  ██████╗ ███████╗███╗   ██╗████████╗
  ████╗ ████║██║   ██║╚══██╔══╝██╔══██╗██╔════╝ ██╔════╝████╗  ██║╚══██╔══╝
  ██╔████╔██║██║   ██║   ██║   ███████║██║  ███╗█████╗  ██╔██╗ ██║   ██║
  ██║╚██╔╝██║██║   ██║   ██║   ██╔══██║██║   ██║██╔══╝  ██║╚██╗██║   ██║
  ██║ ╚═╝ ██║╚██████╔╝   ██║   ██║  ██║╚██████╔╝███████╗██║ ╚████║   ██║
  ╚═╝     ╚═╝ ╚═════╝    ╚═╝   ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═╝  ╚═══╝   ╚═╝
                          ███████╗██████╗ ██╗  ██╗
                          ██╔════╝██╔══██╗██║ ██╔╝
                          ███████╗██║  ██║█████╔╝
                          ╚════██║██║  ██║██╔═██╗
                          ███████║██████╔╝██║  ██╗
                          ╚══════╝╚═════╝ ╚═╝  ╚═╝
```

<p align="center">
  <a href="https://www.npmjs.com/package/@mutagent/sdk"><img src="https://img.shields.io/npm/v/@mutagent/sdk?style=for-the-badge&color=cb3837&logo=npm&logoColor=white" alt="npm"></a>
  <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-18+-339933?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js"></a>
  <a href="https://bun.sh"><img src="https://img.shields.io/badge/Bun-1.1+-f472b6?style=for-the-badge&logo=bun&logoColor=white" alt="Bun"></a>
  <a href="https://www.typescriptlang.org"><img src="https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"></a>
  <a href="#license"><img src="https://img.shields.io/badge/License-Proprietary-ff6b6b?style=for-the-badge" alt="License: Proprietary"></a>
</p>

<p align="center">
  <strong>Type-safe. Framework-agnostic. Production-ready.</strong><br>
  <em>The official TypeScript SDK for the MutagenT AI Engineering Platform.</em>
</p>

---

## Table of Contents

- [What is MutagenT SDK?](#what-is-mutagent-sdk)
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Authentication](#authentication)
- [Prompts](#prompts)
- [Datasets](#datasets)
- [Evaluations](#evaluations)
- [Optimization](#optimization)
- [Tracing & Observability](#tracing--observability)
- [Agents](#agents)
- [Playground](#playground)
- [Pagination](#pagination)
- [Retries](#retries)
- [Error Handling](#error-handling)
- [Custom HTTP Client](#custom-http-client)
- [Tree-shakeable Imports](#tree-shakeable-imports)
- [TypeScript Support](#typescript-support)
- [Framework Integrations](#framework-integrations)
- [API Reference](#api-reference)
- [See Also](#see-also)

---

## What is MutagenT SDK?

The **MutagenT SDK** is a developer-friendly, type-safe TypeScript client for the [MutagenT AI platform](https://mutagent.io). It gives you programmatic access to everything MutagenT offers: create and version prompts, upload evaluation datasets, run automated evaluations, trigger auto-optimization jobs, collect LLM traces, and manage AI agents — all from your own code.

---

## Features

| Feature | Description |
|---------|-------------|
| **Prompt Management** | Create, version, update, and delete prompts programmatically |
| **Dataset Operations** | Upload, export, clone, and manage evaluation datasets |
| **Evaluation Engine** | Define criteria, run automated evaluations, and retrieve scored results |
| **Auto-Optimization** | Start optimization jobs that iteratively improve your prompts against metrics |
| **Tracing & Observability** | OpenTelemetry-compatible tracing for LLM calls, chains, agents, and custom spans |
| **Agents** | Create and manage AI agents with conversation history and streaming chat |
| **Playground** | Execute and evaluate prompts interactively without running a full pipeline |
| **Multi-tenant** | Organizations, workspaces, provider configs, and team membership |
| **Full Type Safety** | End-to-end TypeScript with Zod-validated responses |
| **Multiple Runtimes** | Works with Bun, Node.js, Deno, and Edge runtimes |
| **Tree-shakeable** | Import only what you need for smaller bundles |
| **Configurable Retries** | Per-call and global retry strategies with exponential backoff |
| **Pagination** | Async iterable responses for all paginated list endpoints |

---

## Installation

### npm

```bash
npm install @mutagent/sdk
```

### pnpm

```bash
pnpm add @mutagent/sdk
```

### yarn

```bash
yarn add @mutagent/sdk
```

### bun

```bash
bun add @mutagent/sdk
```

> This package ships both CommonJS (`require`) and ES Modules (`import`) builds.

---

## Quick Start

```typescript
import { Mutagent } from '@mutagent/sdk';

const mutagent = new Mutagent({
  security: {
    apiKey: process.env.MUTAGENT_API_KEY,
  },
});

// Create a prompt
const prompt = await mutagent.prompt.createPrompt({
  name: 'Customer Support Template',
  content: 'You are a helpful support agent. User query: {{query}}',
  variables: ['query'],
});

// Add a dataset
const dataset = await mutagent.promptDatasets.createPromptDataset({
  id: prompt.id,
  name: 'Support Tickets',
});

await mutagent.promptDatasetItems.bulkCreatePromptDatasetItems({
  id: dataset.id,
  items: [
    { input: { query: 'How do I reset my password?' }, expected: '...' },
    { input: { query: 'What are your business hours?' }, expected: '...' },
  ],
});

// Start optimization
const job = await mutagent.optimization.optimizePrompt({
  id: prompt.id,
  datasetId: dataset.id,
  metric: 'response_quality',
});

console.log(`Optimization started: ${job.id}`);
```

---

## Authentication

### API Key

```typescript
import { Mutagent } from '@mutagent/sdk';

const mutagent = new Mutagent({
  security: {
    apiKey: process.env.MUTAGENT_API_KEY,
  },
});
```

### Bearer Token

```typescript
const mutagent = new Mutagent({
  security: {
    bearerAuth: process.env.MUTAGENT_BEARER_AUTH,
  },
});
```

### Authentication Schemes

| Scheme | Type | Environment Variable |
|--------|------|----------------------|
| `apiKey` | API Key | `MUTAGENT_API_KEY` |
| `bearerAuth` | HTTP Bearer | `MUTAGENT_BEARER_AUTH` |

Both schemes are supported globally and apply to all operations.

---

## Prompts

Prompts are the core resource in MutagenT. Every dataset, evaluation, and optimization job is scoped to a prompt.

### Create a Prompt

```typescript
const prompt = await mutagent.prompt.createPrompt({
  name: 'Summarizer',
  content: 'Summarize the following text concisely: {{text}}',
  variables: ['text'],
  outputSchema: {
    type: 'object',
    properties: {
      summary: { type: 'string' },
      keyPoints: { type: 'array', items: { type: 'string' } },
    },
    required: ['summary'],
  },
});
```

### List Prompts

```typescript
const prompts = await mutagent.prompt.listPrompts();

// With pagination
for await (const page of prompts) {
  console.log(page);
}
```

### Get a Prompt

```typescript
const prompt = await mutagent.prompt.getPrompt({ id: 'prompt-id' });
```

### Update a Prompt

```typescript
await mutagent.prompt.updatePrompt({
  id: 'prompt-id',
  content: 'Updated template: {{input}}',
  name: 'Updated Name',
});
```

### Delete a Prompt

```typescript
await mutagent.prompt.deletePrompt({ id: 'prompt-id' });
```

### Prompt Versioning

Every update creates a new version. You can also create versions explicitly:

```typescript
// Create a new version
const version = await mutagent.prompt.createPromptVersion({
  id: 'prompt-id',
  content: 'Revised version of the prompt: {{input}}',
});

// List all versions
const versions = await mutagent.prompt.listPromptVersions({ id: 'prompt-id' });

// Get analytics across versions
const analytics = await mutagent.prompt.getPromptAnalytics({ id: 'prompt-id' });

// Compare model performance across versions
const comparisons = await mutagent.prompt.getPromptModelComparisons({ id: 'prompt-id' });
```

---

## Datasets

Datasets hold the input/expected-output pairs used for evaluations and optimization.

### Create a Dataset

```typescript
const dataset = await mutagent.promptDatasets.createPromptDataset({
  id: 'prompt-id',
  name: 'Production Queries',
  description: 'Real queries sampled from production traffic',
});
```

### Add Items

```typescript
// Single item
await mutagent.promptDatasetItems.createPromptDatasetItem({
  id: dataset.id,
  input: { query: 'What is the return policy?' },
  expected: { summary: 'Returns accepted within 30 days with receipt.' },
});

// Bulk add (recommended for large datasets)
await mutagent.promptDatasetItems.bulkCreatePromptDatasetItems({
  id: dataset.id,
  items: [
    { input: { query: 'How do I cancel?' }, expected: { summary: '...' } },
    { input: { query: 'Where is my order?' }, expected: { summary: '...' } },
  ],
});
```

### List, Get, Update, Delete Items

```typescript
// List items
const items = await mutagent.promptDatasetItems.listPromptDatasetItems({ id: dataset.id });

// Get a specific item
const item = await mutagent.promptDatasetItems.getPromptDatasetItem({
  id: dataset.id,
  itemId: 'item-id',
});

// Update an item
await mutagent.promptDatasetItems.updatePromptDatasetItem({
  id: dataset.id,
  itemId: 'item-id',
  expected: { summary: 'Corrected expected output.' },
});

// Delete an item
await mutagent.promptDatasetItems.deletePromptDatasetItem({
  id: dataset.id,
  itemId: 'item-id',
});
```

### Clone and Export

```typescript
// Clone a dataset
const clone = await mutagent.promptDatasets.clonePromptDataset({ id: dataset.id });

// Export a dataset
const exported = await mutagent.promptDatasets.exportPromptDataset({ id: dataset.id });
```

---

## Evaluations

Evaluations score your prompt's outputs against defined criteria using a dataset.

### Create an Evaluation

```typescript
const evaluation = await mutagent.promptEvaluations.createEvaluation({
  promptId: 'prompt-id',
  datasetId: 'dataset-id',
  name: 'Quality Check',
  evalConfig: {
    criteria: [
      { name: 'Accuracy', description: 'Is the output factually accurate?' },
      { name: 'Conciseness', description: 'Is the output appropriately brief?' },
    ],
  },
});
```

### Run an Evaluation

```typescript
await mutagent.promptEvaluations.runEvaluation({ id: evaluation.id });
```

### Get Evaluation Results

```typescript
const results = await mutagent.promptEvaluations.getEvaluationResult({
  id: evaluation.id,
});

console.log(`Score: ${results.overallScore}`);
```

### Evaluation Version History

```typescript
// Get evaluation version history
const history = await mutagent.promptEvaluations.getEvaluationHistory({
  id: evaluation.id,
});

// Get results aggregated by prompt version
const aggregated = await mutagent.promptEvaluations.getEvaluationResultsAggregated({
  id: evaluation.id,
});
```

---

## Optimization

The optimization engine automatically improves your prompts based on evaluation metrics.

### Start an Optimization Job

```typescript
const job = await mutagent.optimization.optimizePrompt({
  id: 'prompt-id',
  datasetId: 'dataset-id',
  metric: 'response_quality',
  maxIterations: 5,
  targetScore: 0.95,
});

console.log(`Job started: ${job.id}`);
```

### Poll Job Status

```typescript
const status = await mutagent.optimization.getOptimization({ id: job.id });

console.log(`Status: ${status.status}`);  // 'running' | 'paused' | 'completed' | 'failed'
```

### Track Score Progression

```typescript
const progress = await mutagent.optimization.getOptimizationProgress({ id: job.id });

// Returns an array of (iteration, score) pairs
for (const point of progress.scores) {
  console.log(`Iteration ${point.iteration}: ${point.score}`);
}
```

### Get Final Results

```typescript
const results = await mutagent.optimization.getOptimizationResults({ id: job.id });

console.log(`Best version: ${results.bestVersionId}`);
console.log(`Score improvement: ${results.baselineScore} → ${results.bestScore}`);
```

### Pause, Resume, and Cancel

```typescript
await mutagent.optimization.pauseOptimization({ id: job.id });
await mutagent.optimization.resumeOptimization({ id: job.id });
await mutagent.optimization.cancelOptimization({ id: job.id });
```

---

## Tracing & Observability

The SDK ships a built-in OpenTelemetry-compatible tracing module. It captures LLM calls, chains, agents, and custom operations and sends them to MutagenT for analysis.

### Initialize Tracing

Call `initTracing` once at application startup:

```typescript
import { initTracing, shutdownTracing } from '@mutagent/sdk';

initTracing({
  apiKey: process.env.MUTAGENT_API_KEY!,
  endpoint: 'https://api.mutagent.io',
  environment: 'production',
  batchSize: 10,        // spans per flush batch (default: 10)
  flushInterval: 5000,  // flush interval in ms (default: 5000)
});

// Flush and close on app exit
process.on('SIGTERM', async () => {
  await shutdownTracing();
  process.exit(0);
});
```

### @trace Decorator

The easiest way to instrument class methods:

```typescript
import { trace } from '@mutagent/sdk';

class SupportAgent {
  @trace({ kind: 'agent', name: 'support-agent' })
  async handleQuery(query: string) {
    const response = await this.generate(query);
    return response;
  }

  @trace({ kind: 'llm.chat', name: 'gpt-4o' })
  private async generate(query: string) {
    // LLM call — traced automatically with input/output/duration
    return callOpenAI(query);
  }
}
```

### withTrace Wrapper

For functional-style code or when you need fine-grained control:

```typescript
import { withTrace } from '@mutagent/sdk';

async function ragPipeline(query: string) {
  return await withTrace(
    { kind: 'chain', name: 'rag-pipeline' },
    async (span) => {
      span.setAttributes({ 'gen_ai.model': 'gpt-4o', 'user.query': query });

      const docs = await retrieveDocuments(query);
      span.addEvent('documents_retrieved', { count: docs.length });

      const answer = await generateAnswer(query, docs);
      span.setOutput({ text: answer, sources: docs.map(d => d.id) });

      return answer;
    }
  );
}
```

### Manual Spans

```typescript
import { startSpan, endSpan, getCurrentSpan, getCurrentTraceId } from '@mutagent/sdk';

const span = startSpan({ kind: 'tool', name: 'web-search' });
span.setAttributes({ query: 'latest AI news' });

try {
  const results = await webSearch('latest AI news');
  span.setOutput(results);
  endSpan(span);
} catch (err) {
  span.setStatus('error', String(err));
  endSpan(span);
}
```

### Span Kinds

| SpanKind | Description | Example Use Case |
|----------|-------------|------------------|
| `llm.chat` | Chat completion calls | OpenAI ChatGPT, Anthropic Claude |
| `llm.completion` | Text completion calls | Legacy completions |
| `llm.embedding` | Embedding generation | OpenAI Embeddings, Cohere Embed |
| `chain` | Sequential processing pipeline | LangChain chains, RAG pipelines |
| `agent` | Autonomous agent execution | ReAct agents |
| `graph` | State graph execution | LangGraph workflows |
| `node` | Individual graph node | State transitions |
| `edge` | Graph transition | Conditional routing |
| `workflow` | Multi-step workflows | Business process automation |
| `tool` | External tool calls | API calls, calculators |
| `retrieval` | Document retrieval | Vector search, keyword search |
| `rerank` | Result reranking | Cohere Rerank, cross-encoders |
| `guardrail` | Safety/validation checks | PII detection, content filtering |
| `custom` | Custom operations | Your domain-specific ops |

### Ingest Traces via API

You can also send traces programmatically via the SDK:

```typescript
// Ingest a single trace
await mutagent.traces.ingestTrace({
  traceId: 'trace-id',
  spans: [ /* ... */ ],
});

// Batch ingest
await mutagent.traces.ingestTraceBatch({
  traces: [ /* ... */ ],
});

// OTLP ingestion (standard OpenTelemetry format)
await mutagent.traces.ingestOtlp({ /* OTLP payload */ });

// Query traces
const traces = await mutagent.traces.listTraces();
const stats = await mutagent.traces.getTraceStats();
const summary = await mutagent.traces.getAnalyticsSummary();
```

---

## Agents

Agents are persistent AI entities backed by a prompt. They maintain conversation history and support streaming.

### Create an Agent

```typescript
const agent = await mutagent.agents.createAgent({
  name: 'Support Agent',
  description: 'Handles customer support queries',
  promptId: 'prompt-id',
});
```

### List and Get Agents

```typescript
const agents = await mutagent.agents.listAgents();
const agent = await mutagent.agents.getAgent({ id: 'agent-id' });
const agentBySlug = await mutagent.agents.getAgentBySlug({ slug: 'support-agent' });
```

### Update and Delete

```typescript
await mutagent.agents.updateAgent({ id: 'agent-id', name: 'Updated Name' });
await mutagent.agents.deleteAgent({ id: 'agent-id' });
```

### Conversations

```typescript
// Start a conversation
const conversation = await mutagent.agentConversations.createAgentConversation({
  id: agent.id,
});

// Send a message
await mutagent.conversations.sendConversationMessage({
  id: conversation.id,
  content: 'How do I reset my password?',
});

// List messages
const messages = await mutagent.conversations.listConversationMessages({
  id: conversation.id,
});

// Fork a conversation (branch off from a specific point)
const forked = await mutagent.conversations.forkConversation({
  id: conversation.id,
  messageId: 'message-id',
});
```

### Streaming Chat

```typescript
// Send a streaming message
await mutagent.agentChatStreaming.sendStreamMessage({
  id: conversation.id,
  content: 'Tell me about your return policy.',
});

// Poll stream events
const events = await mutagent.agentChatStreaming.getStreamEvents({
  id: conversation.id,
});
```

---

## Playground

The Playground lets you execute and evaluate a prompt without running a full optimization pipeline.

### Execute a Prompt

```typescript
const result = await mutagent.playground.playgroundCall({
  promptId: 'prompt-id',
  input: { query: 'What are your hours?' },
});

console.log(result.output);
```

### Evaluate in the Playground

```typescript
const evalResult = await mutagent.playground.playgroundEval({
  promptId: 'prompt-id',
  input: { query: 'What are your hours?' },
  expected: { summary: 'Open 9 AM to 5 PM, Monday to Friday.' },
});

console.log(`Score: ${evalResult.score}`);
```

---

## Pagination

All list endpoints return async iterables. Iterate with `for await...of`:

```typescript
const result = await mutagent.promptDatasets.listPromptDatasets({
  promptId: 42,
  limit: 20,
  offset: 0,
});

for await (const page of result) {
  console.log(page);
}
```

---

## Retries

### Per-call Retry Config

```typescript
const result = await mutagent.userProfile.getProfile({
  retries: {
    strategy: 'backoff',
    backoff: {
      initialInterval: 500,   // ms
      maxInterval: 30000,     // ms
      exponent: 1.5,
      maxElapsedTime: 120000, // ms
    },
    retryConnectionErrors: true,
  },
});
```

### Global Retry Config

Set a default retry policy for all calls:

```typescript
const mutagent = new Mutagent({
  retryConfig: {
    strategy: 'backoff',
    backoff: {
      initialInterval: 500,
      maxInterval: 30000,
      exponent: 1.5,
      maxElapsedTime: 120000,
    },
    retryConnectionErrors: true,
  },
  security: {
    apiKey: process.env.MUTAGENT_API_KEY,
  },
});
```

---

## Error Handling

All HTTP errors extend `MutagentError`:

```typescript
import { Mutagent } from '@mutagent/sdk';
import * as errors from '@mutagent/sdk/models/errors';

try {
  const prompt = await mutagent.prompt.getPrompt({ id: 'does-not-exist' });
} catch (error) {
  if (error instanceof errors.MutagentError) {
    console.error(`HTTP ${error.statusCode}: ${error.message}`);

    if (error instanceof errors.ErrorMessage) {
      console.error('API error:', error.data$.error);
    }
  }
}
```

### Error Properties

| Property | Type | Description |
|----------|------|-------------|
| `error.message` | `string` | Human-readable error message |
| `error.statusCode` | `number` | HTTP status code (e.g. `404`, `401`) |
| `error.headers` | `Headers` | HTTP response headers |
| `error.body` | `string` | Raw HTTP response body |
| `error.rawResponse` | `Response` | Raw HTTP response object |
| `error.data$` | varies | Structured error data (where available) |

### Error Classes

**Base class:**
- `MutagentError` — all HTTP error responses extend this

**Domain errors (extend `MutagentError`):**
- `ErrorMessage` — general API error message
- `ErrorMessageStatusCode` — error with explicit status code
- `ErrorResponse` — standard error response
- `OptimizationError` — optimization-specific errors
- `TraceError` — tracing ingestion errors
- `ProviderError` — provider config errors
- `WsError` — WebSocket/streaming errors
- `TestConnectionResultError` — provider connection test failures
- `ResponseValidationError` — server returned unexpected shape

**Network errors (client-side):**
- `ConnectionError` — could not reach the server
- `RequestTimeoutError` — request exceeded the timeout
- `RequestAbortedError` — request was aborted
- `InvalidRequestError` — invalid input before the request was sent
- `UnexpectedClientError` — unrecognised client-side error

---

## Custom HTTP Client

The SDK uses the native Fetch API internally. You can swap in any fetcher — useful for proxying, testing, or custom timeouts:

```typescript
import { Mutagent } from '@mutagent/sdk';
import { HTTPClient } from '@mutagent/sdk/lib/http';
import { ProxyAgent } from 'undici';

const dispatcher = new ProxyAgent('http://proxy.example.com:8080');

const httpClient = new HTTPClient({
  fetcher: (input, init) =>
    fetch(input, { ...init, dispatcher } as RequestInit),
});

// Add a request timeout and custom header
httpClient.addHook('beforeRequest', (request) => {
  const next = new Request(request, {
    signal: request.signal ?? AbortSignal.timeout(10_000),
  });
  next.headers.set('x-app-version', '1.0.0');
  return next;
});

// Log errors
httpClient.addHook('requestError', (error, request) => {
  console.error(`Request failed: ${request.method} ${request.url}`, error);
});

const mutagent = new Mutagent({ httpClient, security: { apiKey: process.env.MUTAGENT_API_KEY } });
```

---

## Tree-shakeable Imports

All SDK methods are also available as standalone functions. This is ideal for serverless environments or browser bundles where tree-shaking matters:

```typescript
import {
  promptCreatePrompt,
  promptListPrompts,
  promptDatasetsCreatePromptDataset,
  promptDatasetItemsBulkCreatePromptDatasetItems,
  optimizationOptimizePrompt,
  optimizationGetOptimizationResults,
} from '@mutagent/sdk/functions';

import { Mutagent } from '@mutagent/sdk';

const client = new Mutagent({ security: { apiKey: process.env.MUTAGENT_API_KEY } });

const prompt = await promptCreatePrompt(client, {
  name: 'My Prompt',
  content: 'Template: {{input}}',
});

const dataset = await promptDatasetsCreatePromptDataset(client, {
  id: prompt.id,
  name: 'My Dataset',
});
```

Full list of standalone functions is available in [FUNCTIONS.md](./FUNCTIONS.md).

---

## TypeScript Support

The SDK is written in TypeScript and ships full type declarations.

### Client Constructor Types

```typescript
import type { MutagentOptions } from '@mutagent/sdk';

const options: MutagentOptions = {
  security: { apiKey: process.env.MUTAGENT_API_KEY },
  serverURL: 'https://api.mutagent.io/v1',
  retryConfig: { strategy: 'backoff', backoff: { /* ... */ } },
};
```

### Response Types

All responses are fully typed. IDE autocomplete works out of the box:

```typescript
import type { Prompt, Dataset, EvaluationResult, OptimizationJob } from '@mutagent/sdk/models/components';

const prompt: Prompt = await mutagent.prompt.getPrompt({ id: 'prompt-id' });
```

### Debugging

Enable debug logging to inspect every request and response. Use only in local development — debug logs contain API keys and secrets:

```typescript
const mutagent = new Mutagent({ debugLogger: console, security: { apiKey: '...' } });
```

Or set `MUTAGENT_DEBUG=true` in your environment.

---

## Framework Integrations

Use MutagenT with your favourite AI framework. The CLI can generate integration boilerplate automatically:

```bash
npx @mutagent/cli integrate mastra
npx @mutagent/cli integrate langchain
npx @mutagent/cli integrate langgraph
npx @mutagent/cli integrate vercel-ai
npx @mutagent/cli integrate openai
```

### Mastra

```typescript
import { MutagentObserver } from '@mutagent/sdk/mastra';

const observer = new MutagentObserver({
  apiKey: process.env.MUTAGENT_API_KEY,
});
```

### LangChain

```typescript
import { MutagentCallbackHandler } from '@mutagent/sdk/langchain';
import { ChatOpenAI } from '@langchain/openai';

const handler = new MutagentCallbackHandler({
  apiKey: process.env.MUTAGENT_API_KEY,
  promptId: 'my-prompt-id',
});

const llm = new ChatOpenAI({ callbacks: [handler] });
```

### Vercel AI SDK

```typescript
import { withMutagent } from '@mutagent/sdk/vercel-ai';
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await withMutagent(
  streamText({ model: openai('gpt-4o'), messages }),
  { apiKey: process.env.MUTAGENT_API_KEY }
);
```

### Migration from Langfuse

```typescript
// Before (Langfuse)
import { Langfuse } from 'langfuse';
const langfuse = new Langfuse({
  publicKey: process.env.LANGFUSE_PUBLIC_KEY,
  secretKey: process.env.LANGFUSE_SECRET_KEY,
});

// After (MutagenT)
import { initTracing } from '@mutagent/sdk/tracing';
initTracing({ apiKey: process.env.MUTAGENT_API_KEY! });
```

---

## API Reference

### Available Namespaces

| Namespace | Key Methods | Description |
|-----------|-------------|-------------|
| `prompt` | `createPrompt`, `listPrompts`, `getPrompt`, `updatePrompt`, `deletePrompt`, `createPromptVersion`, `listPromptVersions`, `getPromptAnalytics` | Prompt management and versioning |
| `promptDatasets` | `createPromptDataset`, `listDatasetsForPrompt`, `getPromptDataset`, `updatePromptDataset`, `deletePromptDataset`, `clonePromptDataset`, `exportPromptDataset` | Dataset operations |
| `promptDatasetItems` | `createPromptDatasetItem`, `bulkCreatePromptDatasetItems`, `listPromptDatasetItems`, `getPromptDatasetItem`, `updatePromptDatasetItem`, `deletePromptDatasetItem` | Dataset item CRUD |
| `promptEvaluations` | `createEvaluation`, `listEvaluations`, `getEvaluation`, `runEvaluation`, `getEvaluationResult`, `getEvaluationHistory`, `getEvaluationResultsAggregated` | Evaluation engine |
| `optimization` | `optimizePrompt`, `getOptimization`, `listOptimizations`, `getOptimizationProgress`, `getOptimizationResults`, `getOptimizationStates`, `pauseOptimization`, `resumeOptimization`, `cancelOptimization` | Auto-optimization jobs |
| `playground` | `playgroundCall`, `playgroundEval` | Interactive prompt execution |
| `agents` | `createAgent`, `listAgents`, `getAgent`, `getAgentBySlug`, `updateAgent`, `deleteAgent` | Agent CRUD |
| `agentConversations` | `createAgentConversation`, `listAgentConversations` | Agent conversation management |
| `conversations` | `getConversation`, `sendConversationMessage`, `listConversationMessages`, `updateConversation`, `deleteConversation`, `forkConversation` | Conversation operations |
| `agentChatStreaming` | `sendStreamMessage`, `getStreamEvents` | Real-time streaming chat |
| `agentDatasets` | `createAgentDataset`, `listAgentDatasets`, `getAgentDataset`, `updateAgentDataset`, `deleteAgentDataset`, `cloneAgentDataset`, `exportAgentDataset` | Agent evaluation datasets |
| `agentDatasetItems` | `createAgentDatasetItem`, `bulkCreateAgentDatasetItems`, `listAgentDatasetItems`, `getAgentDatasetItem`, `updateAgentDatasetItem`, `deleteAgentDatasetItem` | Agent dataset item operations |
| `traces` | `ingestTrace`, `ingestTraceBatch`, `ingestOtlp`, `listTraces`, `getTrace`, `getTraceStats`, `getAnalyticsSummary`, `deleteTrace` | Trace observability and ingestion |
| `providerConfigs` | `createProvider`, `listProviders`, `getProvider`, `updateProvider`, `deleteProvider`, `testProvider`, `listAvailableModels`, `getModelsCatalog` | LLM provider configurations |
| `workspaces` | `createWorkspace`, `listWorkspaces`, `getWorkspace`, `updateWorkspace`, `deleteWorkspace`, `setDefaultWorkspace` | Workspace management |
| `workspaceMembers` | `addWorkspaceMember`, `listWorkspaceMembers`, `updateWorkspaceMember`, `removeWorkspaceMember` | Workspace membership |
| `organizations` | `createOrganization`, `listOrganizations`, `getOrganization`, `updateOrganization`, `deleteOrganization`, `getOrganizationBySlug` | Organization management |
| `organizationMembers` | `addOrganizationMember`, `listOrganizationMembers`, `updateOrganizationMember`, `removeOrganizationMember` | Organization membership |
| `userProfile` | `getProfile`, `updateProfile`, `changePassword`, `deleteAccount`, `listSessions`, `deleteSession` | User profile management |
| `invitations` | `createInvitation`, `listInvitations`, `getInvitation`, `resendInvitation`, `deleteInvitation` | Team invitations |
| `experiments` | `createExperiment`, `listExperiments`, `getExperiment`, `executeExperiment`, `completeExperiment`, `addExperimentResult`, `deleteExperiment` | Experiments |

For complete per-method docs, see [docs/sdks/](./docs/sdks/).

---

## See Also

- **[@mutagent/cli](https://www.npmjs.com/package/@mutagent/cli)** — Command-line interface for MutagenT
- **[docs.mutagent.io](https://docs.mutagent.io)** — Full platform documentation
- **[Integration Guides](https://docs.mutagent.io/integrations/overview)** — Mastra, LangChain, LangGraph, Vercel AI, OpenAI
- **[Tracing Setup](https://docs.mutagent.io/tracing/setup)** — OTel integration walkthrough
- **[API Reference](https://docs.mutagent.io/api)** — Complete REST API reference
- **[mutagent.io](https://mutagent.io)** — Homepage

---

## License

This software is proprietary and confidential. Unauthorized copying, distribution, or use is strictly prohibited.

(c) 2026 MutagenT. All rights reserved.

---

<p align="center">
  <sub>Built with care by the MutagenT Team</sub>
</p>

<p align="center">
  <a href="https://twitter.com/mutagent">Twitter</a> •
  <a href="https://discord.gg/mutagent">Discord</a> •
  <a href="https://mutagent.io">Website</a> •
  <a href="https://docs.mutagent.io">Documentation</a>
</p>
