> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withperf.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK

> Official Perf SDK for JavaScript and TypeScript

# JavaScript SDK

The official Perf SDK for JavaScript and TypeScript provides a type-safe, feature-rich client for the Perf API with streaming support, automatic retries, and comprehensive error handling.

## Installation

```bash theme={null}
npm install @perf_technology/sdk
# or
yarn add @perf_technology/sdk
# or
pnpm add @perf_technology/sdk
```

## Quick Start

```typescript theme={null}
import { PerfClient } from '@perf_technology/sdk';

const client = new PerfClient({
  apiKey: 'pk_live_your_key_here',
});

// Simple chat completion
const response = await client.chat({
  messages: [{ role: 'user', content: 'Hello, world!' }],
  maxCostPerCall: 0.01,
});

console.log(response.output);
console.log(`Cost: $${response.billing.costUsd}`);
console.log(`Model: ${response.modelUsed}`);
```

## Configuration

```typescript theme={null}
const client = new PerfClient({
  apiKey: 'pk_live_xxx',           // Required: Your API key
  baseUrl: 'https://api.withperf.pro', // Optional: Custom base URL
  timeout: 30000,                  // Optional: Request timeout in ms (default: 30000)
  maxRetries: 3,                   // Optional: Max retry attempts (default: 3)
});
```

## Chat Completions

### Basic Request

```typescript theme={null}
const response = await client.chat({
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'What is the capital of France?' }
  ],
});

console.log(response.output); // "The capital of France is Paris."
```

### With Cost Control

```typescript theme={null}
const response = await client.chat({
  messages: [{ role: 'user', content: 'Explain quantum computing' }],
  maxCostPerCall: 0.005,  // Maximum 0.5 cents
});

if (response.billing.costWarning) {
  console.log('Cost exceeded budget, cheaper model was used');
}
```

### Request Options

```typescript theme={null}
const response = await client.chat({
  messages: [{ role: 'user', content: 'Generate a haiku' }],

  // Cost control
  maxCostPerCall: 0.01,

  // Generation parameters
  temperature: 0.7,
  maxTokens: 500,
  topP: 0.9,
  frequencyPenalty: 0.5,
  presencePenalty: 0.5,
  stop: ['\n\n'],

  // Output format
  responseFormat: 'json',

  // Tracking
  userId: 'user_123',
  metadata: {
    sessionId: 'sess_abc',
    feature: 'chat',
  },
});
```

## Streaming

Stream responses for real-time output:

```typescript theme={null}
const stream = await client.chatStream({
  messages: [{ role: 'user', content: 'Write a short story' }],
});

for await (const chunk of stream) {
  if (chunk.done) {
    // Final chunk with metadata
    console.log(`\nModel: ${chunk.modelUsed}`);
    console.log(`Cost: $${chunk.billing.costUsd}`);
  } else {
    // Content chunk
    process.stdout.write(chunk.chunk);
  }
}
```

### Stream to String Helper

```typescript theme={null}
const content = await client.chatStreamToString({
  messages: [{ role: 'user', content: 'Tell me a joke' }],
});

console.log(content);
```

## Error Handling

The SDK provides typed error classes for different error scenarios:

