npm package: @hudsonly/ai
Description: Official Node.js SDK for the Hudsonly AI API
Author: Hudsonly
Latest version: 0.1.0

# Hudsonly AI Node.js SDK

Official Node.js/TypeScript SDK for the [Hudsonly AI API](https://ai.hudsonly.com) — Text-to-Speech, Speech-to-Text, Text Embeddings, and Avatar Video Generation.

## Installation

```bash
npm install hudsonly
```

## Quick Start

```typescript
import HudsonlyAI from 'hudsonly';

const client = new HudsonlyAI({ apiKey: 'your-api-token' });

// Text to Speech
const tts = await client.tts.generate({ text: 'Hello world', voice: 'af_heart' });
console.log(tts.audioUrl);

// Speech to Text
const transcript = await client.transcription.generate({ audio: './recording.mp3' });
console.log(transcript.text);

// Text Embeddings
const embeddings = await client.embeddings.generate({ texts: ['Hello', 'World'] });
console.log(embeddings.embeddings);

// Avatar Video (auto-polls until complete)
const avatar = await client.avatar.generate({
  image: './photo.jpg',
  audio: './speech.mp3',
  model: 'sadtalker',
});
console.log(avatar.videoUrl);
```

## Services

### Text to Speech

```typescript
const result = await client.tts.generate({
  text: 'Hello world',
  voice: 'af_heart',    // Voice identifier
  format: 'mp3',        // 'mp3' or 'wav'
  speed: 1.0,           // 0.5 to 2.0
});
console.log(result.audioUrl, result.durationSeconds);
```

### Speech to Text (Transcription)

```typescript
// From a local file
const result = await client.transcription.generate({
  audio: './recording.mp3',
  model: 'base',        // 'tiny', 'base', 'small', 'medium'
  language: 'en',       // Optional, auto-detected if omitted
});
console.log(result.text);
result.segments.forEach(s => console.log(`[${s.start}s - ${s.end}s] ${s.text}`));

// From a URL
const result = await client.transcription.generate({
  audioUrl: 'https://example.com/audio.mp3',
});

// From a Buffer
const buffer = fs.readFileSync('./audio.mp3');
const result = await client.transcription.generate({ audio: buffer });
```

### Text Embeddings

```typescript
const result = await client.embeddings.generate({ texts: ['Hello', 'World'] });
console.log(result.embeddings);   // [[0.1, 0.2, ...], [0.3, 0.4, ...]]
console.log(result.dimension);    // 1024
```

### Avatar Video Generation

```typescript
// Auto-poll (recommended)
const result = await client.avatar.generate({
  image: './photo.jpg',
  audio: './speech.mp3',
  model: 'sadtalker',
  pollInterval: 5,       // Seconds between polls
  timeout: 600,          // Max wait time
});
console.log(result.videoUrl);

// Manual submission
const task = await client.avatar.create({
  image: './photo.jpg',
  audio: './speech.mp3',
});
console.log(task.id, task.status);

// LivePortrait (video-driven)
const result = await client.avatar.generate({
  image: './photo.jpg',
  video: './driving_video.mp4',
  model: 'liveportrait',
});
```

## Resources

### Tasks

```typescript
const tasks = await client.tasks.list({ service: 'avatar', status: 'completed' });
tasks.data.forEach(t => console.log(t.id, t.status));

const task = await client.tasks.get('task-uuid');
```

### Credits

```typescript
const balance = await client.credits.balance();
console.log(balance.balance);

const history = await client.credits.history({ type: 'usage', perPage: 50 });
history.data.forEach(t => console.log(t.amount, t.description));
```

## Other Methods

```typescript
const services = await client.services();
const limits = await client.rateLimits();
```

## Error Handling

```typescript
import {
  HudsonlyAI,
  AuthenticationError,
  InsufficientCreditsError,
  RateLimitError,
  ValidationError,
  TaskError,
  TaskTimeoutError,
} from 'hudsonly';

try {
  const result = await client.tts.generate({ text: 'Hello' });
} catch (err) {
  if (err instanceof AuthenticationError) console.log('Invalid API key');
  if (err instanceof InsufficientCreditsError) console.log('Not enough credits');
  if (err instanceof RateLimitError) console.log(`Retry after ${err.retryAfter}s`);
  if (err instanceof ValidationError) console.log('Errors:', err.errors);
}
```

## Requirements

- Node.js 18+ (uses native `fetch`)
- TypeScript 5+ (optional, full type definitions included)

## License

MIT