JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 9
  • Score
    100M100P100Q51940F
  • License MIT

Official TypeScript SDK for AI Director - Intelligent AI API Gateway with automatic failover, caching, and JSON extraction

Package Exports

  • @altsafe/aidirector

Readme

@altsafe/aidirector

Official TypeScript SDK for AI Director — the intelligent AI API gateway with automatic failover, response caching, and JSON extraction.

npm version TypeScript License: MIT

Features

  • 🔐 HMAC Authentication — Secure request signing (Node.js & browser)
  • 10-minute Timeout — Handles long-running AI requests
  • 🔄 Automatic Retries — Exponential backoff with configurable limits
  • 📦 Structured Errors — Type-safe error handling
  • 🌊 Streaming Support — Real-time response streaming
  • 🎯 Full TypeScript — Complete type definitions

Installation

npm install @altsafe/aidirector
# or
bun add @altsafe/aidirector
# or
pnpm add @altsafe/aidirector

Quick Start

import { AIDirector } from '@altsafe/aidirector';

const client = new AIDirector({
  secretKey: process.env.AIDIRECTOR_SECRET_KEY!,
  baseUrl: 'https://your-api.example.com',
});

const result = await client.generate({
  chainId: 'your-chain-id',
  prompt: 'Generate 5 user profiles with name and email',
  schema: { name: 'string', email: 'string' },
});

if (result.success) {
  console.log('Users:', result.data.valid);
  console.log('Model:', result.meta.modelUsed);
  console.log('Cached:', result.meta.cached);
}

Usage Examples

Next.js Server Actions

'use server';

import { AIDirector } from '@altsafe/aidirector';

const client = new AIDirector({
  secretKey: process.env.AIDIRECTOR_SECRET_KEY!,
});

export async function generateContent(prompt: string) {
  return client.generate({
    chainId: process.env.DEFAULT_CHAIN_ID!,
    prompt,
  });
}

API Routes

// app/api/generate/route.ts
import { NextResponse } from 'next/server';
import { AIDirector } from '@altsafe/aidirector';

const client = new AIDirector({
  secretKey: process.env.AIDIRECTOR_SECRET_KEY!,
});

export async function POST(request: Request) {
  const { prompt, chainId } = await request.json();
  const result = await client.generate({ chainId, prompt });
  return NextResponse.json(result);
}

Streaming

await client.generateStream(
  {
    chainId: 'my-chain',
    prompt: 'Write a long story...',
  },
  {
    onChunk: (chunk) => process.stdout.write(chunk),
    onComplete: (result) => console.log('\nDone!', result.meta),
    onError: (error) => console.error('Error:', error),
  }
);

Error Handling

import { 
  AIDirector, 
  TimeoutError, 
  RateLimitError,
  ValidationError,
  isAIDirectorError,
  isRetryableError,
} from '@altsafe/aidirector';

try {
  const result = await client.generate({ chainId, prompt });
} catch (error) {
  if (error instanceof TimeoutError) {
    console.log('Request timed out after', error.timeoutMs, 'ms');
  } else if (error instanceof RateLimitError) {
    console.log('Rate limited, retry after', error.retryAfterMs, 'ms');
  } else if (error instanceof ValidationError) {
    console.log('Validation failed:', error.validationErrors);
  } else if (isAIDirectorError(error)) {
    console.log('AI Director error:', error.code, error.message);
    
    // Check if we should retry
    if (isRetryableError(error)) {
      console.log('This error is retryable');
    }
  }
}

API Reference

new AIDirector(config)

Option Type Default Description
secretKey string Required. Your API secret key
baseUrl string localhost:3000 API base URL
timeout number 600000 Request timeout (ms)
maxRetries number 3 Max retry attempts
debug boolean false Enable console logging

client.generate(options)

Generate content using your fallback chain.

Option Type Required Description
chainId string Yes Fallback chain ID
prompt string Yes Prompt to send
schema object No JSON schema for validation
timeout number No Override timeout for this request
options.temperature number No Randomness (0-2)
options.maxTokens number No Max output tokens
options.topP number No Nucleus sampling (0-1)
options.topK number No Top-K sampling
options.systemPrompt string No System prompt to prepend

