skytells 1.0.2 → 1.0.4

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.
Files changed (47) hide show
  1. package/README.md +332 -121
  2. package/dist/chat.cjs +33 -0
  3. package/dist/chat.d.ts +82 -0
  4. package/dist/chat.js +33 -0
  5. package/dist/client.cjs +1151 -35
  6. package/dist/client.d.ts +776 -27
  7. package/dist/client.js +1151 -35
  8. package/dist/embeddings.cjs +40 -0
  9. package/dist/embeddings.d.ts +38 -0
  10. package/dist/embeddings.js +40 -0
  11. package/dist/endpoints.cjs +25 -7
  12. package/dist/endpoints.d.ts +18 -0
  13. package/dist/endpoints.js +25 -7
  14. package/dist/http.cjs +638 -53
  15. package/dist/http.d.ts +136 -2
  16. package/dist/http.js +638 -53
  17. package/dist/index.cjs +52 -6
  18. package/dist/index.d.ts +46 -7
  19. package/dist/index.js +52 -6
  20. package/dist/orchestrator.cjs +202 -0
  21. package/dist/orchestrator.d.ts +142 -0
  22. package/dist/orchestrator.js +202 -0
  23. package/dist/prediction-urls.cjs +38 -0
  24. package/dist/prediction-urls.d.ts +18 -0
  25. package/dist/prediction-urls.js +38 -0
  26. package/dist/responses.cjs +23 -0
  27. package/dist/responses.d.ts +60 -0
  28. package/dist/responses.js +23 -0
  29. package/dist/safety.cjs +323 -0
  30. package/dist/safety.d.ts +91 -0
  31. package/dist/safety.js +323 -0
  32. package/dist/types/index.d.ts +2 -0
  33. package/dist/types/index.js +2 -0
  34. package/dist/types/inference.types.d.ts +583 -0
  35. package/dist/types/inference.types.js +65 -0
  36. package/dist/types/model.types.d.ts +58 -4
  37. package/dist/types/model.types.js +13 -0
  38. package/dist/types/orchestrator.types.d.ts +61 -0
  39. package/dist/types/orchestrator.types.js +7 -0
  40. package/dist/types/predict.types.d.ts +258 -16
  41. package/dist/types/predict.types.js +22 -0
  42. package/dist/types/shared.types.d.ts +156 -3
  43. package/dist/types/shared.types.js +73 -2
  44. package/dist/webhooks.cjs +310 -0
  45. package/dist/webhooks.d.ts +171 -0
  46. package/dist/webhooks.js +310 -0
  47. package/package.json +26 -2
