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.
- package/README.md +332 -121
- package/dist/chat.cjs +33 -0
- package/dist/chat.d.ts +82 -0
- package/dist/chat.js +33 -0
- package/dist/client.cjs +1151 -35
- package/dist/client.d.ts +776 -27
- package/dist/client.js +1151 -35
- package/dist/embeddings.cjs +40 -0
- package/dist/embeddings.d.ts +38 -0
- package/dist/embeddings.js +40 -0
- package/dist/endpoints.cjs +25 -7
- package/dist/endpoints.d.ts +18 -0
- package/dist/endpoints.js +25 -7
- package/dist/http.cjs +638 -53
- package/dist/http.d.ts +136 -2
- package/dist/http.js +638 -53
- package/dist/index.cjs +52 -6
- package/dist/index.d.ts +46 -7
- package/dist/index.js +52 -6
- package/dist/orchestrator.cjs +202 -0
- package/dist/orchestrator.d.ts +142 -0
- package/dist/orchestrator.js +202 -0
- package/dist/prediction-urls.cjs +38 -0
- package/dist/prediction-urls.d.ts +18 -0
- package/dist/prediction-urls.js +38 -0
- package/dist/responses.cjs +23 -0
- package/dist/responses.d.ts +60 -0
- package/dist/responses.js +23 -0
- package/dist/safety.cjs +323 -0
- package/dist/safety.d.ts +91 -0
- package/dist/safety.js +323 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/inference.types.d.ts +583 -0
- package/dist/types/inference.types.js +65 -0
- package/dist/types/model.types.d.ts +58 -4
- package/dist/types/model.types.js +13 -0
- package/dist/types/orchestrator.types.d.ts +61 -0
- package/dist/types/orchestrator.types.js +7 -0
- package/dist/types/predict.types.d.ts +258 -16
- package/dist/types/predict.types.js +22 -0
- package/dist/types/shared.types.d.ts +156 -3
- package/dist/types/shared.types.js +73 -2
- package/dist/webhooks.cjs +310 -0
- package/dist/webhooks.d.ts +171 -0
- package/dist/webhooks.js +310 -0
- package/package.json +26 -2
package/dist/client.cjs
CHANGED
|
@@ -1,59 +1,1175 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
+
const { HTTP, HTTP_DEFAULT_REQUEST_TIMEOUT_MS } = require("./http.js");
|
|
20
|
+
const { ENDPOINTS, ORCHESTRATOR_BASE_URL } = require("./endpoints.js");
|
|
21
|
+
const { Orchestrator } = require("./orchestrator.js");
|
|
22
|
+
const { resolvePredictionResourceUrl } = require("./prediction-urls.js");
|
|
23
|
+
const { Chat } = require("./chat.js");
|
|
24
|
+
const { Responses } = require("./responses.js");
|
|
25
|
+
const { Embeddings } = require("./embeddings.js");
|
|
26
|
+
const { Safety } = require("./safety.js");
|
|
27
|
+
const { PredictionStatus } = require("./types/index.js");
|
|
28
|
+
const { Webhook, createWebhookListener } = require("./webhooks.js");
|
|
29
|
+
const { SkytellsError } = require("./types/shared.types.js");
|
|
30
|
+
const DEFAULT_POLL_INTERVAL = 5000;
|
|
31
|
+
/**
|
|
32
|
+
* Time-to-live for in-memory cache of `GET /model/{slug}` responses used when
|
|
33
|
+
* a guarded predict/create/run uses `compatibilityCheck: true`. After this interval the next guarded request refetches the model.
|
|
34
|
+
*/
|
|
35
|
+
const PREFETCHED_MODEL_CACHE_TTL_MS = module.exports.PREFETCHED_MODEL_CACHE_TTL_MS = 10 * 60 * 1000;
|
|
36
|
+
/**
|
|
37
|
+
* Max distinct model slugs kept in the compatibility-check cache. Oldest entries are removed (FIFO) when exceeded.
|
|
38
|
+
* Prevents unbounded growth if callers use many unique `model` strings over time.
|
|
39
|
+
*/
|
|
40
|
+
const PREFETCHED_MODEL_CACHE_MAX_SLUGS = module.exports.PREFETCHED_MODEL_CACHE_MAX_SLUGS = 64;
|
|
41
|
+
/**
|
|
42
|
+
* Default request timeout when {@link ClientOptions.runtime} is `"edge"` and `timeout` is omitted
|
|
43
|
+
* (aligns with common ~25–30s serverless / edge ceilings).
|
|
44
|
+
*/
|
|
45
|
+
const EDGE_DEFAULT_REQUEST_TIMEOUT_MS = module.exports.EDGE_DEFAULT_REQUEST_TIMEOUT_MS = 25000;
|
|
46
|
+
/** Max model slugs in the inference-compat cache when `runtime` is `"edge"` (lower memory). */
|
|
47
|
+
const EDGE_PREFETCH_MAX_SLUGS = module.exports.EDGE_PREFETCH_MAX_SLUGS = 16;
|
|
48
|
+
let edgeRuntimeHintLogged = false;
|
|
49
|
+
let orchestratorKeyFormatWarned = false;
|
|
50
|
+
function logEdgeRuntimeHints(params) {
|
|
51
|
+
if (edgeRuntimeHintLogged) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
edgeRuntimeHintLogged = true;
|
|
55
|
+
const lines = [
|
|
56
|
+
'[skytells] ClientOptions.runtime "edge" — edge-oriented defaults and tips:',
|
|
57
|
+
` • Request timeout: ${params.requestTimeoutMs}ms${params.userSetTimeout
|
|
58
|
+
? ''
|
|
59
|
+
: ' (edge default when timeout omitted; pass timeout in options to override)'}.`,
|
|
60
|
+
` • Inference compat cache: max ${params.prefetchMaxSlugs} slug(s).`,
|
|
61
|
+
' • For wait()/run(…, onProgress): pass AbortSignal and maxWait to stay within wall-clock limits.',
|
|
62
|
+
' • Webhook HMAC: Web Crypto (crypto.subtle) only.',
|
|
63
|
+
];
|
|
64
|
+
if (params.retryRetries > 2) {
|
|
65
|
+
lines.push(` • retry.retries=${params.retryRetries} stacks delay on failures — keep low on edge.`);
|
|
66
|
+
}
|
|
67
|
+
if (params.userSetTimeout && params.requestTimeoutMs > 30000) {
|
|
68
|
+
lines.push(` • timeout ${params.requestTimeoutMs}ms may exceed typical edge limits (~25–30s); consider lowering.`);
|
|
69
|
+
}
|
|
70
|
+
console.warn(lines.join('\n'));
|
|
71
|
+
}
|
|
72
|
+
const DEPRECATED_PREDICTION_METHOD_HINTS = {
|
|
73
|
+
streamPrediction: 'Use prediction.stream() on the Prediction instance returned from client.run(), or pass prediction response urls when needed.',
|
|
74
|
+
cancelPrediction: 'Use prediction.cancel() on the Prediction from client.run().',
|
|
75
|
+
deletePrediction: 'Use prediction.delete() on the Prediction from client.run().',
|
|
76
|
+
};
|
|
77
|
+
function deprecateSkytellsClientPredictionMethod(name) {
|
|
78
|
+
console.warn(`[skytells] SkytellsClient.${name}() is deprecated and will be removed in a future major version. ${DEPRECATED_PREDICTION_METHOD_HINTS[name]}`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Terminal prediction statuses — polling stops when the prediction reaches one of these.
|
|
82
|
+
*/
|
|
83
|
+
const TERMINAL_STATUSES = new Set([
|
|
84
|
+
PredictionStatus.SUCCEEDED,
|
|
85
|
+
PredictionStatus.FAILED,
|
|
86
|
+
PredictionStatus.CANCELLED,
|
|
87
|
+
]);
|
|
88
|
+
/** JSON body for `POST /predict` — normalizes {@link Webhook} to plain `webhook`. */
|
|
89
|
+
function predictionBodyForHttp(payload, overrides) {
|
|
90
|
+
const { webhook, ...rest } = payload;
|
|
91
|
+
const webhookJson = webhook === undefined ? undefined : webhook instanceof Webhook ? webhook.toJSON() : webhook;
|
|
92
|
+
return {
|
|
93
|
+
...rest,
|
|
94
|
+
...(webhookJson ? { webhook: webhookJson } : {}),
|
|
95
|
+
...overrides,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Represents a completed prediction with convenience methods for accessing output
|
|
100
|
+
* and managing the prediction lifecycle (cancel, delete).
|
|
101
|
+
*
|
|
102
|
+
* Returned by {@link SkytellsClient.run}. Wraps a {@link PredictionResponse} and
|
|
103
|
+
* exposes `.output` to get results as a normalized `string[]`, plus `.cancel()`
|
|
104
|
+
* and `.delete()` for lifecycle management.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
|
|
109
|
+
* const [imageUrl] = prediction.output;
|
|
110
|
+
* console.log(prediction.id, prediction.status);
|
|
111
|
+
* const streamMeta = await prediction.stream(); // stream endpoint info (uses urls.stream)
|
|
112
|
+
* // Clean up when done
|
|
113
|
+
* await prediction.delete();
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export class Prediction {
|
|
117
|
+
/** @internal Use {@link SkytellsClient.run} to create a Prediction. */
|
|
118
|
+
constructor(http, data) {
|
|
119
|
+
this.http = http;
|
|
120
|
+
this.data = data;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The full prediction response object from the API.
|
|
124
|
+
* Contains all fields: status, id, input, output, metrics, metadata, urls, etc.
|
|
125
|
+
*/
|
|
126
|
+
get response() {
|
|
127
|
+
return this.data;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The unique prediction identifier.
|
|
131
|
+
* Use this to fetch, cancel, or delete the prediction later via the client.
|
|
132
|
+
*/
|
|
133
|
+
get id() {
|
|
134
|
+
return this.data.id;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The current status of the prediction.
|
|
138
|
+
* Possible values: `pending`, `starting`, `started`, `processing`, `succeeded`, `failed`, `cancelled`.
|
|
139
|
+
*/
|
|
140
|
+
get status() {
|
|
141
|
+
return this.data.status;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The raw prediction output as returned by the API.
|
|
145
|
+
*
|
|
146
|
+
* Can be a single `string`, a `string[]`, or `undefined` if incomplete.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* // Single output (string)
|
|
151
|
+
* console.log(prediction.output); // "https://..."
|
|
152
|
+
*
|
|
153
|
+
* // Multiple outputs (string[])
|
|
154
|
+
* console.log(prediction.output[0]); // "https://..."
|
|
155
|
+
*
|
|
156
|
+
* // Check type
|
|
157
|
+
* if (Array.isArray(prediction.output)) {
|
|
158
|
+
* for (const item of prediction.output) { console.log(item); }
|
|
159
|
+
* }
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
get output() {
|
|
163
|
+
return this.data.output;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns the output, normalized to a single value:
|
|
167
|
+
*
|
|
168
|
+
* - `undefined` / `null` → `undefined`
|
|
169
|
+
* - `"https://..."` → `"https://..."`
|
|
170
|
+
* - `["https://..."]` → `"https://..."` (single-element array unwrapped)
|
|
171
|
+
* - `["a", "b"]` → `["a", "b"]` (multi-element array kept as-is)
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const result = prediction.outputs();
|
|
176
|
+
* // string if single output, string[] if multiple, undefined if none
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
outputs() {
|
|
180
|
+
if (!this.data.output) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
if (typeof this.data.output === 'string') {
|
|
184
|
+
return this.data.output;
|
|
185
|
+
}
|
|
186
|
+
if (this.data.output.length === 1) {
|
|
187
|
+
return this.data.output[0];
|
|
188
|
+
}
|
|
189
|
+
return this.data.output;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Returns the full raw prediction response as a plain JSON object.
|
|
193
|
+
*
|
|
194
|
+
* @returns The raw `PredictionResponse` data from the API.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
|
|
199
|
+
* const json = prediction.raw();
|
|
200
|
+
* console.log(json.id, json.status, json.output, json.metrics);
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
raw() {
|
|
204
|
+
return this.data;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Fetches streaming metadata for this prediction (`GET` using `urls.stream` when present).
|
|
208
|
+
* Same behavior as the deprecated {@link SkytellsClient.streamPrediction} with this prediction’s id and urls.
|
|
209
|
+
*
|
|
210
|
+
* @returns The prediction response from the stream-info endpoint (includes `urls`, etc.).
|
|
211
|
+
*/
|
|
212
|
+
async stream() {
|
|
213
|
+
const url = resolvePredictionResourceUrl('stream', this.data.id, this.data.urls, this.http.getBaseUrl());
|
|
214
|
+
return this.http.request('GET', url);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Cancels this prediction. Only works if the prediction is still in progress
|
|
218
|
+
* (status is `pending`, `starting`, `started`, or `processing`).
|
|
219
|
+
*
|
|
220
|
+
* @returns The updated prediction response with `status: 'cancelled'`.
|
|
221
|
+
* @throws {SkytellsError} If the prediction cannot be cancelled or the request fails.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
|
|
226
|
+
* await prediction.cancel();
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
async cancel() {
|
|
230
|
+
const url = resolvePredictionResourceUrl('cancel', this.data.id, this.data.urls, this.http.getBaseUrl());
|
|
231
|
+
return this.http.request('POST', url);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Deletes this prediction and its associated output/assets from storage.
|
|
235
|
+
*
|
|
236
|
+
* @returns The prediction response confirming deletion.
|
|
237
|
+
* @throws {SkytellsError} If the prediction cannot be deleted or the request fails.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```ts
|
|
241
|
+
* const prediction = await client.run("flux-pro", { input: { prompt: "a cat" } });
|
|
242
|
+
* const [url] = prediction.output;
|
|
243
|
+
* // ... use the output ...
|
|
244
|
+
* await prediction.delete(); // clean up
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
async delete() {
|
|
248
|
+
const url = resolvePredictionResourceUrl('delete', this.data.id, this.data.urls, this.http.getBaseUrl());
|
|
249
|
+
return this.http.request('DELETE', url);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Sub-API for managing predictions. Accessible via `client.predictions`.
|
|
254
|
+
*
|
|
255
|
+
* Provides methods to create predictions in the background, fetch them by ID,
|
|
256
|
+
* and list them with filters.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* // Create a background prediction
|
|
261
|
+
* const prediction = await client.predictions.create({
|
|
262
|
+
* model: "flux-pro",
|
|
263
|
+
* input: { prompt: "A sunset" },
|
|
264
|
+
* });
|
|
265
|
+
*
|
|
266
|
+
* // Fetch it later
|
|
267
|
+
* const result = await client.predictions.get(prediction.id);
|
|
268
|
+
*
|
|
269
|
+
* // List recent predictions by model
|
|
270
|
+
* const { data } = await client.predictions.list({ model: "flux-pro", since: "2026-01-01" });
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export class PredictionsAPI {
|
|
274
|
+
/** @internal */
|
|
275
|
+
constructor(http, onBeforePredict) {
|
|
276
|
+
this.http = http;
|
|
277
|
+
this.onBeforePredict = onBeforePredict;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Creates a prediction in the background (does not wait for completion).
|
|
281
|
+
*
|
|
282
|
+
* The prediction starts processing asynchronously. Use {@link get} to poll,
|
|
283
|
+
* or {@link SkytellsClient.wait} to block until it finishes.
|
|
284
|
+
*
|
|
285
|
+
* @param payload - The prediction request parameters.
|
|
286
|
+
* @param payload.model - The model slug (e.g. `"flux-pro"`).
|
|
287
|
+
* @param payload.input - Key-value input parameters for the model.
|
|
288
|
+
* @param payload.webhook - Optional webhook to receive events.
|
|
289
|
+
* @param payload.stream - Enable streaming (default: `false`).
|
|
290
|
+
* @param sdk - SDK-only options (not sent in JSON). When `sdk.compatibilityCheck === true`, runs inference compatibility guard before POST.
|
|
291
|
+
* @returns The initial prediction response with `status: 'pending'` or `'starting'`.
|
|
292
|
+
* @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits).
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```ts
|
|
296
|
+
* const prediction = await client.predictions.create({
|
|
297
|
+
* model: "flux-pro",
|
|
298
|
+
* input: { prompt: "An astronaut riding a unicorn" },
|
|
299
|
+
* });
|
|
300
|
+
* console.log(prediction.id, prediction.status); // "pending"
|
|
301
|
+
*
|
|
302
|
+
* // Wait for it to finish
|
|
303
|
+
* const result = await client.wait(prediction);
|
|
304
|
+
* console.log(result.output);
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
async create(payload, sdk) {
|
|
308
|
+
if (this.onBeforePredict) {
|
|
309
|
+
await this.onBeforePredict(payload, sdk);
|
|
310
|
+
}
|
|
311
|
+
return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload, { await: false }));
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Fetches a prediction by its ID.
|
|
315
|
+
*
|
|
316
|
+
* @param id - The prediction ID.
|
|
317
|
+
* @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}`.
|
|
318
|
+
* @returns The prediction response with current status, output, metrics, etc.
|
|
319
|
+
* @throws {SkytellsError} If the prediction is not found or the request fails.
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```ts
|
|
323
|
+
* const prediction = await client.predictions.get("pred_abc123");
|
|
324
|
+
* if (prediction.status === "succeeded") {
|
|
325
|
+
* console.log(prediction.output);
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
async get(id, urls) {
|
|
330
|
+
const url = resolvePredictionResourceUrl('get', id, urls, this.http.getBaseUrl());
|
|
331
|
+
return this.http.request('GET', url);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Lists predictions with optional filters and pagination.
|
|
335
|
+
*
|
|
336
|
+
* @param options - Filter and pagination options.
|
|
337
|
+
* @param options.page - Page number (default: 1).
|
|
338
|
+
* @param options.since - Only include predictions created on or after this date (`YYYY-MM-DD`).
|
|
339
|
+
* @param options.until - Only include predictions created on or before this date (`YYYY-MM-DD`).
|
|
340
|
+
* @param options.model - Filter by model slug.
|
|
341
|
+
* @returns A paginated response with `data` (predictions array) and `pagination` metadata.
|
|
342
|
+
* @throws {SkytellsError} On authentication failure or invalid parameters.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* // List all predictions
|
|
347
|
+
* const { data, pagination } = await client.predictions.list();
|
|
348
|
+
*
|
|
349
|
+
* // Filter by model and date range
|
|
350
|
+
* const filtered = await client.predictions.list({
|
|
351
|
+
* model: "flux-pro",
|
|
352
|
+
* since: "2026-01-01",
|
|
353
|
+
* until: "2026-03-15",
|
|
354
|
+
* page: 2,
|
|
355
|
+
* });
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
async list(options) {
|
|
359
|
+
const params = new URLSearchParams();
|
|
360
|
+
if (options === null || options === void 0 ? void 0 : options.page) {
|
|
361
|
+
params.set('page', String(options.page));
|
|
362
|
+
}
|
|
363
|
+
if (options === null || options === void 0 ? void 0 : options.since) {
|
|
364
|
+
params.set('from', options.since);
|
|
365
|
+
}
|
|
366
|
+
if (options === null || options === void 0 ? void 0 : options.until) {
|
|
367
|
+
params.set('to', options.until);
|
|
368
|
+
}
|
|
369
|
+
if (options === null || options === void 0 ? void 0 : options.model) {
|
|
370
|
+
params.set('model', options.model);
|
|
371
|
+
}
|
|
372
|
+
const query = params.toString();
|
|
373
|
+
const path = query ? `${ENDPOINTS.PREDICTIONS}?${query}` : ENDPOINTS.PREDICTIONS;
|
|
374
|
+
return this.http.request('GET', path);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Sub-API for browsing and fetching models. Accessible via `client.models`.
|
|
379
|
+
*
|
|
380
|
+
* Provides `.list()` to get all models and `.get()` to fetch a single model by slug.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```ts
|
|
384
|
+
* const allModels = await client.models.list();
|
|
385
|
+
* const model = await client.models.get("flux-pro", { fields: ["input_schema"] });
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
export class ModelsAPI {
|
|
389
|
+
/** @internal */
|
|
390
|
+
constructor(http) {
|
|
391
|
+
this.http = http;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Lists all available models on the Skytells platform.
|
|
395
|
+
*
|
|
396
|
+
* @param options - Optional configuration.
|
|
397
|
+
* @param options.fields - Additional fields to include in the response
|
|
398
|
+
* (e.g. `["input_schema", "output_schema"]`). By default, schemas are not included.
|
|
399
|
+
* @returns An array of model objects with name, type, pricing, metadata, etc.
|
|
400
|
+
* @throws {SkytellsError} On authentication failure or server error.
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```ts
|
|
404
|
+
* const allModels = await client.models.list();
|
|
405
|
+
* for (const m of allModels) {
|
|
406
|
+
* console.log(m.name, m.type);
|
|
407
|
+
* }
|
|
408
|
+
*
|
|
409
|
+
* // Include input schemas
|
|
410
|
+
* const withSchemas = await client.models.list({ fields: ["input_schema"] });
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
async list(options) {
|
|
414
|
+
var _a;
|
|
415
|
+
let path = ENDPOINTS.MODELS;
|
|
416
|
+
if ((_a = options === null || options === void 0 ? void 0 : options.fields) === null || _a === void 0 ? void 0 : _a.length) {
|
|
417
|
+
path += `?fields=${options.fields.join(',')}`;
|
|
418
|
+
}
|
|
419
|
+
return this.http.request('GET', path);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Fetches a single model by its slug.
|
|
423
|
+
*
|
|
424
|
+
* @param slug - The model slug identifier (e.g. `"flux-pro"`, `"truefusion"`, `"beatfusion"`).
|
|
425
|
+
* @param options - Optional configuration.
|
|
426
|
+
* @param options.fields - Additional fields to include (e.g. `["input_schema", "output_schema"]`).
|
|
427
|
+
* @returns The model object with name, type, pricing, metadata, and optionally schemas.
|
|
428
|
+
* @throws {SkytellsError} If the model is not found (`MODEL_NOT_FOUND`) or the request fails.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* const model = await client.models.get("flux-pro");
|
|
433
|
+
* console.log(model.name, model.pricing);
|
|
434
|
+
*
|
|
435
|
+
* // With schemas
|
|
436
|
+
* const detailed = await client.models.get("flux-pro", {
|
|
437
|
+
* fields: ["input_schema", "output_schema"],
|
|
438
|
+
* });
|
|
439
|
+
* console.log(detailed.input_schema);
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
442
|
+
async get(slug, options) {
|
|
443
|
+
var _a;
|
|
444
|
+
let path = ENDPOINTS.MODEL_BY_SLUG(slug);
|
|
445
|
+
if ((_a = options === null || options === void 0 ? void 0 : options.fields) === null || _a === void 0 ? void 0 : _a.length) {
|
|
446
|
+
path += `?fields=${options.fields.join(',')}`;
|
|
447
|
+
}
|
|
448
|
+
return this.http.request('GET', path);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* The main Skytells API client. Provides methods to run predictions, list models,
|
|
453
|
+
* and manage prediction lifecycle.
|
|
454
|
+
*
|
|
455
|
+
* Create an instance using {@link Skytells} or the constructor directly.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```ts
|
|
459
|
+
* const Skytells = require("skytells");
|
|
460
|
+
*
|
|
461
|
+
* const client = Skytells("sk-your-api-key", {
|
|
462
|
+
* timeout: 30000,
|
|
463
|
+
* retry: { retries: 2 },
|
|
464
|
+
* });
|
|
465
|
+
*
|
|
466
|
+
* // Run a model and get output
|
|
467
|
+
* const prediction = await client.run("flux-pro", {
|
|
468
|
+
* input: { prompt: "An astronaut riding a unicorn" },
|
|
469
|
+
* });
|
|
470
|
+
* const [imageUrl] = prediction.output;
|
|
471
|
+
*
|
|
472
|
+
* // List and fetch models
|
|
473
|
+
* const allModels = await client.models.list();
|
|
474
|
+
* const model = await client.models.get("flux-pro");
|
|
475
|
+
*
|
|
476
|
+
* // Background prediction
|
|
477
|
+
* const bg = await client.predictions.create({
|
|
478
|
+
* model: "flux-pro",
|
|
479
|
+
* input: { prompt: "A sunset" },
|
|
480
|
+
* });
|
|
481
|
+
* const result = await client.wait(bg);
|
|
482
|
+
*
|
|
483
|
+
* // Queue multiple predictions
|
|
484
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
|
|
485
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
|
|
486
|
+
* const results = await client.dispatch();
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
3
489
|
export class SkytellsClient {
|
|
4
490
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
491
|
+
* Sub-API for managing predictions.
|
|
492
|
+
* Provides `.create()`, `.get()`, and `.list()` methods.
|
|
493
|
+
*/
|
|
494
|
+
get predictions() {
|
|
495
|
+
if (!this._predictions) {
|
|
496
|
+
this._predictions = new PredictionsAPI(this.http, (p, sdk) => this._maybeCompatibilityGuard(p.model, sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck));
|
|
497
|
+
}
|
|
498
|
+
return this._predictions;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Alias of {@link predictions} (singular). Same instance — use whichever reads best.
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```ts
|
|
505
|
+
* await client.prediction.create({ model: 'flux-pro', input: { prompt: '…' } });
|
|
506
|
+
* // same as client.predictions.create(...)
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
get prediction() {
|
|
510
|
+
return this.predictions;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Sub-API for browsing and fetching models.
|
|
514
|
+
* Provides `.list()` and `.get()` methods.
|
|
515
|
+
*/
|
|
516
|
+
get models() {
|
|
517
|
+
if (!this._models) {
|
|
518
|
+
this._models = new ModelsAPI(this.http);
|
|
519
|
+
}
|
|
520
|
+
return this._models;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Chat completions. Same as OpenAI's client.chat.completions.
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```ts
|
|
527
|
+
* const completion = await client.chat.completions.create({
|
|
528
|
+
* model: 'deepbrain-router',
|
|
529
|
+
* messages: [{ role: 'user', content: 'Hello' }],
|
|
530
|
+
* });
|
|
531
|
+
* ```
|
|
532
|
+
*/
|
|
533
|
+
get chat() {
|
|
534
|
+
if (!this._chat) {
|
|
535
|
+
this._chat = new Chat(this.http);
|
|
536
|
+
}
|
|
537
|
+
return this._chat;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Responses API (`POST /v1/responses`). Same as `client.chat.responses`.
|
|
541
|
+
*
|
|
542
|
+
* Follows the OpenAI Responses API schema. Supports both non-streaming and streaming modes.
|
|
543
|
+
*
|
|
544
|
+
* @example Non-streaming:
|
|
545
|
+
* ```ts
|
|
546
|
+
* const response = await client.responses.create({
|
|
547
|
+
* model: 'gpt-5.3-codex',
|
|
548
|
+
* input: [{ role: 'user', content: 'Explain recursion simply.' }],
|
|
549
|
+
* instructions: 'You are a helpful tutor.',
|
|
550
|
+
* });
|
|
551
|
+
* console.log(response.output[0].content[0].text);
|
|
552
|
+
* ```
|
|
553
|
+
*
|
|
554
|
+
* @example Streaming:
|
|
555
|
+
* ```ts
|
|
556
|
+
* const stream = await client.responses.create({
|
|
557
|
+
* model: 'gpt-5.3-codex',
|
|
558
|
+
* input: [{ role: 'user', content: 'Explain recursion simply.' }],
|
|
559
|
+
* stream: true,
|
|
560
|
+
* });
|
|
561
|
+
* for await (const event of stream) {
|
|
562
|
+
* console.log(event.type, event);
|
|
563
|
+
* }
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
get responses() {
|
|
567
|
+
if (!this._responses) {
|
|
568
|
+
this._responses = new Responses(this.http);
|
|
569
|
+
}
|
|
570
|
+
return this._responses;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Embeddings. Same as OpenAI's client.embeddings.
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```ts
|
|
577
|
+
* const embedding = await client.embeddings.create({
|
|
578
|
+
* model: 'text-embedding-3-small',
|
|
579
|
+
* input: 'Hello world',
|
|
580
|
+
* });
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
get embeddings() {
|
|
584
|
+
if (!this._embeddings) {
|
|
585
|
+
this._embeddings = new Embeddings(this.http);
|
|
586
|
+
}
|
|
587
|
+
return this._embeddings;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Safety checks. Proactive (checkText, checkImage) and response parsing (wasFiltered, evaluate).
|
|
591
|
+
* evaluate() accepts text, image URLs, choices, completions, prediction results, or arrays of any.
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```ts
|
|
595
|
+
* const result = await client.safety.checkText('user input');
|
|
596
|
+
* if (client.safety.wasFiltered(completion)) { ... }
|
|
597
|
+
* const evalResult = await client.safety.evaluate('user text', SafetyTemplates.STRICT);
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
get safety() {
|
|
601
|
+
if (!this._safety) {
|
|
602
|
+
this._safety = new Safety(this.http);
|
|
603
|
+
}
|
|
604
|
+
return this._safety;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* [Skytells Orchestrator](https://learn.skytells.ai/docs/products/orchestrator/api-reference) — workflows,
|
|
608
|
+
* executions, webhook triggers, integrations, etc.
|
|
609
|
+
*
|
|
610
|
+
* Requires **`ClientOptions.orchestratorApiKey`** (`wfb_…`). Uses an internal HTTP stack aimed at the Orchestrator
|
|
611
|
+
* host ({@link ORCHESTRATOR_BASE_URL}): Bearer only, no `x-api-key`. Same `timeout`, `headers`, `retry`, and
|
|
612
|
+
* `fetch` as the main Skytells client — pass both keys on one {@link SkytellsClient} when you need both products.
|
|
613
|
+
*
|
|
614
|
+
* @throws {SkytellsError} `SDK_ERROR` if `orchestratorApiKey` was not set.
|
|
615
|
+
*/
|
|
616
|
+
get orchestrator() {
|
|
617
|
+
if (!this._orchestratorApiKey) {
|
|
618
|
+
throw new SkytellsError('client.orchestrator requires ClientOptions.orchestratorApiKey (Orchestrator wfb_… key). It is not your Skytells sk-… platform key.', 'SDK_ERROR', 'https://learn.skytells.ai/docs/products/orchestrator/api-keys', 0);
|
|
619
|
+
}
|
|
620
|
+
if (!this._orchestrator) {
|
|
621
|
+
const b = this._orchestratorHttpBundle;
|
|
622
|
+
this._orchestrator = new Orchestrator(new HTTP(this._orchestratorApiKey, this._orchestratorBaseUrl, b.timeout, b.headers, b.retry, b.fetch, 'orchestrator'));
|
|
623
|
+
}
|
|
624
|
+
return this._orchestrator;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Target runtime from {@link ClientOptions.runtime} (`"default"` when omitted).
|
|
628
|
+
*/
|
|
629
|
+
get runtime() {
|
|
630
|
+
return this._runtime;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Read-only resolved settings (timeouts, cache cap) for debugging and tests.
|
|
634
|
+
*/
|
|
635
|
+
get config() {
|
|
636
|
+
return {
|
|
637
|
+
runtime: this._runtime,
|
|
638
|
+
requestTimeoutMs: this._requestTimeoutMs,
|
|
639
|
+
prefetchMaxSlugs: this._prefetchCap,
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Creates a new Skytells API client.
|
|
644
|
+
*
|
|
645
|
+
* @param apiKey - Your Skytells API key (starts with `sk-`). Required for authenticated endpoints.
|
|
646
|
+
* @param options - Client configuration options.
|
|
647
|
+
* @param options.baseUrl - Override the default API base URL.
|
|
648
|
+
* @param options.timeout - Request timeout in milliseconds (default: 60000, or 25000 when `runtime: "edge"` and omitted).
|
|
649
|
+
* @param options.headers - Custom headers to include in every request.
|
|
650
|
+
* @param options.retry - Retry configuration: `retries`, `retryDelay`, `retryOn` status codes.
|
|
651
|
+
* @param options.fetch - Custom `fetch` implementation (useful for testing, proxying, or
|
|
652
|
+
* disabling Next.js fetch caching).
|
|
653
|
+
* @param options.runtime - `"edge"` for Workers / Vercel Edge / etc.: shorter default timeout, smaller compat cache, one-time hints.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```ts
|
|
657
|
+
* const client = new SkytellsClient("sk-your-api-key");
|
|
658
|
+
*
|
|
659
|
+
* // With options:
|
|
660
|
+
* const client = new SkytellsClient("sk-your-api-key", {
|
|
661
|
+
* timeout: 30000,
|
|
662
|
+
* retry: { retries: 3, retryDelay: 1000 },
|
|
663
|
+
* headers: { "X-Custom-Header": "value" },
|
|
664
|
+
* });
|
|
665
|
+
*
|
|
666
|
+
* // Next.js App Router — disable fetch caching:
|
|
667
|
+
* const client = new SkytellsClient("sk-your-api-key", {
|
|
668
|
+
* fetch: (url, opts) => fetch(url, { ...opts, cache: "no-store" }),
|
|
669
|
+
* });
|
|
670
|
+
*
|
|
671
|
+
* // Edge / serverless:
|
|
672
|
+
* const edge = new SkytellsClient("sk-…", { runtime: "edge" });
|
|
673
|
+
*
|
|
674
|
+
* // Skytells + Orchestrator (optional wfb_… key — same client):
|
|
675
|
+
* const both = new SkytellsClient("sk-…", { orchestratorApiKey: "wfb_…" });
|
|
676
|
+
* ```
|
|
8
677
|
*/
|
|
9
678
|
constructor(apiKey, options = {}) {
|
|
10
|
-
|
|
679
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
680
|
+
this._queue = [];
|
|
681
|
+
/**
|
|
682
|
+
* In-memory `GET /model/{slug}` results for the per-prediction guard. Lazy-allocated; bounded by
|
|
683
|
+
* {@link SkytellsClient.config | config.prefetchMaxSlugs} and TTL {@link PREFETCHED_MODEL_CACHE_TTL_MS}.
|
|
684
|
+
*/
|
|
685
|
+
this._prefetchedModelCache = null;
|
|
686
|
+
const runtime = (_a = options.runtime) !== null && _a !== void 0 ? _a : 'default';
|
|
687
|
+
const isEdge = runtime === 'edge';
|
|
688
|
+
const userSetTimeout = options.timeout !== undefined;
|
|
689
|
+
const requestTimeoutMs = userSetTimeout
|
|
690
|
+
? options.timeout
|
|
691
|
+
: isEdge
|
|
692
|
+
? EDGE_DEFAULT_REQUEST_TIMEOUT_MS
|
|
693
|
+
: HTTP_DEFAULT_REQUEST_TIMEOUT_MS;
|
|
694
|
+
const prefetchCap = isEdge ? EDGE_PREFETCH_MAX_SLUGS : PREFETCHED_MODEL_CACHE_MAX_SLUGS;
|
|
695
|
+
this._runtime = runtime;
|
|
696
|
+
this._requestTimeoutMs = requestTimeoutMs;
|
|
697
|
+
this._prefetchCap = prefetchCap;
|
|
698
|
+
if (isEdge) {
|
|
699
|
+
logEdgeRuntimeHints({
|
|
700
|
+
requestTimeoutMs,
|
|
701
|
+
retryRetries: (_c = (_b = options.retry) === null || _b === void 0 ? void 0 : _b.retries) !== null && _c !== void 0 ? _c : 0,
|
|
702
|
+
userSetTimeout,
|
|
703
|
+
prefetchMaxSlugs: prefetchCap,
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
this.http = new HTTP(apiKey, options.baseUrl, requestTimeoutMs, options.headers, options.retry, options.fetch);
|
|
707
|
+
this._orchestratorApiKey = ((_d = options.orchestratorApiKey) === null || _d === void 0 ? void 0 : _d.trim()) || undefined;
|
|
708
|
+
if (this._orchestratorApiKey && !this._orchestratorApiKey.startsWith('wfb_')) {
|
|
709
|
+
if (!orchestratorKeyFormatWarned) {
|
|
710
|
+
orchestratorKeyFormatWarned = true;
|
|
711
|
+
console.warn('[skytells] orchestratorApiKey normally starts with "wfb_" (Orchestrator webhook key, separate from sk-…). See https://learn.skytells.ai/docs/products/orchestrator/api-keys');
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
this._orchestratorBaseUrl = ((_e = options.orchestratorBaseUrl) === null || _e === void 0 ? void 0 : _e.trim()) || ORCHESTRATOR_BASE_URL;
|
|
715
|
+
this._orchestratorHttpBundle = {
|
|
716
|
+
timeout: requestTimeoutMs,
|
|
717
|
+
headers: (_f = options.headers) !== null && _f !== void 0 ? _f : {},
|
|
718
|
+
retry: (_g = options.retry) !== null && _g !== void 0 ? _g : {},
|
|
719
|
+
fetch: options.fetch,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Build a {@link WebhookListener} for your HTTP server. Verifies `X-Skytells-Signature` per
|
|
724
|
+
* [Skytells webhooks](https://docs.skytells.ai/webhooks/).
|
|
725
|
+
*
|
|
726
|
+
* - **`mode: 'general'`** (default): HMAC key is your API key — omitted `apiKey` uses this client’s key.
|
|
727
|
+
* - **`mode: 'enterprise'`**: pass `secret` from the dashboard.
|
|
728
|
+
*
|
|
729
|
+
* @example
|
|
730
|
+
* ```ts
|
|
731
|
+
* const hooks = client.webhookListener({ mode: 'general' });
|
|
732
|
+
* hooks.on(WebhookEvent.COMPLETED, async (p) => console.log(p.id));
|
|
733
|
+
* // Next.js: export async function POST(req: Request) { return hooks.handleRequest(req); }
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
webhookListener(options = {}) {
|
|
737
|
+
var _a;
|
|
738
|
+
const apiKey = (_a = options.apiKey) !== null && _a !== void 0 ? _a : this.http.getApiKey();
|
|
739
|
+
return createWebhookListener({ ...options, apiKey });
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Alias of {@link SkytellsClient.webhookListener}. Chain handlers: `client.listen().on(WebhookEvent.COMPLETED, fn)`.
|
|
743
|
+
*/
|
|
744
|
+
listen(options) {
|
|
745
|
+
return this.webhookListener(options);
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Clears cached model metadata used when guarded predict/create/run passes `compatibilityCheck: true`.
|
|
749
|
+
*
|
|
750
|
+
* @param modelSlug - If set, only evicts that slug; otherwise clears the entire cache.
|
|
751
|
+
*
|
|
752
|
+
* @example
|
|
753
|
+
* ```ts
|
|
754
|
+
* // After a model was updated server-side, force the next predict to refetch metadata:
|
|
755
|
+
* client.purgePrefetchedModelCache("flux-pro");
|
|
756
|
+
*
|
|
757
|
+
* // Clear all cached slugs
|
|
758
|
+
* client.purgePrefetchedModelCache();
|
|
759
|
+
* ```
|
|
760
|
+
*/
|
|
761
|
+
purgePrefetchedModelCache(modelSlug) {
|
|
762
|
+
const cache = this._prefetchedModelCache;
|
|
763
|
+
if (!cache) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
if (modelSlug !== undefined) {
|
|
767
|
+
cache.delete(modelSlug);
|
|
768
|
+
if (cache.size === 0) {
|
|
769
|
+
this._prefetchedModelCache = null;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
this._prefetchedModelCache = null;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Returns model metadata for the inference compatibility check, using {@link _prefetchedModelCache} when fresh.
|
|
778
|
+
*/
|
|
779
|
+
async _getModelForCompatibilityCheck(slug) {
|
|
780
|
+
const now = Date.now();
|
|
781
|
+
if (!this._prefetchedModelCache) {
|
|
782
|
+
this._prefetchedModelCache = new Map();
|
|
783
|
+
}
|
|
784
|
+
const cache = this._prefetchedModelCache;
|
|
785
|
+
const cached = cache.get(slug);
|
|
786
|
+
if (cached && cached.expiresAt > now) {
|
|
787
|
+
// Move to end of Map iteration order so FIFO eviction keeps recently used slugs.
|
|
788
|
+
cache.delete(slug);
|
|
789
|
+
cache.set(slug, cached);
|
|
790
|
+
return cached.model;
|
|
791
|
+
}
|
|
792
|
+
if (cached) {
|
|
793
|
+
cache.delete(slug);
|
|
794
|
+
}
|
|
795
|
+
const model = await this.models.get(slug);
|
|
796
|
+
cache.set(slug, {
|
|
797
|
+
model,
|
|
798
|
+
expiresAt: now + PREFETCHED_MODEL_CACHE_TTL_MS,
|
|
799
|
+
});
|
|
800
|
+
while (cache.size > this._prefetchCap) {
|
|
801
|
+
const oldest = cache.keys().next().value;
|
|
802
|
+
if (oldest === undefined) {
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
cache.delete(oldest);
|
|
806
|
+
}
|
|
807
|
+
return model;
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* @internal When `compatibilityCheck === true`, throws SDK_ERROR if the model is chat-only here.
|
|
811
|
+
*/
|
|
812
|
+
async _maybeCompatibilityGuard(modelSlug, compatibilityCheck) {
|
|
813
|
+
var _a;
|
|
814
|
+
if (compatibilityCheck !== true) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
try {
|
|
818
|
+
const modelData = await this._getModelForCompatibilityCheck(modelSlug);
|
|
819
|
+
if ((_a = modelData.metadata) === null || _a === void 0 ? void 0 : _a.openai_compatible) {
|
|
820
|
+
throw new SkytellsError(`This model supports the OpenAI Chat Completions API. Did you mean client.chat.completions.create()? Use it for chat-style inference.`, 'SDK_ERROR', `Model "${modelData.namespace}" is OpenAI-compatible. Use client.chat.completions.create() instead of predict() or run().`, 0);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
catch (e) {
|
|
824
|
+
if (e instanceof SkytellsError && e.errorId === 'SDK_ERROR') {
|
|
825
|
+
throw e;
|
|
826
|
+
}
|
|
827
|
+
// If model fetch fails (e.g. MODEL_NOT_FOUND), let the predict request proceed
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Sends a prediction request to the Skytells API.
|
|
832
|
+
*
|
|
833
|
+
* This is the low-level prediction method. For most use cases, prefer {@link run}
|
|
834
|
+
* which waits for completion and returns a {@link Prediction} object with convenience methods.
|
|
835
|
+
*
|
|
836
|
+
* @param payload - The prediction request parameters.
|
|
837
|
+
* @param payload.model - The model slug to run (e.g. `"flux-pro"`, `"truefusion"`).
|
|
838
|
+
* @param payload.input - Key-value input parameters for the model (e.g. `{ prompt: "..." }`).
|
|
839
|
+
* @param payload.await - If `true`, the request blocks until the prediction completes (default: `false`).
|
|
840
|
+
* @param payload.stream - If `true`, enables streaming for the prediction (default: `false`).
|
|
841
|
+
* @param payload.webhook - Optional webhook configuration to receive prediction events.
|
|
842
|
+
* @param sdk - SDK-only options (not sent in JSON). When `sdk.compatibilityCheck === true`, runs inference compatibility guard before POST.
|
|
843
|
+
* @returns The prediction response object.
|
|
844
|
+
* @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits, etc.).
|
|
845
|
+
*
|
|
846
|
+
* @example
|
|
847
|
+
* ```ts
|
|
848
|
+
* // Fire-and-forget (returns immediately with status: "pending")
|
|
849
|
+
* const response = await client.predict({
|
|
850
|
+
* model: "flux-pro",
|
|
851
|
+
* input: { prompt: "A sunset over mountains" },
|
|
852
|
+
* });
|
|
853
|
+
* console.log(response.id); // use predictions.get(id) to poll
|
|
854
|
+
*
|
|
855
|
+
* // Wait for completion
|
|
856
|
+
* const result = await client.predict({
|
|
857
|
+
* model: "flux-pro",
|
|
858
|
+
* input: { prompt: "A sunset over mountains" },
|
|
859
|
+
* await: true,
|
|
860
|
+
* });
|
|
861
|
+
* console.log(result.output); // ["https://..."]
|
|
862
|
+
* ```
|
|
863
|
+
*/
|
|
864
|
+
async predict(payload, sdk) {
|
|
865
|
+
await this._maybeCompatibilityGuard(payload.model, sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck);
|
|
866
|
+
return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload));
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Runs a model, waits for completion, and returns a {@link Prediction} object.
|
|
870
|
+
*
|
|
871
|
+
* This is the recommended way to generate content. It automatically sets `await: true`,
|
|
872
|
+
* checks for failures, and returns a `Prediction` with `.output`, `.cancel()`, and `.delete()`.
|
|
873
|
+
*
|
|
874
|
+
* If an `onProgress` callback is provided, the prediction is created in the background
|
|
875
|
+
* and polled every 5 seconds. The callback is invoked on each poll with the latest
|
|
876
|
+
* prediction state, allowing you to track progress.
|
|
877
|
+
*
|
|
878
|
+
* @param model - The model slug to run (e.g. `"flux-pro"`, `"truefusion"`, `"beatfusion"`).
|
|
879
|
+
* @param options - Run options.
|
|
880
|
+
* @param options.input - Key-value input parameters for the model.
|
|
881
|
+
* @param options.stream - If `true`, enables streaming (default: `false`).
|
|
882
|
+
* @param options.webhook - Optional webhook configuration.
|
|
883
|
+
* @param onProgress - Optional callback invoked on each poll with the current prediction state.
|
|
884
|
+
* @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 })`).
|
|
885
|
+
* @remarks With `onProgress`, uses `predictions.create` + {@link wait}. Then {@link RunOptions.interval},
|
|
886
|
+
* {@link RunOptions.maxWait}, and {@link RunOptions.signal} apply (same as {@link WaitOptions}).
|
|
887
|
+
* @returns A {@link Prediction} object with output and lifecycle methods.
|
|
888
|
+
* @throws {SkytellsError} On API errors or if the prediction fails (`PREDICTION_FAILED`).
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* ```ts
|
|
892
|
+
* // Simple run (blocks until complete)
|
|
893
|
+
* const prediction = await client.run("flux-pro", {
|
|
894
|
+
* input: { prompt: "An astronaut riding a rainbow unicorn" },
|
|
895
|
+
* });
|
|
896
|
+
* const [imageUrl] = prediction.output;
|
|
897
|
+
*
|
|
898
|
+
* // With progress tracking
|
|
899
|
+
* const prediction = await client.run("flux-pro", {
|
|
900
|
+
* input: { prompt: "An astronaut riding a unicorn" },
|
|
901
|
+
* }, (p) => {
|
|
902
|
+
* // Note: metrics.progress may not be available during early processing stages
|
|
903
|
+
* console.log(`Status: ${p.status}, Progress: ${p.metrics?.progress ?? 'n/a'}`);
|
|
904
|
+
* });
|
|
905
|
+
* ```
|
|
906
|
+
*/
|
|
907
|
+
async run(model, options, onProgress, sdk) {
|
|
908
|
+
const { input, webhook, stream, interval, maxWait, signal } = options;
|
|
909
|
+
const predictionBody = { input, webhook, stream };
|
|
910
|
+
let data;
|
|
911
|
+
if (onProgress) {
|
|
912
|
+
data = await this.predictions.create({ model, ...predictionBody }, sdk);
|
|
913
|
+
data = await this.wait(data, { interval, maxWait, signal }, onProgress);
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
data = await this.predict({ model, ...predictionBody, await: true }, sdk);
|
|
917
|
+
}
|
|
918
|
+
if (data.status === PredictionStatus.FAILED) {
|
|
919
|
+
throw new SkytellsError(data.response || 'Prediction failed', 'PREDICTION_FAILED', `Prediction ${data.id} failed`);
|
|
920
|
+
}
|
|
921
|
+
return new Prediction(this.http, data);
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Polls a prediction until it reaches a terminal status (`succeeded`, `failed`, or `cancelled`).
|
|
925
|
+
*
|
|
926
|
+
* @param prediction - The prediction response to wait on (must have an `id`).
|
|
927
|
+
* @param options - Polling options.
|
|
928
|
+
* @param options.interval - Polling interval in milliseconds (default: 5000).
|
|
929
|
+
* @param options.maxWait - Maximum wait time in milliseconds. Throws if exceeded.
|
|
930
|
+
* @param options.signal - If aborted, stops polling and throws `ABORTED` (no further poll timers scheduled).
|
|
931
|
+
* @param onProgress - Optional callback invoked on each poll with the latest prediction state.
|
|
932
|
+
* @returns The final prediction response.
|
|
933
|
+
* @throws {SkytellsError} If `maxWait` is exceeded (`WAIT_TIMEOUT`) or `signal` is aborted (`ABORTED`).
|
|
934
|
+
*
|
|
935
|
+
* @example
|
|
936
|
+
* ```ts
|
|
937
|
+
* const bg = await client.predictions.create({
|
|
938
|
+
* model: "flux-pro",
|
|
939
|
+
* input: { prompt: "A cat" },
|
|
940
|
+
* });
|
|
941
|
+
*
|
|
942
|
+
* const result = await client.wait(bg);
|
|
943
|
+
* console.log(result.output);
|
|
944
|
+
*
|
|
945
|
+
* // With progress and timeout
|
|
946
|
+
* const result = await client.wait(bg, { interval: 2000, maxWait: 120000 }, (p) => {
|
|
947
|
+
* console.log(p.status, p.metrics?.progress);
|
|
948
|
+
* });
|
|
949
|
+
* ```
|
|
950
|
+
*/
|
|
951
|
+
async wait(prediction, options, onProgress) {
|
|
952
|
+
var _a;
|
|
953
|
+
const id = prediction === null || prediction === void 0 ? void 0 : prediction.id;
|
|
954
|
+
if (id == null || id === '') {
|
|
955
|
+
throw new SkytellsError('Cannot wait on a prediction without an id', 'SDK_ERROR', 'PredictionResponse.id is required for polling', 0);
|
|
956
|
+
}
|
|
957
|
+
const rawInterval = (_a = options === null || options === void 0 ? void 0 : options.interval) !== null && _a !== void 0 ? _a : DEFAULT_POLL_INTERVAL;
|
|
958
|
+
const interval = typeof rawInterval === 'number' && Number.isFinite(rawInterval) && rawInterval >= 0
|
|
959
|
+
? rawInterval
|
|
960
|
+
: DEFAULT_POLL_INTERVAL;
|
|
961
|
+
const rawMax = options === null || options === void 0 ? void 0 : options.maxWait;
|
|
962
|
+
const maxWaitMs = typeof rawMax === 'number' && Number.isFinite(rawMax) && rawMax >= 0 ? rawMax : undefined;
|
|
963
|
+
const signal = options === null || options === void 0 ? void 0 : options.signal;
|
|
964
|
+
const startTime = Date.now();
|
|
965
|
+
const deadline = typeof maxWaitMs === 'number' ? startTime + maxWaitMs : null;
|
|
966
|
+
let current = prediction;
|
|
967
|
+
if (TERMINAL_STATUSES.has(current.status)) {
|
|
968
|
+
return current;
|
|
969
|
+
}
|
|
970
|
+
let firstPoll = true;
|
|
971
|
+
while (!TERMINAL_STATUSES.has(current.status)) {
|
|
972
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
973
|
+
throw SkytellsClient.abortWaitError();
|
|
974
|
+
}
|
|
975
|
+
const now = Date.now();
|
|
976
|
+
if (deadline !== null && now >= deadline) {
|
|
977
|
+
throw new SkytellsError(`Prediction ${current.id} did not complete within ${maxWaitMs}ms`, 'WAIT_TIMEOUT', `Timed out after ${maxWaitMs}ms. Last status: ${current.status}`, 408);
|
|
978
|
+
}
|
|
979
|
+
if (!firstPoll) {
|
|
980
|
+
const remaining = deadline !== null ? deadline - Date.now() : interval;
|
|
981
|
+
if (deadline !== null && remaining <= 0) {
|
|
982
|
+
throw new SkytellsError(`Prediction ${current.id} did not complete within ${maxWaitMs}ms`, 'WAIT_TIMEOUT', `Timed out after ${maxWaitMs}ms. Last status: ${current.status}`, 408);
|
|
983
|
+
}
|
|
984
|
+
const sleepMs = Math.min(interval, Math.max(0, remaining));
|
|
985
|
+
await this.delay(sleepMs, signal);
|
|
986
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
987
|
+
throw SkytellsClient.abortWaitError();
|
|
988
|
+
}
|
|
989
|
+
if (deadline !== null && Date.now() >= deadline) {
|
|
990
|
+
throw new SkytellsError(`Prediction ${current.id} did not complete within ${maxWaitMs}ms`, 'WAIT_TIMEOUT', `Timed out after ${maxWaitMs}ms. Last status: ${current.status}`, 408);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
firstPoll = false;
|
|
994
|
+
current = await this.predictions.get(current.id, current.urls);
|
|
995
|
+
if (onProgress) {
|
|
996
|
+
onProgress(current);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return current;
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Adds a prediction request to the local queue.
|
|
1003
|
+
*
|
|
1004
|
+
* Queued items are not sent to the API until {@link dispatch} is called.
|
|
1005
|
+
* Useful for batching multiple predictions together.
|
|
1006
|
+
*
|
|
1007
|
+
* @param payload - The prediction request to queue.
|
|
1008
|
+
* @param sdk - Optional SDK options for this item (e.g. `{ compatibilityCheck: true }`), forwarded to {@link PredictionsAPI.create} on {@link dispatch}.
|
|
1009
|
+
*
|
|
1010
|
+
* @example
|
|
1011
|
+
* ```ts
|
|
1012
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
|
|
1013
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
|
|
1014
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Bird" } });
|
|
1015
|
+
*
|
|
1016
|
+
* const results = await client.dispatch();
|
|
1017
|
+
* // results is an array of PredictionResponse for each queued item
|
|
1018
|
+
* ```
|
|
1019
|
+
*/
|
|
1020
|
+
queue(payload, sdk) {
|
|
1021
|
+
this._queue.push({ request: payload, sdk });
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Dispatches all queued predictions, sending them to the API concurrently.
|
|
1025
|
+
*
|
|
1026
|
+
* Clears the queue after dispatching. Each prediction is created in the background
|
|
1027
|
+
* (non-blocking). Use {@link wait} on individual results if you need to wait for completion.
|
|
1028
|
+
*
|
|
1029
|
+
* @returns An array of prediction responses, one for each queued item.
|
|
1030
|
+
* @throws {SkytellsError} Uses **`Promise.all`**: if **any** `predictions.create` rejects, the whole
|
|
1031
|
+
* `dispatch()` rejects with that error (fail-fast). Partial successes are not returned.
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```ts
|
|
1035
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Cat" } });
|
|
1036
|
+
* client.queue({ model: "flux-pro", input: { prompt: "Dog" } });
|
|
1037
|
+
*
|
|
1038
|
+
* const results = await client.dispatch();
|
|
1039
|
+
* for (const pred of results) {
|
|
1040
|
+
* console.log(pred.id, pred.status);
|
|
1041
|
+
* }
|
|
1042
|
+
*
|
|
1043
|
+
* // Wait for all to complete
|
|
1044
|
+
* const completed = await Promise.all(results.map(p => client.wait(p)));
|
|
1045
|
+
* ```
|
|
1046
|
+
*/
|
|
1047
|
+
async dispatch() {
|
|
1048
|
+
const items = this._queue.splice(0);
|
|
1049
|
+
const results = await Promise.all(items.map((item) => this.predictions.create(item.request, item.sdk)));
|
|
1050
|
+
return results;
|
|
11
1051
|
}
|
|
12
1052
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @
|
|
1053
|
+
* Retrieves the streaming endpoint for a prediction.
|
|
1054
|
+
*
|
|
1055
|
+
* @deprecated Use {@link Prediction.stream} on the {@link Prediction} from {@link SkytellsClient.run} instead,
|
|
1056
|
+
* or pass `urls` from a stored `PredictionResponse` when calling without a `Prediction` instance.
|
|
1057
|
+
*
|
|
1058
|
+
* @param id - The prediction ID to stream.
|
|
1059
|
+
* @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.stream` is set, that URL is used.
|
|
1060
|
+
* @returns The prediction response with streaming URL info.
|
|
1061
|
+
* @throws {SkytellsError} If the prediction is not found or streaming is not available.
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* ```ts
|
|
1065
|
+
* const stream = await client.streamPrediction("pred_abc123");
|
|
1066
|
+
* console.log(stream.urls?.stream);
|
|
1067
|
+
* ```
|
|
16
1068
|
*/
|
|
17
|
-
async
|
|
18
|
-
|
|
1069
|
+
async streamPrediction(id, urls) {
|
|
1070
|
+
deprecateSkytellsClientPredictionMethod('streamPrediction');
|
|
1071
|
+
const url = resolvePredictionResourceUrl('stream', id, urls, this.http.getBaseUrl());
|
|
1072
|
+
return this.http.request('GET', url);
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* Cancels a running prediction by its ID.
|
|
1076
|
+
*
|
|
1077
|
+
* @deprecated Use {@link Prediction.cancel} on the {@link Prediction} from {@link SkytellsClient.run} instead.
|
|
1078
|
+
* Only predictions with status `pending`, `starting`, `started`, or `processing` can be cancelled.
|
|
1079
|
+
*
|
|
1080
|
+
* @param id - The prediction ID to cancel.
|
|
1081
|
+
* @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.cancel` is set, that URL is used.
|
|
1082
|
+
* @returns The updated prediction response with `status: 'cancelled'`.
|
|
1083
|
+
* @throws {SkytellsError} If the prediction cannot be cancelled or is not found.
|
|
1084
|
+
*
|
|
1085
|
+
* @example
|
|
1086
|
+
* ```ts
|
|
1087
|
+
* await client.cancelPrediction("pred_abc123");
|
|
1088
|
+
* ```
|
|
1089
|
+
*/
|
|
1090
|
+
async cancelPrediction(id, urls) {
|
|
1091
|
+
deprecateSkytellsClientPredictionMethod('cancelPrediction');
|
|
1092
|
+
const url = resolvePredictionResourceUrl('cancel', id, urls, this.http.getBaseUrl());
|
|
1093
|
+
return this.http.request('POST', url);
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Deletes a prediction and its associated output/assets.
|
|
1097
|
+
*
|
|
1098
|
+
* @deprecated Use {@link Prediction.delete} on the {@link Prediction} from {@link SkytellsClient.run} instead.
|
|
1099
|
+
*
|
|
1100
|
+
* @param id - The prediction ID to delete.
|
|
1101
|
+
* @param urls - Optional `urls` from a prior `PredictionResponse`. When `urls.delete` is set, that URL is used.
|
|
1102
|
+
* @returns The prediction response confirming deletion.
|
|
1103
|
+
* @throws {SkytellsError} If the prediction is not found or the request fails.
|
|
1104
|
+
*
|
|
1105
|
+
* @example
|
|
1106
|
+
* ```ts
|
|
1107
|
+
* await client.deletePrediction("pred_abc123");
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
async deletePrediction(id, urls) {
|
|
1111
|
+
deprecateSkytellsClientPredictionMethod('deletePrediction');
|
|
1112
|
+
const url = resolvePredictionResourceUrl('delete', id, urls, this.http.getBaseUrl());
|
|
1113
|
+
return this.http.request('DELETE', url);
|
|
1114
|
+
}
|
|
1115
|
+
/** Stops {@link wait} polling when `signal` aborts; clears the pending timer so nothing keeps firing. */
|
|
1116
|
+
static abortWaitError() {
|
|
1117
|
+
return new SkytellsError('Wait aborted', 'ABORTED', 'Polling stopped because the AbortSignal was aborted.', 0);
|
|
19
1118
|
}
|
|
20
1119
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @param id The prediction ID
|
|
23
|
-
* @returns A promise that resolves to the prediction response
|
|
1120
|
+
* @param signal - When present and aborted, the promise rejects with `ABORTED` and the timer is cleared.
|
|
24
1121
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
1122
|
+
delay(ms, signal) {
|
|
1123
|
+
const d = Math.max(0, ms);
|
|
1124
|
+
if (!signal) {
|
|
1125
|
+
return new Promise((resolve) => setTimeout(resolve, d));
|
|
1126
|
+
}
|
|
1127
|
+
if (signal.aborted) {
|
|
1128
|
+
return Promise.reject(SkytellsClient.abortWaitError());
|
|
1129
|
+
}
|
|
1130
|
+
return new Promise((resolve, reject) => {
|
|
1131
|
+
let settled = false;
|
|
1132
|
+
const finish = (fn) => {
|
|
1133
|
+
if (settled) {
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
settled = true;
|
|
1137
|
+
clearTimeout(tid);
|
|
1138
|
+
signal.removeEventListener('abort', onAbort);
|
|
1139
|
+
fn();
|
|
1140
|
+
};
|
|
1141
|
+
const onAbort = () => {
|
|
1142
|
+
finish(() => reject(SkytellsClient.abortWaitError()));
|
|
1143
|
+
};
|
|
1144
|
+
signal.addEventListener('abort', onAbort);
|
|
1145
|
+
const tid = setTimeout(() => {
|
|
1146
|
+
finish(() => resolve());
|
|
1147
|
+
}, d);
|
|
1148
|
+
});
|
|
27
1149
|
}
|
|
1150
|
+
// ── Deprecated aliases ──────────────────────────────────────────────
|
|
28
1151
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @returns A promise that resolves to an array of models
|
|
1152
|
+
* @deprecated Use {@link predictions}.list() instead. This method will be removed in a future version.
|
|
31
1153
|
*/
|
|
32
|
-
async
|
|
33
|
-
return this.
|
|
1154
|
+
async listPredictions(page) {
|
|
1155
|
+
return this.predictions.list({ page });
|
|
34
1156
|
}
|
|
35
1157
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @param id The prediction ID
|
|
38
|
-
* @returns A promise that resolves to the prediction response
|
|
1158
|
+
* @deprecated Use {@link models}.list() instead. This method will be removed in a future version.
|
|
39
1159
|
*/
|
|
40
|
-
async
|
|
41
|
-
return this.
|
|
1160
|
+
async listModels(options) {
|
|
1161
|
+
return this.models.list(options);
|
|
42
1162
|
}
|
|
43
1163
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @param id The prediction ID
|
|
46
|
-
* @returns A promise that resolves to the prediction response
|
|
1164
|
+
* @deprecated Use {@link predictions}.get() instead. This method will be removed in a future version.
|
|
47
1165
|
*/
|
|
48
|
-
async
|
|
49
|
-
return this.
|
|
1166
|
+
async getPrediction(id, urls) {
|
|
1167
|
+
return this.predictions.get(id, urls);
|
|
50
1168
|
}
|
|
51
1169
|
/**
|
|
52
|
-
*
|
|
53
|
-
* @param id The prediction ID
|
|
54
|
-
* @returns A promise that resolves to the prediction response
|
|
1170
|
+
* @deprecated Use {@link models}.get() instead. This method will be removed in a future version.
|
|
55
1171
|
*/
|
|
56
|
-
async
|
|
57
|
-
return this.
|
|
1172
|
+
async getModel(slug, options) {
|
|
1173
|
+
return this.models.get(slug, options);
|
|
58
1174
|
}
|
|
59
1175
|
}
|