Returns: Promise<GenerateResult>

interface GenerateResult {
  success: boolean;
  data: {
    valid: unknown[];      // Schema-compliant objects
    invalid: unknown[];    // Failed validation but parsed
    rawContent?: string;   // Raw AI response
  };
  meta: {
    cached: boolean;
    modelUsed: string;
    tokensUsed: { input: number; output: number };
    latencyMs: number;
    attemptedModels: string[];
    finishReason?: string;
  };
  error?: {
    code: string;
    message: string;
    retryable?: boolean;
  };
}

client.generateStream(options, callbacks)

Stream responses in real-time.

interface StreamCallbacks {
  onChunk?: (chunk: string) => void;
  onComplete?: (result: GenerateResult) => void;
  onError?: (error: Error) => void;
  onProgress?: (progress: StreamProgress) => void;
}

client.listModels()

List all available AI models.

const models = await client.listModels();
// Returns: ModelInfo[]

client.listChains()

Get your fallback chains (requires session auth).

const chains = await client.listChains();
// Returns: ChainInfo[]

client.getUsage(options?)

Get usage statistics for your account.

const usage = await client.getUsage({ 
  startDate: new Date('2024-01-01'),
  endDate: new Date(),
});
// Returns: UsageStats

client.health()

Health check to verify API connection.

const { ok, latencyMs, version } = await client.health();

client.withConfig(overrides)

Create a new client with different configuration.

const debugClient = client.withConfig({ debug: true });
const fastClient = client.withConfig({ timeout: 30000 });

Error Classes

Error Code Retryable Properties Description
ConfigurationError CONFIGURATION_ERROR No Invalid client setup
AuthenticationError AUTH_ERROR No statusCode Invalid credentials
RateLimitError RATE_LIMITED Yes retryAfterMs Too many requests
TimeoutError TIMEOUT Yes timeoutMs Request timed out
NetworkError NETWORK_ERROR Yes originalError Connection failed
ChainExecutionError CHAIN_FAILED No attemptedModels All models failed
ValidationError VALIDATION_ERROR No validationErrors Schema validation failed
ServerError SERVER_ERROR Yes statusCode Internal server error

Error Helpers

import { isAIDirectorError, isRetryableError } from '@altsafe/aidirector';

// Check if error is from AI Director
if (isAIDirectorError(error)) {
  console.log(error.code, error.message);
}

// Check if error should be retried
if (isRetryableError(error)) {
  // Implement retry logic
}

Advanced: HMAC Utilities

For custom integrations, you can use the HMAC utilities directly:

import { 
  generateSignature, 
  getKeyPrefix, 
  isValidSecretKey 
} from '@altsafe/aidirector';

// Validate a secret key format
if (isValidSecretKey(key)) {
  console.log('Valid key');
}

// Get key prefix for headers
const prefix = getKeyPrefix(secretKey); // "aid_sk_xxxx"

// Generate signature for custom requests
const signature = await generateSignature(
  secretKey,
  'POST',
  '/api/v1/generate',
  JSON.stringify(body),
  Date.now()
);

TypeScript Types

All types are exported for your convenience:

import type {
  // Configuration
  AIDirectorConfig,
  
  // Generation
  GenerateOptions,
  GenerateResult,
  GenerateData,
  GenerateMeta,
  GenerateError,
  GenerationParameters,
  TokenUsage,
  
  // Streaming
  StreamCallbacks,
  StreamProgress,
  
  // Chains & Models
  ChainInfo,
  ChainStep,
  ModelInfo,
  
  // Usage & Health
  UsageStats,
  HealthResult,
} from '@altsafe/aidirector';

Security

⚠️ Server-side only! Never expose your secret key to browsers.

  • ✅ Next.js API routes / Server Actions
  • ✅ Express.js / Fastify
  • ✅ Angular Universal (SSR)
  • ✅ Edge Functions (Vercel, Cloudflare)
  • ❌ Client-side JavaScript

Store your secret key in environment variables:

AIDIRECTOR_SECRET_KEY=aid_sk_your_secret_key_here

License

MIT © altsafe