npm package: @lunos/client
Description: Official TypeScript client library for Lunos AI API - A comprehensive AI proxy service supporting chat completions, image generation, audio synthesis, embeddings, and more.
Author: superXdev
Latest version: 1.5.0

# Lunos AI Client Library

[![npm version](https://badge.fury.io/js/%40lunos%2Fclient.svg)](https://badge.fury.io/js/%40lunos%2Fclient)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![npm downloads](https://img.shields.io/npm/dm/@lunos/client.svg)](https://www.npmjs.com/package/@lunos/client)

Official TypeScript client library for the [Lunos AI API](https://lunos.tech) - A comprehensive AI proxy service supporting multiple AI providers including OpenAI, Anthropic, Google, and more.

## Features

-  🤖 **Multi-Provider Support**: Access OpenAI, Anthropic, Google, and other AI models through a single API
-  💬 **Chat Completions**: Full support for chat conversations with streaming
-  🎨 **Image Generation**: Create images with DALL-E, Midjourney, and other models
-  🔊 **Audio Generation**: Text-to-speech with multiple voices and formats
-  📊 **Embeddings**: Generate and work with text embeddings
-  🔍 **Model Discovery**: Browse and search available models
-  ⚡ **TypeScript First**: Full TypeScript support with comprehensive type definitions
-  🛡️ **Error Handling**: Robust error handling with specific error types
-  🔄 **Retry Logic**: Automatic retry with exponential backoff
-  📁 **File Operations**: Built-in utilities for saving generated content
-  🎯 **SOLID Principles**: Well-architected, extensible, and maintainable code

## Installation

```bash
npm install @lunos/client
```

```bash
yarn add @lunos/client
```

```bash
pnpm add @lunos/client
```

## Quick Start

```typescript
import { LunosClient } from "@lunos/client";

// Initialize the client
const client = new LunosClient({
   apiKey: "your-api-key-here",
   baseUrl: "https://api.lunos.tech",
   appId: "my-application", // Optional: for analytics and usage tracking
});

// Chat completion
const response = await client.chat.createCompletion({
   model: "openai/gpt-4.1",
   messages: [{ role: "user", content: "Hello, how are you?" }],
});

console.log(response.choices[0].message.content);
```

### Application ID (App ID) for Analytics

The client supports an optional `appId` parameter for analytics and usage tracking. This helps track which applications are using the API and provides insights into usage patterns.

```typescript
// Set default appId for all requests
const client = new LunosClient({
   apiKey: "your-api-key",
   appId: "my-application", // Default appId for all requests
});

// Override appId for specific requests
const response = await client.chat.createCompletion({
   model: "openai/gpt-4.1",
   messages: [{ role: "user", content: "Hello!" }],
   appId: "chat-feature", // Specific appId for this request
});

// AppId is supported across all AI generation endpoints
const imageResponse = await client.image.generate({
   prompt: "A beautiful sunset",
   model: "openai/dall-e-3",
   appId: "image-generator",
});

const audioResponse = await client.audio.textToSpeech({
   text: "Hello world",
   voice: "alloy",
   appId: "audio-service",
});

const embedding = await client.embedding.embedText(
   "Sample text",
   "openai/text-embedding-3-small",
   "embedding-tool"
);
```

The `appId` will be included as the `X-App-ID` header in all requests and stored in the `query_history` table for analytics and usage tracking per application.

````

## API Reference

### Client Configuration

```typescript
import { LunosClient, LunosConfig } from "@lunos/client";

const config: Partial<LunosConfig> = {
   apiKey: "your-api-key",
   baseUrl: "https://api.lunos.tech",
   timeout: 30000,
   retries: 3,
   retryDelay: 1000,
   fallback_model: "openai/gpt-4o", // Optional fallback model
   appId: "my-application", // Optional: for analytics and usage tracking
   debug: false,
   headers: {
      "Custom-Header": "value",
   },
};

const client = new LunosClient(config);
````

### Chat Completions

```typescript
// Simple chat completion
const response = await client.chat.createCompletion({
   model: "openai/gpt-4.1",
   messages: [{ role: "user", content: "Write a short story about a robot." }],
   temperature: 0.7,
   max_tokens: 500,
   appId: "chat-feature", // Optional: override default appId for this request
});

// Streaming chat completion with callback
let fullResponse = "";
const stream = await client.chat.createCompletionWithStream(
   {
      model: "openai/gpt-4.1",
      messages: [{ role: "user", content: "Write a poem about AI." }],
   },
   (chunk) => {
      fullResponse += chunk;
      process.stdout.write(chunk);
   }
);

// Streaming chat completion without callback (returns stream)
const stream = await client.chat.createCompletionStream({
   model: "openai/gpt-4.1",
   messages: [{ role: "user", content: "Explain quantum computing." }],
});

// Process the stream manually
const reader = stream.getReader();
const decoder = new TextDecoder();
let buffer = "";

try {
   while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split("\n");
      buffer = lines.pop() || "";

      for (const line of lines) {
         if (line.startsWith("data: ")) {
            const data = line.slice(6);
            if (data === "[DONE]") break;

            try {
               const parsed = JSON.parse(data);
               if (parsed.choices?.[0]?.delta?.content) {
                  process.stdout.write(parsed.choices[0].delta.content);
               }
            } catch (e) {
               // Ignore parsing errors
            }
         }
      }
   }
} finally {
   reader.releaseLock();
}

// Convenience methods
const response = await client.chat.chatWithUser(
   "What is the capital of France?",
   "openai/gpt-4o"
);

const response = await client.chat.chatWithSystem(
   "You are a helpful assistant.",
   "What is 2+2?",
   "openai/gpt-4.1"
);
```

### Fallback Model Support

The client supports automatic fallback to alternative models when the primary model fails after retries. This is useful for ensuring high availability and graceful degradation.

```typescript
// Per-request fallback model
const response = await client.chat.createCompletion({
   model: "openai/gpt-4-turbo", // Primary model
   fallback_model: "openai/gpt-4o", // Fallback model
   messages: [{ role: "user", content: "Explain quantum computing." }],
   temperature: 0.5,
   max_tokens: 300,
});

// Client-level fallback model configuration
const clientWithFallback = client.withFallbackModel("openai/gpt-4o");

const response = await clientWithFallback.chat.createCompletion({
   model: "openai/gpt-4-turbo", // Will fallback to gpt-4o if needed
   messages: [{ role: "user", content: "What is machine learning?" }],
});

// Streaming with fallback model
const stream = await client.chat.createCompletionStream({
   model: "openai/gpt-4-turbo",
   fallback_model: "openai/gpt-4o",
   messages: [{ role: "user", content: "Write a story." }],
   stream: true,
});
```

**How it works:**

-  When a model-related error occurs after all retry attempts, the client automatically tries the fallback model
-  Fallback is triggered for errors containing keywords like "model not found", "model unavailable", etc.
-  Debug mode will log when fallback models are used
-  Both regular and streaming requests support fallback models

### Image Generation

```typescript
// Generate an image
const image = await client.image.generateImage({
   model: "openai/dall-e-3",
   prompt: "A beautiful sunset over mountains",
   size: "1024x1024",
   quality: "hd",
});

// Convenience methods
const image = await client.image.generate(
   "A futuristic city skyline",
   "openai/dall-e-3"
);

const image = await client.image.generateWithSize(
   "A cat playing with yarn",
   512,
   512,
   "openai/dall-e-2"
);

const image = await client.image.generateHD(
   "A detailed portrait of a dragon",
   "openai/dall-e-3"
);

// Generate multiple images
const images = await client.image.generateMultiple(
   "A flower in different seasons",
   4,
   "openai/dall-e-3"
);
```

### Audio Generation

```typescript
// Text-to-speech
const audio = await client.audio.generateAudio({
   model: "openai/tts-1",
   input: "Hello, this is a test of text to speech.",
   voice: "alloy",
   response_format: "mp3",
});

// Save to file
await client.audio.generateAudioToFile(
   {
      input: "Hello world",
      voice: "alloy",
      model: "openai/tts-1",
   },
   "./output/hello.mp3"
);

// Convenience methods
const audio = await client.audio.textToSpeech(
   "Hello, how are you today?",
   "alloy",
   "openai/tts-1"
);

const audio = await client.audio.textToSpeechWithSpeed(
   "This is a test of speed control.",
   1.5,
   "nova",
   "openai/tts-1"
);
```

### Audio Transcription

```typescript
// Transcribe audio
const transcription = await client.audio.transcribeAudio({
   file: audioBuffer, // Buffer or base64 string
   model: "openai/whisper-1",
   response_format: "verbose_json",
});

// Transcribe from file
const transcription = await client.audio.transcribeFromFile(
   "./audio/recording.mp3",
   "openai/whisper-1"
);
```

### Embeddings

```typescript
// Create embeddings
const embedding = await client.embedding.createEmbedding({
   model: "openai/text-embedding-3-small",
   input: "This is a sample text for embedding.",
});

// Convenience methods
const embedding = await client.embedding.embedText(
   "This is a sample text.",
   "openai/text-embedding-3-small"
);

const embeddings = await client.embedding.embedMultiple(
   ["First text", "Second text", "Third text"],
   "openai/text-embedding-3-small"
);

// Calculate similarity
const similarity = EmbeddingService.cosineSimilarity(embedding1, embedding2);
const distance = EmbeddingService.euclideanDistance(embedding1, embedding2);
```

### Model Information

```typescript
// Get all models
const models = await client.models.getModels();

// Get models by capability
const chatModels = await client.models.getChatModels();
const imageModels = await client.models.getImageModels();
const audioModels = await client.models.getAudioModels();
const embeddingModels = await client.models.getEmbeddingModels();

// Get specific model
const gpt4 = await client.models.getModelById("openai/gpt-4.1");

// Check model capabilities
const supportsChat = await client.models.supportsCapability(
   "openai/gpt-4.1",
   "chat"
);

// Search models
const searchResults = await client.models.searchModels("gpt");
```

### Error Handling

```typescript
import { LunosError, APIError, ValidationError } from "@lunos/client";

try {
   const response = await client.chat.createCompletion({
      model: "openai/gpt-4.1",
      messages: [{ role: "user", content: "Hello" }],
   });
} catch (error) {
   if (error instanceof LunosError) {
      console.error("Lunos API Error:", error.message);
      console.error("Status:", error.status);
      console.error("Code:", error.code);
   } else {
      console.error("Unexpected error:", error);
   }
}
```

### Streaming

```typescript
import { StreamProcessor } from "@lunos/client";

// Process streaming response
const stream = await client.chat.createCompletionStream({
   model: "openai/gpt-4.1",
   messages: [{ role: "user", content: "Write a story." }],
});

const processor = new StreamProcessor();
await processor.processStream(stream, (chunk) => {
   console.log("Received chunk:", chunk);
});
```

### File Operations

```typescript
import { FileUtils } from "@lunos/client";

// Save buffer to file
await FileUtils.saveBufferToFile(audioBuffer, "./output/audio.mp3");

// Read file as buffer
const buffer = await FileUtils.readFileAsBuffer("./input/image.png");

// Convert file to base64
const base64 = await FileUtils.fileToBase64("./input/audio.wav");

// Convert base64 to buffer
const buffer = FileUtils.base64ToBuffer(base64String);
```

### Client Configuration Methods

```typescript
// Create client with different configuration
const debugClient = client.withDebug();
const timeoutClient = client.withTimeout(60000);
const customHeadersClient = client.withHeaders({
   "X-Custom-Header": "value",
});
const fallbackClient = client.withFallbackModel("openai/gpt-4o");

// Update configuration
client.updateConfig({
   timeout: 60000,
   debug: true,
});

// Health check
const isHealthy = await client.healthCheck();

// Get usage information
const usage = await client.getUsage();
```

## Advanced Usage

### Custom Fetch Implementation

```typescript
import { fetch } from "node-fetch";

const client = new LunosClient({
   apiKey: "your-api-key",
   fetch: fetch as typeof globalThis.fetch,
});
```

### Retry Configuration

```typescript
const client = new LunosClient({
   apiKey: "your-api-key",
   retries: 5,
   retryDelay: 2000,
});
```

### Request Cancellation

```typescript
const controller = new AbortController();

const response = await client.chat.createCompletion(
   {
      model: "openai/gpt-4.1",
      messages: [{ role: "user", content: "Hello" }],
   },
   {
      signal: controller.signal,
   }
);

// Cancel the request
controller.abort();
```

### Validation

```typescript
import { ValidationUtils } from "@lunos/client";

// Validate chat request
ValidationUtils.validateChatCompletionRequest({
   messages: [{ role: "user", content: "Hello" }],
});

// Validate image generation
ValidationUtils.validateImageGenerationRequest({
   prompt: "A beautiful landscape",
});
```

## Error Types

-  `LunosError`: Base error class
-  `APIError`: API-specific errors
-  `ValidationError`: Input validation errors
-  `AuthenticationError`: Authentication failures
-  `RateLimitError`: Rate limit exceeded
-  `NetworkError`: Network-related errors

## TypeScript Support

The library is built with TypeScript and provides comprehensive type definitions:

```typescript
import type {
   ChatMessage,
   ChatCompletionRequest,
   ChatCompletionResponse,
   ImageGenerationRequest,
   AudioGenerationRequest,
   EmbeddingRequest,
   Model,
} from "@lunos/client";
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

## License

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

## Support

-  Documentation: [https://lunos.tech/docs](https://lunos.tech/docs)
-  Issues: [GitHub Issues](https://github.com/lunos-tech/client-js/issues)
-  Email: hello@lunos.tech

## Changelog

### 1.3.0

#### Breaking Changes

-  **Model API Structure Overhaul:**
   -  Update speech generation response logic.
   -  Add PCM conversion to WAV util.
   -  The `Model` type and all related API responses have changed.
   -  All code, types, and examples now use the new model structure.
   -  All references to model grouping, categories, and latest models have been removed.
-  **Audio Transcription:**
   -  All audio transcription functions and types have been removed (not available in Lunos).

#### Improvements

-  **Documentation:**
   -  Updated all code examples and documentation to use the new model structure and fields.
   -  Added a new section describing the model object structure with a sample JSON.
   -  Updated all example files and their README to match the new API.
-  **Validation:**
   -  Voice validation for Google TTS now supports a comprehensive list of voices.
-  **General:**
   -  Improved error handling and parameter validation throughout the client.

### 1.2.0

-  Added fallback model support for automatic model switching on errors
-  Added `fallback_model` parameter to chat completion requests
-  Added `withFallbackModel()` method to client configuration
-  Enhanced error handling with model-specific fallback logic
-  Added validation for fallback model configuration
-  Updated documentation with fallback model examples

### 1.1.0

-  Enhanced error handling and retry logic
-  Improved TypeScript type definitions
-  Added comprehensive validation utilities
-  Updated dependencies and build configuration

### 1.0.0

-  Initial release
-  Full TypeScript support
-  Chat completions with streaming
-  Image generation
-  Audio generation and transcription
-  Embeddings
-  Model discovery
-  Comprehensive error handling
-  File operations utilities