hydra-aidirector 1.6.0 → 1.6.2
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/README.md +310 -399
- package/dist/index.d.mts +69 -28
- package/dist/index.d.ts +69 -28
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- package/package.json +13 -12
package/README.md
CHANGED
|
@@ -1,399 +1,310 @@
|
|
|
1
|
-
# hydra-aidirector
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await client.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
chainId: '
|
|
244
|
-
prompt: '
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
| `generateBatch(chainId, items)` | Process multiple prompts |
|
|
312
|
-
| `listModels()` | List available AI models |
|
|
313
|
-
| `listChains()` | List your fallback chains |
|
|
314
|
-
| `getUsage(options)` | Get usage statistics |
|
|
315
|
-
| `health()` | Check API health |
|
|
316
|
-
| `healthDetailed()` | Get detailed component health |
|
|
317
|
-
| `registerWebhook(config)` | Register async webhook |
|
|
318
|
-
| `unregisterWebhook(id)` | Remove a webhook |
|
|
319
|
-
| `listWebhooks()` | List all webhooks |
|
|
320
|
-
| `updateWebhook(id, updates)` | Modify webhook config |
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## Error Handling
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
import {
|
|
328
|
-
RateLimitError,
|
|
329
|
-
TimeoutError,
|
|
330
|
-
AuthenticationError,
|
|
331
|
-
QuotaExceededError,
|
|
332
|
-
WorkerError,
|
|
333
|
-
FileProcessingError,
|
|
334
|
-
isRetryableError,
|
|
335
|
-
} from 'hydra-aidirector';
|
|
336
|
-
|
|
337
|
-
try {
|
|
338
|
-
const result = await client.generate({ chainId: 'x', prompt: 'y' });
|
|
339
|
-
} catch (error) {
|
|
340
|
-
if (error instanceof RateLimitError) {
|
|
341
|
-
console.log(`Retry after ${error.retryAfterMs}ms`);
|
|
342
|
-
} else if (error instanceof QuotaExceededError) {
|
|
343
|
-
console.log(`Quota exceeded: ${error.used}/${error.limit} (${error.tier})`);
|
|
344
|
-
} else if (error instanceof TimeoutError) {
|
|
345
|
-
console.log(`Timed out after ${error.timeoutMs}ms`);
|
|
346
|
-
} else if (error instanceof AuthenticationError) {
|
|
347
|
-
console.log('Invalid API key');
|
|
348
|
-
} else if (error instanceof WorkerError) {
|
|
349
|
-
console.log('Worker failed - will retry');
|
|
350
|
-
} else if (error instanceof FileProcessingError) {
|
|
351
|
-
console.log(`File error: ${error.reason} - ${error.filename}`);
|
|
352
|
-
} else if (isRetryableError(error)) {
|
|
353
|
-
console.log('Transient error - safe to retry');
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Pricing
|
|
361
|
-
|
|
362
|
-
**BYOK (Bring Your Own Key)** — You pay AI providers directly. Hydra charges only for API access:
|
|
363
|
-
|
|
364
|
-
| Tier | Price/mo | Requests | Overage |
|
|
365
|
-
|------|----------|----------|---------|
|
|
366
|
-
| Free | $0 | 1,000 | Blocked |
|
|
367
|
-
| Starter | $9 | 25,000 | $0.50/1K |
|
|
368
|
-
| Pro | $29 | 100,000 | $0.40/1K |
|
|
369
|
-
| Scale | $79 | 500,000 | $0.30/1K |
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
## TypeScript Support
|
|
374
|
-
|
|
375
|
-
Full type safety with comprehensive types:
|
|
376
|
-
|
|
377
|
-
```typescript
|
|
378
|
-
import type {
|
|
379
|
-
GenerateOptions,
|
|
380
|
-
GenerateResult,
|
|
381
|
-
StreamCallbacks,
|
|
382
|
-
FileAttachment,
|
|
383
|
-
ChainInfo,
|
|
384
|
-
ModelInfo,
|
|
385
|
-
} from 'hydra-aidirector';
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
---
|
|
389
|
-
|
|
390
|
-
## Requirements
|
|
391
|
-
|
|
392
|
-
- Node.js 18+
|
|
393
|
-
- TypeScript 5+ (optional but recommended)
|
|
394
|
-
|
|
395
|
-
---
|
|
396
|
-
|
|
397
|
-
## License
|
|
398
|
-
|
|
399
|
-
MIT © [Hydra](https://hydrai.dev)
|
|
1
|
+
# hydra-aidirector
|
|
2
|
+
|
|
3
|
+
One client. One secret. One AI gateway.
|
|
4
|
+
|
|
5
|
+
`hydra-aidirector` is the official TypeScript SDK for [Hydra](https://hydrai.dev/docs). It gives your app one clean path for generation, failover chains, structured output, scoped caching, streaming, usage, health, and webhooks without making you glue providers together by hand.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add hydra-aidirector
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install hydra-aidirector
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { Hydra } from 'hydra-aidirector';
|
|
21
|
+
|
|
22
|
+
const client = new Hydra({
|
|
23
|
+
secretKey: process.env.HYDRA_SECRET_KEY!, // hyd_sk_...
|
|
24
|
+
baseUrl: process.env.HYDRA_BASE_URL!, // https://your-hydra-instance.com
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const result = await client.generate({
|
|
28
|
+
chainId: 'support-replies',
|
|
29
|
+
prompt: 'Return 3 short onboarding emails as JSON.',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (result.success) {
|
|
33
|
+
console.log(result.data.valid);
|
|
34
|
+
} else {
|
|
35
|
+
console.error(result.error);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Why Teams Use It
|
|
40
|
+
|
|
41
|
+
- One typed client for generation, streaming, usage, health, and webhooks.
|
|
42
|
+
- Automatic failover across the models in your chain.
|
|
43
|
+
- Structured output recovery when providers return noisy JSON.
|
|
44
|
+
- Cache controls that let you keep shared prompts fast and sensitive prompts private.
|
|
45
|
+
- One request trail to inspect when latency, cost, or provider behavior starts drifting.
|
|
46
|
+
|
|
47
|
+
## How Generation Works
|
|
48
|
+
|
|
49
|
+
Hydra uses the optimized 3-step flow by default for simple requests. That path keeps the fast lane lean by moving the long model call out of the request path that fronts your app.
|
|
50
|
+
|
|
51
|
+
When a request needs the full server pipeline, the SDK automatically falls back to the legacy endpoint. That includes:
|
|
52
|
+
|
|
53
|
+
- `schema`
|
|
54
|
+
- `noCache`
|
|
55
|
+
- `cacheScope`
|
|
56
|
+
- `cacheQuality`
|
|
57
|
+
- `strictJson`
|
|
58
|
+
- `maxRetries`
|
|
59
|
+
|
|
60
|
+
You can also force the legacy path yourself:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
await client.generate({
|
|
64
|
+
chainId: 'support-replies',
|
|
65
|
+
prompt: 'Return a fresh answer',
|
|
66
|
+
useOptimized: false,
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Structured Output
|
|
71
|
+
|
|
72
|
+
Use `schema` when the response shape matters:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = await client.generate({
|
|
76
|
+
chainId: 'invoice-parser',
|
|
77
|
+
prompt: 'Extract the invoice fields.',
|
|
78
|
+
schema: {
|
|
79
|
+
invoiceNumber: 'string',
|
|
80
|
+
amount: 'number',
|
|
81
|
+
currency: 'string',
|
|
82
|
+
},
|
|
83
|
+
strictJson: true,
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If the provider comes back with malformed JSON, Hydra will still try to recover the payload before the request fails.
|
|
88
|
+
|
|
89
|
+
## Cache Control
|
|
90
|
+
|
|
91
|
+
Use request-level cache controls when freshness or privacy matters:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
await client.generate({
|
|
95
|
+
chainId: 'account-summary',
|
|
96
|
+
prompt: 'Summarize this customer account.',
|
|
97
|
+
cacheScope: 'user',
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await client.generate({
|
|
101
|
+
chainId: 'pricing-faq',
|
|
102
|
+
prompt: 'Return the current pricing summary.',
|
|
103
|
+
cacheScope: 'global',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await client.generate({
|
|
107
|
+
chainId: 'one-off',
|
|
108
|
+
prompt: 'Generate a fresh variant.',
|
|
109
|
+
noCache: true,
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Tune cache matching when you want better reuse:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
await client.generate({
|
|
117
|
+
chainId: 'reporting',
|
|
118
|
+
prompt: 'Generate the weekly report.',
|
|
119
|
+
cacheQuality: 'HIGH',
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Streaming
|
|
124
|
+
|
|
125
|
+
Stream parsed objects as they arrive:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
await client.generateStream(
|
|
129
|
+
{
|
|
130
|
+
chainId: 'catalog-generator',
|
|
131
|
+
prompt: 'Generate 50 product blurbs as JSON.',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
onObject: (object, index) => {
|
|
135
|
+
console.log(index, object);
|
|
136
|
+
},
|
|
137
|
+
onComplete: (result) => {
|
|
138
|
+
console.log(result.objectCount);
|
|
139
|
+
},
|
|
140
|
+
onError: (error) => {
|
|
141
|
+
console.error(error);
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Batch Generation
|
|
148
|
+
|
|
149
|
+
Run multiple prompts in one call:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
const batch = await client.generateBatch('catalog-generator', [
|
|
153
|
+
{ id: 'a', prompt: 'Describe product A' },
|
|
154
|
+
{ id: 'b', prompt: 'Describe product B' },
|
|
155
|
+
{ id: 'c', prompt: 'Describe product C' },
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
console.log(batch.summary);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## File Attachments
|
|
162
|
+
|
|
163
|
+
Send files as base64 and let Hydra handle the processing path:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import fs from 'node:fs';
|
|
167
|
+
|
|
168
|
+
const file = fs.readFileSync('report.pdf');
|
|
169
|
+
|
|
170
|
+
const result = await client.generate({
|
|
171
|
+
chainId: 'document-analysis',
|
|
172
|
+
prompt: 'Summarize this report.',
|
|
173
|
+
files: [
|
|
174
|
+
{
|
|
175
|
+
data: file.toString('base64'),
|
|
176
|
+
filename: 'report.pdf',
|
|
177
|
+
mimeType: 'application/pdf',
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Usage And Health
|
|
184
|
+
|
|
185
|
+
Get normalized usage metrics:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
const usage = await client.getUsage({
|
|
189
|
+
startDate: new Date('2026-03-01T00:00:00.000Z'),
|
|
190
|
+
endDate: new Date('2026-04-01T00:00:00.000Z'),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
console.log(usage.totalRequests);
|
|
194
|
+
console.log(usage.cachedRequests);
|
|
195
|
+
console.log(usage.byModelList);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Basic health:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const health = await client.health();
|
|
202
|
+
console.log(health.ok, health.latencyMs, health.version);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Detailed health requires an admin key:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const detailed = await client.healthDetailed();
|
|
209
|
+
console.log(detailed.status);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Webhooks
|
|
213
|
+
|
|
214
|
+
Register, list, update, and remove webhooks from the SDK:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
await client.registerWebhook({
|
|
218
|
+
requestId: 'req_123',
|
|
219
|
+
url: 'https://example.com/webhooks/hydra',
|
|
220
|
+
secret: 'super-secret-webhook-key',
|
|
221
|
+
retryCount: 3,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const webhooks = await client.listWebhooks();
|
|
225
|
+
|
|
226
|
+
await client.updateWebhook(webhooks[0].id, {
|
|
227
|
+
retryCount: 5,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
await client.unregisterWebhook(webhooks[0].id);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Cancellation
|
|
234
|
+
|
|
235
|
+
Cancel long-running requests with `AbortController`:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
const controller = new AbortController();
|
|
239
|
+
|
|
240
|
+
setTimeout(() => controller.abort(), 5000);
|
|
241
|
+
|
|
242
|
+
await client.generate({
|
|
243
|
+
chainId: 'long-job',
|
|
244
|
+
prompt: 'Generate a long report.',
|
|
245
|
+
signal: controller.signal,
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Error Handling
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
import {
|
|
253
|
+
AuthenticationError,
|
|
254
|
+
QuotaExceededError,
|
|
255
|
+
RateLimitError,
|
|
256
|
+
TimeoutError,
|
|
257
|
+
isRetryableError,
|
|
258
|
+
} from 'hydra-aidirector';
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
await client.generate({
|
|
262
|
+
chainId: 'support-replies',
|
|
263
|
+
prompt: 'Write a response.',
|
|
264
|
+
});
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (error instanceof AuthenticationError) {
|
|
267
|
+
console.error('Your Hydra secret key is invalid.');
|
|
268
|
+
} else if (error instanceof QuotaExceededError) {
|
|
269
|
+
console.error(error.tier, error.used, error.limit);
|
|
270
|
+
} else if (error instanceof RateLimitError) {
|
|
271
|
+
console.error(error.retryAfterMs);
|
|
272
|
+
} else if (error instanceof TimeoutError) {
|
|
273
|
+
console.error(error.timeoutMs);
|
|
274
|
+
} else if (isRetryableError(error)) {
|
|
275
|
+
console.error('Safe to retry.');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## API Surface
|
|
281
|
+
|
|
282
|
+
- `generate(options)`
|
|
283
|
+
- `generateStream(options, callbacks)`
|
|
284
|
+
- `generateBatch(chainId, items, options?)`
|
|
285
|
+
- `listModels()`
|
|
286
|
+
- `listChains()`
|
|
287
|
+
- `getUsage(options?)`
|
|
288
|
+
- `health()`
|
|
289
|
+
- `healthDetailed()`
|
|
290
|
+
- `registerWebhook(config)`
|
|
291
|
+
- `listWebhooks()`
|
|
292
|
+
- `updateWebhook(id, updates)`
|
|
293
|
+
- `unregisterWebhook(id)`
|
|
294
|
+
- `withConfig(overrides)`
|
|
295
|
+
|
|
296
|
+
## Requirements
|
|
297
|
+
|
|
298
|
+
- Node.js 18+
|
|
299
|
+
- Bun 1.0+ or another runtime with `fetch`
|
|
300
|
+
- TypeScript 5+ for typed projects
|
|
301
|
+
|
|
302
|
+
## Get Started
|
|
303
|
+
|
|
304
|
+
- Docs: [hydrai.dev/docs](https://hydrai.dev/docs)
|
|
305
|
+
- Dashboard: [hydrai.dev/signin](https://hydrai.dev/signin)
|
|
306
|
+
- Contact: [hydrai.dev/contact](https://hydrai.dev/contact)
|
|
307
|
+
|
|
308
|
+
## License
|
|
309
|
+
|
|
310
|
+
MIT
|