Official TypeScript SDK for Hydra - Intelligent AI API Gateway with automatic failover, caching, and JSON extraction
npm install hydra-aidirectorbash
npm install hydra-aidirector
or
pnpm add hydra-aidirector
or
yarn add hydra-aidirector
`
---
Quick Start
`typescript
import { Hydra } from 'hydra-aidirector';
const client = new Hydra({
secretKey: process.env.HYDRA_SECRET_KEY!, // hyd_sk_...
baseUrl: 'https://your-instance.vercel.app',
});
// Basic generation
const result = await client.generate({
chainId: 'my-chain',
prompt: 'Generate 5 user profiles as JSON',
});
if (result.success) {
console.log(result.data.valid); // Parsed, schema-validated objects
}
`
---
Core Features
$3
Define fallback chains in your dashboard. If Gemini fails, Hydra automatically tries OpenRouter, Claude, etc.
$3
LLMs sometimes return broken JSON. Hydra extracts and repairs it automatically:
`typescript
const result = await client.generate({ chainId: 'x', prompt: 'Get user' });
if (result.meta.recovered) {
console.log('JSON was malformed but healed!');
console.log(result.data.healingReport);
// [{ original: "{name: 'foo'", healed: { name: "foo" }, fixes: ["Added closing brace"] }]
}
`
$3
Hydra's self-healing JSON repair works in both modes. The difference is how the model behaves:
| Mode | Model Behavior | Healing Role |
|------|----------------|--------------|
| Strict (strictJson: true) | Model is forced to output pure JSON via native API constraints. Output is already clean. | Safety net — rarely needed since output is constrained. |
| Non-Strict (strictJson: false) | Model outputs best-effort JSON (may include markdown, prose, or broken syntax). | Primary mechanism — extracts and repairs JSON from messy output. |
`typescript
// Strict mode - model constrained to pure JSON
await client.generate({
chainId: 'gemini-chain',
prompt: 'Extract invoice data',
schema: invoiceSchema,
strictJson: true, // No markdown, no explanations
});
// Non-strict mode - flexible output, Hydra heals as needed
await client.generate({
chainId: 'any-chain',
prompt: 'Generate a creative story with metadata',
schema: storySchema,
strictJson: false, // Allow model to be creative, Hydra extracts JSON
});
`
---
Streaming (Recommended for Large Responses)
Process JSON objects as they arrive — perfect for UIs that need instant feedback:
`typescript
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
Process multiple prompts in parallel with automatic error handling:
`typescript
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});
`
---
Caching
$3
Control how responses are cached:
`typescript
// Global cache (shared across users - default)
await client.generate({ chainId: 'x', prompt: 'Facts', cacheScope: 'global' });
// User-scoped cache (private to authenticated user)
await client.generate({ chainId: 'x', prompt: 'My profile', cacheScope: 'user' });
// Skip cache entirely
await client.generate({ chainId: 'x', prompt: 'Random', cacheScope: 'skip' });
`
$3
Control the trade-off between cache hit rate and precision:
| Level | Behavior |
|-------|----------|
| STANDARD | Balanced fuzzy matching. Good for most cases. |
| HIGH | Stricter matching. Higher quality hits, lower hit rate. |
| MAX_EFFICIENCY | Aggressive matching. Maximum cost savings, less precision. |
`typescript
await client.generate({
chainId: 'my-chain',
prompt: 'Generate report',
cacheQuality: 'MAX_EFFICIENCY', // Maximize cache hits
});
`
$3
The AI can override cache scope by including a _cache directive in its output:
`json
{
"data": { "...": "..." },
"_cache": { "scope": "user" }
}
`
The directive is automatically stripped from your final response.
---
File Attachments
Upload documents for analysis. Hydra handles type detection and model compatibility:
`typescript
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',
}],
});
`
---
Request Cancellation
Cancel long-running requests with AbortSignal:
`typescript
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // Cancel after 5s
try {
const result = await client.generate({
chainId: 'my-chain',
prompt: 'Long task',
signal: controller.signal,
});
} catch (error) {
if (error instanceof TimeoutError) {
console.log('Request was cancelled');
}
}
`
---
Thinking Mode
Enable reasoning models to show their thought process:
`typescript
const result = await client.generate({
chainId: 'reasoning-chain',
prompt: 'Solve this complex problem step by step',
options: {
thinkingMode: true,
},
});
`
---
Webhooks
Register callbacks for async notifications:
`typescript
// Register
await client.registerWebhook({
requestId: 'req_123',
url: 'https://your-domain.com/webhooks/hydra',
secret: 'your-webhook-secret',
retryCount: 3,
});
// Manage
const webhooks = await client.listWebhooks();
await client.updateWebhook('webhook_id', { retryCount: 5 });
await client.unregisterWebhook('webhook_id');
`
---
Configuration Reference
$3
| 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 in ms (10 min) |
| maxRetries | number | 3 | Max retry attempts |
| debug | boolean | false | Enable debug logging |
$3
| 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 sharing behavior |
| cacheQuality | 'STANDARD' \| 'HIGH' \| 'MAX_EFFICIENCY' | 'STANDARD' | Cache match precision |
| strictJson | boolean | true | Force strict JSON mode |
| signal | AbortSignal | - | Cancellation signal |
| maxRetries | number | Client default | Override retries |
| requestId | string | Auto-generated | Custom request ID |
| files | FileAttachment[] | - | File attachments |
| useOptimized | boolean | true | Use 3-step cost-saving flow |
| noCache | boolean | false | Skip cache entirely |
---
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
`typescript
import {
RateLimitError,
TimeoutError,
AuthenticationError,
QuotaExceededError,
WorkerError,
FileProcessingError,
isRetryableError,
} from 'hydra-aidirector';
try {
const result = await client.generate({ chainId: 'x', prompt: 'y' });
} 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(Timed out after ${error.timeoutMs}ms);
} else if (error instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (error instanceof WorkerError) {
console.log('Worker failed - will retry');
} else if (error instanceof FileProcessingError) {
console.log(File error: ${error.reason} - ${error.filename});
} else if (isRetryableError(error)) {
console.log('Transient error - safe to retry');
}
}
`
---
Pricing
BYOK (Bring Your Own Key) — You pay AI providers directly. Hydra charges only for API access:
| Tier | Price/mo | Requests | Overage |
|------|----------|----------|---------|
| Free | $0 | 1,000 | Blocked |
| Starter | $9 | 25,000 | $0.50/1K |
| Pro | $29 | 100,000 | $0.40/1K |
| Scale | $79 | 500,000 | $0.30/1K |
---
TypeScript Support
Full type safety with comprehensive types:
`typescript
import type {
GenerateOptions,
GenerateResult,
StreamCallbacks,
FileAttachment,
ChainInfo,
ModelInfo,
} from 'hydra-aidirector';
``