hydra-aidirector 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hydra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ # hydra-aidirector - Client SDK
2
+ # hydra-aidirector
3
+
4
+ The official Node.js/TypeScript client for [Hydra](https://hydrai.dev).
5
+
6
+ Hydra is a high-performance AI API gateway that provides:
7
+ - 🔄 **Automatic Failover**: Never let an LLM outage break your app
8
+ - ⚡ **God-Tier Caching**: Reduce costs and latency with smart response caching
9
+ - 🛡️ **Self-Healing AI**: Auto-extract JSON, strip markdown, and repair malformed responses with `healingReport`
10
+ - 🧠 **Thinking Mode**: Support for reasoning models like Gemini 2.0 Flash Thinking
11
+ - 📊 **Detailed Usage**: Track token usage, latency, and costs per model
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install hydra-aidirector
17
+ # or
18
+ pnpm add hydra-aidirector
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { Hydra } from 'hydra-aidirector';
25
+
26
+ const ai = new Hydra({
27
+ secretKey: process.env.HYDRA_SECRET_KEY!,
28
+ baseUrl: 'https://your-instance.vercel.app',
29
+ });
30
+
31
+ // Generate content
32
+ const result = await ai.generate({
33
+ chainId: 'my-chain',
34
+ prompt: 'Generate 5 user profiles',
35
+ });
36
+
37
+ if (result.success) {
38
+ console.log(result.data.valid);
39
+ }
40
+ ```
41
+
42
+ ## Features
43
+
44
+ - 🔐 **HMAC Authentication** - Secure request signing
45
+ - ⚡ **3-Step Architecture** - Token → Worker → Complete (minimizes costs)
46
+ - 📎 **File Attachments** - Upload and process documents
47
+ - 🔄 **Automatic Retries** - Exponential backoff on failures
48
+ - 💾 **Smart Caching** - Two-tier (user/global) cache with AI-directed scoping
49
+ - 🎯 **TypeScript** - Full type safety with comprehensive types
50
+ - 🛑 **Request Cancellation** - Support for AbortSignal
51
+ - 🪝 **Webhooks** - Async notification callbacks
52
+
53
+ ## Streaming (Recommended for Large Responses)
54
+
55
+ ```typescript
56
+ await client.generateStream(
57
+ {
58
+ chainId: 'my-chain',
59
+ prompt: 'Generate 100 product descriptions',
60
+ },
61
+ {
62
+ onObject: (obj, index) => {
63
+ console.log(`Object ${index}:`, obj);
64
+ renderToUI(obj); // Render immediately!
65
+ },
66
+ onComplete: (result) => {
67
+ console.log(`Done! ${result.objectCount} objects`);
68
+ },
69
+ onError: (error) => {
70
+ console.error('Stream failed:', error);
71
+ },
72
+ }
73
+ );
74
+ ```
75
+
76
+ ## Batch Generation
77
+
78
+ ```typescript
79
+ const result = await client.generateBatch('my-chain', [
80
+ { id: 'item1', prompt: 'Describe product A' },
81
+ { id: 'item2', prompt: 'Describe product B' },
82
+ { id: 'item3', prompt: 'Describe product C' },
83
+ ]);
84
+
85
+ console.log(`Processed ${result.summary.succeeded}/${result.summary.total}`);
86
+ ```
87
+
88
+ ## Request Cancellation
89
+
90
+ ```typescript
91
+ const controller = new AbortController();
92
+
93
+ // Cancel after 5 seconds
94
+ setTimeout(() => controller.abort(), 5000);
95
+
96
+ try {
97
+ const result = await client.generate({
98
+ chainId: 'my-chain',
99
+ prompt: 'Long running prompt',
100
+ signal: controller.signal,
101
+ });
102
+ } catch (error) {
103
+ if (error instanceof TimeoutError) {
104
+ console.log('Request was cancelled');
105
+ }
106
+ }
107
+ ```
108
+
109
+ ## Cache Control
110
+
111
+ ```typescript
112
+ // Global cache (shared across users - default)
113
+ const result = await client.generate({
114
+ chainId: 'my-chain',
115
+ prompt: 'Static content',
116
+ cacheScope: 'global',
117
+ });
118
+
119
+ // User-scoped cache (private to user)
120
+ const userResult = await client.generate({
121
+ chainId: 'my-chain',
122
+ prompt: 'Personalized content',
123
+ cacheScope: 'user',
124
+ });
125
+
126
+ // Skip cache entirely
127
+ const freshResult = await client.generate({
128
+ chainId: 'my-chain',
129
+ prompt: 'Always fresh',
130
+ cacheScope: 'skip',
131
+ });
132
+ ```
133
+
134
+ ## File Attachments
135
+
136
+ ```typescript
137
+ import fs from 'fs';
138
+
139
+ const fileBuffer = fs.readFileSync('report.pdf');
140
+
141
+ const result = await client.generate({
142
+ chainId: 'document-analysis',
143
+ prompt: 'Summarize this document',
144
+ files: [{
145
+ data: fileBuffer.toString('base64'),
146
+ filename: 'report.pdf',
147
+ mimeType: 'application/pdf',
148
+ }],
149
+ });
150
+ ```
151
+
152
+ ## Webhooks
153
+
154
+ ```typescript
155
+ // Register a webhook
156
+ await client.registerWebhook({
157
+ requestId: 'req_123',
158
+ url: 'https://your-domain.com/webhooks/hydra',
159
+ secret: 'your-webhook-secret',
160
+ retryCount: 3,
161
+ });
162
+
163
+ // List webhooks
164
+ const webhooks = await client.listWebhooks();
165
+
166
+ // Update webhook
167
+ await client.updateWebhook('webhook_id', { retryCount: 5 });
168
+
169
+ // Unregister webhook
170
+ await client.unregisterWebhook('webhook_id');
171
+ ```
172
+
173
+ ## Thinking Mode (Reasoning Models)
174
+
175
+ ```typescript
176
+ const result = await client.generate({
177
+ chainId: 'reasoning-chain',
178
+ prompt: 'Solve this complex problem step by step',
179
+ options: {
180
+ thinkingMode: true, // Shows model reasoning process
181
+ },
182
+ });
183
+ ```
184
+
185
+ ## Configuration
186
+
187
+ | Option | Type | Default | Description |
188
+ |--------|------|---------|-------------|
189
+ | `secretKey` | `string` | **required** | Your API key (`hyd_sk_...`) |
190
+ | `baseUrl` | `string` | `http://localhost:3000` | API base URL |
191
+ | `timeout` | `number` | `600000` | Request timeout (10 min) |
192
+ | `maxRetries` | `number` | `3` | Max retry attempts |
193
+ | `debug` | `boolean` | `false` | Enable debug logging |
194
+
195
+ ## Generate Options
196
+
197
+ | Option | Type | Default | Description |
198
+ |--------|------|---------|-------------|
199
+ | `chainId` | `string` | **required** | Fallback chain ID |
200
+ | `prompt` | `string` | **required** | The prompt to send |
201
+ | `schema` | `object` | - | JSON schema for validation |
202
+ | `cacheScope` | `'global' \| 'user' \| 'skip'` | `'global'` | Cache behavior |
203
+ | `signal` | `AbortSignal` | - | Cancellation signal |
204
+ | `maxRetries` | `number` | Client setting | Override retries |
205
+ | `requestId` | `string` | Auto-generated | Custom request ID |
206
+ | `files` | `FileAttachment[]` | - | File attachments |
207
+ | `useOptimized` | `boolean` | `true` | Use 3-step flow |
208
+
209
+ ## API Methods
210
+
211
+ | Method | Description |
212
+ |--------|-------------|
213
+ | `generate(options)` | Generate content with fallback chain |
214
+ | `generateStream(options, callbacks)` | Stream JSON objects in real-time |
215
+ | `generateBatch(chainId, items)` | Process multiple prompts |
216
+ | `listModels()` | List available AI models |
217
+ | `listChains()` | List your fallback chains |
218
+ | `getUsage(options)` | Get usage statistics |
219
+ | `health()` | Check API health |
220
+ | `healthDetailed()` | Get detailed component health |
221
+ | `registerWebhook(config)` | Register async webhook |
222
+ | `unregisterWebhook(id)` | Remove a webhook |
223
+ | `listWebhooks()` | List all webhooks |
224
+ | `updateWebhook(id, updates)` | Modify webhook config |
225
+
226
+ ## Error Handling
227
+
228
+ ```typescript
229
+ import {
230
+ RateLimitError,
231
+ TimeoutError,
232
+ AuthenticationError,
233
+ QuotaExceededError,
234
+ WorkerError,
235
+ FileProcessingError,
236
+ } from 'hydra-aidirector';
237
+
238
+ try {
239
+ const result = await client.generate({ ... });
240
+ } catch (error) {
241
+ if (error instanceof RateLimitError) {
242
+ console.log(`Retry after ${error.retryAfterMs}ms`);
243
+ } else if (error instanceof QuotaExceededError) {
244
+ console.log(`Quota exceeded: ${error.used}/${error.limit} (${error.tier})`);
245
+ } else if (error instanceof TimeoutError) {
246
+ console.log(`Request timed out after ${error.timeoutMs}ms`);
247
+ } else if (error instanceof AuthenticationError) {
248
+ console.log('Invalid API key');
249
+ } else if (error instanceof WorkerError) {
250
+ console.log('Worker processing failed - will retry');
251
+ } else if (error instanceof FileProcessingError) {
252
+ console.log(`File error: ${error.reason} - ${error.filename}`);
253
+ }
254
+ }
255
+ ```
256
+
257
+ ## Self-Healing Reports
258
+
259
+ When `hydra-aidirector` fixes a malformed JSON response, it includes a `healingReport` in the data object:
260
+
261
+ ```typescript
262
+ const result = await client.generate({ ... });
263
+
264
+ if (result.success && result.meta.recovered) {
265
+ console.log('JSON was malformed but healed!');
266
+ console.log(result.data.healingReport);
267
+ // [{ original: "{name: 'foo'", healed: {name: "foo"}, fixes: ["Added missing brace"] }]
268
+ }
269
+ ```
270
+
271
+ ## AI-Directed Caching
272
+
273
+ The AI can control caching by including a `_cache` directive in its JSON output:
274
+
275
+ ```json
276
+ {
277
+ "data": { ... },
278
+ "_cache": { "scope": "user" }
279
+ }
280
+ ```
281
+
282
+ Scopes:
283
+ - `global` - Share response across all users (default)
284
+ - `user` - Cache per-user only
285
+ - `skip` - Do not cache this response
286
+
287
+ The directive is automatically stripped from the final response.
288
+
289
+ ## Pricing
290
+
291
+ BYOK (Bring Your Own Key) - You pay for AI costs directly to providers.
292
+
293
+ | Tier | Price | Requests | Overage |
294
+ |------|-------|----------|---------|
295
+ | Free | $0 | 1K | Blocked |
296
+ | Starter | $9 | 25K | $0.50/1K |
297
+ | Pro | $29 | 100K | $0.40/1K |
298
+ | Scale | $79 | 500K | $0.30/1K |
299
+
300
+ ## License
301
+
302
+ MIT