Package Exports
- @altsafe/aidirector
Readme
hydra-aidirector - Client SDK
hydra-aidirector
The official Node.js/TypeScript client for Hydra.
Hydra is a high-performance AI API gateway that provides:
- 🔄 Automatic Failover: Never let an LLM outage break your app
- ⚡ God-Tier Caching: Reduce costs and latency with smart response caching
- 🛡️ Self-Healing AI: Auto-extract JSON, strip markdown, and repair malformed responses with
healingReport - 🧠 Thinking Mode: Support for reasoning models like Gemini 2.0 Flash Thinking
- 📊 Detailed Usage: Track token usage, latency, and costs per model
Installation
npm install hydra-aidirector
# or
pnpm add hydra-aidirectorQuick Start
import { Hydra } from 'hydra-aidirector';
const ai = new Hydra({
secretKey: process.env.HYDRA_SECRET_KEY!,
baseUrl: 'https://your-instance.vercel.app',
});
// Generate content
const result = await ai.generate({
chainId: 'my-chain',
prompt: 'Generate 5 user profiles',
});
if (result.success) {
console.log(result.data.valid);
}Features
- 🔐 HMAC Authentication - Secure request signing
- ⚡ 3-Step Architecture - Token → Worker → Complete (minimizes costs)
- 📎 File Attachments - Upload and process documents
- 🔄 Automatic Retries - Exponential backoff on failures
- 💾 Smart Caching - Two-tier (user/global) cache with AI-directed scoping
- 🎯 TypeScript - Full type safety with comprehensive types
- 🛑 Request Cancellation - Support for AbortSignal
- 🪝 Webhooks - Async notification callbacks
Streaming (Recommended for Large Responses)
await client.generateStream(
{
chainId: 'my-chain',
prompt: 'Generate 100 product descriptions',
},
{
onObject: (obj, index) => {
console.log(`Object ${index}:`, obj);
renderToUI(obj); // Render immediately!
},
onComplete: (result) => {
console.log(`Done! ${result.objectCount} objects`);
},
onError: (error) => {
console.error('Stream failed:', error);
},
}
);Batch Generation
const result = await client.generateBatch('my-chain', [
{ id: 'item1', prompt: 'Describe product A' },
{ id: 'item2', prompt: 'Describe product B' },
{ id: 'item3', prompt: 'Describe product C' },
]);
console.log(`Processed ${result.summary.succeeded}/${result.summary.total}`);Request Cancellation
const controller = new AbortController();
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
const result = await client.generate({
chainId: 'my-chain',
prompt: 'Long running prompt',
signal: controller.signal,
});
} catch (error) {
if (error instanceof TimeoutError) {
console.log('Request was cancelled');
}
}Cache Control
// Global cache (shared across users - default)
const result = await client.generate({
chainId: 'my-chain',
prompt: 'Static content',
cacheScope: 'global',
});
// User-scoped cache (private to user)
const userResult = await client.generate({
chainId: 'my-chain',
prompt: 'Personalized content',
cacheScope: 'user',
});
// Skip cache entirely
const freshResult = await client.generate({
chainId: 'my-chain',
prompt: 'Always fresh',
cacheScope: 'skip',
});File Attachments
import fs from 'fs';
const fileBuffer = fs.readFileSync('report.pdf');
const result = await client.generate({
chainId: 'document-analysis',
prompt: 'Summarize this document',
files: [{
data: fileBuffer.toString('base64'),
filename: 'report.pdf',
mimeType: 'application/pdf',
}],
});Webhooks
// Register a webhook
await client.registerWebhook({
requestId: 'req_123',
url: 'https://your-domain.com/webhooks/hydra',
secret: 'your-webhook-secret',
retryCount: 3,
});
// List webhooks
const webhooks = await client.listWebhooks();
// Update webhook
await client.updateWebhook('webhook_id', { retryCount: 5 });
// Unregister webhook
await client.unregisterWebhook('webhook_id');Thinking Mode (Reasoning Models)
const result = await client.generate({
chainId: 'reasoning-chain',
prompt: 'Solve this complex problem step by step',
options: {
thinkingMode: true, // Shows model reasoning process
},
});Configuration
| Option | Type | Default | Description |
|---|---|---|---|
secretKey |
string |
required | Your API key (hyd_sk_...) |
baseUrl |
string |
http://localhost:3000 |
API base URL |
timeout |
number |
600000 |
Request timeout (10 min) |
maxRetries |
number |
3 |
Max retry attempts |
debug |
boolean |
false |
Enable debug logging |
Generate Options
| Option | Type | Default | Description |
|---|---|---|---|
chainId |
string |
required | Fallback chain ID |
prompt |
string |
required | The prompt to send |
schema |
object |
- | JSON schema for validation |
cacheScope |
'global' | 'user' | 'skip' |
'global' |
Cache behavior |
signal |
AbortSignal |
- | Cancellation signal |
maxRetries |
number |
Client setting | Override retries |
requestId |
string |
Auto-generated | Custom request ID |
files |
FileAttachment[] |
- | File attachments |
useOptimized |
boolean |
true |
Use 3-step flow |
API Methods
| Method | Description |
|---|---|
generate(options) |
Generate content with fallback chain |
generateStream(options, callbacks) |
Stream JSON objects in real-time |
generateBatch(chainId, items) |
Process multiple prompts |
listModels() |
List available AI models |
listChains() |
List your fallback chains |
getUsage(options) |
Get usage statistics |
health() |
Check API health |
healthDetailed() |
Get detailed component health |
registerWebhook(config) |
Register async webhook |
unregisterWebhook(id) |
Remove a webhook |
listWebhooks() |
List all webhooks |
updateWebhook(id, updates) |
Modify webhook config |
Error Handling
import {
RateLimitError,
TimeoutError,
AuthenticationError,
QuotaExceededError,
WorkerError,
FileProcessingError,
} from 'hydra-aidirector';
try {
const result = await client.generate({ ... });
} catch (error) {
if (error instanceof RateLimitError) {
console.log(`Retry after ${error.retryAfterMs}ms`);
} else if (error instanceof QuotaExceededError) {
console.log(`Quota exceeded: ${error.used}/${error.limit} (${error.tier})`);
} else if (error instanceof TimeoutError) {
console.log(`Request timed out after ${error.timeoutMs}ms`);
} else if (error instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (error instanceof WorkerError) {
console.log('Worker processing failed - will retry');
} else if (error instanceof FileProcessingError) {
console.log(`File error: ${error.reason} - ${error.filename}`);
}
}Self-Healing Reports
When hydra-aidirector fixes a malformed JSON response, it includes a healingReport in the data object:
const result = await client.generate({ ... });
if (result.success && result.meta.recovered) {
console.log('JSON was malformed but healed!');
console.log(result.data.healingReport);
// [{ original: "{name: 'foo'", healed: {name: "foo"}, fixes: ["Added missing brace"] }]
}AI-Directed Caching
The AI can control caching by including a _cache directive in its JSON output:
{
"data": { ... },
"_cache": { "scope": "user" }
}Scopes:
global- Share response across all users (default)user- Cache per-user onlyskip- Do not cache this response
The directive is automatically stripped from the final response.
Pricing
BYOK (Bring Your Own Key) - You pay for AI costs directly to providers.
| Tier | Price | Requests | Overage |
|---|---|---|---|
| Free | $0 | 1K | Blocked |
| Starter | $9 | 25K | $0.50/1K |
| Pro | $29 | 100K | $0.40/1K |
| Scale | $79 | 500K | $0.30/1K |
License
MIT