```typescript theme={null}
import {
  PerfClient,
  PerfError,
  AuthenticationError,
  RateLimitError,
  ValidationError,
  ServerError,
} from '@perf_technology/sdk';

try {
  const response = await client.chat({
    messages: [{ role: 'user', content: 'Hello' }],
  });
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter}s`);
    // Wait and retry
  } else if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
    // Don't retry - fix the API key
  } else if (error instanceof ValidationError) {
    console.error(`Invalid request: ${error.message}`);
    // Fix the request parameters
  } else if (error instanceof ServerError) {
    console.error('Server error - will auto-retry');
    // SDK will automatically retry
  } else if (error instanceof PerfError) {
    console.error(`Error: ${error.code} - ${error.message}`);

    if (error.isRetryable) {
      // Safe to retry
    }
  }
}
```

### Error Properties

All `PerfError` instances have these properties:

| Property      | Type    | Description                     |
| ------------- | ------- | ------------------------------- |
| `code`        | string  | Machine-readable error code     |
| `message`     | string  | Human-readable description      |
| `status`      | number  | HTTP status code                |
| `requestId`   | string  | Unique request ID for debugging |
| `isRetryable` | boolean | Whether safe to retry           |

### Rate Limit Error

```typescript theme={null}
if (error instanceof RateLimitError) {
  console.log(error.retryAfter);  // Seconds to wait
  console.log(error.limit);       // Rate limit ceiling
  console.log(error.remaining);   // Remaining requests
  console.log(error.reset);       // Unix timestamp when limit resets
}
```

## TypeScript Support

The SDK is written in TypeScript and exports all types:

```typescript theme={null}
import type {
  ChatRequest,
  ChatResponse,
  Message,
  StreamChunk,
  PerfClientOptions,
} from '@perf_technology/sdk';

const request: ChatRequest = {
  messages: [{ role: 'user', content: 'Hello' }],
  maxCostPerCall: 0.01,
};
```

## Response Types

### ChatResponse

```typescript theme={null}
interface ChatResponse {
  modelUsed: string;
  output: string;
  billing: {
    costUsd: number;
    costWarning: boolean;
  };
  tokens: {
    input: number;
    output: number;
    total: number;
  };
  metadata: {
    callId: string;
    taskType: string;
    complexityScore: number;
    routingReason: string;
    latencyMs: number;
    fallbackUsed: boolean;
    validationPassed: boolean;
    timestamp: string;
  };
}
```

### StreamChunk

```typescript theme={null}
// Content chunk
interface ContentChunk {
  chunk: string;
  done: false;
}

// Final chunk
interface FinalChunk {
  chunk: '';
  done: true;
  modelUsed: string;
  billing: { costUsd: number };
  tokens: { input: number; output: number; total: number };
  metadata: { /* ... */ };
}
```

## Examples

### Multi-turn Conversation

```typescript theme={null}
const messages = [
  { role: 'user', content: 'What is 2+2?' },
];

const response1 = await client.chat({ messages });
console.log(response1.output); // "4"

messages.push({ role: 'assistant', content: response1.output });
messages.push({ role: 'user', content: 'Multiply that by 3' });

const response2 = await client.chat({ messages });
console.log(response2.output); // "12"
```

### JSON Output

```typescript theme={null}
const response = await client.chat({
  messages: [{
    role: 'user',
    content: 'Extract: John Smith, john@example.com, 555-1234. Return JSON with name, email, phone.'
  }],
  responseFormat: 'json',
  temperature: 0.2,
});

const data = JSON.parse(response.output);
console.log(data.name);  // "John Smith"
console.log(data.email); // "john@example.com"
```

### React Hook Example

```typescript theme={null}
import { useState, useCallback } from 'react';
import { PerfClient } from '@perf_technology/sdk';

const client = new PerfClient({ apiKey: process.env.PERF_API_KEY });

export function useChat() {
  const [messages, setMessages] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  const sendMessage = useCallback(async (content: string) => {
    const userMessage = { role: 'user', content };
    setMessages(prev => [...prev, userMessage]);
    setIsLoading(true);

    try {
      const response = await client.chat({
        messages: [...messages, userMessage],
      });

      setMessages(prev => [
        ...prev,
        { role: 'assistant', content: response.output }
      ]);
    } finally {
      setIsLoading(false);
    }
  }, [messages]);

  return { messages, sendMessage, isLoading };
}
```

## Requirements

* Node.js 18.0.0 or higher
* TypeScript 5.0+ (for TypeScript users)

## Support

* **npm**: [@perf\_technology/sdk](https://www.npmjs.com/package/@perf_technology/sdk)
* **Documentation**: [docs.withperf.pro](https://docs.withperf.pro)
* **Email**: [support@withperf.pro](mailto:support@withperf.pro)