package/dist/client.d.ts CHANGED
@@ -1,45 +1,794 @@
1
- import { PredictionRequest, PredictionResponse, Model, ClientOptions } from './types/index.js';
1
+ /**
2
+ * Skytells prediction client: models catalog, create/poll/wait predictions, queue batching, and
3
+ * optional per-request inference compatibility guard (second argument `{ compatibilityCheck: true }` on `predict` / `create`, fourth on `run`).
4
+ *
5
+ * **Memory / lifecycle (for long‑lived servers):**
6
+ * - Sub-APIs (`chat`, `embeddings`, …) are created lazily on first access.
7
+ * - When a call passes `{ compatibilityCheck: true }`, model metadata is cached per slug with TTL
8
+ * {@link PREFETCHED_MODEL_CACHE_TTL_MS} and a cap from {@link SkytellsClient.config | config.prefetchMaxSlugs}
9
+ * (smaller when {@link ClientOptions.runtime} is `"edge"`).
10
+ * - {@link SkytellsClient.wait} / `run(..., onProgress)` use `setTimeout` between polls; pass {@link WaitOptions.signal}
11
+ * (or `RunOptions.signal` with `onProgress`) to abort and stop scheduling further delays.
12
+ * - {@link Prediction} holds the shared {@link HTTP} client and a snapshot of the API response (expected).
13
+ * - {@link SkytellsClient.queue} is an unbounded in-memory array — call {@link SkytellsClient.dispatch} or avoid piling
14
+ * requests if you need a hard limit (enforce in your app).
15
+ * - Timeouts, stream cleanup, and polling guards: see **Reliability.md** in the repo docs.
16
+ *
17
+ * @module client
18
+ */
19
+ import { HTTP } from './http.js';
20
+ import { Orchestrator } from './orchestrator.js';
21
+ import { Chat } from './chat.js';
22
+ import { Responses } from './responses.js';
23
+ import { Embeddings } from './embeddings.js';
24
+ import { Safety } from './safety.js';
25
+ import type { PredictionRequest, PredictionResponse, RunOptions, PredictionsListOptions, OnProgressCallback, WaitOptions, PredictionSdkOptions, PaginatedResponse, Model, ModelFieldsOptions, ClientOptions, SkytellsRuntime } from './types/index.js';
26
+ import { PredictionStatus } from './types/index.js';
27
+ import type { WebhookListener } from './webhooks.js';
28
+ import { type WebhookListenerOptions } from './webhooks.js';
29
+ /**
30
+ * Time-to-live for in-memory cache of `GET /model/{slug}` responses used when
31
+ * a guarded predict/create/run uses `compatibilityCheck: true`. After this interval the next guarded request refetches the model.
32
+ */
33
+ export declare const PREFETCHED_MODEL_CACHE_TTL_MS: number;
34
+ /**
35
+ * Max distinct model slugs kept in the compatibility-check cache. Oldest entries are removed (FIFO) when exceeded.
36
+ * Prevents unbounded growth if callers use many unique `model` strings over time.
37
+ */
38
+ export declare const PREFETCHED_MODEL_CACHE_MAX_SLUGS = 64;
39
+ /**
40
+ * Default request timeout when {@link ClientOptions.runtime} is `"edge"` and `timeout` is omitted
41
+ * (aligns with common ~25–30s serverless / edge ceilings).
42
+ */
43
+ export declare const EDGE_DEFAULT_REQUEST_TIMEOUT_MS = 25000;
44
+ /** Max model slugs in the inference-compat cache when `runtime` is `"edge"` (lower memory). */
45
+ export declare const EDGE_PREFETCH_MAX_SLUGS = 16;
46
+ /**
47
+ * Represents a completed prediction with convenience methods for accessing output
48
+ * and managing the prediction lifecycle (cancel, delete).
49
+ *
50
+ * Returned by {@link SkytellsClient.run}. Wraps a {@link PredictionResponse} and
51
+ * exposes `.output` to get results as a normalized `string[]`, plus `.cancel()`
52
+ * and `.delete()` for lifecycle management.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
57
+ * const [imageUrl] = prediction.output;
58
+ * console.log(prediction.id, prediction.status);
59
+ * const streamMeta = await prediction.stream(); // stream endpoint info (uses urls.stream)
60
+ * // Clean up when done
61
+ * await prediction.delete();
62
+ * ```
63
+ */
64
+ export declare class Prediction {
65
+ private http;
66
+ private data;
67
+ /** @internal Use {@link SkytellsClient.run} to create a Prediction. */
68
+ constructor(http: HTTP, data: PredictionResponse);
69
+ /**
70
+ * The full prediction response object from the API.
71
+ * Contains all fields: status, id, input, output, metrics, metadata, urls, etc.
72
+ */
73
+ get response(): PredictionResponse;
74
+ /**
75
+ * The unique prediction identifier.
76
+ * Use this to fetch, cancel, or delete the prediction later via the client.
77
+ */
78
+ get id(): string;
79
+ /**
80
+ * The current status of the prediction.
81
+ * Possible values: `pending`, `starting`, `started`, `processing`, `succeeded`, `failed`, `cancelled`.
82
+ */
83
+ get status(): PredictionStatus;
84
+ /**
85
+ * The raw prediction output as returned by the API.
86
+ *
87
+ * Can be a single `string`, a `string[]`, or `undefined` if incomplete.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * // Single output (string)
92
+ * console.log(prediction.output); // "https://..."
93
+ *
94
+ * // Multiple outputs (string[])
95
+ * console.log(prediction.output[0]); // "https://..."
96
+ *
97
+ * // Check type
98
+ * if (Array.isArray(prediction.output)) {
99
+ * for (const item of prediction.output) { console.log(item); }
100
+ * }
101
+ * ```
102
+ */
103
+ get output(): string | string[] | undefined;
104
+ /**
105
+ * Returns the output, normalized to a single value:
106
+ *
107
+ * - `undefined` / `null` → `undefined`
108
+ * - `"https://..."` → `"https://..."`
109
+ * - `["https://..."]` → `"https://..."` (single-element array unwrapped)
110
+ * - `["a", "b"]` → `["a", "b"]` (multi-element array kept as-is)
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * const result = prediction.outputs();
115
+ * // string if single output, string[] if multiple, undefined if none
116
+ * ```
117
+ */
118
+ outputs(): string | string[] | undefined;
119
+ /**
120
+ * Returns the full raw prediction response as a plain JSON object.
121
+ *
122
+ * @returns The raw `PredictionResponse` data from the API.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
127
+ * const json = prediction.raw();
128
+ * console.log(json.id, json.status, json.output, json.metrics);
129
+ * ```
130
+ */
131
+ raw(): PredictionResponse;
132
+ /**
133
+ * Fetches streaming metadata for this prediction (`GET` using `urls.stream` when present).
134
+ * Same behavior as the deprecated {@link SkytellsClient.streamPrediction} with this prediction’s id and urls.
135
+ *
136
+ * @returns The prediction response from the stream-info endpoint (includes `urls`, etc.).
137
+ */
138
+ stream(): Promise<PredictionResponse>;
139
+ /**
140
+ * Cancels this prediction. Only works if the prediction is still in progress
141
+ * (status is `pending`, `starting`, `started`, or `processing`).
142
+ *
143
+ * @returns The updated prediction response with `status: 'cancelled'`.
144
+ * @throws {SkytellsError} If the prediction cannot be cancelled or the request fails.
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
149
+ * await prediction.cancel();
150
+ * ```
151
+ */
152
+ cancel(): Promise<PredictionResponse>;
153
+ /**
154
+ * Deletes this prediction and its associated output/assets from storage.
155
+ *
156
+ * @returns The prediction response confirming deletion.
157
+ * @throws {SkytellsError} If the prediction cannot be deleted or the request fails.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
162
+ * const [url] = prediction.output;
163
+ * // ... use the output ...
164
+ * await prediction.delete(); // clean up
165
+ * ```
166
+ */
167
+ delete(): Promise<PredictionResponse>;
168
+ }
169
+ /**
170
+ * Sub-API for managing predictions. Accessible via `client.predictions`.
171
+ *
172
+ * Provides methods to create predictions in the background, fetch them by ID,
173
+ * and list them with filters.
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * // Create a background prediction
178
+ * const prediction = await client.predictions.create({
179
+ * model: "flux-pro",
180
+ * input: { prompt: "A sunset" },
181
+ * });
182
+ *
183
+ * // Fetch it later
184
+ * const result = await client.predictions.get(prediction.id);
185
+ *
186
+ * // List recent predictions by model
187
+ * const { data } = await client.predictions.list({ model: "flux-pro", since: "2026-01-01" });
188
+ * ```
189
+ */
190
+ export declare class PredictionsAPI {
191
+ private http;
192
+ private onBeforePredict?;
193
+ /** @internal */
194
+ constructor(http: HTTP, onBeforePredict?: (payload: PredictionRequest, sdk?: PredictionSdkOptions) => Promise<void>);
195
+ /**
196
+ * Creates a prediction in the background (does not wait for completion).
197
+ *
198
+ * The prediction starts processing asynchronously. Use {@link get} to poll,
199
+ * or {@link SkytellsClient.wait} to block until it finishes.
200
+ *
201
+ * @param payload - The prediction request parameters.
202
+ * @param payload.model - The model slug (e.g. `"flux-pro"`).
203
+ * @param payload.input - Key-value input parameters for the model.
204
+ * @param payload.webhook - Optional webhook to receive events.
205
+ * @param payload.stream - Enable streaming (default: `false`).
206
+ * @param sdk - SDK-only options (not sent in JSON). When `sdk.compatibilityCheck === true`, runs inference compatibility guard before POST.
207
+ * @returns The initial prediction response with `status: 'pending'` or `'starting'`.
208
+ * @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits).
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * const prediction = await client.predictions.create({
213
+ * model: "flux-pro",
214
+ * input: { prompt: "An astronaut riding a unicorn" },
215
+ * });
216
+ * console.log(prediction.id, prediction.status); // "pending"
217
+ *
218
+ * // Wait for it to finish
219
+ * const result = await client.wait(prediction);
220
+ * console.log(result.output);
221
+ * ```
222
+ */
223
+ create(payload: PredictionRequest, sdk?: PredictionSdkOptions): Promise<PredictionResponse>;
224
+ /**
225
+ * Fetches a prediction by its ID.
226
+ *
227
+ * @param id - The prediction ID.
228
+ * @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.get` is set, that absolute URL is used (API protocol); otherwise `GET {baseUrl}/predictions/{id}`.
229
+ * @returns The prediction response with current status, output, metrics, etc.
230
+ * @throws {SkytellsError} If the prediction is not found or the request fails.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * const prediction = await client.predictions.get("pred_abc123");
235
+ * if (prediction.status === "succeeded") {
236
+ * console.log(prediction.output);
237
+ * }
238
+ * ```
239
+ */
240
+ get(id: string, urls?: PredictionResponse['urls']): Promise<PredictionResponse>;
241
+ /**
242
+ * Lists predictions with optional filters and pagination.
243
+ *
244
+ * @param options - Filter and pagination options.
245
+ * @param options.page - Page number (default: 1).
246
+ * @param options.since - Only include predictions created on or after this date (`YYYY-MM-DD`).
247
+ * @param options.until - Only include predictions created on or before this date (`YYYY-MM-DD`).
248
+ * @param options.model - Filter by model slug.
249
+ * @returns A paginated response with `data` (predictions array) and `pagination` metadata.
250
+ * @throws {SkytellsError} On authentication failure or invalid parameters.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * // List all predictions
255
+ * const { data, pagination } = await client.predictions.list();
256
+ *
257
+ * // Filter by model and date range
258
+ * const filtered = await client.predictions.list({
259
+ * model: "flux-pro",
260
+ * since: "2026-01-01",
261
+ * until: "2026-03-15",
262
+ * page: 2,
263
+ * });
264
+ * ```
265
+ */
266
+ list(options?: PredictionsListOptions): Promise<PaginatedResponse<PredictionResponse>>;
267
+ }
268
+ /**
269
+ * Sub-API for browsing and fetching models. Accessible via `client.models`.
270
+ *
271
+ * Provides `.list()` to get all models and `.get()` to fetch a single model by slug.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * const allModels = await client.models.list();
276
+ * const model = await client.models.get("flux-pro", { fields: ["input_schema"] });
277
+ * ```
278
+ */
279
+ export declare class ModelsAPI {
280
+ private http;
281
+ /** @internal */
282
+ constructor(http: HTTP);
283
+ /**
284
+ * Lists all available models on the Skytells platform.
285
+ *
286
+ * @param options - Optional configuration.
287
+ * @param options.fields - Additional fields to include in the response
288
+ * (e.g. `["input_schema", "output_schema"]`). By default, schemas are not included.
289
+ * @returns An array of model objects with name, type, pricing, metadata, etc.
290
+ * @throws {SkytellsError} On authentication failure or server error.
291
+ *
292
+ * @example
293
+ * ```ts
294
+ * const allModels = await client.models.list();
295
+ * for (const m of allModels) {
296
+ * console.log(m.name, m.type);
297
+ * }
298
+ *
299
+ * // Include input schemas
300
+ * const withSchemas = await client.models.list({ fields: ["input_schema"] });
301
+ * ```
302
+ */
303
+ list(options?: ModelFieldsOptions): Promise<Model[]>;
304
+ /**
305
+ * Fetches a single model by its slug.
306
+ *
307
+ * @param slug - The model slug identifier (e.g. `"flux-pro"`, `"truefusion"`, `"beatfusion"`).
308
+ * @param options - Optional configuration.
309
+ * @param options.fields - Additional fields to include (e.g. `["input_schema", "output_schema"]`).
310
+ * @returns The model object with name, type, pricing, metadata, and optionally schemas.
311
+ * @throws {SkytellsError} If the model is not found (`MODEL_NOT_FOUND`) or the request fails.
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * const model = await client.models.get("flux-pro");
316
+ * console.log(model.name, model.pricing);
317
+ *
318
+ * // With schemas
319
+ * const detailed = await client.models.get("flux-pro", {
320
+ * fields: ["input_schema", "output_schema"],
321
+ * });
322
+ * console.log(detailed.input_schema);
323
+ * ```
324
+ */
325
+ get(slug: string, options?: ModelFieldsOptions): Promise<Model>;
326
+ }
327
+ /**
328
+ * The main Skytells API client. Provides methods to run predictions, list models,
329
+ * and manage prediction lifecycle.
330
+ *
331
+ * Create an instance using {@link Skytells} or the constructor directly.
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * import Skytells from "skytells";
336
+ *
337
+ * const client = Skytells("sk-your-api-key", {
338
+ * timeout: 30000,
339
+ * retry: { retries: 2 },
340
+ * });
341
+ *
342
+ * // Run a model and get output
343
+ * const prediction = await client.run("flux-pro", {
344
+ * input: { prompt: "An astronaut riding a unicorn" },
345
+ * });
346
+ * const [imageUrl] = prediction.output;
347
+ *
348
+ * // List and fetch models
349
+ * const allModels = await client.models.list();
350
+ * const model = await client.models.get("flux-pro");
351
+ *
352
+ * // Background prediction
353
+ * const bg = await client.predictions.create({
354
+ * model: "flux-pro",
355
+ * input: { prompt: "A sunset" },
356
+ * });
357
+ * const result = await client.wait(bg);
358
+ *
359
+ * // Queue multiple predictions
360
+ * client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
361
+ * client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
362
+ * const results = await client.dispatch();
363
+ * ```
364
+ */
2
365
  export declare class SkytellsClient {
3
366
  private http;
367
+ private readonly _runtime;
368
+ private readonly _requestTimeoutMs;
369
+ private readonly _prefetchCap;
370
+ private _queue;
371
+ private _predictions?;
372
+ private _models?;
373
+ private _chat?;
374
+ private _responses?;
375
+ private _embeddings?;
376
+ private _safety?;
377
+ private _orchestrator?;
378
+ private readonly _orchestratorApiKey?;
379
+ private readonly _orchestratorBaseUrl;
380
+ private readonly _orchestratorHttpBundle;
381
+ /**
382
+ * Sub-API for managing predictions.
383
+ * Provides `.create()`, `.get()`, and `.list()` methods.
384
+ */
385
+ get predictions(): PredictionsAPI;
386
+ /**
387
+ * Alias of {@link predictions} (singular). Same instance — use whichever reads best.
388
+ *
389
+ * @example
390
+ * ```ts
391
+ * await client.prediction.create({ model: 'flux-pro', input: { prompt: '…' } });
392
+ * // same as client.predictions.create(...)
393
+ * ```
394
+ */
395
+ get prediction(): PredictionsAPI;
396
+ /**
397
+ * Sub-API for browsing and fetching models.
398
+ * Provides `.list()` and `.get()` methods.
399
+ */
400
+ get models(): ModelsAPI;
4
401
  /**
5
- * Creates a new Skytells client
6
- * @param apiKey Your Skytells API key
7
- * @param options Configuration options
402
+ * Chat completions. Same as OpenAI's client.chat.completions.
403
+ *
404
+ * @example
405
+ * ```ts
406
+ * const completion = await client.chat.completions.create({
407
+ * model: 'deepbrain-router',
408
+ * messages: [{ role: 'user', content: 'Hello' }],
409
+ * });
410
+ * ```
411
+ */
412
+ get chat(): Chat;
413
+ /**
414
+ * Responses API (`POST /v1/responses`). Same as `client.chat.responses`.
415
+ *
416
+ * Follows the OpenAI Responses API schema. Supports both non-streaming and streaming modes.
417
+ *
418
+ * @example Non-streaming:
419
+ * ```ts
420
+ * const response = await client.responses.create({
421
+ * model: 'gpt-5.3-codex',
422
+ * input: [{ role: 'user', content: 'Explain recursion simply.' }],
423
+ * instructions: 'You are a helpful tutor.',
424
+ * });
425
+ * console.log(response.output[0].content[0].text);
426
+ * ```
427
+ *
428
+ * @example Streaming:
429
+ * ```ts
430
+ * const stream = await client.responses.create({
431
+ * model: 'gpt-5.3-codex',
432
+ * input: [{ role: 'user', content: 'Explain recursion simply.' }],
433
+ * stream: true,
434
+ * });
435
+ * for await (const event of stream) {
436
+ * console.log(event.type, event);
437
+ * }
438
+ * ```
439
+ */
440
+ get responses(): Responses;
441
+ /**
442
+ * Embeddings. Same as OpenAI's client.embeddings.
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * const embedding = await client.embeddings.create({
447
+ * model: 'text-embedding-3-small',
448
+ * input: 'Hello world',
449
+ * });
450
+ * ```
451
+ */
452
+ get embeddings(): Embeddings;
453
+ /**
454
+ * Safety checks. Proactive (checkText, checkImage) and response parsing (wasFiltered, evaluate).
455
+ * evaluate() accepts text, image URLs, choices, completions, prediction results, or arrays of any.
456
+ *
457
+ * @example
458
+ * ```ts
459
+ * const result = await client.safety.checkText('user input');
460
+ * if (client.safety.wasFiltered(completion)) { ... }
461
+ * const evalResult = await client.safety.evaluate('user text', SafetyTemplates.STRICT);
462
+ * ```
463
+ */
464
+ get safety(): Safety;
465
+ /**
466
+ * [Skytells Orchestrator](https://learn.skytells.ai/docs/products/orchestrator/api-reference) — workflows,
467
+ * executions, webhook triggers, integrations, etc.
468
+ *
469
+ * Requires **`ClientOptions.orchestratorApiKey`** (`wfb_…`). Uses an internal HTTP stack aimed at the Orchestrator
470
+ * host ({@link ORCHESTRATOR_BASE_URL}): Bearer only, no `x-api-key`. Same `timeout`, `headers`, `retry`, and
471
+ * `fetch` as the main Skytells client — pass both keys on one {@link SkytellsClient} when you need both products.
472
+ *
473
+ * @throws {SkytellsError} `SDK_ERROR` if `orchestratorApiKey` was not set.
474
+ */
475
+ get orchestrator(): Orchestrator;
476
+ /**
477
+ * Target runtime from {@link ClientOptions.runtime} (`"default"` when omitted).
478
+ */
479
+ get runtime(): SkytellsRuntime;
480
+ /**
481
+ * Read-only resolved settings (timeouts, cache cap) for debugging and tests.
482
+ */
483
+ get config(): Readonly<{
484
+ runtime: SkytellsRuntime;
485
+ requestTimeoutMs: number;
486
+ prefetchMaxSlugs: number;
487
+ }>;
488
+ /**
489
+ * In-memory `GET /model/{slug}` results for the per-prediction guard. Lazy-allocated; bounded by
490
+ * {@link SkytellsClient.config | config.prefetchMaxSlugs} and TTL {@link PREFETCHED_MODEL_CACHE_TTL_MS}.
491
+ */
492
+ private _prefetchedModelCache;
493
+ /**
494
+ * Creates a new Skytells API client.
495
+ *
496
+ * @param apiKey - Your Skytells API key (starts with `sk-`). Required for authenticated endpoints.
497
+ * @param options - Client configuration options.
498
+ * @param options.baseUrl - Override the default API base URL.
499
+ * @param options.timeout - Request timeout in milliseconds (default: 60000, or 25000 when `runtime: "edge"` and omitted).
500
+ * @param options.headers - Custom headers to include in every request.
501
+ * @param options.retry - Retry configuration: `retries`, `retryDelay`, `retryOn` status codes.
502
+ * @param options.fetch - Custom `fetch` implementation (useful for testing, proxying, or
503
+ * disabling Next.js fetch caching).
504
+ * @param options.runtime - `"edge"` for Workers / Vercel Edge / etc.: shorter default timeout, smaller compat cache, one-time hints.
505
+ *
506
+ * @example
507
+ * ```ts
508
+ * const client = new SkytellsClient("sk-your-api-key");
509
+ *
510
+ * // With options:
511
+ * const client = new SkytellsClient("sk-your-api-key", {
512
+ * timeout: 30000,
513
+ * retry: { retries: 3, retryDelay: 1000 },
514
+ * headers: { "X-Custom-Header": "value" },
515
+ * });
516
+ *
517
+ * // Next.js App Router — disable fetch caching:
518
+ * const client = new SkytellsClient("sk-your-api-key", {
519
+ * fetch: (url, opts) => fetch(url, { ...opts, cache: "no-store" }),
520
+ * });
521
+ *
522
+ * // Edge / serverless:
523
+ * const edge = new SkytellsClient("sk-…", { runtime: "edge" });
524
+ *
525
+ * // Skytells + Orchestrator (optional wfb_… key — same client):
526
+ * const both = new SkytellsClient("sk-…", { orchestratorApiKey: "wfb_…" });
527
+ * ```
8
528
  */
9
529
  constructor(apiKey?: string, options?: ClientOptions);
10
530
  /**
11
- * Send a prediction request to the Skytells API
12
- * @param payload The prediction request parameters
13
- * @returns A promise that resolves to the prediction response
531
+ * Build a {@link WebhookListener} for your HTTP server. Verifies `X-Skytells-Signature` per
532
+ * [Skytells webhooks](https://docs.skytells.ai/webhooks/).
533
+ *
534
+ * - **`mode: 'general'`** (default): HMAC key is your API key — omitted `apiKey` uses this client’s key.
535
+ * - **`mode: 'enterprise'`**: pass `secret` from the dashboard.
536
+ *
537
+ * @example
538
+ * ```ts
539
+ * const hooks = client.webhookListener({ mode: 'general' });
540
+ * hooks.on(WebhookEvent.COMPLETED, async (p) => console.log(p.id));
541
+ * // Next.js: export async function POST(req: Request) { return hooks.handleRequest(req); }
542
+ * ```
543
+ */
544
+ webhookListener(options?: WebhookListenerOptions): WebhookListener;
545
+ /**
546
+ * Alias of {@link SkytellsClient.webhookListener}. Chain handlers: `client.listen().on(WebhookEvent.COMPLETED, fn)`.
547
+ */
548
+ listen(options?: WebhookListenerOptions): WebhookListener;
549
+ /**
550
+ * Clears cached model metadata used when guarded predict/create/run passes `compatibilityCheck: true`.
551
+ *
552
+ * @param modelSlug - If set, only evicts that slug; otherwise clears the entire cache.
553
+ *
554
+ * @example
555
+ * ```ts
556
+ * // After a model was updated server-side, force the next predict to refetch metadata:
557
+ * client.purgePrefetchedModelCache("flux-pro");
558
+ *
559
+ * // Clear all cached slugs
560
+ * client.purgePrefetchedModelCache();
561
+ * ```
562
+ */
563
+ purgePrefetchedModelCache(modelSlug?: string): void;
564
+ /**
565
+ * Returns model metadata for the inference compatibility check, using {@link _prefetchedModelCache} when fresh.
566
+ */
567
+ private _getModelForCompatibilityCheck;
568
+ /**
569
+ * @internal When `compatibilityCheck === true`, throws SDK_ERROR if the model is chat-only here.
570
+ */
571
+ private _maybeCompatibilityGuard;
572
+ /**
573
+ * Sends a prediction request to the Skytells API.
574
+ *
575
+ * This is the low-level prediction method. For most use cases, prefer {@link run}
576
+ * which waits for completion and returns a {@link Prediction} object with convenience methods.
577
+ *
578
+ * @param payload - The prediction request parameters.
579
+ * @param payload.model - The model slug to run (e.g. `"flux-pro"`, `"truefusion"`).
580
+ * @param payload.input - Key-value input parameters for the model (e.g. `{ prompt: "..." }`).
581
+ * @param payload.await - If `true`, the request blocks until the prediction completes (default: `false`).
582
+ * @param payload.stream - If `true`, enables streaming for the prediction (default: `false`).
583
+ * @param payload.webhook - Optional webhook configuration to receive prediction events.
584
+ * @param sdk - SDK-only options (not sent in JSON). When `sdk.compatibilityCheck === true`, runs inference compatibility guard before POST.
585
+ * @returns The prediction response object.
586
+ * @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits, etc.).
587
+ *
588
+ * @example
589
+ * ```ts
590
+ * // Fire-and-forget (returns immediately with status: "pending")
591
+ * const response = await client.predict({
592
+ * model: "flux-pro",
593
+ * input: { prompt: "A sunset over mountains" },
594
+ * });
595
+ * console.log(response.id); // use predictions.get(id) to poll
596
+ *
597
+ * // Wait for completion
598
+ * const result = await client.predict({
599
+ * model: "flux-pro",
600
+ * input: { prompt: "A sunset over mountains" },
601
+ * await: true,
602
+ * });
603
+ * console.log(result.output); // ["https://..."]
604
+ * ```
605
+ */
606
+ predict(payload: PredictionRequest, sdk?: PredictionSdkOptions): Promise<PredictionResponse>;
607
+ /**
608
+ * Runs a model, waits for completion, and returns a {@link Prediction} object.
609
+ *
610
+ * This is the recommended way to generate content. It automatically sets `await: true`,
611
+ * checks for failures, and returns a `Prediction` with `.output`, `.cancel()`, and `.delete()`.
612
+ *
613
+ * If an `onProgress` callback is provided, the prediction is created in the background
614
+ * and polled every 5 seconds. The callback is invoked on each poll with the latest
615
+ * prediction state, allowing you to track progress.
616
+ *
617
+ * @param model - The model slug to run (e.g. `"flux-pro"`, `"truefusion"`, `"beatfusion"`).
618
+ * @param options - Run options.
619
+ * @param options.input - Key-value input parameters for the model.
620
+ * @param options.stream - If `true`, enables streaming (default: `false`).
621
+ * @param options.webhook - Optional webhook configuration.
622
+ * @param onProgress - Optional callback invoked on each poll with the current prediction state.
623
+ * @param sdk - SDK-only options. When `sdk.compatibilityCheck === true`, runs inference guard before predict/create. Use `undefined` for `onProgress` when you only need `sdk` (e.g. `run(m, o, undefined, { compatibilityCheck: true })`).
624
+ * @remarks With `onProgress`, uses `predictions.create` + {@link wait}. Then {@link RunOptions.interval},
625
+ * {@link RunOptions.maxWait}, and {@link RunOptions.signal} apply (same as {@link WaitOptions}).
626
+ * @returns A {@link Prediction} object with output and lifecycle methods.
627
+ * @throws {SkytellsError} On API errors or if the prediction fails (`PREDICTION_FAILED`).
628
+ *
629
+ * @example
630
+ * ```ts
631
+ * // Simple run (blocks until complete)
632
+ * const prediction = await client.run("flux-pro", {
633
+ * input: { prompt: "An astronaut riding a rainbow unicorn" },
634
+ * });
635
+ * const [imageUrl] = prediction.output;
636
+ *
637
+ * // With progress tracking
638
+ * const prediction = await client.run("flux-pro", {
639
+ * input: { prompt: "An astronaut riding a unicorn" },
640
+ * }, (p) => {
641
+ * // Note: metrics.progress may not be available during early processing stages
642
+ * console.log(`Status: ${p.status}, Progress: ${p.metrics?.progress ?? 'n/a'}`);
643
+ * });
644
+ * ```
645
+ */
646
+ run(model: string, options: RunOptions, onProgress?: OnProgressCallback, sdk?: PredictionSdkOptions): Promise<Prediction>;
647
+ /**
648
+ * Polls a prediction until it reaches a terminal status (`succeeded`, `failed`, or `cancelled`).
649
+ *
650
+ * @param prediction - The prediction response to wait on (must have an `id`).
651
+ * @param options - Polling options.
652
+ * @param options.interval - Polling interval in milliseconds (default: 5000).
653
+ * @param options.maxWait - Maximum wait time in milliseconds. Throws if exceeded.
654
+ * @param options.signal - If aborted, stops polling and throws `ABORTED` (no further poll timers scheduled).
655
+ * @param onProgress - Optional callback invoked on each poll with the latest prediction state.
656
+ * @returns The final prediction response.
657
+ * @throws {SkytellsError} If `maxWait` is exceeded (`WAIT_TIMEOUT`) or `signal` is aborted (`ABORTED`).
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * const bg = await client.predictions.create({
662
+ * model: "flux-pro",
663
+ * input: { prompt: "A cat" },
664
+ * });
665
+ *
666
+ * const result = await client.wait(bg);
667
+ * console.log(result.output);
668
+ *
669
+ * // With progress and timeout
670
+ * const result = await client.wait(bg, { interval: 2000, maxWait: 120000 }, (p) => {
671
+ * console.log(p.status, p.metrics?.progress);
672
+ * });
673
+ * ```
674
+ */
675
+ wait(prediction: PredictionResponse, options?: WaitOptions, onProgress?: OnProgressCallback): Promise<PredictionResponse>;
676
+ /**
677
+ * Adds a prediction request to the local queue.
678
+ *
679
+ * Queued items are not sent to the API until {@link dispatch} is called.
680
+ * Useful for batching multiple predictions together.
681
+ *
682
+ * @param payload - The prediction request to queue.
683
+ * @param sdk - Optional SDK options for this item (e.g. `{ compatibilityCheck: true }`), forwarded to {@link PredictionsAPI.create} on {@link dispatch}.
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
688
+ * client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
689
+ * client.queue({ model: "flux-pro", input: { prompt: "Bird" } });
690
+ *
691
+ * const results = await client.dispatch();
692
+ * // results is an array of PredictionResponse for each queued item
693
+ * ```
694
+ */
695
+ queue(payload: PredictionRequest, sdk?: PredictionSdkOptions): void;
696
+ /**
697
+ * Dispatches all queued predictions, sending them to the API concurrently.
698
+ *
699
+ * Clears the queue after dispatching. Each prediction is created in the background
700
+ * (non-blocking). Use {@link wait} on individual results if you need to wait for completion.
701
+ *
702
+ * @returns An array of prediction responses, one for each queued item.
703
+ * @throws {SkytellsError} Uses **`Promise.all`**: if **any** `predictions.create` rejects, the whole
704
+ * `dispatch()` rejects with that error (fail-fast). Partial successes are not returned.
705
+ *
706
+ * @example
707
+ * ```ts
708
+ * client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
709
+ * client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
710
+ *
711
+ * const results = await client.dispatch();
712
+ * for (const pred of results) {
713
+ * console.log(pred.id, pred.status);
714
+ * }
715
+ *
716
+ * // Wait for all to complete
717
+ * const completed = await Promise.all(results.map(p => client.wait(p)));
718
+ * ```
719
+ */
720
+ dispatch(): Promise<PredictionResponse[]>;
721
+ /**
722
+ * Retrieves the streaming endpoint for a prediction.
723
+ *
724
+ * @deprecated Use {@link Prediction.stream} on the {@link Prediction} from {@link SkytellsClient.run} instead,
725
+ * or pass `urls` from a stored `PredictionResponse` when calling without a `Prediction` instance.
726
+ *
727
+ * @param id - The prediction ID to stream.
728
+ * @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.stream` is set, that URL is used.
729
+ * @returns The prediction response with streaming URL info.
730
+ * @throws {SkytellsError} If the prediction is not found or streaming is not available.
731
+ *
732
+ * @example
733
+ * ```ts
734
+ * const stream = await client.streamPrediction("pred_abc123");
735
+ * console.log(stream.urls?.stream);
736
+ * ```
737
+ */
738
+ streamPrediction(id: string, urls?: PredictionResponse['urls']): Promise<PredictionResponse>;
739
+ /**
740
+ * Cancels a running prediction by its ID.
741
+ *
742
+ * @deprecated Use {@link Prediction.cancel} on the {@link Prediction} from {@link SkytellsClient.run} instead.
743
+ * Only predictions with status `pending`, `starting`, `started`, or `processing` can be cancelled.
744
+ *
745
+ * @param id - The prediction ID to cancel.
746
+ * @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.cancel` is set, that URL is used.
747
+ * @returns The updated prediction response with `status: 'cancelled'`.
748
+ * @throws {SkytellsError} If the prediction cannot be cancelled or is not found.
749
+ *
750
+ * @example
751
+ * ```ts
752
+ * await client.cancelPrediction("pred_abc123");
753
+ * ```
754
+ */
755
+ cancelPrediction(id: string, urls?: PredictionResponse['urls']): Promise<PredictionResponse>;
756
+ /**
757
+ * Deletes a prediction and its associated output/assets.
758
+ *
759
+ * @deprecated Use {@link Prediction.delete} on the {@link Prediction} from {@link SkytellsClient.run} instead.
760
+ *
761
+ * @param id - The prediction ID to delete.
762
+ * @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.delete` is set, that URL is used.
763
+ * @returns The prediction response confirming deletion.
764
+ * @throws {SkytellsError} If the prediction is not found or the request fails.
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * await client.deletePrediction("pred_abc123");
769
+ * ```
14
770
  */
15
- predict(payload: PredictionRequest): Promise<PredictionResponse>;
771
+ deletePrediction(id: string, urls?: PredictionResponse['urls']): Promise<PredictionResponse>;
772
+ /** Stops {@link wait} polling when `signal` aborts; clears the pending timer so nothing keeps firing. */
773
+ private static abortWaitError;
16
774
  /**
17
- * Get a prediction by ID
18
- * @param id The prediction ID
19
- * @returns A promise that resolves to the prediction response
775
+ * @param signal - When present and aborted, the promise rejects with `ABORTED` and the timer is cleared.
20
776
  */
21
- getPrediction(id: string): Promise<PredictionResponse>;
777
+ private delay;
22
778
  /**
23
- * List all available models
24
- * @returns A promise that resolves to an array of models
779
+ * @deprecated Use {@link predictions}.list() instead. This method will be removed in a future version.
25
780
  */
26
- listModels(): Promise<Model[]>;
781
+ listPredictions(page?: number): Promise<PaginatedResponse<PredictionResponse>>;
27
782
  /**
28
- * Stream a prediction by ID
29
- * @param id The prediction ID
30
- * @returns A promise that resolves to the prediction response
783
+ * @deprecated Use {@link models}.list() instead. This method will be removed in a future version.
31
784
  */
32
- streamPrediction(id: string): Promise<PredictionResponse>;
785
+ listModels(options?: ModelFieldsOptions): Promise<Model[]>;
33
786
  /**
34
- * Cancel a prediction by ID
35
- * @param id The prediction ID
36
- * @returns A promise that resolves to the prediction response
787
+ * @deprecated Use {@link predictions}.get() instead. This method will be removed in a future version.
37
788
  */
38
- cancelPrediction(id: string): Promise<PredictionResponse>;
789
+ getPrediction(id: string, urls?: PredictionResponse['urls']): Promise<PredictionResponse>;
39
790
  /**
40
- * Delete a prediction by ID
41
- * @param id The prediction ID
42
- * @returns A promise that resolves to the prediction response
791
+ * @deprecated Use {@link models}.get() instead. This method will be removed in a future version.
43
792
  */
44
- deletePrediction(id: string): Promise<PredictionResponse>;
793
+ getModel(slug: string, options?: ModelFieldsOptions): Promise<Model>;
45
794
  }