npm package: @incredible-ai/sdk
Description: Incredible API TypeScript SDK compatible with Anthropic's client interface
Author: Incredible API Team
Latest version: 1.0.0

# Incredible TypeScript SDK

Official TypeScript SDK for the Incredible API - A unified interface to access 100+ AI models and services.

[![npm version](https://badge.fury.io/js/@incredible-ai%2Fsdk.svg)](https://www.npmjs.com/package/@incredible-ai/sdk)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## ✨ Features

- 🎯 **17 API Endpoints** - Full coverage of the Incredible API
- 🔥 **Callable Pattern** - Clean, intuitive syntax
- 📝 **Full TypeScript Support** - Complete type definitions with IntelliSense
- 🔄 **Streaming Support** - Server-Sent Events (SSE) for real-time responses
- ⚡ **Automatic Retries** - Built-in retry logic with exponential backoff
- 🛡️ **Error Handling** - Comprehensive error classes
- 🎨 **Utilities** - Helper functions for common tasks
- 🌐 **Browser & Node.js** - Works in both environments

## 📦 Installation

```bash
npm install @incredible-ai/sdk
```

Or with other package managers:

```bash
# Yarn
yarn add @incredible-ai/sdk

# pnpm
pnpm add @incredible-ai/sdk

# Bun
bun add @incredible-ai/sdk
```

## 🚀 Quick Start

```typescript
import { IncredibleClient } from '@incredible-ai/sdk';

// Initialize the client
const client = new IncredibleClient({
  apiKey: process.env.INCREDIBLE_API_KEY, // or provide directly
  baseUrl: 'https://api.incredible.one', // optional, defaults to production
});

// ✨ Callable pattern (recommended)
const answer = await client.answer({ query: "What is 2+2?" });
console.log(answer.answer); // "4"

// Alternative: Resource pattern
const answer2 = await client.answer.create({ query: "What is TypeScript?" });
console.log(answer2.answer);
```

## 🎯 All 17 API Endpoints

### 1. **Answer** - Simple Q&A

```typescript
// Basic answer
const response = await client.answer({
  query: "What is the capital of France?",
});
console.log(response.answer);

// Structured output with JSON schema
const structured = await client.answer({
  query: "Analyze this product review",
  responseFormat: {
    type: "object",
    properties: {
      sentiment: { type: "string", enum: ["positive", "negative", "neutral"] },
      score: { type: "number" },
      summary: { type: "string" },
    },
  },
});
console.log(structured.data);

// Streaming
for await (const chunk of client.answer.stream({ query: "Tell me a story" })) {
  if (chunk.type === 'content') {
    process.stdout.write(chunk.text);
  }
}
```

### 2. **Messages** - Chat Completion (Anthropic-compatible)

```typescript
// Basic chat
const message = await client.messages({
  model: 'claude-3-5-sonnet-20241022',
  maxTokens: 1024,
  messages: [
    { role: 'user', content: 'Hello! How are you?' }
  ],
});
console.log(message.content[0].text);

// With system prompt
const message2 = await client.messages.create({
  model: 'claude-3-5-haiku-20241022',
  maxTokens: 1024,
  system: 'You are a helpful coding assistant.',
  messages: [
    { role: 'user', content: 'Write a function to reverse a string in TypeScript' }
  ],
});

// Streaming
const stream = await client.messages.stream({
  model: 'small-1',
  maxTokens: 1024,
  messages: [{ role: 'user', content: 'Count to 10' }],
});

for await (const event of stream) {
  if (event.type === 'content_block_delta') {
    process.stdout.write(event.delta?.text || '');
  }
}

const finalMessage = await stream.finalMessage();
console.log('\nFinal:', finalMessage.content[0].text);
```

### 3. **Completions** - Text Completion

```typescript
// Text completion
const completion = await client.completions({
  prompt: 'The future of AI is',
  model: 'gpt-4o-mini',
  maxTokens: 100,
  temperature: 0.7,
});
console.log(completion.text);

// Streaming
for await (const chunk of client.completions.stream({ 
  prompt: 'Write a poem about coding',
  maxTokens: 200,
})) {
  process.stdout.write(chunk.text);
}
```

### 4. **Conversation** - Multi-turn Chat

```typescript
// Multi-turn conversation
const conv = await client.conversation({
  messages: [
    { role: 'user', content: 'Hi! My name is Alice.' },
    { role: 'assistant', content: 'Hello Alice! Nice to meet you.' },
    { role: 'user', content: 'What is my name?' },
  ],
});
console.log(conv.message); // "Your name is Alice."

// With streaming
for await (const chunk of client.conversation.stream({
  messages: [
    { role: 'user', content: 'Tell me about TypeScript' },
  ],
  system: 'You are a programming expert.',
})) {
  if (chunk.type === 'content') {
    process.stdout.write(chunk.text);
  }
}
```

### 5. **Agent** - Tool Calling with Kimi K2

```typescript
// Agent with tools
const tools = [
  {
    name: 'get_weather',
    description: 'Get the current weather for a location',
    input_schema: {
      type: 'object',
      properties: {
        location: { type: 'string', description: 'City name' },
        unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
      },
      required: ['location'],
    },
  },
];

const agentResponse = await client.agent({
  messages: [
    { role: 'user', content: 'What is the weather in Paris?' }
  ],
  tools,
  maxTokens: 1024,
});

console.log(agentResponse.content);
if (agentResponse.toolCalls) {
  console.log('Tool calls:', agentResponse.toolCalls);
}
```

### 6. **Images** - Image Generation

```typescript
// Generate an image
const image = await client.images({
  prompt: 'A serene sunset over mountains',
  aspectRatio: '16:9',
  seed: 42,
});
console.log('Image URL:', image.url);

// Alternative method
const image2 = await client.images.generate({
  prompt: 'Futuristic cityscape at night',
  aspectRatio: '1:1',
  format: 'png',
});
```

### 7. **Videos** - Video Generation

```typescript
// Generate a video
const video = await client.videos({
  prompt: 'A cat playing with a ball of yarn',
  resolution: '720p',
  duration: 8,
});
console.log('Video URL:', video.url);

// Image-to-video
const video2 = await client.videos.generate({
  prompt: 'Animate this image with gentle motion',
  imageUrl: 'https://example.com/image.jpg',
  resolution: '1080p',
});
```

### 8. **Research (Web Search)** - Exa.AI Search

```typescript
// Web search
const results = await client.research({
  query: 'TypeScript best practices 2024',
  numResults: 10,
  contents: true,
});

results.results.forEach(result => {
  console.log(`${result.title}: ${result.url}`);
  console.log(result.snippet);
});

// Advanced search
const filtered = await client.research.webSearch({
  query: 'machine learning',
  numResults: 5,
  includeDomains: ['arxiv.org', 'papers.nips.cc'],
  startPublishedDate: '2024-01-01',
});
```

### 9. **Deep Research** - In-depth Research

```typescript
// Deep research with citations
const research = await client.research.deepResearch({
  query: 'Impact of large language models on software development',
  numSources: 10,
  includeCitations: true,
});

console.log(research.findings);
console.log('Citations:', research.citations);
```

### 10. **Models** - List Available Models

```typescript
// List all models
const models = await client.models.list();
console.log(`Total models: ${models.total}`);

models.models.forEach(model => {
  console.log(`${model.name}: ${model.description}`);
  if (model.pricing) {
    console.log(`  Input: $${model.pricing.inputCostPer1M}/1M tokens`);
    console.log(`  Output: $${model.pricing.outputCostPer1M}/1M tokens`);
  }
});

// Get specific model
const model = await client.models.retrieve('claude-3-5-sonnet-20241022');
console.log(model);
```

### 11-13. **OCR** - Optical Character Recognition

```typescript
// Check OCR health
const health = await client.ocr.health();
console.log('OCR Status:', health.status);

// Extract text from image
const imageOCR = await client.ocr.image({
  image: 'https://example.com/document.jpg',
  language: 'en',
  includeConfidence: true,
});
console.log('Text:', imageOCR.text);
console.log('Confidence:', imageOCR.confidence);

// Extract text from PDF
const pdfOCR = await client.ocr.pdf({
  pdf: 'https://example.com/document.pdf',
  pages: [1, 2, 3], // or null for all pages
});

pdfOCR.pages.forEach(page => {
  console.log(`Page ${page.pageNumber}:`);
  console.log(page.text);
});
```

### 14-17. **Integrations** - Third-party Services

```typescript
// List all integrations (192+ services)
const integrations = await client.integrations.list();
console.log(`Available integrations: ${integrations.total}`);

integrations.integrations.forEach(integration => {
  console.log(`${integration.name} (${integration.category})`);
});

// Get integration details
const slack = await client.integrations.retrieve('slack');
console.log(slack.integration.features);

// Connect to an integration
const connection = await client.integrations.connect('notion', {
  userId: 'user-123',
  apiKey: 'notion-api-key',
});
console.log('Connected:', connection.connectionId);

// Execute integration feature
const result = await client.integrations.execute('github', {
  userId: 'user-123',
  featureName: 'create_issue',
  inputs: {
    repo: 'myorg/myrepo',
    title: 'Bug report',
    body: 'Description of the bug',
  },
});
console.log('Result:', result.result);
```

## 🔧 Configuration

```typescript
const client = new IncredibleClient({
  // Required: Your API key
  apiKey: 'your-api-key',
  
  // Optional: Base URL (defaults to production)
  baseUrl: 'https://api.incredible.one',
  
  // Optional: Timeout in milliseconds
  timeout: 60000,
  
  // Optional: Maximum retries
  maxRetries: 3,
  
  // Optional: Custom headers
  headers: {
    'X-Custom-Header': 'value',
  },
  
  // Optional: Streaming thinking mode
  streamThinkingMode: 'mute', // or 'default'
});
```

## 🛠️ Utilities

The SDK includes helpful utility functions:

```typescript
import { utils } from '@incredible-ai/sdk';

// Token estimation
const tokens = utils.estimateTokens('Hello, world!');
console.log(`Estimated tokens: ${tokens}`);

const messageTokens = utils.estimateMessageTokens([
  { content: 'Hello' },
  { content: 'How are you?' },
]);

// Cost estimation
const cost = utils.estimateCost('claude-3-5-sonnet-20241022', 1000, 500);
console.log(`Estimated cost: ${utils.formatCost(cost)}`);

// Context management
const context = new utils.ContextManager();
context.addUser('Hello!');
context.addAssistant('Hi! How can I help?');
context.addUser('Tell me about TypeScript');

const messages = context.getMessages();
const truncated = context.truncate(1000); // Fit within 1000 tokens

// Retry logic
import { retryOnError } from '@incredible-ai/sdk/utils';

const result = await retryOnError(
  async () => await client.answer({ query: 'Hello' }),
  {
    maxRetries: 3,
    initialDelay: 1000,
    backoffMultiplier: 2,
  }
);

// Format messages
import { formatMessages, userMessage, systemMessage } from '@incredible-ai/sdk/utils';

const msgs = formatMessages('Hello!'); // Converts to [{ role: 'user', content: 'Hello!' }]
const user = userMessage('What is AI?');
const system = systemMessage('You are a helpful assistant.');
```

## 🚨 Error Handling

```typescript
import {
  IncredibleError,
  AuthenticationError,
  NotFoundError,
  RateLimitError,
  ValidationError,
  InsufficientCreditsError,
  APIConnectionError,
  APITimeoutError,
} from '@incredible-ai/sdk';

try {
  const response = await client.answer({ query: 'Hello' });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof InsufficientCreditsError) {
    console.error('Not enough credits:', error.creditsInfo);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded, try again later');
  } else if (error instanceof ValidationError) {
    console.error('Invalid parameters:', error.details);
  } else if (error instanceof APIConnectionError) {
    console.error('Network error:', error.message);
  } else if (error instanceof IncredibleError) {
    console.error(`API error (${error.statusCode}):`, error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}
```

## 📖 TypeScript Support

Full TypeScript support with comprehensive type definitions:

```typescript
import type {
  // Client types
  ClientOptions,
  
  // Message types
  MessageCreateParams,
  MessageResponse,
  MessageContentBlock,
  
  // Completion types
  CompletionCreateParams,
  CompletionResponse,
  
  // Image types
  ImageGenerateParams,
  ImageGenerateResponse,
  
  // Video types
  VideoGenerateParams,
  VideoGenerateResponse,
  
  // Research types
  WebSearchParams,
  WebSearchResponse,
  DeepResearchParams,
  DeepResearchResponse,
  
  // Agent types
  AgentCreateParams,
  AgentResponse,
  
  // Answer types
  AnswerCreateParams,
  AnswerResponse,
  StructuredAnswerResponse,
  
  // Conversation types
  ConversationCreateParams,
  ConversationResponse,
  
  // OCR types
  OCRImageParams,
  OCRPDFParams,
  
  // Integration types
  Integration,
  IntegrationExecuteParams,
} from '@incredible-ai/sdk';
```

## 🌐 Environment Variables

Set your API key as an environment variable:

```bash
export INCREDIBLE_API_KEY="your-api-key"
```

Or use a `.env` file:

```env
INCREDIBLE_API_KEY=your-api-key
```

## 📚 Examples

Check out the [examples](./examples/) directory for more:

- [Basic Usage](./examples/basic-usage/)
- [Streaming Demo](./examples/streaming-demo/)
- [Integration Demo](./examples/integration-demo/)

## 🔗 Links

- [API Documentation](https://docs.incredible.one)
- [GitHub Repository](https://github.com/Norditech-AB/Incredible-SDK-TypeScript)
- [npm Package](https://www.npmjs.com/package/@incredible-ai/sdk)
- [Support](https://incredible.one/support)

## 📄 License

MIT License - see [LICENSE](LICENSE) for details

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 💬 Support

- Email: support@incredible.one
- Discord: [Join our community](https://discord.gg/incredible)
- GitHub Issues: [Report a bug](https://github.com/Norditech-AB/Incredible-SDK-TypeScript/issues)

---

Made with ❤️ by the Incredible team